Code cleanup
This commit is contained in:
368
main.py
368
main.py
@@ -1,24 +1,26 @@
|
||||
#!/usr/bin/env python3
|
||||
import config
|
||||
import subprocess
|
||||
import os
|
||||
import os.path
|
||||
import serial
|
||||
import threading
|
||||
|
||||
import json
|
||||
import bottle
|
||||
from bottle import route, run, request, post
|
||||
import time
|
||||
import sys
|
||||
import logging
|
||||
import math
|
||||
import numpy as np
|
||||
import os
|
||||
import string
|
||||
import subprocess
|
||||
import threading
|
||||
import time
|
||||
from collections import OrderedDict
|
||||
|
||||
import bottle
|
||||
import numpy as np
|
||||
import scipy.misc
|
||||
import serial
|
||||
|
||||
import config
|
||||
|
||||
logging.basicConfig(filename='pixelserver.log', level=config.LogLevel)
|
||||
running = True
|
||||
|
||||
|
||||
########################################################################
|
||||
# Utils #
|
||||
########################################################################
|
||||
@@ -26,42 +28,52 @@ class DataSource:
|
||||
def __init__(self, initial):
|
||||
self.data = initial
|
||||
self.listeners = []
|
||||
|
||||
def getData(self):
|
||||
return self.data
|
||||
|
||||
def addListener(self, listener):
|
||||
self.listeners.append(listener)
|
||||
return self
|
||||
|
||||
def pushData(self, data):
|
||||
self.data = data
|
||||
for listener in self.listeners:
|
||||
with listener:
|
||||
listener.notify_all()
|
||||
|
||||
|
||||
class WatchDog(threading.Thread):
|
||||
def __init__(self, check, action):
|
||||
super().__init__()
|
||||
super().__init__(daemon=True)
|
||||
self.check = check
|
||||
self.action = action
|
||||
self.running = True
|
||||
|
||||
def run(self):
|
||||
while running and self.running:
|
||||
if self.check():
|
||||
logging.error("Watchdog: Executed")
|
||||
self.action()
|
||||
time.sleep(1)
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
|
||||
|
||||
class LogReader(threading.Thread):
|
||||
def __init__(self, runner):
|
||||
super().__init__()
|
||||
super().__init__(daemon=True)
|
||||
self.runner = runner
|
||||
self.log = ""
|
||||
self.running = True
|
||||
|
||||
def clear(self):
|
||||
self.log = ""
|
||||
|
||||
def getLog(self):
|
||||
return self.log
|
||||
|
||||
def run(self):
|
||||
logging.info("LogReader started")
|
||||
while running and self.running:
|
||||
@@ -70,37 +82,44 @@ class LogReader(threading.Thread):
|
||||
except Exception as e:
|
||||
print(e)
|
||||
logging.error(str(e))
|
||||
time.sleep(1)
|
||||
time.sleep(1)
|
||||
logging.info("LogReader closed")
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
|
||||
|
||||
|
||||
class Frame:
|
||||
def __init__(self, buffer, channels=3):
|
||||
self.buffer = buffer
|
||||
self.created = time.time()
|
||||
self.channels = channels
|
||||
|
||||
def clone(self):
|
||||
f = Frame(self.buffer+0, self.channels)
|
||||
f = Frame(self.buffer + 0, self.channels)
|
||||
f.created = self.created
|
||||
return f
|
||||
|
||||
|
||||
########################################################################
|
||||
# GUI #
|
||||
########################################################################
|
||||
if config.UseGui:
|
||||
import pygame
|
||||
|
||||
|
||||
class Gui(threading.Thread):
|
||||
def __init__(self, datasource):
|
||||
super().__init__()
|
||||
super().__init__(daemon=True)
|
||||
self.cv = threading.Condition()
|
||||
self.datasource = datasource.addListener(self.cv)
|
||||
|
||||
def run(self):
|
||||
last_frame = time.time()
|
||||
logging.info("Starting GUI")
|
||||
sf = config.GuiScaleFactor
|
||||
screen = pygame.display.set_mode((sf*config.ScreenX, sf*config.ScreenY))
|
||||
pygame.init()
|
||||
screen = pygame.display.set_mode((sf * config.ScreenX, sf * config.ScreenY))
|
||||
pygame.display.set_caption("Pixelserver - GUI Vis")
|
||||
while running:
|
||||
for event in pygame.event.get():
|
||||
@@ -113,35 +132,38 @@ if config.UseGui:
|
||||
for x in range(config.ScreenX):
|
||||
for y in range(config.ScreenY):
|
||||
color = (frame.buffer[y, x, 0], frame.buffer[y, x, 1], frame.buffer[y, x, 2])
|
||||
pygame.draw.rect(screen, color, pygame.Rect(sf*x, sf*y, sf, sf))
|
||||
pygame.draw.rect(screen, color, pygame.Rect(sf * x, sf * y, sf, sf))
|
||||
elif frame.channels == 4:
|
||||
for x in range(config.ScreenX):
|
||||
for y in range(config.ScreenY):
|
||||
w = frame.buffer[y, x, 3]//2
|
||||
color = (frame.buffer[y, x, 0]//2+w, frame.buffer[y, x, 1]//2+w, frame.buffer[y, x, 2]//2+w)
|
||||
pygame.draw.rect(screen, color, pygame.Rect(sf*x, sf*y, sf, sf))
|
||||
#logging.debug("Time to gui: "+str(time.time()-frame.created))
|
||||
w = frame.buffer[y, x, 3] // 2
|
||||
color = (frame.buffer[y, x, 0] // 2 + w, frame.buffer[y, x, 1] // 2 + w, frame.buffer[y, x, 2] // 2 + w)
|
||||
pygame.draw.rect(screen, color, pygame.Rect(sf * x, sf * y, sf, sf))
|
||||
# logging.debug("Time to gui: " + str(time.time() - frame.created))
|
||||
pygame.display.flip()
|
||||
if time.time() < last_frame+1/config.GuiFPS:
|
||||
time.sleep(time.time()-(last_frame+1/config.GuiFPS))
|
||||
#time.sleep(0.01)
|
||||
if time.time() < last_frame + 1 / config.GuiFPS:
|
||||
time.sleep(max(0.01, time.time() - (last_frame + 1 / config.GuiFPS)))
|
||||
# time.sleep(0.01)
|
||||
last_frame = time.time()
|
||||
|
||||
logging.info("Closing GUI")
|
||||
def join(self):
|
||||
|
||||
def join(self, **kwargs):
|
||||
with self.cv:
|
||||
self.cv.notify_all()
|
||||
super().join()
|
||||
|
||||
|
||||
########################################################################
|
||||
# Serial #
|
||||
########################################################################
|
||||
class SerialWriter(threading.Thread):
|
||||
def __init__(self, datasource):
|
||||
super().__init__()
|
||||
super().__init__(daemon=True)
|
||||
self.cv = threading.Condition()
|
||||
self.datasource = datasource.addListener(self.cv)
|
||||
self.updateGamma = False
|
||||
|
||||
def run(self):
|
||||
should_connect = True
|
||||
ser = None
|
||||
@@ -153,17 +175,17 @@ class SerialWriter(threading.Thread):
|
||||
should_connect = False
|
||||
logging.info("Serial Opened")
|
||||
with self.cv:
|
||||
self.cv.wait(timeout = 1/30)
|
||||
self.cv.wait(timeout=1 / 30)
|
||||
frame = self.datasource.getData()
|
||||
data = frame.buffer.reshape((config.ScreenX*config.ScreenY*frame.channels,)).astype(np.uint8).tobytes()
|
||||
data = frame.buffer.reshape((config.ScreenX * config.ScreenY * frame.channels,)).astype(np.uint8).tobytes()
|
||||
if self.updateGamma:
|
||||
buf = bytearray(b"\x00")*4*256
|
||||
buf = bytearray(b"\x00") * 4 * 256
|
||||
for i in range(256):
|
||||
apply = lambda x, g: max(0, min(255, int(math.pow(x/255, g)*255)))
|
||||
buf[i] = apply(i, self.r)
|
||||
buf[i+256] = apply(i, self.g)
|
||||
buf[i+512] = apply(i, self.b)
|
||||
buf[i+512+256] = apply(i, self.w)
|
||||
apply = lambda x, g: max(0, min(255, int(math.pow(x / 255, g) * 255)))
|
||||
buf[i] = apply(i, self.r)
|
||||
buf[i + 256] = apply(i, self.g)
|
||||
buf[i + 512] = apply(i, self.b)
|
||||
buf[i + 512 + 256] = apply(i, self.w)
|
||||
ser.write(b"\x02")
|
||||
ser.write(buf)
|
||||
self.updateGamma = False
|
||||
@@ -173,36 +195,37 @@ class SerialWriter(threading.Thread):
|
||||
elif frame.channels == 4:
|
||||
ser.write(b"\03")
|
||||
ser.write(data)
|
||||
logging.debug("Time to gui: "+str(time.time()-frame.created))
|
||||
logging.debug("Time to gui: " + str(time.time() - frame.created))
|
||||
ser.flush()
|
||||
except Exception as e:
|
||||
if ser != None:
|
||||
if ser is not None:
|
||||
ser.close()
|
||||
ser = None
|
||||
logging.warning("Serial was close because: "+str(e))
|
||||
logging.warning(f"Serial was close because: {e}")
|
||||
should_connect = True
|
||||
time.sleep(5)
|
||||
logging.info("Closing SerialWriter")
|
||||
def join(self):
|
||||
|
||||
def join(self, **kwargs):
|
||||
with self.cv:
|
||||
self.cv.notify_all()
|
||||
super().join()
|
||||
|
||||
def setGamma(self, r, g, b, w):
|
||||
with self.cv:
|
||||
self.r, self.g, self.b, self.w = r, g, b, w
|
||||
self.r, self.g, self.b, self.w = r, g, b, w
|
||||
self.updateGamma = True
|
||||
self.cv.notify_all()
|
||||
|
||||
|
||||
########################################################################
|
||||
# App #
|
||||
########################################################################
|
||||
class App(threading.Thread):
|
||||
def __init__(self, cmd, param, listener, is_persistent, is_white=False, path="."):
|
||||
super().__init__()
|
||||
#start app
|
||||
if type(cmd) != list:
|
||||
cmd = [cmd,]
|
||||
args = cmd+[str(config.ScreenX), str(config.ScreenY), param]
|
||||
super().__init__(daemon=True)
|
||||
# start app
|
||||
args = cmd + [str(config.ScreenX), str(config.ScreenY), param]
|
||||
self.app = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE, close_fds=True, cwd=path)
|
||||
self.last_update = time.time()
|
||||
self.cv = threading.Condition()
|
||||
@@ -215,20 +238,21 @@ class App(threading.Thread):
|
||||
self.listener = listener
|
||||
self.is_persistent = is_persistent
|
||||
self.is_white = is_white
|
||||
|
||||
def run(self):
|
||||
while running and self.running and self.alive():
|
||||
oshandle = self.app.stdout.fileno()
|
||||
try:
|
||||
bytes = 4 if self.is_white else 3
|
||||
data = os.read(oshandle, config.ScreenX*config.ScreenY*bytes)
|
||||
assert len(data) == config.ScreenX*config.ScreenY*bytes
|
||||
buffer = np.frombuffer(data, dtype=np.uint8, count=config.ScreenX*config.ScreenY*bytes)
|
||||
buffer = buffer.reshape((config.ScreenY, config.ScreenX, bytes))
|
||||
|
||||
frame = Frame(buffer, channels=bytes)
|
||||
channels = 4 if self.is_white else 3
|
||||
data = os.read(oshandle, config.ScreenX * config.ScreenY * channels)
|
||||
assert len(data) == config.ScreenX * config.ScreenY * channels
|
||||
buffer = np.frombuffer(data, dtype=np.uint8, count=config.ScreenX * config.ScreenY * channels)
|
||||
buffer = buffer.reshape((config.ScreenY, config.ScreenX, channels))
|
||||
|
||||
frame = Frame(buffer, channels=channels)
|
||||
self.last_update = time.time()
|
||||
self.datasource.pushData(frame)
|
||||
except Exception as e:
|
||||
except:
|
||||
logging.debug("Exception in App.run")
|
||||
with self.listener:
|
||||
self.listener.notify_all()
|
||||
@@ -238,8 +262,10 @@ class App(threading.Thread):
|
||||
self.logreader.join()
|
||||
self.app.wait()
|
||||
logging.debug("App stopped")
|
||||
|
||||
def alive(self):
|
||||
return self.app.poll() == None
|
||||
return self.app.poll() is None
|
||||
|
||||
def stop(self):
|
||||
self.running = False
|
||||
self.app.kill()
|
||||
@@ -249,20 +275,24 @@ class App(threading.Thread):
|
||||
self.logreader.stop()
|
||||
self.app.wait()
|
||||
logging.debug("App stopped")
|
||||
|
||||
def getLog(self):
|
||||
return self.logreader.getLog()
|
||||
|
||||
def terminateApp(self):
|
||||
logging.error("Terminate app!")
|
||||
self.stop()
|
||||
|
||||
def isAppTimedOut(self):
|
||||
return time.time()-self.last_update > config.NoDataTimeout
|
||||
return time.time() - self.last_update > config.NoDataTimeout
|
||||
|
||||
|
||||
########################################################################
|
||||
# Main #
|
||||
########################################################################
|
||||
class AppRunner(threading.Thread):
|
||||
def __init__(self):
|
||||
super().__init__()
|
||||
super().__init__(daemon=True)
|
||||
self.last_crashlog = ""
|
||||
self.currentApp = -1
|
||||
self.requestedApp = 0
|
||||
@@ -274,137 +304,159 @@ class AppRunner(threading.Thread):
|
||||
self.serial.start()
|
||||
self.persistent_apps = {}
|
||||
self.filters = OrderedDict()
|
||||
#start persistent apps
|
||||
for app, i in zip(config.Apps, range(len(config.Apps))):
|
||||
if app["persistent"]:
|
||||
# start persistent apps
|
||||
for i, app in enumerate(config.Apps):
|
||||
if app.persistent:
|
||||
self.startApp(i)
|
||||
if config.UseGui:
|
||||
self.gui = Gui(self.datasource)
|
||||
self.gui.start()
|
||||
|
||||
def requestApp(self, app, param=""):
|
||||
with self.cv:
|
||||
self.requestedApp = app
|
||||
self.param = param
|
||||
self.cv.notify_all()
|
||||
logging.info("Requesting app: "+str(app))
|
||||
logging.info("Requesting app: " + str(app))
|
||||
|
||||
def startApp(self, i, param=""):
|
||||
app = config.Apps[i]
|
||||
newapp = App(app["cmd"], param, self.cv, is_persistent=app["persistent"], is_white=app["white"], path=app["path"])
|
||||
newapp = App(app.cmd, param, self.cv, is_persistent=app.persistent, is_white=app.white, path=app.path)
|
||||
newapp.datasource.addListener(self.cv)
|
||||
newapp.start()
|
||||
if app["persistent"]:
|
||||
self.persistent_apps[self.currentApp] = newapp
|
||||
if app.persistent:
|
||||
self.persistent_apps[self.currentApp] = newapp
|
||||
return newapp
|
||||
|
||||
def updateApp(self):
|
||||
try:
|
||||
if self.app != None and not self.app.is_persistent:
|
||||
self.app.stop()
|
||||
self.currentApp = self.requestedApp
|
||||
if (self.currentApp in self.persistent_apps.keys()
|
||||
and self.persistent_apps[self.currentApp].alive()):
|
||||
if self.app is not None and not self.app.is_persistent:
|
||||
self.app.stop()
|
||||
self.currentApp = self.requestedApp
|
||||
if self.currentApp in self.persistent_apps.keys() and self.persistent_apps[self.currentApp].alive():
|
||||
self.app = self.persistent_apps[self.currentApp]
|
||||
else:
|
||||
self.app = self.startApp(self.requestedApp, self.param)
|
||||
else:
|
||||
self.app = self.startApp(self.requestedApp, self.param)
|
||||
except FileNotFoundError as e:
|
||||
print(e)
|
||||
print(e)
|
||||
|
||||
def run(self):
|
||||
logging.info("Starting Apprunner")
|
||||
while running:
|
||||
with self.cv:
|
||||
if self.app == None or not self.app.alive():
|
||||
if self.app != None:
|
||||
if self.app is None or not self.app.alive():
|
||||
if self.app is not None:
|
||||
self.last_crashlog = self.app.getLog()
|
||||
self.requestedApp = 0
|
||||
if self.requestedApp != None:
|
||||
self.requestedApp = 0
|
||||
if self.requestedApp is not None:
|
||||
self.updateApp()
|
||||
self.requestedApp = None
|
||||
frame = self.app.datasource.getData().clone()
|
||||
#logging.debug("Runner in time: "+str(time.time()-frame.created))
|
||||
for _, f in self.filters.items():
|
||||
frame.buffer = f(frame.buffer)
|
||||
#logging.debug("Runner out time: "+str(time.time()-frame.created))
|
||||
self.datasource.pushData(frame)
|
||||
|
||||
if self.app is not None:
|
||||
frame = self.app.datasource.getData().clone()
|
||||
# logging.debug("Runner in time: " + str(time.time() - frame.created))
|
||||
for _, f in self.filters.items():
|
||||
frame.buffer = f(frame.buffer)
|
||||
# logging.debug("Runner out time: " + str(time.time() - frame.created))
|
||||
self.datasource.pushData(frame)
|
||||
self.cv.wait()
|
||||
self.serial.join()
|
||||
if config.UseGui:
|
||||
self.gui.join()
|
||||
logging.info("Close Apprunner")
|
||||
|
||||
def getLog(self):
|
||||
if self.app == None:
|
||||
if self.app is None:
|
||||
return ""
|
||||
return self.app.getLog()
|
||||
|
||||
def setGamma(self, r, g, b, w):
|
||||
self.serial.setGamma(r, g, b, w)
|
||||
|
||||
def setFilter(self, name, filter):
|
||||
self.filters[name] = filter
|
||||
|
||||
def removeFilter(self, name):
|
||||
if name in self.filters.keys():
|
||||
del self.filters[name]
|
||||
|
||||
|
||||
########################################################################
|
||||
# Filter Api #
|
||||
########################################################################
|
||||
def MakeBrightnessFilter(intensity):
|
||||
def filter(img):
|
||||
return (img*intensity).astype(np.uint8)
|
||||
return (img * intensity).astype(np.uint8)
|
||||
|
||||
return filter
|
||||
|
||||
|
||||
def FlipXFilter(intensity):
|
||||
return intensity[:,::-1,:]
|
||||
return intensity[:, ::-1, :]
|
||||
|
||||
|
||||
def FlipYFilter(intensity):
|
||||
return intensity[::-1,:,:]
|
||||
return intensity[::-1, :, :]
|
||||
|
||||
|
||||
def MakeBrightnessImageFilter(name):
|
||||
img = scipy.misc.imread("filter/"+name+".png", flatten=True)/255
|
||||
#img = np.transpose(img)
|
||||
img = scipy.misc.imread("filter/" + name + ".png", flatten=True) / 255
|
||||
|
||||
# img = np.transpose(img)
|
||||
def filter(intensity):
|
||||
intensity = intensity.astype(float)
|
||||
for i in range(intensity.shape[2]):
|
||||
intensity[:,:,i] *= img
|
||||
intensity[:, :, i] *= img
|
||||
return intensity.astype(np.uint8)
|
||||
|
||||
return filter
|
||||
|
||||
def strings(str):
|
||||
allowed_chars = string.ascii_letters+string.digits+"+-*/()."
|
||||
|
||||
def strings(s):
|
||||
allowed_chars = string.ascii_letters + string.digits + "+-*/()."
|
||||
i = 0
|
||||
outlist = []
|
||||
while i != len(str):
|
||||
if str[i] not in allowed_chars:
|
||||
raise Exception("Unexpected char "+str[i])
|
||||
if str[i] not in string.ascii_letters:
|
||||
i+=1
|
||||
while i != len(s):
|
||||
if s[i] not in allowed_chars:
|
||||
raise Exception("Unexpected char " + s[i])
|
||||
if s[i] not in string.ascii_letters:
|
||||
i += 1
|
||||
continue
|
||||
out = ""
|
||||
while i != len(str) and str[i] in string.ascii_letters+string.digits:
|
||||
out += str[i]
|
||||
i+=1
|
||||
while i != len(s) and s[i] in string.ascii_letters + string.digits:
|
||||
out += s[i]
|
||||
i += 1
|
||||
outlist.append(out)
|
||||
return outlist
|
||||
|
||||
|
||||
def eval_safer(expr, x, y, t):
|
||||
symbols = {"x": x, "y": y, "t": t,
|
||||
symbols = {"x": x, "y": y, "t": t,
|
||||
"sin": np.sin, "cos": np.cos, "exp": np.exp, "tan": np.tan}
|
||||
strs = strings(expr)
|
||||
for s in strs:
|
||||
if s not in symbols.keys():
|
||||
raise Exception("unexpected symbol: "+s)
|
||||
raise Exception("unexpected symbol: " + s)
|
||||
return eval(expr, {}, symbols)
|
||||
|
||||
|
||||
|
||||
def MakeBrightnessExprFilter(expr):
|
||||
t0 = time.time()
|
||||
x, y = np.meshgrid(np.arange(config.ScreenX), np.arange(config.ScreenY))
|
||||
eval_safer(expr, 0, 0, 0)
|
||||
|
||||
def filter(intensity):
|
||||
t = time.time()-t0
|
||||
t = time.time() - t0
|
||||
intensity = intensity.astype(float)
|
||||
filter = 0*x+eval_safer(expr, x, y, t)
|
||||
filter = 0 * x + eval_safer(expr, x, y, t)
|
||||
filter = np.clip(np.nan_to_num(filter), 0, 1)
|
||||
for i in range(intensity.shape[2]):
|
||||
intensity[:,:,i] *= filter
|
||||
intensity[:, :, i] *= filter
|
||||
return intensity.astype(np.uint8)
|
||||
|
||||
return filter
|
||||
|
||||
|
||||
########################################################################
|
||||
# Web Api #
|
||||
########################################################################
|
||||
@@ -412,63 +464,74 @@ def MakeBrightnessExprFilter(expr):
|
||||
def enable_cors_generic_route():
|
||||
add_cors_headers()
|
||||
|
||||
|
||||
@bottle.hook('after_request')
|
||||
def enable_cors_after_request_hook():
|
||||
add_cors_headers()
|
||||
|
||||
|
||||
def add_cors_headers():
|
||||
bottle.response.headers['Access-Control-Allow-Origin'] = '*'
|
||||
bottle.response.headers['Access-Control-Allow-Methods'] = \
|
||||
'GET, POST, PUT, OPTIONS'
|
||||
bottle.response.headers['Access-Control-Allow-Headers'] = \
|
||||
'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
|
||||
bottle.response.headers['Access-Control-Allow-Methods'] = 'GET, POST, PUT, OPTIONS'
|
||||
bottle.response.headers['Access-Control-Allow-Headers'] = 'Origin, Accept, Content-Type, X-Requested-With, X-CSRF-Token'
|
||||
|
||||
|
||||
def startApp(name, param=""):
|
||||
for i in range(len(config.Apps)):
|
||||
if config.Apps[i]["name"] == name:
|
||||
for i, app in enumerate(config.Apps):
|
||||
if app.name == name:
|
||||
runner.requestApp(i, param)
|
||||
return "ok"
|
||||
return "not_found"
|
||||
|
||||
@route("/apps/list")
|
||||
|
||||
@bottle.route("/apps/list")
|
||||
def apps_list():
|
||||
s = []
|
||||
for app in config.Apps:
|
||||
s.append({"name": app["name"],
|
||||
"guiname": app["guiname"],
|
||||
"persistent": app["persistent"]})
|
||||
return json.dumps(s)
|
||||
|
||||
@route("/apps/start/<name>")
|
||||
return json.dumps([
|
||||
{
|
||||
"name": app.name,
|
||||
"guiname": app.guiname,
|
||||
"persistent": app.persistent,
|
||||
} for app in config.Apps
|
||||
])
|
||||
|
||||
|
||||
@bottle.route("/apps/start/<name>")
|
||||
def apps_start_param(name):
|
||||
return startApp(name)
|
||||
|
||||
@post("/apps/start/<name>")
|
||||
|
||||
@bottle.post("/apps/start/<name>")
|
||||
def apps_start_post(name):
|
||||
param = request.forms.get('param')
|
||||
param = bottle.request.forms.get('param')
|
||||
return startApp(name, param)
|
||||
|
||||
@route("/apps/start/<name>/<param>")
|
||||
|
||||
|
||||
@bottle.route("/apps/start/<name>/<param>")
|
||||
def apps_start(name, param):
|
||||
return startApp(name, param)
|
||||
|
||||
@route("/apps/log")
|
||||
|
||||
@bottle.route("/apps/log")
|
||||
def apps_log():
|
||||
return runner.getLog()
|
||||
|
||||
@route("/apps/crashlog")
|
||||
|
||||
@bottle.route("/apps/crashlog")
|
||||
def apps_log():
|
||||
return runner.last_crashlog
|
||||
|
||||
@route("/apps/running")
|
||||
def apps_running():
|
||||
return config.Apps[runner.currentApp]["name"]
|
||||
|
||||
@route("/")
|
||||
@bottle.route("/apps/running")
|
||||
def apps_running():
|
||||
return config.Apps[runner.currentApp].name
|
||||
|
||||
|
||||
@bottle.route("/")
|
||||
def index():
|
||||
return bottle.static_file("index.html", root='html')
|
||||
|
||||
@route("/setgamma/<r>/<g>/<b>/<w>")
|
||||
|
||||
@bottle.route("/setgamma/<r>/<g>/<b>/<w>")
|
||||
def setGamma(r, g, b, w):
|
||||
r = float(r)
|
||||
g = float(g)
|
||||
@@ -477,15 +540,17 @@ def setGamma(r, g, b, w):
|
||||
runner.setGamma(r, g, b, w)
|
||||
return "ok"
|
||||
|
||||
@route("/setbrightness/<i>")
|
||||
|
||||
@bottle.route("/setbrightness/<i>")
|
||||
def setIntensity(i):
|
||||
i = float(i)
|
||||
if i < 0 or i > 1:
|
||||
if not 0 <= i <= 1:
|
||||
return "bad_value"
|
||||
runner.setFilter("0_intensity", MakeBrightnessFilter(i))
|
||||
return "ok"
|
||||
|
||||
@route("/filter/flipx/<do>")
|
||||
|
||||
@bottle.route("/filter/flipx/<do>")
|
||||
def flipx(do):
|
||||
if do == "true":
|
||||
runner.setFilter("1_flipx", FlipXFilter)
|
||||
@@ -493,7 +558,8 @@ def flipx(do):
|
||||
runner.removeFilter("1_flipx")
|
||||
return "ok"
|
||||
|
||||
@route("/filter/flipy/<do>")
|
||||
|
||||
@bottle.route("/filter/flipy/<do>")
|
||||
def flipy(do):
|
||||
if do == "true":
|
||||
runner.setFilter("1_flipy", FlipYFilter)
|
||||
@@ -501,48 +567,34 @@ def flipy(do):
|
||||
runner.removeFilter("1_flipy")
|
||||
return "ok"
|
||||
|
||||
@route("/filter/img/<name>")
|
||||
|
||||
@bottle.route("/filter/img/<name>")
|
||||
def setfilter(name):
|
||||
if name == "none":
|
||||
runner.removeFilter("3_imgfilter")
|
||||
else:
|
||||
runner.setFilter("3_imgfilter", MakeBrightnessImageFilter(name))
|
||||
return "ok"
|
||||
@post("/filter/expr/")
|
||||
|
||||
|
||||
@bottle.post("/filter/expr/")
|
||||
def filter_expr():
|
||||
expr = request.forms.get('expr')
|
||||
expr = bottle.request.forms.get('expr')
|
||||
if expr == "" or expr == "none":
|
||||
runner.removeFilter("5_brightnessfunction")
|
||||
else:
|
||||
runner.setFilter("5_brightnessfunction", MakeBrightnessExprFilter(expr))
|
||||
return "ok"
|
||||
|
||||
|
||||
|
||||
########################################################################
|
||||
# Startup #
|
||||
########################################################################
|
||||
#normalize config
|
||||
for app in config.Apps:
|
||||
if "persistent" not in app.keys():
|
||||
app["persistent"] = False
|
||||
if "guiname" not in app.keys():
|
||||
app["guiname"] = app["name"]
|
||||
if "white" not in app.keys():
|
||||
app["white"] = False
|
||||
if "path" not in app.keys():
|
||||
app["path"] = "."
|
||||
cmd = app["cmd"]
|
||||
#remove non existing apps
|
||||
#if type(cmd) == str and not os.path.isfile(cmd):
|
||||
#config.Apps.remove(app)
|
||||
#logging.warning("Removed app "+app["name"])
|
||||
|
||||
|
||||
runner = AppRunner()
|
||||
runner.start()
|
||||
|
||||
#runner.setFilter("5_crazy", MakeBrightnessExprFilter("0.5+0.25*sin(x/3)/x"))
|
||||
run(host=config.WebHost, port=config.WebPort)
|
||||
# runner.setFilter("5_crazy", MakeBrightnessExprFilter("0.5+0.25*sin(x/3)/x"))
|
||||
bottle.run(host=config.WebHost, port=config.WebPort)
|
||||
|
||||
########################################################################
|
||||
# Shutdown #
|
||||
|
Reference in New Issue
Block a user