diff --git a/notiframe/.vscode/settings.json b/notiframe/.vscode/settings.json new file mode 100644 index 0000000..6805dff --- /dev/null +++ b/notiframe/.vscode/settings.json @@ -0,0 +1,5 @@ +{ + "python.linting.pylintEnabled": true, + "python.linting.enabled": true, + "python.pythonPath": "/usr/bin/python2" +} \ No newline at end of file diff --git a/notiframe/NotiFrame.py b/notiframe/NotiFrame.py deleted file mode 100755 index f2246b7..0000000 --- a/notiframe/NotiFrame.py +++ /dev/null @@ -1,113 +0,0 @@ -from PIL import Image, ImageDraw, ImageFont, ImageOps -import re -import time -import widgets.widget as widget -import argparse -import os -import toml -try: - import drivers.epd7in5b - testMode = False -except: - testMode = True - -mydir = os.path.dirname(os.path.abspath(__file__)) - -parser = argparse.ArgumentParser(description="NotiFrame display") -parser.add_argument('-t', '--test', help='enable test mode', action='store_true') -args = parser.parse_args() -if args.test: - testMode = True - -print("RUNNING IN TESTMODE: "+str(testMode)) - -if not testMode: - epd = epd7in5b.EPD() - epd.init() - -def convert(input): - if isinstance(input, dict): - return dict((convert(key), convert(value)) for key, value in input.iteritems()) - elif isinstance(input, list): - return [convert(element) for element in input] - elif isinstance(input, unicode): - return input.encode('utf-8') - else: - return input - -uni_config = toml.load(os.path.join(mydir, 'config.toml')) -config = convert(uni_config) - -config2 = {'resWidth': 640, 'resHeight': 384, 'cellsWidth': 3, 'cellsHeight': 3, 'widgets': [ -{'type': 'image', 'posX': 0, 'posY': 0, 'width': 3, 'height': 3, 'bwStyle': 'mono', 'scaleMode': 'fill', 'filename': 'forest.jpg'}, -{'type': 'trello', 'posX': 0, 'posY': 0, 'width': 1, 'height': 3, 'board': 'Organisation', 'list': 'Plans'}, -{'type': 'trello', 'posX': 1, 'posY': 0, 'width': 2, 'height': 3, 'board': 'E-paper', 'list': 'To Do:'} -]} - -#print(toml.dumps(config)) -#print(config) -#print(config2) - -cwidth = int(round(int(config['resWidth'])/int(config['cellsWidth']))) -cheight = int(round(int(config['resHeight'])/int(config['cellsHeight']))) - -image_yellow = Image.new('1', (config['resWidth'], config['resHeight']), 255) # 255: clear the frame -draw_yellow = ImageDraw.Draw(image_yellow) -image_black = Image.new('1', (config['resWidth'], config['resHeight']), 255) # 255: clear the frame -draw_black = ImageDraw.Draw(image_black) - -#str1 = open("text.txt", "r").read() -#str2 = open("text.txt", "r").read() -#str3 = open("text.txt", "r").read() -#strList = [] -#strList.append(str1) -#strList.append(str2) -#strList.append(str3) - -def initWidgets(): - widgetList = [] - for widg_conf in config['widgets']: - if widg_conf['type'] == 'image': - widgetList.append(widget.ImageWidget(cwidth, cheight, (widg_conf['posX'], widg_conf['posY']), - (widg_conf['width'], widg_conf['height']), widg_conf['bwStyle'], widg_conf['scaleMode'], - os.path.join(mydir, os.path.join('widgets/resources/images/', widg_conf['filename'])))) - if widg_conf['type'] == 'trello': - widgetList.append(widget.TrelloWidget(cwidth, cheight, (widg_conf['posX'], widg_conf['posY']), - (widg_conf['width'], widg_conf['height']), widg_conf['board'], widg_conf['list'])) - - #widgetList.append(widget.ImageWidget(cwidth, cheight, (0, 0), (3, 3), "mono", "fill", os.path.join(mydir, os.path.join('widgets/resources/images/', 'forest.jpg')))) - #widgetList.append(widget.TrelloWidget(cwidth, cheight, (0, 0), (1, 3), "Organisation", "Plans")) - #widgetList.append(widget.TrelloWidget(cwidth, cheight, (1, 0), (2, 3), "E-paper", "Done")) - #widgetList.append(widget.ImageWidget(cwidth, cheight, (1, 2), (2, 1), "mono", "fill", "forest.jpg")) - #widgetList.append(widget.TextWidget(cwidth, cheight, (0, 0), (1, 3), str2)) - #widgetList.append(widget.TextWidget(cwidth, cheight, (0, 0), (2, 3), str1)) - #widgetList.append(widget.ImageWidget(cwidth, cheight, (1, 0), (1, 3), "mono", "fill", "g.jpg")) - return widgetList - -def drawWidget(w): - coordX = w.cellX*cwidth - coordY = w.cellY*cheight - image_black.paste(im=w.image_black, mask=w.mask_black, box=(coordX, coordY)) - image_yellow.paste(w.image_yellow, (coordX, coordY)) - -def render(index): - if index is not 0: - for widg in widgetList: - widg.updateWidget() - draw_black.rectangle(xy=((0,0), image_black.size), fill=255) - draw_yellow.rectangle(xy=((0,0), image_yellow.size), fill=255) - for widg in widgetList: - drawWidget(widg) - if not testMode: - epd.display_frame(epd.get_frame_buffer(image_black),epd.get_frame_buffer(image_yellow)) - else: - image_black.save(os.path.join(mydir, 'test/imgBlack.bmp')) - image_yellow.save(os.path.join(mydir, 'test/imgYellow.bmp')) - -widgetList = initWidgets() -i = 0 -while(True): - print("RENDERING "+str(i)) - render(i) - i = (i + 1) - #time.sleep(10) diff --git a/notiframe/fetcher/Fetcher.py b/notiframe/fetcher/Fetcher.py new file mode 100644 index 0000000..8ed329d --- /dev/null +++ b/notiframe/fetcher/Fetcher.py @@ -0,0 +1,54 @@ +from PIL import Image, ImageDraw, ImageFont, ImageOps +import re +import time +#import widgets.widget as widget +import argparse +import os +import toml + +import requests +from io import BytesIO + +try: + import drivers.epd7in5b + testMode = False +except: + testMode = True + +canvas_url_black = 'http://0.0.0.0:5000/display' + +mydir = os.path.dirname(os.path.abspath(__file__)) + +parser = argparse.ArgumentParser(description="NotiFrame display") +parser.add_argument('-t', '--test', help='enable test mode', action='store_true') +args = parser.parse_args() +if args.test: + testMode = True + +print("RUNNING IN TESTMODE: "+str(testMode)) +if not testMode: + epd = drivers.epd7in5b.EPD() + epd.init() + +def render(index): + while(True): + print("requesting display image") + try: + blk = requests.get(canvas_url_black) + #ylw = requests.get(urlylw) + image_black = Image.open(BytesIO(blk.content)) + image_yellow = None + #image_yellow = Image.open(BytesIO(ylw.content)) + #draw_black.rectangle(xy=((0,0), image_black.size), fill=255) + #draw_yellow.rectangle(xy=((0,0), image_yellow.size), fill=255) + if not testMode: + epd.display_frame(epd.get_frame_buffer(image_black.rotate(180)),epd.get_frame_buffer(image_yellow.rotate(180))) + else: + image_black.save(os.path.join(mydir, 'test/imgBlackDisplayClient.bmp')) + #image_yellow.save(os.path.join(mydir, 'test/imgYellow.bmp')) + except: + print("failed to load display image") + i =+ 1 + time.sleep(20) +i = 0 +render(i) \ No newline at end of file diff --git a/notiframe/drivers/__init__.py b/notiframe/fetcher/drivers/__init__.py similarity index 100% rename from notiframe/drivers/__init__.py rename to notiframe/fetcher/drivers/__init__.py diff --git a/notiframe/drivers/epd7in5b.py b/notiframe/fetcher/drivers/epd7in5b.py similarity index 96% rename from notiframe/drivers/epd7in5b.py rename to notiframe/fetcher/drivers/epd7in5b.py index b275fde..94d249a 100755 --- a/notiframe/drivers/epd7in5b.py +++ b/notiframe/fetcher/drivers/epd7in5b.py @@ -25,7 +25,7 @@ # import epdif -import Image +from PIL import Image import RPi.GPIO as GPIO # Display resolution @@ -142,7 +142,7 @@ class EPD: self.digital_write(self.reset_pin, GPIO.LOW) # module reset self.delay_ms(200) self.digital_write(self.reset_pin, GPIO.HIGH) - self.delay_ms(200) + self.delay_ms(200) def get_frame_buffer(self, image): buf = [0xFF] * (self.width * self.height / 8) @@ -175,7 +175,7 @@ class EPD: temp3 = 0x00 #black else: temp3 = 0x03 #white - + temp3 = (temp3 << 4) & 0xFF temp1 = (temp1 << 1) & 0xFF temp2 = (temp2 << 1) & 0xFF @@ -201,4 +201,3 @@ class EPD: self.send_data(0xa5) ### END OF FILE ### - diff --git a/notiframe/drivers/epdif.py b/notiframe/fetcher/drivers/epdif.py similarity index 100% rename from notiframe/drivers/epdif.py rename to notiframe/fetcher/drivers/epdif.py diff --git a/notiframe/fetcher/test/imgBlackDisplayClient.bmp b/notiframe/fetcher/test/imgBlackDisplayClient.bmp new file mode 100644 index 0000000..4419d99 Binary files /dev/null and b/notiframe/fetcher/test/imgBlackDisplayClient.bmp differ diff --git a/notiframe/test/card_image.bmp b/notiframe/test/card_image.bmp deleted file mode 100755 index 931fa42..0000000 Binary files a/notiframe/test/card_image.bmp and /dev/null differ diff --git a/notiframe/test/imgBlack.bmp b/notiframe/test/imgBlack.bmp deleted file mode 100644 index fe5d3d9..0000000 Binary files a/notiframe/test/imgBlack.bmp and /dev/null differ diff --git a/notiframe/test/mask.bmp b/notiframe/test/mask.bmp deleted file mode 100755 index fbe8a88..0000000 Binary files a/notiframe/test/mask.bmp and /dev/null differ diff --git a/notiframe/webserver/Notiframe.py b/notiframe/webserver/Notiframe.py new file mode 100644 index 0000000..6fe70aa --- /dev/null +++ b/notiframe/webserver/Notiframe.py @@ -0,0 +1,239 @@ +from flask import Flask, render_template, request, redirect, url_for, send_file +import toml +import os + +from PIL import Image, ImageDraw, ImageFont, ImageOps +import re +import time +import widgets.widget as widget +import argparse + +app = Flask(__name__) + +mydir = os.path.dirname(os.path.abspath(__file__)) +# print(mydir) +###mydir = os.path.join(mydir, '../') +# print(mydir) + +def convert(input): + if isinstance(input, dict): + return dict((convert(key), convert(value)) for key, value in input.iteritems()) + elif isinstance(input, list): + return [convert(element) for element in input] + elif isinstance(input, unicode): + return input.encode('utf-8') + else: + return input + +#################################################### +#################################################### +#################################################### + +uni_config = toml.load(os.path.join(mydir, 'config.toml')) +config = convert(uni_config) + +config2 = {'resWidth': 640, 'resHeight': 384, 'cellsWidth': 3, 'cellsHeight': 3, 'widgets': [ +{'type': 'image', 'posX': 0, 'posY': 0, 'width': 3, 'height': 3, 'bwStyle': 'mono', 'scaleMode': 'fill', 'filename': 'forest.jpg'}, +{'type': 'trello', 'posX': 0, 'posY': 0, 'width': 1, 'height': 3, 'board': 'Organisation', 'list': 'Plans'}, +{'type': 'trello', 'posX': 1, 'posY': 0, 'width': 2, 'height': 3, 'board': 'E-paper', 'list': 'To Do:'} +]} + +cwidth = int(round(int(config['resWidth'])/int(config['cellsWidth']))) +cheight = int(round(int(config['resHeight'])/int(config['cellsHeight']))) + +image_yellow = Image.new('1', (config['resWidth'], config['resHeight']), 255) # 255: clear the frame +draw_yellow = ImageDraw.Draw(image_yellow) +image_black = Image.new('1', (config['resWidth'], config['resHeight']), 255) # 255: clear the frame +draw_black = ImageDraw.Draw(image_black) + +#################################################### +#################################################### +#################################################### + +# HOMEPAGE +@app.route('/home', methods=['GET', 'POST']) +def home(): # Toml config passed to html page via two dicts. + # Form data passed back to webserver as JSON. + config = read_config() + widgLists, sysList = prep_dict_for_web(config) + + if request.method == 'POST': + jsonData = request.get_json() + print(jsonData) + jsonData = convert(jsonData) + + # update system variables + for key in sysList: + print("%" + jsonData[key] + "$") + if jsonData[key]: + if isInt(jsonData[key]): + #print(request.form[key] + " is int") + sysList[key] = int(jsonData[key]) + else: + sysList[key] = jsonData[key] + # update widget variables + # for i in range(len(widgLists)): + # for key in widgLists[i]: + # if request.form[key+str(i)]: + # widgLists[i][key] = request.form[key+str(i)] + for i in range(len(widgLists)): + for key in widgLists[i]: + # print(request.form[key+str(i)]) + if jsonData[key + str(i)]: + if isInt(jsonData[key + str(i)]): + #print(request.form[key+str(i)] + " is int") + widgLists[i][key] = int(jsonData[key + str(i)]) + else: + widgLists[i][key] = jsonData[key + str(i)] + + update_config(widgLists, sysList) + + widgTypes = widgetTypes() + + return render_template('home.html', title='Overview', widgLists=widgLists, sysList=sysList, widgTypes=widgTypes) + +@app.route('/newWidget', methods=['GET', 'POST']) +def newWidget(): # + #if request.method == 'GET': + widgType = request.args['type'] + conf_defaults = pull_default_conf(widgType) + #import pdb; pdb.set_trace() + if request.method == 'POST': + #widgType = request.form['ty'] + jsonData = request.get_json() + print(jsonData) + jsonData = convert(jsonData) + + return render_template('newWidget.html', title='Overview', conf_defaults=conf_defaults) + + +@app.route('/display', methods=['GET', 'POST']) +def display(): + location = 'test/imgBlack.bmp' + updateWidgets() + return send_file(location) + + +def pull_default_conf(widgType=None): + uni_config = toml.load(os.path.join(mydir, 'config.toml')) + config = convert(uni_config) + + conf_dict = { + 'trello': { + 'board': {'default': '', 'datatype': 'text'}, + 'list': {'default': '', 'datatype': 'text'}, + 'width': {'default': 1, 'datatype': 'number', 'min': 1, 'max': config['cellsWidth']}, + 'height': {'default': 1, 'datatype': 'number', 'min': 1, 'max': config['cellsHeight']}, + 'posX': {'default': 0, 'datatype': 'number', 'min': 0, 'max': config['cellsWidth']-1}, + 'posY': {'default': 0, 'datatype': 'number', 'min': 0, 'max': config['cellsHeight']-1} + }, + 'text': { + 'text': {'default': 'abcdefghijklmnopqrstuvwxyz', 'datatype': 'text'}, + 'width': {'default': 1, 'datatype': 'number', 'min': 1, 'max': config['cellsWidth']}, + 'height': {'default': 1, 'datatype': 'number', 'min': 1, 'max': config['cellsHeight']}, + 'posX': {'default': 0, 'datatype': 'number', 'min': 0, 'max': config['cellsWidth']-1}, + 'posY': {'default': 0, 'datatype': 'number', 'min': 0, 'max': config['cellsHeight']-1} + }, + 'image': { + 'file': {'default': 'img.jpg', 'datatype': 'text'}, + 'bwMode': {'default': 'mono', 'datatype': 'text'}, + 'scaleMode': {'default': 'fill', 'datatype': 'text'}, + 'width': {'default': 1, 'datatype': 'number', 'min': 1, 'max': config['cellsWidth']}, + 'height': {'default': 1, 'datatype': 'number', 'min': 1, 'max': config['cellsHeight']}, + 'posX': {'default': 0, 'datatype': 'number', 'min': 0, 'max': config['cellsWidth']-1}, + 'posY': {'default': 0, 'datatype': 'number', 'min': 0, 'max': config['cellsHeight']-1} + } + } + + if widgType != None: + conf_dict = conf_dict.get(widgType) + + return conf_dict + +def widgetTypes(): + dflt_conf = pull_default_conf() + widgTypes = [] + for key in dflt_conf.keys(): + widgTypes.append(key) + return widgTypes + +def isInt(s): + try: + int(s) + return True + except ValueError: + return False + + +def prep_dict_for_web(config): + widgLists = config['widgets'] # list of dicts + sysList = {} # dict + for key in config: + if key != 'widgets': + sysList[key] = config[key] + return widgLists, sysList + + +def read_config(): + uni_config = toml.load(os.path.join(mydir, 'config.toml')) + config = convert(uni_config) + # print(config) + # config = {'widgets': [ + #{'width': 3, 'posX': 0, 'posY': 0, 'scaleMode': 'fill', 'bwStyle': 'mono', 'type': 'image', 'filename': 'forest.jpg', 'height': 3}, + #{'list': 'Plans', 'height': 3, 'width': 1, 'board': 'Organisation', 'posX': 0, 'posY': 0, 'type': 'trello'}, + #{'list': 'To Do:', 'height': 3, 'width': 2, 'board': 'E-paper', 'posX': 1, 'posY': 0, 'type': 'trello'} + # ], 'cellsHeight': 3, 'resHeight': 384, 'resWidth': 640, 'cellsWidth': 3} + return config + + +def update_config(widgLists, sysList): + config = {'widgets': widgLists} + for key in sysList: + config[key] = sysList[key] + convert(config) + path = os.path.join(mydir, 'config.toml') + with open(path, "w+") as config_file: + config_file.write(toml.dumps(config)) + +#################################################### +#################################################### +#################################################### + +def initWidgets(): + widgetList = [] + for widg_conf in config['widgets']: + if widg_conf['type'] == 'image': + widgetList.append(widget.ImageWidget(cwidth, cheight, (widg_conf['posX'], widg_conf['posY']), + (widg_conf['width'], widg_conf['height']), widg_conf['bwStyle'], widg_conf['scaleMode'], + os.path.join(mydir, os.path.join('widgets/resources/images/', widg_conf['filename'])))) + if widg_conf['type'] == 'trello': + widgetList.append(widget.TrelloWidget(cwidth, cheight, (widg_conf['posX'], widg_conf['posY']), + (widg_conf['width'], widg_conf['height']), widg_conf['board'], widg_conf['list'])) + return widgetList + +def drawWidget(w): + coordX = w.cellX*cwidth + coordY = w.cellY*cheight + image_black.paste(im=w.image_black, mask=w.mask_black, box=(coordX, coordY)) + image_yellow.paste(w.image_yellow, (coordX, coordY)) + +def updateWidgets(): + for widg in widgetList: + print(" updating trello widget") + widg.updateWidget() + print("") + draw_black.rectangle(xy=((0,0), image_black.size), fill=255) + draw_yellow.rectangle(xy=((0,0), image_yellow.size), fill=255) + for widg in widgetList: + drawWidget(widg) + image_black.save(os.path.join(mydir, 'test/imgBlack.bmp')) + image_yellow.save(os.path.join(mydir, 'test/imgYellow.bmp')) + +widgetList = initWidgets() + +#################################################### +#################################################### +#################################################### + +if __name__ == '__main__': + app.run(debug=True, host='0.0.0.0') diff --git a/notiframe/config.toml b/notiframe/webserver/config.toml similarity index 73% rename from notiframe/config.toml rename to notiframe/webserver/config.toml index ee9157b..ae65947 100755 --- a/notiframe/config.toml +++ b/notiframe/webserver/config.toml @@ -22,20 +22,11 @@ posY = 0 type = "trello" [[widgets]] -list = "To Do:" -height = 2 +list = "Active:" +height = 3 width = 2 board = "E-paper" posX = 1 posY = 0 type = "trello" -[[widgets]] -list = "Tasks" -height = 1 -width = 2 -board = "Organisation" -posX = 1 -posY = 2 -type = "trello" - diff --git a/notiframe/webserver/templates/home.html b/notiframe/webserver/templates/home.html index ebe47db..d4e672f 100644 --- a/notiframe/webserver/templates/home.html +++ b/notiframe/webserver/templates/home.html @@ -8,6 +8,8 @@
+ +

