From 81e40142f7ad6215da1cc4d2c66fd26d4bcbb0eb Mon Sep 17 00:00:00 2001 From: Josef Date: Sun, 8 Dec 2019 17:44:43 +0800 Subject: [PATCH] redesign --- notiframe/.vscode/settings.json | 5 + notiframe/NotiFrame.py | 113 --------- notiframe/fetcher/Fetcher.py | 54 ++++ notiframe/{ => fetcher}/drivers/__init__.py | 0 notiframe/{ => fetcher}/drivers/epd7in5b.py | 7 +- notiframe/{ => fetcher}/drivers/epdif.py | 0 .../fetcher/test/imgBlackDisplayClient.bmp | Bin 0 -> 30782 bytes notiframe/test/card_image.bmp | Bin 7230 -> 0 bytes notiframe/test/imgBlack.bmp | Bin 30782 -> 0 bytes notiframe/test/mask.bmp | Bin 7230 -> 0 bytes notiframe/webserver/Notiframe.py | 239 ++++++++++++++++++ notiframe/{ => webserver}/config.toml | 13 +- notiframe/webserver/templates/home.html | 16 ++ notiframe/webserver/templates/newWidget.html | 87 +++++++ notiframe/webserver/test/card_image.bmp | Bin 0 -> 21566 bytes notiframe/{ => webserver}/test/greyscale.bmp | Bin notiframe/webserver/test/imgBlack.bmp | Bin 0 -> 30782 bytes .../webserver/test/imgBlackDisplayClient.bmp | Bin 0 -> 30782 bytes .../{ => webserver}/test/imgBlackWidget.bmp | Bin notiframe/{ => webserver}/test/imgYellow.bmp | Bin .../{ => webserver}/test/imgYellowWidget.bmp | Bin notiframe/webserver/test/mask.bmp | Bin 0 -> 21566 bytes notiframe/webserver/webserver.py | 109 -------- notiframe/{ => webserver}/widgets/__init__.py | 0 .../widgets/resources/fonts/DejaVuSans.ttf | Bin .../resources/fonts/DejaVuSansMono.ttf | Bin .../widgets/resources/fonts/FreeMonoBold.ttf | Bin .../widgets/resources/images/calvin.jpg | Bin .../widgets/resources/images/folk.png | Bin .../widgets/resources/images/forest.jpg | Bin .../widgets/resources/images/leaves.jpg | Bin .../widgets/resources/images/onyxbook.jpg | Bin .../widgets/resources/images/staff.png | Bin .../widgets/resources/images/steps.jpg | Bin .../widgets/resources/images/tree.jpg | Bin notiframe/{ => webserver}/widgets/widget.py | 81 +++++- 36 files changed, 482 insertions(+), 242 deletions(-) create mode 100644 notiframe/.vscode/settings.json delete mode 100755 notiframe/NotiFrame.py create mode 100644 notiframe/fetcher/Fetcher.py rename notiframe/{ => fetcher}/drivers/__init__.py (100%) rename notiframe/{ => fetcher}/drivers/epd7in5b.py (96%) rename notiframe/{ => fetcher}/drivers/epdif.py (100%) create mode 100644 notiframe/fetcher/test/imgBlackDisplayClient.bmp delete mode 100755 notiframe/test/card_image.bmp delete mode 100644 notiframe/test/imgBlack.bmp delete mode 100755 notiframe/test/mask.bmp create mode 100644 notiframe/webserver/Notiframe.py rename notiframe/{ => webserver}/config.toml (73%) create mode 100644 notiframe/webserver/templates/newWidget.html create mode 100755 notiframe/webserver/test/card_image.bmp rename notiframe/{ => webserver}/test/greyscale.bmp (100%) create mode 100644 notiframe/webserver/test/imgBlack.bmp create mode 100644 notiframe/webserver/test/imgBlackDisplayClient.bmp rename notiframe/{ => webserver}/test/imgBlackWidget.bmp (100%) rename notiframe/{ => webserver}/test/imgYellow.bmp (100%) rename notiframe/{ => webserver}/test/imgYellowWidget.bmp (100%) create mode 100755 notiframe/webserver/test/mask.bmp delete mode 100644 notiframe/webserver/webserver.py rename notiframe/{ => webserver}/widgets/__init__.py (100%) rename notiframe/{ => webserver}/widgets/resources/fonts/DejaVuSans.ttf (100%) rename notiframe/{ => webserver}/widgets/resources/fonts/DejaVuSansMono.ttf (100%) rename notiframe/{ => webserver}/widgets/resources/fonts/FreeMonoBold.ttf (100%) rename notiframe/{ => webserver}/widgets/resources/images/calvin.jpg (100%) rename notiframe/{ => webserver}/widgets/resources/images/folk.png (100%) rename notiframe/{ => webserver}/widgets/resources/images/forest.jpg (100%) rename notiframe/{ => webserver}/widgets/resources/images/leaves.jpg (100%) rename notiframe/{ => webserver}/widgets/resources/images/onyxbook.jpg (100%) rename notiframe/{ => webserver}/widgets/resources/images/staff.png (100%) rename notiframe/{ => webserver}/widgets/resources/images/steps.jpg (100%) rename notiframe/{ => webserver}/widgets/resources/images/tree.jpg (100%) rename notiframe/{ => webserver}/widgets/widget.py (89%) 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 0000000000000000000000000000000000000000..4419d999cd4b7a31f3860e148dfcfe11bd035748 GIT binary patch literal 30782 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 literal 0 HcmV?d00001 diff --git a/notiframe/test/card_image.bmp b/notiframe/test/card_image.bmp deleted file mode 100755 index 931fa426c13ac51f1093185919e4b470aea31f01..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 7230 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 Z&p^-)Djx7;3U4wgef;xfI7F)< z_fxK0iJ0
+ +

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 0000000000000000000000000000000000000000..53181b503a71f920ddd1dfc05298e0123832dd2d GIT binary patch literal 21566 zcmeI2UvLx09mh#14Kv0T%(O)lz$(o{^U(6QQ#6HGN&1kNl=h+jW{4dWQo9e0WVe>& z!IqEVkCkbRdF-k)=r4vYbOq>EqrVus z&=sItjs9ZjLRWxpHTsL83ta)a)#xvVE_4OxR-?Zdy3iG%TaEr==t5V3ZZ-Ogp$lCB zy4C0}hAwmk=vJe@7`o6Epj(apV(3CwfNnMV%l|-^V{29zY%+ch1slCC`qncFx2T^% zCncqDcXU$q&0i{^Lgy_Tc0?SJ}jaUcE2a)6m^``^gAQC;jEVCe8FIJ++oto+b?)Eb? zJ5F48d|-Kf2j)hzQs>{~h9dXG<<0-9_O}pqVt*mQ&t7+YDD?UZhZBaQfTg}gK5$hbw903#&Y%E-Yq z>(BAgRtMYa$@5IikECFl)3|j}_mgRq{A+XL;UYKXoo;<%0&^*T8aR8Wmwy7diBXM9 z@UE!m29NTtc-qhURexTg)uZ?mcmX)C$IE+wUDSf(`k|c5 z*>FC5F31ISa9|59lymaCN)Ar(S2b>`S;C3F&e;Szy|Z(^BQVmkZ=~P!jV4QV){1+T z+u#1uB>VBc4o62|xJ4QcxBq*xwnLR;oNaM78gPn-0)em;DBNAhR20ADM&;Hz4`c3d zr^3D0BCVSzHwaPYS(4xp8B*`93v(wMJbHuswvkqCdYDIYVm z?M{-5O((TXbo1ZQ=g4FZYz7Fr37xwqbziVlCA@nOG&hY!0?#!L5Tr74q z^!LEQ)GU~rdZc_li9xb+{T`X*3TC3b)C$`{d^iouVw9HMtV_zk3KrJKjw(!DS0VmqF1B&1RkHU0 zcl`FwQQ_#hjf;j&D8k`jOGC{Wl^5+wl%k!Ft3_uP4mFprVkM83s@1_zv&=s;$f4Kk8iBpde4Cs>yooQwIf>Q{~Er2^a~7vH?p$99Vy1 zy3b*Dj!m^L+WSqOL+=glj5lW^0~_CvdPl~jfsIMctICPz#e(QgvqJB=s0h145-)R} zLw;7~3nJ?(a8hsJWyu>Cs=35@v03yqL}q%=O*vs#DBG%VBet213AWozxOLN)syT%H zdD6L9?p)LfyFwD-SdNb)7!`zbMfqxOH?(iUw{ZfuFLlxySxm~@`f0}oX1ry0#J$UO z*V^NoKRs1anY2%o1JD&Etehywq*M-W@PPv-F|we%g zqJ3N(kQ{eSx&%oeoY>xRa56A#`)!AKFfQ)7i@vC{o=&F_4+OZQlK3+Ji=zu@L1}Oe zpQd7b{NQw?Zahs-wD#iYig**k0WE6l~PR$~RiBezD{|Y1}pfh)BdTczMz3eRIpvTC(g7Qv;(*A%W2W!Ki zD8}fS%d9HbBwlwmXk4OhF5|rJEcrwAa*-`3Vn@vO_pGq_`IAgpm8eltPqFwN z2T}@<4)Y;26U@rU)T!1qHH$RV#f9}74xyGrs&A{=EQ%8zi(hnRDd#2zB_D$a* z{zTwJ83jN0EB-Rkm$5${u0>9KE17vKWnO$?%ivGgRCDafuN|=d@&(I~HMm_)UjFX; zZ~Vr}M7CPTx7#CgPc@q(8V9{n)e-8>fw`=kf_hj*97@{&qGB_MwBR5B literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..4419d999cd4b7a31f3860e148dfcfe11bd035748 GIT binary patch literal 30782 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 literal 0 HcmV?d00001 diff --git a/notiframe/webserver/test/imgBlackDisplayClient.bmp b/notiframe/webserver/test/imgBlackDisplayClient.bmp new file mode 100644 index 0000000000000000000000000000000000000000..20e269f53cdc224fc9294f2bf5d43c88cbf61f6e GIT binary patch literal 30782 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 x0nyxVs-Y_TIy%t}jT_A(%M2W)$#m2JE27 literal 0 HcmV?d00001 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 0000000000000000000000000000000000000000..9f3c5d80b3b70496d167c74933938bfcc4349bbc GIT binary patch literal 21566 zcmeI0K~BRk6a^hN?BEF5a*9@B&yM>f=iwBQxDW?Gfc;r!Y*il`Bs8w##kk)|C(lvb z$EVYCiFT^}Lp@%mQr3D*^%Jd*zutWxHx;y_wa;wZlC{>calPn;4KOt?dSL@h&5K^x z08{g#7dF7uyy%4uFf}iFVFOIfi(c3OQ}d!1Ho(-p=!Fe1H7|N$15C|}Uf2Lr^P(3v zz|_3xg$*z@FM44EOwG%$dnsk%Is3HUh1#b67dj(vQFq%J?c?{TyYGLYGxG7Hy16s! z0LS^Vb?3pvouRdz(7K%+z3h|((2HK!08{g#7dF7uyy%4uFf}iFVFOIf%Rlfk^KTf@ z(pt9e=zU{$f1BM;XZPvod# zvQrX3FM44EOwEg4*Z@=Wq8B#6)V%104KOt?SMW0PoFiIV%hnyekIU{iv-?~Bw~2Vz zUE9DiTB0yCbJ&Awk}-{;+@Mm+4UYv2o(7@MsC literal 0 HcmV?d00001 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 = "" + + + + + + +