EDIT EXISTING CONFIG

{% for n in range(widgLists| length) %}

Widget {{n}}

@@ -27,9 +29,22 @@
+ +

ADD NEW WIDGET

+
+

New Widget

+ Type: + +
+
+ + \ No newline at end of file diff --git a/notiframe/webserver/templates/newWidget.html b/notiframe/webserver/templates/newWidget.html new file mode 100644 index 0000000..e3c3721 --- /dev/null +++ b/notiframe/webserver/templates/newWidget.html @@ -0,0 +1,87 @@ + + + + + + + + + + + + +
+ + +

SPECIFY NEW CONFIG DETAILS

+
+ {% for key, value in conf_defaults.iteritems() %} + {{key}}: + {% if value['datatype'] == 'text' %} + + {% endif %} + {% if value['datatype'] == 'number' %} + + {% endif %} +
+
+ {% endfor %} + +
+ +
+ + + + + + diff --git a/notiframe/webserver/test/card_image.bmp b/notiframe/webserver/test/card_image.bmp new file mode 100755 index 0000000..53181b5 Binary files /dev/null and b/notiframe/webserver/test/card_image.bmp differ diff --git a/notiframe/test/greyscale.bmp b/notiframe/webserver/test/greyscale.bmp similarity index 100% rename from notiframe/test/greyscale.bmp rename to notiframe/webserver/test/greyscale.bmp diff --git a/notiframe/webserver/test/imgBlack.bmp b/notiframe/webserver/test/imgBlack.bmp new file mode 100644 index 0000000..4419d99 Binary files /dev/null and b/notiframe/webserver/test/imgBlack.bmp differ diff --git a/notiframe/webserver/test/imgBlackDisplayClient.bmp b/notiframe/webserver/test/imgBlackDisplayClient.bmp new file mode 100644 index 0000000..20e269f Binary files /dev/null and b/notiframe/webserver/test/imgBlackDisplayClient.bmp differ diff --git a/notiframe/test/imgBlackWidget.bmp b/notiframe/webserver/test/imgBlackWidget.bmp similarity index 100% rename from notiframe/test/imgBlackWidget.bmp rename to notiframe/webserver/test/imgBlackWidget.bmp diff --git a/notiframe/test/imgYellow.bmp b/notiframe/webserver/test/imgYellow.bmp similarity index 100% rename from notiframe/test/imgYellow.bmp rename to notiframe/webserver/test/imgYellow.bmp diff --git a/notiframe/test/imgYellowWidget.bmp b/notiframe/webserver/test/imgYellowWidget.bmp similarity index 100% rename from notiframe/test/imgYellowWidget.bmp rename to notiframe/webserver/test/imgYellowWidget.bmp diff --git a/notiframe/webserver/test/mask.bmp b/notiframe/webserver/test/mask.bmp new file mode 100755 index 0000000..9f3c5d8 Binary files /dev/null and b/notiframe/webserver/test/mask.bmp differ diff --git a/notiframe/webserver/webserver.py b/notiframe/webserver/webserver.py deleted file mode 100644 index c48c463..0000000 --- a/notiframe/webserver/webserver.py +++ /dev/null @@ -1,109 +0,0 @@ -from flask import Flask, render_template, request, redirect, url_for -import toml -import os - -app = Flask(__name__) - -mydir = os.path.dirname(os.path.abspath(__file__)) -# print(mydir) -mydir = os.path.join(mydir, '../') -# print(mydir) - -essentials = {'type': None, 'height': None, - 'width': None, 'posX': None, 'posY': None} -trello_options = {'board': None, 'list': None} -image_options = {'filename': None, 'scaleMode': None, 'bwStyle': None} - - -def convert(input): - if isinstance(input, dict): - return dict((convert(key), convert(value)) for key, value in input.iteritems()) - elif isinstance(input, list): - return [convert(element) for element in input] - elif isinstance(input, unicode): - return input.encode('utf-8') - else: - return input - -# HOMEPAGE -@app.route('/home', methods=['GET', 'POST']) -def home(): # Toml config passed to html page via two dicts. - # Form data passed back to webserver as JSON. - config = read_config() - widgLists, sysList = prep_dict_for_web(config) - - if request.method == 'POST': - jsonData = request.get_json() - print(jsonData) - jsonData = convert(jsonData) - - # update system variables - for key in sysList: - print("%" + jsonData[key] + "$") - if jsonData[key]: - if isInt(jsonData[key]): - #print(request.form[key] + " is int") - sysList[key] = int(jsonData[key]) - else: - sysList[key] = jsonData[key] - # update widget variables - # for i in range(len(widgLists)): - # for key in widgLists[i]: - # if request.form[key+str(i)]: - # widgLists[i][key] = request.form[key+str(i)] - for i in range(len(widgLists)): - for key in widgLists[i]: - # print(request.form[key+str(i)]) - if jsonData[key + str(i)]: - if isInt(jsonData[key + str(i)]): - #print(request.form[key+str(i)] + " is int") - widgLists[i][key] = int(jsonData[key + str(i)]) - else: - widgLists[i][key] = jsonData[key + str(i)] - - update_config(widgLists, sysList) - - return render_template('home.html', title='Overview', widgLists=widgLists, sysList=sysList) - - -def isInt(s): - try: - int(s) - return True - except ValueError: - return False - - -def prep_dict_for_web(config): - widgLists = config['widgets'] # list of dicts - sysList = {} # dict - for key in config: - if key != 'widgets': - sysList[key] = config[key] - return widgLists, sysList - - -def read_config(): - uni_config = toml.load(os.path.join(mydir, 'config.toml')) - config = convert(uni_config) - # print(config) - # config = {'widgets': [ - #{'width': 3, 'posX': 0, 'posY': 0, 'scaleMode': 'fill', 'bwStyle': 'mono', 'type': 'image', 'filename': 'forest.jpg', 'height': 3}, - #{'list': 'Plans', 'height': 3, 'width': 1, 'board': 'Organisation', 'posX': 0, 'posY': 0, 'type': 'trello'}, - #{'list': 'To Do:', 'height': 3, 'width': 2, 'board': 'E-paper', 'posX': 1, 'posY': 0, 'type': 'trello'} - # ], 'cellsHeight': 3, 'resHeight': 384, 'resWidth': 640, 'cellsWidth': 3} - return config - - -def update_config(widgLists, sysList): - config = {'widgets': widgLists} - for key in sysList: - config[key] = sysList[key] - convert(config) - path = os.path.join(mydir, 'config.toml') - with open(path, "w+") as config_file: - config_file.write(toml.dumps(config)) - - -if __name__ == '__main__': - app.run(debug=True, host='0.0.0.0') diff --git a/notiframe/widgets/__init__.py b/notiframe/webserver/widgets/__init__.py similarity index 100% rename from notiframe/widgets/__init__.py rename to notiframe/webserver/widgets/__init__.py diff --git a/notiframe/widgets/resources/fonts/DejaVuSans.ttf b/notiframe/webserver/widgets/resources/fonts/DejaVuSans.ttf similarity index 100% rename from notiframe/widgets/resources/fonts/DejaVuSans.ttf rename to notiframe/webserver/widgets/resources/fonts/DejaVuSans.ttf diff --git a/notiframe/widgets/resources/fonts/DejaVuSansMono.ttf b/notiframe/webserver/widgets/resources/fonts/DejaVuSansMono.ttf similarity index 100% rename from notiframe/widgets/resources/fonts/DejaVuSansMono.ttf rename to notiframe/webserver/widgets/resources/fonts/DejaVuSansMono.ttf diff --git a/notiframe/widgets/resources/fonts/FreeMonoBold.ttf b/notiframe/webserver/widgets/resources/fonts/FreeMonoBold.ttf similarity index 100% rename from notiframe/widgets/resources/fonts/FreeMonoBold.ttf rename to notiframe/webserver/widgets/resources/fonts/FreeMonoBold.ttf diff --git a/notiframe/widgets/resources/images/calvin.jpg b/notiframe/webserver/widgets/resources/images/calvin.jpg similarity index 100% rename from notiframe/widgets/resources/images/calvin.jpg rename to notiframe/webserver/widgets/resources/images/calvin.jpg diff --git a/notiframe/widgets/resources/images/folk.png b/notiframe/webserver/widgets/resources/images/folk.png similarity index 100% rename from notiframe/widgets/resources/images/folk.png rename to notiframe/webserver/widgets/resources/images/folk.png diff --git a/notiframe/widgets/resources/images/forest.jpg b/notiframe/webserver/widgets/resources/images/forest.jpg similarity index 100% rename from notiframe/widgets/resources/images/forest.jpg rename to notiframe/webserver/widgets/resources/images/forest.jpg diff --git a/notiframe/widgets/resources/images/leaves.jpg b/notiframe/webserver/widgets/resources/images/leaves.jpg similarity index 100% rename from notiframe/widgets/resources/images/leaves.jpg rename to notiframe/webserver/widgets/resources/images/leaves.jpg diff --git a/notiframe/widgets/resources/images/onyxbook.jpg b/notiframe/webserver/widgets/resources/images/onyxbook.jpg similarity index 100% rename from notiframe/widgets/resources/images/onyxbook.jpg rename to notiframe/webserver/widgets/resources/images/onyxbook.jpg diff --git a/notiframe/widgets/resources/images/staff.png b/notiframe/webserver/widgets/resources/images/staff.png similarity index 100% rename from notiframe/widgets/resources/images/staff.png rename to notiframe/webserver/widgets/resources/images/staff.png diff --git a/notiframe/widgets/resources/images/steps.jpg b/notiframe/webserver/widgets/resources/images/steps.jpg similarity index 100% rename from notiframe/widgets/resources/images/steps.jpg rename to notiframe/webserver/widgets/resources/images/steps.jpg diff --git a/notiframe/widgets/resources/images/tree.jpg b/notiframe/webserver/widgets/resources/images/tree.jpg similarity index 100% rename from notiframe/widgets/resources/images/tree.jpg rename to notiframe/webserver/widgets/resources/images/tree.jpg diff --git a/notiframe/widgets/widget.py b/notiframe/webserver/widgets/widget.py similarity index 89% rename from notiframe/widgets/widget.py rename to notiframe/webserver/widgets/widget.py index 7a3d465..e78ebd4 100755 --- a/notiframe/widgets/widget.py +++ b/notiframe/webserver/widgets/widget.py @@ -6,10 +6,22 @@ import os import requests from requests_oauthlib import OAuth1Session import re +import toml + +import time mydir = os.path.dirname(os.path.abspath(__file__)) +t = time.time() +def timer(): + global t + newT = time.time() + print("Time " + str(newT-t)) + t = newT + def textBox(text, font, position, limits, colour, draw_black): + print(" textbox") + timer() str = "" limit = [0, 0] limit[0] = limits[0] - position[0] @@ -54,6 +66,8 @@ def putImage(imagepath, maskpath, position, colour): draw_yellow.bitmap((0, 0), black_invert, 255) def roundRect(draw, topLeft, bottomRight, arcsize, type): + print(" roundrect") + timer() a = 180 arcStart = topLeft arcEnd = (arcStart[0] + arcsize, arcStart[1] + arcsize) @@ -111,7 +125,15 @@ def roundRect(draw, topLeft, bottomRight, arcsize, type): draw.line((lineStart, lastLineEnd)) - +def convert(input): + if isinstance(input, dict): + return dict((convert(key), convert(value)) for key, value in input.iteritems()) + elif isinstance(input, list): + return [convert(element) for element in input] + elif isinstance(input, unicode): + return input.encode('utf-8') + else: + return input class TextWidget(): @@ -263,6 +285,8 @@ class TrelloWidget(): self.boardName = boardName self.listName = listName + + self.width = dim[0] self.height = dim[1] self.wt = cwidth * dim[0] @@ -284,10 +308,23 @@ class TrelloWidget(): self.font2 = ImageFont.truetype(fontpath, 13) self.font3 = ImageFont.truetype(fontpath, 10) + uni_config = toml.load(os.path.join(os.path.join(mydir, '..'), 'config.toml')) + config = convert(uni_config) + self.conf_dict = { + 'type': {'default': 'trello'}, + 'board': {'default': ''}, + 'list': {'default': ''}, + 'width': {'default': 1, 'min': 1, 'max': config['cellsWidth']}, + 'height': {'default': 1, 'min': 1, 'max': config['cellsHeight']}, + 'posX': {'default': 0, 'min': 0, 'max': config['cellsWidth']-1}, + 'posY': {'default': 0, 'min': 0, 'max': config['cellsHeight']-1} + } + self.updateWidget() def initTrelloClient(self): print("CONNECTING TO TRELLO") + timer() self.trello_key = 'a3d8f7c04c266e5c9571f6b7747aa353' self.trello_secret = 'd4ac9968d997aa3e5a0ebf129a627b03701520de6ff19834c81d6d9c56fe7e9b' try: @@ -359,13 +396,25 @@ class TrelloWidget(): return access_token, resource_owner_key, resource_owner_secret def updateWidget(self): + print(" init trello client") + timer() self.initTrelloClient() + print(" generating canvas") + timer() self.image_black = Image.new('1', (self.wt, self.ht), 255) self.mask_black = Image.new('1', (self.wt, self.ht), 255) + print(" cards from board") + timer() card_list = self.cardsFromBoard(self.boardName, self.listName) + print(" print cards") + timer() self.printCards(card_list) + print(" saving images") + timer() self.image_black.save(os.path.join(mydir, '../test/card_image.bmp')) self.mask_black.save(os.path.join(mydir, '../test/mask.bmp')) + print(" done") + timer() #self.draw_black.rectangle((0, 0, self.wt, self.ht), fill=255) #inclusive/exclusive dimensions? #self.draw_yellow.rectangle((0, 0, self.wt, self.ht), fill=255) #textBox(content, self.font, (0,0), (self.wt, self.ht), "black", self.draw_black) @@ -378,6 +427,8 @@ class TrelloWidget(): self.lastY = 0 def makeCard(self, card): + print(" making card") + timer() # calculate card dimensions for an image to draw the card on # then draw the card on the widget canvas # card dimensions: wt/width, ht/height (cards as large as one cell) @@ -394,7 +445,8 @@ class TrelloWidget(): self.drawText(card.name, self.font1, card_draw, card_image, card_wt, offset, padding) self.cardLastY += 4 - self.drawText(card.description, self.font3, card_draw, card_image, card_wt, offset, padding) + if card.description != "": + self.drawText(card.description, self.font3, card_draw, card_image, card_wt, offset, padding) card_ht = self.cardLastY+padding @@ -414,23 +466,42 @@ class TrelloWidget(): def drawText(self, text, font, draw, ima, card_wt, offset, padding): #self.cardLastY += 4 sizex, sizey = textBox(text, font, (offset+padding, self.cardLastY), - (card_wt-(offset+padding), ima.size[1]), "black", draw) + (card_wt-(offset+padding), ima.size[1]), "black", draw) # find predicted height of textbox and set lastY to it self.cardLastY += sizey def cardsFromBoard(self, boardName, listName): cards = [] all_boards = self.client.list_boards() - + print(" 1") + timer() for board in all_boards: + print(" 2") + timer() if board.name == boardName: slctd_board = board slctd_board.list_lists() all_lists_in_board = slctd_board.all_lists() - for lst in all_lists_in_board: + print(" 3") + timer() if lst.name == listName: card_list = lst.list_cards() for crd in card_list: + print(" 4") + timer() cards.append(self.makeCard(crd)) return cards + + +class surfWidget(): + # this widget displays an image + def __init__(self, cwidth, cheight, xy=(0, 0), dim=(1, 1)): + self.name = "" + + + + + + +