From c8786f6006337290b7e5eff78709609ca8d8fe86 Mon Sep 17 00:00:00 2001 From: Ace Date: Tue, 12 May 2020 19:30:45 +0200 Subject: [PATCH] Revert "modules refactoring + slight changes to folder structure" This reverts commit 3fe9675befdb8f61bc276559025a2e903d3382ab. --- inkycal/Inkycal.py | 14 +- inkycal/__init__.py | 1 - inkycal/__pycache__/Inkycal.cpython-37.pyc | Bin 1700 -> 0 bytes inkycal/__pycache__/__init__.cpython-37.pyc | Bin 170 -> 0 bytes inkycal/config/__init__.py | 4 - .../__pycache__/__init__.cpython-37.pyc | Bin 265 -> 0 bytes .../config/__pycache__/layout.cpython-37.pyc | Bin 2975 -> 0 bytes .../config/__pycache__/parser.cpython-37.pyc | Bin 3813 -> 0 bytes .../settings_parser.cpython-37.pyc | Bin 3829 -> 0 bytes inkycal/config/layout.py | 102 ---- inkycal/config/parser.py | 137 ----- inkycal/config/settings.json | 42 -- inkycal/custom/__init__.py | 1 - .../__pycache__/__init__.cpython-37.pyc | Bin 164 -> 0 bytes .../custom/__pycache__/fonts.cpython-37.pyc | Bin 1402 -> 0 bytes .../__pycache__/functions.cpython-37.pyc | Bin 5173 -> 0 bytes inkycal/custom/functions.py | 362 ------------- inkycal/display/__init__.py | 2 + .../__pycache__/__init__.cpython-37.pyc | Bin 208 -> 0 bytes .../display/__pycache__/layout.cpython-37.pyc | Bin 2976 -> 0 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 139 -> 0 bytes .../__pycache__/epd_4_in_2.cpython-37.pyc | Bin 8576 -> 0 bytes .../__pycache__/epd_7_in_5.cpython-37.pyc | Bin 4287 -> 0 bytes .../epd_7_in_5_colour.cpython-37.pyc | Bin 4072 -> 0 bytes .../epd_7_in_5_v2_colour.cpython-37.pyc | Bin 3751 -> 0 bytes .../__pycache__/epdconfig.cpython-37.pyc | Bin 4245 -> 0 bytes .../__pycache__/__init__.cpython-37.pyc | Bin 131 -> 0 bytes .../inkycal_calendar.cpython-37.pyc | Bin 5296 -> 0 bytes .../__pycache__/inkycal_rss.cpython-37.pyc | Bin 4121 -> 0 bytes .../inkycal_weather.cpython-37.pyc | Bin 8361 -> 0 bytes inkycal/modules/inkycal_rss.py | 28 +- inkycal/modules/inkycal_weather.py | 479 ------------------ 32 files changed, 17 insertions(+), 1155 deletions(-) delete mode 100644 inkycal/__pycache__/Inkycal.cpython-37.pyc delete mode 100644 inkycal/__pycache__/__init__.cpython-37.pyc delete mode 100644 inkycal/config/__init__.py delete mode 100644 inkycal/config/__pycache__/__init__.cpython-37.pyc delete mode 100644 inkycal/config/__pycache__/layout.cpython-37.pyc delete mode 100644 inkycal/config/__pycache__/parser.cpython-37.pyc delete mode 100644 inkycal/config/__pycache__/settings_parser.cpython-37.pyc delete mode 100644 inkycal/config/layout.py delete mode 100644 inkycal/config/parser.py delete mode 100644 inkycal/config/settings.json delete mode 100644 inkycal/custom/__init__.py delete mode 100644 inkycal/custom/__pycache__/__init__.cpython-37.pyc delete mode 100644 inkycal/custom/__pycache__/fonts.cpython-37.pyc delete mode 100644 inkycal/custom/__pycache__/functions.cpython-37.pyc delete mode 100644 inkycal/custom/functions.py delete mode 100644 inkycal/display/__pycache__/__init__.cpython-37.pyc delete mode 100644 inkycal/display/__pycache__/layout.cpython-37.pyc delete mode 100644 inkycal/display/drivers/__pycache__/__init__.cpython-37.pyc delete mode 100644 inkycal/display/drivers/__pycache__/epd_4_in_2.cpython-37.pyc delete mode 100644 inkycal/display/drivers/__pycache__/epd_7_in_5.cpython-37.pyc delete mode 100644 inkycal/display/drivers/__pycache__/epd_7_in_5_colour.cpython-37.pyc delete mode 100644 inkycal/display/drivers/__pycache__/epd_7_in_5_v2_colour.cpython-37.pyc delete mode 100644 inkycal/display/drivers/__pycache__/epdconfig.cpython-37.pyc delete mode 100644 inkycal/modules/__pycache__/__init__.cpython-37.pyc delete mode 100644 inkycal/modules/__pycache__/inkycal_calendar.cpython-37.pyc delete mode 100644 inkycal/modules/__pycache__/inkycal_rss.cpython-37.pyc delete mode 100644 inkycal/modules/__pycache__/inkycal_weather.cpython-37.pyc delete mode 100644 inkycal/modules/inkycal_weather.py diff --git a/inkycal/Inkycal.py b/inkycal/Inkycal.py index a09f5ff..900ec58 100644 --- a/inkycal/Inkycal.py +++ b/inkycal/Inkycal.py @@ -1,6 +1,9 @@ from importlib import import_module -from inkycal.config import settings, layout +from inkycal.configuration.settings_parser import inkycal_settings as settings +from inkycal.display.layout import inkycal_layout as layout + + ##modules = settings.which_modules() ##for module in modules: @@ -9,28 +12,23 @@ from inkycal.config import settings, layout ## #import_module('modules.'+module) ##print(module) -settings_file = "/home/pi/Desktop/Inkycal/inkycal/config/settings.json" +settings_file = '/home/pi/Desktop/settings.json' + class inkycal: - """Main class for inkycal - """ - def __init__(self, settings_file_path): """Load settings file from path""" - # Load settings file self.settings = settings(settings_file_path) self.model = self.settings.model def create_canvas(self): """Create a canvas with same size as the specified model""" - self.layout = layout(model=self.model) def create_custom_canvas(self, width=None, height=None, supports_colour=False): """Create a custom canvas by specifying height and width""" - self.layout = layout(model=model, width=width, height=height, supports_colour=supports_colour) diff --git a/inkycal/__init__.py b/inkycal/__init__.py index 96cd837..e69de29 100644 --- a/inkycal/__init__.py +++ b/inkycal/__init__.py @@ -1 +0,0 @@ -from .Inkycal import inkycal diff --git a/inkycal/__pycache__/Inkycal.cpython-37.pyc b/inkycal/__pycache__/Inkycal.cpython-37.pyc deleted file mode 100644 index 440f34fb688ed8e3756ea1d8ad310ce9b6f81cbd..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 1700 zcmah~&5qkP5GEzrmc8rU%_f^PKoAfCa!`t{fdIJ$*`g^@v`BsFO@|U%QC@SSABUt9 zSnw@-%>%Tj_E_}TQ{SNlde*fC7JY@BIzv&L+6_qoOHtn#0g`gyXdmZp9*nO8+NS;)!fnSNoa#pKKK#VSqm ziFEI@DrfR+(w#g$*HxLKgKk`f`xsU-5>r89Pte#Gp71Y79JB$(J#kHhVt7Fz%#qlE zoq;$M`{DprLL2z?X5hTmx4%wg$;I)N_vUjn7kf^hY2JS<^RkO*mPT zb8?Ov6%-QU)pwp(iC`TDHj{bAW~wUKA~Ex6Q-$N!r)m&W78stGxlr8Jx$Vx$2G5{zhl;4mF`+bP8@82HA3EHXR<$N-O^Z!J3E z0VcnG^i*Yu$ymbDq2! z)CL%FU`|&q@)gu8n`iQDZdg(ZKq<^T3T)s_&(4~DyWi~Vw+aSCsc0fjUc#tV&0q z$Y#khH=vC z4Gy6-z30%~s*Xh;fV7qPzyV2ZB0j$_W-X=CsF>d2o?pGCg9 zh92+=s_P)4AztPZt{CUdh`YuL`Yz`$mr3q+2Aqp3KpS34;7Q6M|&7K-;pXEnTT z3UiHhqR}k$0xukdJwiwQFd)?KPNP9HYkWw TeBAyYo?zRtDcbc8hJp7FpkS=m diff --git a/inkycal/__pycache__/__init__.cpython-37.pyc b/inkycal/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index ad32c12490507525cea34fa3f7fe69806369fa51..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 170 zcmZ?b<>g`k0vYekak4=AF^B^LOhASM5Elyoi4=wu#vF!R#wbQch7_h?22JLdj6h*c z##`)}dD)f8i8+3nOi}Ef5Oxtr?@ERuW*`M7e(C6E&M4u=4F<|$LkeT-r}&y%}*)KNwovn@fnC20E1yCg8%>k diff --git a/inkycal/config/__init__.py b/inkycal/config/__init__.py deleted file mode 100644 index b3de81b..0000000 --- a/inkycal/config/__init__.py +++ /dev/null @@ -1,4 +0,0 @@ -from .parser import settings -print('loaded settings') -from .layout import layout -print('loaded layout') diff --git a/inkycal/config/__pycache__/__init__.cpython-37.pyc b/inkycal/config/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index e8f4ea870c6da0789b51752f621a29060751c771..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 265 zcmXv|u?oU45Y07Oidg&w*MgYARYb(a#l_9RQcTofnuH_{b@gkU{hO{%{(_U&st@ko zz4y4|7HQfe2)}ylPRP$j{1M?W$MPd=oN!R2ge?FO5sz-j=ut&Wx}~kxX}#`-Wbq4d zC4)NgA_S?A{yI>m;DQhT28OXJDsu_f^cQ{QI_uQ2Eu0t5H6PSn>!c2j;(RAAMrzx8 z!cL|X%u2Qt{v3>DD}Ao^g<|r@d!rBX$nsoj8S;E=t2&vMhF_GJH4pmcSRWGT!w0U4 BLvjEB diff --git a/inkycal/config/__pycache__/layout.cpython-37.pyc b/inkycal/config/__pycache__/layout.cpython-37.pyc deleted file mode 100644 index fd9d9ac48fe282cd6f8a2e5a7147beb85503f6fc..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2975 zcmaJDOKjZ6b!PZkimQ+1Zfd7>+X+&;-oTa=CqV)u@lUo>1BP1Uhn5IRP@LHnB`(R% zaAj$`28`H1eJPMj3MA;k272kar{0R3Q=o^QcufE!w*bBM)c0n%wj?AO;yu23^Lz8Y zb8TTEB+zdD^6$U<^8z7XVrSMIAg%!Dp8^sjB7zE*(}=!Jgd^MsM7Z}^!~}bn^u5W| z@OH9aj%z+D#W8()OQjkSHktO+E>|dtLB^gJV|Ay0fk?~ zF=Qh}JZmlxR{->NK$1ih#9)F(j&vV+l02r7FWv19Kp@zkC?#T1c*1``qdBo8LeT{( z6!T)?0g1Z80YQ&7es1KP^nRTTCAS^El@ub+ieaBNUM_cKzHu}4;7n{jz#PCjfc`5W zL8l}pf&r#eDx4ihMN-L8WtCJ?q0wX>a%k^sX?xGs@Vex7#Xc9Au0Ut}SMQkF z>nf=wPk1`kbvb%EdMB&5_%Pd*1;3LCph3NSOQOje@6J|M%f{QxlXPdJ&oT~D-pjQXGQ#4yn7)|%e)+`X5kRGSw7HhXN1pK&2gk( z!#&=3Wwt~20MD*}6(>AB!K}Be$hUjGH|eh@#V=}}Drptb`V%SugTd-Rg9&uM8!d0b zm4~Vv7ot5h>eh0vo=LFSYB#p3iWX*lqr|9JZz(C;$*~?+RjKM`sU`Gm7q3!TQ8&wV zS;bnWbygO!*`Vo-G9hw#l)G8hV7w#TC3~eASNHwK)iNJ6p79khBO12xt*B}V;vzae zlUHOTS!g&||Ba~UVd#G^uWpqixmsnb*QMS8(N-}zq)EP-wg0p%2H9}cDsZLRZ-N-q zpVe`E3yPCyyZ_)V7D-DW#I`Rr3{|G50*UteJR z>hcrZmXLp6PBGVD!?4GY2d^ahKY;#71{71@gW#@f!ky_;ZJ6J-ef5%X9zsfJxo?;r zok9wj(v!eFN$yh^XT`NCow5_aIYETCHJJh|WrEjw4sZR*#J*e^uJE;$3;Zp9VeK?Ods`;ElFLz5@0+DU4w7+R^W7vL zgZrB`@5&moNws>|L-4=DEYhdCESL zJlep=;50gII(a!9LJe&^Avedv#)l`sD5=#l&Nz+;&C~acvYYOKlbglEdpC=RMQA(? zI+n&jGh?BhR1eVW0Qw9d;?Fb81U_a0)-yC?Aq{~J=pu|DOn&(7hD@Q_n1+6YunwR< z1OzcocRH$9W67uY*+;avK8t%Oz3>>=W&?JY6)yqTg-5^@TadS1!|egr1MYjk^#FY2 zPT|oceDKW9-72)dYh1(CVXGh`ePod#df8p9xJQ_=p%L4X)7X3pj diff --git a/inkycal/config/__pycache__/parser.cpython-37.pyc b/inkycal/config/__pycache__/parser.cpython-37.pyc deleted file mode 100644 index 61cc88149fb2f0f51d6902d0311e2455626749c5..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3813 zcmZ`+OK%&=5uO)E6h+Y#C0P&Ka!c#oh=D}eT0b@$Cvf6j+xrrBZ5Vb4B!dxqNRBw1 z8TSljYnJrI8z8qB`33f6k>rp|{zi~fPIC&7lW#c(d&pNk97;lzA-cM|y1uIJ>gwv| zFK1^<3ckPJ{p)XbYl`wO>g1n}#vPRCOAxL!6|Qp4Q=2Mk-P8JdQ&)*+plvh_Rk^S5 z0yn=?xcN$J7Wfn|ey21|XNphvH1WVOUn!8+9x3%w@{7{vQQ))4iDTFAL@cyLT*}0VT5+vZ4o>F z=Fqr<5+xvxf|)B#jjK(aYh33B&6Z}#r+JCb@G_s}6@HFa`5dox=9&hd=L;QL$s#|G z+T=@o8TAxj;j8=tzsN7~HGY}1PO(|!>wE*No#yZHE2vBSef|OJ8U7=zcQY;KD^0F_ z8Q7fJK4*uv=W;uCj=j(pL7&CllN{G`QqA#GjiVNWRC8nWqf~1P)LyDZhpFbH4!x!} zu+iR6wL>>8BwZ_ho}k)p0eygxUXYr7Cl+q2S#fvBn@OalV^*_9?Hi=yqYrZpGbeZ% z{yGUvEJ%FDYH64qeI^P;>s^%SFW?@1K2+Zz0^h3QB3g*fw}{LYWu*DWP#tNpHq>6J zsuJs5eWm`sHqv9`O<}0NRfmdYK2f;wjq*@=sytEri-rP-;=l>gdoyNRuy1ElX%qS(bD8ht#z+najVSYX!QNCc0Lot_#qz^x~z|b8$ua zMEP|%GKL1fw4(5}p7vT3SJ1mGEv%r$WNX#GH0EF7?G9J$396pWNAlo?q^<*}ONM=&mIn@^`4#ZxvwHHjl635!X z0BHt^Gzy)T+jbq!yr5;rZs4ay&-Ob5yW=D~kNs#6hJlD_e9ZlreLGrjut(3`xYb35 zW^uqAzvH=4R}^3_Eew1&j*{)iRI$x(M|I{0F`H=GVuOfqS;Apbx*--Mw2K@PC08Fg zp3@?uvQHMzR3ke=!aAwddFoWl&Pi>@3T&Af#0%*H10z zR^!G7bH28b3faDAw|d*pyDswa=HazEw#4?leK6}nrpLJ!()GTO-m|h5T>8wHIh>ss zI$lh&@mP9*J8gU5#p5Y#v8#4}>)I~J&9E;P;gEN@c$IXXyHV)bM^+$Q+TCdQ6Mw%}Dt?Azoyu|&4a(DofKLJ;KPpvOU&8u3x+q-HDd+is_6 z_Fc|#`b#P=vXKNTVnX(1G@ABz=&uT3N^YZ6XY9+;81LPB~Ji_~n>!eX&XoYga7 zGVa8M|1Xe5mQL0$k<^7V)ySZW#2QH$I0Ug^)Z9E%_>7HAXW(B5x8&KYo#@~~ByXpc z%-a*0#nb(XShg9*VyFAL*z~6_T8<3))D$=mfnPUM181V0*7AL@D7RRYe#nuOeo}*2 z^j4Acj8fJ4lOpb6rT@9M(+&F0PU!A@;zT{nf9Es5cZ9g#amRJGj-ByCE<8$$7H)Jm zwybq1h}s~Erl}>hsu@}l^{Q4;E1IE})m62kn)-3QHtthhlq1WsRfbFzt&Cd*zND5< z&??4jYBHCvu#wMT@`Rw&WuV9>gg|46r@(=N=P53`13Vf0tCFLEa|Ik7oHfZYz_|%d z0i1Gd(u0B?vm@=r2jEW8vjdmX@<@j?o|Y@5a}TWoo+HMyy(h|08yanT{F=$_`wlXb z=P|tg?CciEr<^5jymLbl9J*X)Uc3hpe*@29zTJ0{g*+#mV6N{8^0GV|Vgs#uQG7&< zpAh+&$WMvfCh{{P4I*10^@6yADxJyHS!6@JPaHGjNPRL2GIIZjv_aOZU{J(3T=(n(MRe~h1=BR;X@}L2tPtn zrz6OM_Si4Df8zphM}IwHTf}uebCdKCIj62=-q1aq zafUl#wnq_dYR4v`P8z~k~IdSUAC-e1KS&qOj&qt zw=7HSkjY&l9}>AmY-R@7L4?><4~0W%MiR#V?9A zDc6F?EF&@-1wiP&C+e$pZlJ|(viA9T&(qfNVXDKh<&bH*|CM2Q? P2ql>E6jDQkC9D4h)w?!$ diff --git a/inkycal/config/__pycache__/settings_parser.cpython-37.pyc b/inkycal/config/__pycache__/settings_parser.cpython-37.pyc deleted file mode 100644 index 572c0a2875bfcf40bb5549926e0e85d04b4e0e86..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3829 zcmZ`+&2JmW72hweD2k#fO0qs|%Ogce#X_QN#j?}XEu1?3h?@wG4Z|*hcCq3t$rYEo z>)EAjZAf370=?DfUtnK?wufBuZxlWCw5I|+`POrhLw|3Uq$E^bV&2TWdB68&-n@A; z{MGbyLBaR;+duqnr=lqTqR!~k(YS>YeF?&qy24eid1_rnt$SKmuj?xD47829p(^(j zp5x}X3O8SC^&Fqz`EQlF=}hp+jwbFq=4%D=+GC|!NIok(hytHQP8_>_D`KH7B1hEN z?Vb>hAA3j4^_lI3ZF{wFI|z@2+iJ&b|A^TQ$BjS=?=dN5ud1fGMw`0=4I{MUc7xcX zZw8H9C{Y69D44lY*SK2OxyE&F&}?aze3BRV6fg2=UgGC?na}V_Yo>1SSw7dImCW<= zs7=1W7g0~}CBDor@QeHsU*VTIYvt>CzRK6I+DZNaUq@ZwAM%e-Pw}5%y&GwMw9@42 zmx0Zh?Q?c$doH(Q=hzEP5p-GHKFM)CC)FH3)i`R=OEot}KT5TxK<%YkbeL*B>d>oe zJsa))R6BIjT++7U7YVAZ2G9o>=>)0SbzUp;tI>NQR_eFT-{US(e`hn=$UVW+; zMlN?O9=!1Db56*u8M6-Ap1a9JA^bYVVScPd*-Lm^#7B z@YhISY(e5PRzt(==rd6$T5qF7--CPfps&6~1in+nMYIr|?+}?w%0TmtzB?_bhD3i}hE%Rv4L;epEKM(wQY5lK2%mF_? z#$ybt*ZFzA(9)rWkS1T0S{BfzvMA^B52KJCs?KGWW+a7sfId{k5UY8e~-Q<5=d> zSZ3vo`uxYI6cr!PY!ELs#LMMQ0e1haDubM=B&9gt&mFLA9J$39lW4`)06OV~=0Baifh4 z&EkMLe#>*Cw#dO;n(O&)93@*%sA3!6464izVm8*a$$AmtvV_B=bWO}jXd5{sO0GP1 zJf}fMWuGjbtzzfemXt`fooi{X8*s-)Uflt?9(Kh%9P%C)uaeGkHwr!b$O?pu8&KLwR!0`3 zgNG7`lCeZB**dkPv9V*3O?Z_O`xbdlERZcTw0*~m5Co%e(BmLXjrb^ZQnL~GO}AAy zyDsOrea!tJj)QJ;ZWMF~BAYwBx|-%4pGOFhcACT7-B?hnPK_YMg=J9urUuETMPa|N zM(}jzE`oY5i0@K(-Vq`YX)YA5AB!b|uZ$%vYaCA2C@>?jPC|MVi_~n=!eX&ZoaHlN zGVa8M|1Xe5mQL0$k<^7V)ySZW#0p6mI0Ug^)Z92z_>7HAr{G@*H{{u?oao>}ByXps z%-ds``P2QeShg9*VyF8fvB^6x8;%V5)D$=mfnPOK181UHuZ;G=qTFIp`XNVB`biC9 z(OX5%GfGwGFN(N>mHy|m?RL<0wnKOOb0_Lx{@Y*pog>8kwmYn|b@Z|WGEPv?FCTW{ zQJS}K!@IF%twLec1W`0iEvRM9(DJC4wUS!W47I2(t0mRckL#6TpX$6ES(L3JWXfn| z+%oV5wRnP-F)_pAh3`L_Q_*b0Rm1{DMf0$R!+Ke??+j#8o|Wlk^Zd zr>bS%&^?@aIteG%JS`Pk*%G2x7>p>E6uqn_=SQ|{r-b&ZMLGxMQ_D&V))0(#(XyWR zY;QO+Vd44Ruq?4nCU=N@OymZUT_X30JRm~<&Q45CPLlRS&}8Upi6}pk_bcig_5(kh zGWzB9{IByBDc69=_@fPw&Zj>IF&@}5wiP&C+eZm1-?_O z)v9V1RL5Q$Pc1dNw(I{M+9R^1sN!o-@(l4U3(@)z4DnOqYC$CL6`>Q07A2*{SJXO7 adH!a$CBLLU3{eS$5=?OdsUgCW)&Bz9xjeuC diff --git a/inkycal/config/layout.py b/inkycal/config/layout.py deleted file mode 100644 index 07f8e2c..0000000 --- a/inkycal/config/layout.py +++ /dev/null @@ -1,102 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -""" -Layout module for Inky-Calendar software. -Copyright by aceisace -""" - -import logging - -class layout: - """Page layout handling""" - - logger = logging.getLogger(__name__) - logging.basicConfig(level=logging.DEBUG) - - def __init__(self, model=None, width=None, height=None, - supports_colour=False): - """Initialize parameters for specified epaper model - Use model parameter to specify display OR - Crate a custom display with given width and height""" - - self.background_colour = 'white' - self.text_colour = 'black' - - if (model != None) and (width == None) and (height == None): - display_dimensions = { - 'epd_7_in_5_v2_colour': (800, 400), - 'epd_7_in_5_v2': (800, 400), - 'epd_7_in_5_colour': (640, 384), - 'epd_7_in_5': (640, 384), - 'epd_5_in_83_colour': (600, 448), - 'epd_5_in_83': (600, 448), - 'epd_4_in_2_colour': (400, 300), - 'epd_4_in_2': (400, 300), - } - - self.display_height, self.display_width = display_dimensions[model] - if 'colour' in model: - self.three_colour_support = True - - elif width and height: - self.display_height = width - self.display_width = height - self.supports_colour = supports_colour - - else: - print("Can't create a layout without given sizes") - raise - - self.top_section_width = self.display_width - self.middle_section_width = self.display_width - self.bottom_section_width = self.display_width - self.create_sections() - - def create_sections(self, top_section=0.10, middle_section=0.65, - bottom_section=0.25): - """Allocate fixed percentage height for top and middle section - e.g. 0.2 = 20% (Leave empty for default values) - Set top/bottom_section to 0 to allocate more space for the middle section - """ - scale = lambda percentage: round(percentage * self.display_height) - - if top_section == 0 or bottom_section == 0: - if top_section == 0: - self.top_section_height = 0 - - if bottom_section == 0: - self.bottom_section_height = 0 - - self.middle_section_height = scale(1 - top_section - bottom_section) - else: - if top_section + middle_section + bottom_section > 1.0: - print('All percentages should add up to max 100%, not more!') - raise - - self.top_section_height = scale(top_section) - self.middle_section_height = scale(middle_section) - self.bottom_section_height = (self.display_height - - self.top_section_height - self.middle_section_height) - - logging.debug('top-section size: {} x {} px'.format( - self.top_section_width, self.top_section_height)) - logging.debug('middle-section size: {} x {} px'.format( - self.middle_section_width, self.middle_section_height)) - logging.debug('bottom-section size: {} x {} px'.format( - self.bottom_section_width, self.bottom_section_height)) - - - def get_section_size(self, section): - """Enter top/middle/bottom to get the size of the section as a tuple: - (width, height)""" - - if section not in ['top','middle','bottom']: - raise Exception('Invalid section: ', section) - else: - if section == 'top': - size = (self.top_section_width, self.top_section_height) - elif section == 'middle': - size = (self.middle_section_width, self.middle_section_height) - elif section == 'bottom': - size = (self.bottom_section_width, self.bottom_section_height) - return size diff --git a/inkycal/config/parser.py b/inkycal/config/parser.py deleted file mode 100644 index f0a097d..0000000 --- a/inkycal/config/parser.py +++ /dev/null @@ -1,137 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -""" -Json settings parser. Currently in alpha! -Copyright by aceisace -""" - -import json -from os import chdir #Ad-hoc - -# TODO: -# Check of jsmin can/should be used to parse jsonc settings file -# Remove check of fixed settings file location. Ask user to specify path -# to settings file - -from os import path - -class settings: - """Load and validate settings from the settings file""" - - __supported_languages = ['en', 'de', 'ru', 'it', 'es', 'fr', 'el', 'sv', 'nl', - 'pl', 'ua', 'nb', 'vi', 'zh_tw', 'zh-cn', 'ja', 'ko'] - __supported_units = ['metric', 'imperial'] - __supported_hours = [12, 24] - __supported_display_orientation = ['normal', 'upside_down'] - __supported_models = [ - 'epd_7_in_5_v2_colour', 'epd_7_in_5_v2', - 'epd_7_in_5_colour', 'epd_7_in_5', - 'epd_5_in_83_colour','epd_5_in_83', - 'epd_4_in_2_colour', 'epd_4_in_2' - ] - - def __init__(self, settings_file_path): - """Load settings from path (folder or settings.json file)""" - try: - if settings_file_path.endswith('settings.json'): - folder = settings_file_path.split('/settings.json')[0] - else: - folder = settings_file_path - - chdir(folder) - with open("settings.json") as file: - self.raw_settings = json.load(file) - - except FileNotFoundError: - print('No settings file found in specified location') - - try: - self.language = self.raw_settings['language'] - if self.language not in self.__supported_languages or type(self.language) != str: - print('Unsupported language: {}!. Switching to english'.format(language)) - self.language = 'en' - - - self.units = self.raw_settings['units'] - if self.units not in self.__supported_units or type(self.units) != str: - print('Units ({}) not supported, using metric units.'.format(units)) - self.units = 'metric' - - - self.hours = self.raw_settings['hours'] - if self.hours not in self.__supported_hours or type(self.hours) != int: - print('Selected hours: {} not supported, using 24-hours'.format(hours)) - self.hours = '24' - - - self.model = self.raw_settings['model'] - if self.model not in self.__supported_models or type(self.model) != str: - print('Model: {} not supported. Please select a valid option'.format(model)) - print('Switching to 7.5" ePaper black-white (v1) (fallback)') - self.model = 'epd_7_in_5' - - - self.calibration_hours = self.raw_settings['calibration_hours'] - if not self.calibration_hours or type(self.calibration_hours) != list: - print('Invalid calibration hours: {}'.format(calibration_hours)) - print('Using default option, 0am,12am,6pm') - self.calibration_hours = [0,12,18] - - - self.display_orientation = self.raw_settings['display_orientation'] - if self.display_orientation not in self.__supported_display_orientation or type( - self.display_orientation) != str: - print('Invalid ({}) display orientation.'.format(display_orientation)) - print('Switching to default orientation, normal-mode') - self.display_orientation = 'normal' - - ### Check if empty, If empty, set to none - for sections in self.raw_settings['panels']: - - if sections['location'] == 'top': - self.top_section = sections['type'] - self.top_section_config = sections['config'] - - elif sections['location'] == 'middle': - self.middle_section = sections['type'] - self.middle_section_config = sections['config'] - - elif sections['location'] == 'bottom': - self.bottom_section = sections['type'] - self.bottom_section_config = sections['config'] - - - print('settings loaded') - except Exception as e: - print(e.reason) - - def module_init(self, module_name): - """Get all data from settings file by providing the module name""" - if module_name == self.top_section: - config = self.top_section_config - elif module_name == self.middle_section: - config = self.middle_section_config - elif module_name == self.bottom_section: - config = self.bottom_section_config - else: - print('Invalid module name!') - config = None - - for module in self.raw_settings['panels']: - if module_name == module['type']: - location = module['location'] - - return config, location - - def which_modules(self): - """Returns a list of modules (from settings file) which should be loaded - on start""" - lst = [self.top_section, self.middle_section, self.bottom_section] - return lst - - -def main(): - print('running settings parser as standalone...') - -if __name__ == '__main__': - main() diff --git a/inkycal/config/settings.json b/inkycal/config/settings.json deleted file mode 100644 index 8af98b2..0000000 --- a/inkycal/config/settings.json +++ /dev/null @@ -1,42 +0,0 @@ -{ - "language": "en", - "units": "metric", - "hours": 24, - "model": "epd_7_in_5_v2_colour", - "update_interval": 60, - "calibration_hours": [ - 0, - 12, - 18 - ], - "display_orientation": "normal", - "panels": [ - { - "location": "top", - "type": "inkycal_weather", - "config": { - "api_key": "topsecret", - "location": "Stuttgart, DE" - } - }, - { - "location": "middle", - "type": "inkycal_calendar", - "config": { - "week_starts_on": "Monday", - "ical_urls": [ - "https://calendar.google.com/calendar/ical/en.usa%23holiday%40group.v.calendar.google.com/public/basic.ics" - ] - } - }, - { - "location": "bottom", - "type": "inkycal_rss", - "config": { - "rss_urls": [ - "http://feeds.bbci.co.uk/news/world/rss.xml#" - ] - } - } - ] -} diff --git a/inkycal/custom/__init__.py b/inkycal/custom/__init__.py deleted file mode 100644 index c8f7548..0000000 --- a/inkycal/custom/__init__.py +++ /dev/null @@ -1 +0,0 @@ -from .functions import * diff --git a/inkycal/custom/__pycache__/__init__.cpython-37.pyc b/inkycal/custom/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index e5dea5985a762b129bc6fa0c0b13867285779be6..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 164 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 diff --git a/inkycal/custom/functions.py b/inkycal/custom/functions.py deleted file mode 100644 index 525c30b..0000000 --- a/inkycal/custom/functions.py +++ /dev/null @@ -1,362 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -""" -Inky-Calendar custom-functions for ease-of-use - -Copyright by aceisace -""" -import logging -from PIL import Image, ImageDraw, ImageFont, ImageColor -from urllib.request import urlopen -import os -import time - - -##from glob import glob -##import importlib -##import subprocess as subp -##import numpy -##import arrow -##from pytz import timezone - - - -##"""Set some display parameters""" -##driver = importlib.import_module('drivers.'+model) - -# Get the path to the Inky-Calendar folder -top_level = os.path.dirname( - os.path.abspath(os.path.dirname(__file__))).split('/inkycal')[0] - -# Get path of 'fonts' and 'images' folders within Inky-Calendar folder -fonts_location = top_level + '/fonts/' -images = top_level + '/images/' - -# Get available fonts within fonts folder -fonts = {} - -for path,dirs,files in os.walk(fonts_location): - for filename in files: - if filename.endswith('.otf'): - name = filename.split('.otf')[0] - fonts[name] = os.path.join(path, filename) - - if filename.endswith('.ttf'): - name = filename.split('.ttf')[0] - fonts[name] = os.path.join(path, filename) - -del name, filename, files - -available_fonts = [key for key,values in fonts.items()] - -def get_fonts(): - """Print all available fonts by name""" - for fonts in available_fonts: - print(fonts) - - -def get_system_tz(): - """Get the timezone set by the system""" - try: - local_tz = time.tzname[1] - except: - print('System timezone could not be parsed!') - print('Please set timezone manually!. Setting timezone to None...') - local_tz = None - return local_tz - - -def auto_fontsize(font, max_height): - """Adjust the fontsize to fit 80% of max_height - returns the font object with modified size""" - fontsize = font.getsize('hg')[1] - while font.getsize('hg')[1] <= (max_height * 0.80): - fontsize += 1 - font = ImageFont.truetype(font.path, fontsize) - return font - - -def write(image, xy, box_size, text, font=None, **kwargs): - """Write text on specified image - image = on which image should the text be added? - xy = xy-coordinates as tuple -> (x,y) - box_size = size of text-box -> (width,height) - text = string (what to write) - font = which font to use - """ - allowed_kwargs = ['alignment', 'autofit', 'colour', 'rotation' - 'fill_width', 'fill_height'] - - # Validate kwargs - for key, value in kwargs.items(): - if key not in allowed_kwargs: - print('{0} does not exist'.format(key)) - - # Set kwargs if given, it not, use defaults - alignment = kwargs['alignment'] if 'alignment' in kwargs else 'center' - autofit = kwargs['autofit'] if 'autofit' in kwargs else False - fill_width = kwargs['fill_width'] if 'fill_width' in kwargs else 1.0 - fill_height = kwargs['fill_height'] if 'fill_height' in kwargs else 0.8 - colour = kwargs['colour'] if 'colour' in kwargs else 'black' - rotation = kwargs['rotation'] if 'rotation' in kwargs else None - - x,y = xy - box_width, box_height = box_size - - # Increase fontsize to fit specified height and width of text box - if (autofit == True) or (fill_width != 1.0) or (fill_height != 0.8): - size = 8 - font = ImageFont.truetype(font.path, size) - text_width, text_height = font.getsize(text)[0], font.getsize('hg')[1] - while (text_width < int(box_width * fill_width) and - text_height < int(box_height * fill_height)): - size += 1 - font = ImageFont.truetype(font.path, size) - text_width, text_height = font.getsize(text)[0], font.getsize('hg')[1] - - text_width, text_height = font.getsize(text)[0], font.getsize('hg')[1] - - - # Truncate text if text is too long so it can fit inside the box - if (text_width, text_height) > (box_width, box_height): - logging.debug('text too big for space, truncating now...') - while (text_width, text_height) > (box_width, box_height): - text=text[0:-1] - text_width, text_height = font.getsize(text)[0], font.getsize('hg')[1] - logging.debug('truncated text:', text) - - # Align text to desired position - if alignment == "center" or None: - x = int((box_width / 2) - (text_width / 2)) - elif alignment == 'left': - x = 0 - elif alignment == 'right': - x = int(box_width - text_width) - - y = int((box_height / 2) - (text_height / 2)) - - # Draw the text in the text-box - draw = ImageDraw.Draw(image) - space = Image.new('RGBA', (box_width, box_height)) - ImageDraw.Draw(space).text((x, y), text, fill=colour, font=font) -## space = Image.new('RGBA', (box_width, box_height), color= 'red') -## ImageDraw.Draw(space).text((x, y), text, fill='white', font=font) - - if rotation != None: - space.rotate(rotation, expand = True) - - # Update only region with text (add text with transparent background) - image.paste(space, xy, space) - - -def text_wrap(text, font=None, max_width = None): - """Split long text (text-wrapping). Returns a list""" - lines = [] - if font.getsize(text)[0] < max_width: - lines.append(text) - else: - words = text.split(' ') - i = 0 - while i < len(words): - line = '' - while i < len(words) and font.getsize(line + words[i])[0] <= max_width: - line = line + words[i] + " " - i += 1 - if not line: - line = words[i] - i += 1 - lines.append(line) - return lines - - -def internet_available(): - """check if the internet is available""" - - try: - urlopen('https://google.com',timeout=5) - return True - except URLError as err: - return False - - -def draw_square(image, xy, size, radius=5, thickness=2): - """Draws a square with round corners at (x,y) - xy = position e.g: (5,10) - size = size of square (width, height) - radius: corner radius - thickness = border thickness - """ - - x, y, diameter = xy[0], xy[1], radius*2 - colour='black' - width, height = size - lenght = width - diameter - - # Set coordinates for round square - p1, p2 = (x+radius, y), (x+radius+lenght, y) - p3, p4 = (x+width, y+radius), (x+width, y+radius+lenght) - p5, p6 = (p2[0], y+height), (p1[0], y+height) - p7, p8 = (x, p4[1]), (x,p3[1]) - c1, c2 = (x,y), (x+diameter, y+diameter) - c3, c4 = ((x+width)-diameter, y), (x+width, y+diameter) - c5, c6 = ((x+width)-diameter, (y+height)-diameter), (x+width, y+height) - c7, c8 = (x, (y+height)-diameter), (x+diameter, y+height) - - # Draw lines and arcs, creating a square with round corners - draw = ImageDraw.Draw(image) - - draw.line( (p1, p2) , fill=colour, width = thickness) - draw.line( (p3, p4) , fill=colour, width = thickness) - draw.line( (p5, p6) , fill=colour, width = thickness) - draw.line( (p7, p8) , fill=colour, width = thickness) - draw.arc( (c1, c2) , 180, 270, fill=colour, width=thickness) - draw.arc( (c3, c4) , 270, 360, fill=colour, width=thickness) - draw.arc( (c5, c6) , 0, 90, fill=colour, width=thickness) - draw.arc( (c7, c8) , 90, 180, fill=colour, width=thickness) - - -##"""Custom function to add text on an image""" -##def write_text(space_width, space_height, text, tuple, -## font=default, alignment='middle', autofit = False, fill_width = 1.0, -## fill_height = 0.8, colour = text_colour, rotation = None): -## """tuple refers to (x,y) position on display""" -## if autofit == True or fill_width != 1.0 or fill_height != 0.8: -## size = 8 -## font = ImageFont.truetype(font.path, size) -## text_width, text_height = font.getsize(text)[0], font.getsize('hg')[1] -## while text_width < int(space_width * fill_width) and text_height < int(space_height * fill_height): -## size += 1 -## font = ImageFont.truetype(font.path, size) -## text_width, text_height = font.getsize(text)[0], font.getsize('hg')[1] -## -## text_width, text_height = font.getsize(text)[0], font.getsize('hg')[1] -## -## while (text_width, text_height) > (space_width, space_height): -## text=text[0:-1] -## text_width, text_height = font.getsize(text)[0], font.getsize('hg')[1] -## if alignment is "" or "middle" or None: -## x = int((space_width / 2) - (text_width / 2)) -## if alignment is 'left': -## x = 0 -## if font != w_font: -## y = int((space_height / 2) - (text_height / 1.7)) -## else: -## y = y = int((space_height / 2) - (text_height / 2)) -## -## space = Image.new('RGBA', (space_width, space_height)) -## ImageDraw.Draw(space).text((x, y), text, fill=colour, font=font) -## if rotation != None: -## space.rotate(rotation, expand = True) -## -## if colour == 'black' or 'white': -## image.paste(space, tuple, space) -## else: -## image_col.paste(space, tuple, space) - - -"""Not required anymore?""" -##def clear_image(section, colour = background_colour): -## """Clear the image""" -## width, height = eval(section+'_width'), eval(section+'_height') -## position = (0, eval(section+'_offset')) -## box = Image.new('RGB', (width, height), colour) -## image.paste(box, position) -## -## if three_colour_support == True: -## image_col.paste(box, position) - - -"""Not required anymore?""" -##def crop_image(input_image, section): -## """Crop an input image to the desired section""" -## x1, y1 = 0, eval(section+'_offset') -## x2, y2 = eval(section+'_width'), y1 + eval(section+'_height') -## image = input_image.crop((x1,y1,x2,y2)) -## return image - - -"""Not required anymore?""" -##def fix_ical(ical_url): -## """Use iCalendars in compatability mode (without alarms)""" -## ical = str(urlopen(ical_url).read().decode()) -## beginAlarmIndex = 0 -## while beginAlarmIndex >= 0: -## beginAlarmIndex = ical.find('BEGIN:VALARM') -## if beginAlarmIndex >= 0: -## endAlarmIndex = ical.find('END:VALARM') -## ical = ical[:beginAlarmIndex] + ical[endAlarmIndex+12:] -## return ical - - -"""Not required anymore?""" -##def image_cleanup(): -## """Delete all files in the image folder""" -## print('Cleanup of previous images...', end = '') -## for temp_files in glob(image_path+'*'): -## os.remove(temp_files) -## print('Done') - - -##def optimise_colours(image, threshold=220): -## buffer = numpy.array(image.convert('RGB')) -## red, green = buffer[:, :, 0], buffer[:, :, 1] -## buffer[numpy.logical_and(red <= threshold, green <= threshold)] = [0,0,0] #grey->black -## image = Image.fromarray(buffer) -## return image -## -##def calibrate_display(no_of_cycles): -## """How many times should each colour be calibrated? Default is 3""" -## epaper = driver.EPD() -## epaper.init() -## -## white = Image.new('1', (display_width, display_height), 'white') -## black = Image.new('1', (display_width, display_height), 'black') -## -## print('----------Started calibration of E-Paper display----------') -## if 'colour' in model: -## for _ in range(no_of_cycles): -## print('Calibrating...', end= ' ') -## print('black...', end= ' ') -## epaper.display(epaper.getbuffer(black), epaper.getbuffer(white)) -## print('colour...', end = ' ') -## epaper.display(epaper.getbuffer(white), epaper.getbuffer(black)) -## print('white...') -## epaper.display(epaper.getbuffer(white), epaper.getbuffer(white)) -## print('Cycle {0} of {1} complete'.format(_+1, no_of_cycles)) -## else: -## for _ in range(no_of_cycles): -## print('Calibrating...', end= ' ') -## print('black...', end = ' ') -## epaper.display(epaper.getbuffer(black)) -## print('white...') -## epaper.display(epaper.getbuffer(white)), -## print('Cycle {0} of {1} complete'.format(_+1, no_of_cycles)) -## -## print('-----------Calibration complete----------') -## epaper.sleep() - - -"""Not required anymore?""" -##def check_for_updates(): -## with open(path+'release.txt','r') as file: -## lines = file.readlines() -## installed_release = lines[0].rstrip() -## -## temp = subp.check_output(['curl','-s','https://github.com/aceisace/Inky-Calendar/releases/latest']) -## latest_release_url = str(temp).split('"')[1] -## latest_release = latest_release_url.split('/tag/')[1] -## -## def get_id(version): -## if not version.startswith('v'): -## print('incorrect release format!') -## v = ''.join(version.split('v')[1].split('.')) -## if len(v) == 2: -## v += '0' -## return int(v) -## -## if get_id(installed_release) < get_id(latest_release): -## print('New update available!. Please update to the latest version') -## print('current release:', installed_release, 'new version:', latest_release) -## else: -## print('You are using the latest version of the Inky-Calendar software:', end = ' ') -## print(installed_release) diff --git a/inkycal/display/__init__.py b/inkycal/display/__init__.py index e69de29..35b3f46 100644 --- a/inkycal/display/__init__.py +++ b/inkycal/display/__init__.py @@ -0,0 +1,2 @@ +from .layout import inkycal_layout +print('imported layout class') diff --git a/inkycal/display/__pycache__/__init__.cpython-37.pyc b/inkycal/display/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index f19d538ed1d1d418614198d29b5766466b7d0d4c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 208 zcmZ?b<>g`kf^d(`aaKV3F^B^LOhASM5En}Ti4=wu#vF!RhA0L`hE&EBre;P)h7{&t z22GZij6i8k##?MTiIw@KB~_xCxdr(}C8;S25CMhcoW$Z{KTW10kb$>Y3yL!HN>(xy zu>g5s;+KhjMt*LpenFy0Zfd7>8wQD8Z(vKRlOTbS*p6j8HDD-3Vi)Zo=wLMDu11=j znUb@zv|R&6Y@oRm$R!05^k4(I^xRW!Mb8P)Lr-&U03){oz2(&R$XQzw(sJ zkMBobU04VSv>U(p>u>+GK*+zaGiweIR{-=+0SOWjK?TccMBgRC5$;1G+y^XTf_*^x z-sGL|R9qf#{m)Iwqwp~SBj7>jC!gLd zvN}uhY$AD;sAME-skCv7u4I}GGAX#Ml1eIcn#@BE?T(hV_iPTYOKxZEbCKx^Y{uVv z-$<{kq?SD4=~&n0=;`R)tlr|oY*!ZiZYF>R^YSf;E^oZMTUjj|Z!=HQosB-rI0Rbu z2_*#R`wZy&mi{%;f3q|WXXlU(nx3pg{6?G=@$2#Kg*Ywqa;%z#L)>QhK)00$pRtmDZJ@ygy5EhK zH{r-bRgMeMZW?uKxmV9LSZu8uTT?{~v%WE6)T_6Yl&x^A$5mCTx>;%oJzK@AR94i@ za$Q!jmT8@pMQj#mdZSE;Tps0amNhu<2zSXIX~xxkzj3w92aRW91>A^^ZG5Y$T7tZY zj?eTJ*+>=|Hr9V3>UkLY?!xL;Ig+bYwt7wK9Z+o*i$j{^t6BSR=dM}{u2lO?5QF`* zI*yNF=B)uDzE6F2k}-Pl3!Gy#paBagjMBgfC<7Y5$x^%8Y^5ike}?VL%TK=k3fniA zpWw2D{Nr+p#RePZJ?1=wCDH!`^anDaSofs z)PN~H3EY$90fli^T%FP>I{};%M0h){8q|*P+pGpzBSj$NnU(*TY`XyDBmvA2$F%ky zK}C7g0ZxEpkJ)3W3WggP?i|V<;LaIt2wZBpB82+To&5csJTFrW+d;Mmr2y(cDvKJc zqIIe%72qn9y*6}s8&D?s<;rk{udQ6*Z}SUlr}^1iGTD_}j;ea!OcipFjPsiBCixiR z-^}?y)=*BW)x$A|6=n@lGE-?(DhWjg?ggvG7E~n@yoWSMp(2=ufArT60Q4fD8mc6o zxCfSp(^4ojjb}1X;cy@Bg=gpOQ}rA$O{A(H0o4R=<;iGMB$wWX-hTkd? zZRTTg8k;tqyc`bU5^X#oH^;-qhd00|sns${97lxi>3hc5P4~dg&Eny;o5jN_G@b?< zOXHxKv(Qhf2j~p|eFhNm=NVQ4A1eXt8Je+>hCl~&5k?RuKm2}2rf}VuhH-?j4xm2- z1UXK3I;vOWolhUIk7#jimiKV?!fRlg4cI+ayaHSoUIAC^jlAs|ZV$K~aBlCYUtKTYVm4V}tIL6Z;LxJDGkjCYR8_@X!&Y7o^6RmrW&gr`w z8yh!Z!&A8KPY~h5v_FscL;#PpN;C(H--2M3 z3Z8@JA9Xhqou%t#F~}f*uU)@-=Uw$<+yp~Ry^6>j=ovBrh(Uu-XpLzQP#3~&kr5i6 g0eDg2C}@lkYBn~E?^_27j#c~;-aHzwB9{g1zYc>#tN;K2 diff --git a/inkycal/display/drivers/__pycache__/__init__.cpython-37.pyc b/inkycal/display/drivers/__pycache__/__init__.cpython-37.pyc deleted file mode 100644 index 0f3f6e44d6d22cfdd75d791c49609631109d5e1c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 139 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 diff --git a/inkycal/display/drivers/__pycache__/epd_7_in_5.cpython-37.pyc b/inkycal/display/drivers/__pycache__/epd_7_in_5.cpython-37.pyc deleted file mode 100644 index 033b27f887fc6f52a79ac97184042c6ce8059818..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 4287 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 YllD!WH?w13|2Az-u@R`(4U`A}1yQj;W&i*H diff --git a/inkycal/display/drivers/__pycache__/epd_7_in_5_v2_colour.cpython-37.pyc b/inkycal/display/drivers/__pycache__/epd_7_in_5_v2_colour.cpython-37.pyc deleted file mode 100644 index 862aa0e2de3647387d2eeccf32eb444352614a92..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 3751 zcmbVP%WoUU8K2qbkRl~oVO%9`TEajc1QIDV(zGb@P-UgDfrKz5w@MeTHxy?@uf&&T zS20B_fdbB{ryK$l=t%q3EH9q`z;LTuHPLq+NmEeDnU^ztL8; zT4wlaXJ0y|?Tt-`xE3$^REN{qFv`g|iSw~xu&qK1CsrkYE z?G6b>AGLJ(9sHs7jDu{yEAB6+Y*}kKP9NE!*vGtqX-{}#te-fSMYwqmkYdR72(-H*q_wH>!xSQHf zLK#0!%QSNLgL@y|eULhjgRuKJhE=U7=pFoxsbyULpUsWO!+x+a3OBZc=qMhJHp0Qt zX{X)WkYP0HwNE#s3O@@}v;klEKlj6d|1L%vrx>&Luw-*&DX(?&uJuJPdMYYg^=8L$aJ1OaO-0grN$G{DU zw1k}*vzRj>I`a3NPx<&(!lij+sIBYgk8ka<*gSKjj>=i|O)9|~_uHdDH7HrLW89Pb z@CLZ1o4UPWw;K++sV#&3ldeJuWqB>A%wtmpZK+%uuhX8~rJhCSEt)~>VC@zrwy`pz zz-0)|GJHw2HcP?zqQVrE7lkSQjSiXO9QFFhR5fYrYJ;4k(m`?5(wT{@Tv3c&=3pwl z4z+g1nbIK+XQJ-T#+>4`xxpK9zepUpR{fY3Ute`BDy$!4K6(p;!K0QT4Dzb})12;K9m{(}jftQ< zpks~0ylrip6YU2XLU9;5}td0Y9{8P_0X7FQ#&!w>~l7C zV&}}2R$?Xgxe4D>!f>R?-xI*zp+THpq2povuUI7ZQ@+i9zcY2mAE9UI-sV&!P9hTb zz<2?#0qmM2fKVEt^XlvecsYoouA4BxJ?I9_r5qOQu;1gcu|L{0JPM>0b-0Af19u6Jhw1X<8SeaF4x8W4&@kqgrS7bI#&M-26YGVO1V3J zGe*3|20VfX*P&Hs(xgavY9Pv15wWN|2~W%y7_B~j1^%GDmfm~&JNDLRdkxyVlJDN1 z?bgw(V@g*yoG7TK>9X&(vKl1J3;hPTj8HnG5~6fLDCL>|HVxb+QaDiQYCuX~DhZZ$ zmsi#<+V8bHN8}W^P6aaM;UWsSv-jE`aY{s&5(qT-D#}2E*L6vlEKxC-tt)VVAhEFV z7wBBF@$27Vr{yUs1**HYXkp(x-@ng3{k%JVG_!1u7F1K_XmMd#(NYBP7nW7))YTPw zlequKyg8z(U(x=>$KIV@&{luK%q2rEYeNz(^Zd!DR~2Tw0;lBO3p0WPuxfxrIimo? z2>u}=4sQpm2qCMLkvCKWB>O7}UPk(DKp1fmB;FiTf^mok{q+yls22pIzhGZPVMf7_ zBSkK|p2dG4^m-q(`+@JLWgm4wLzSOaeE;~Q-OFc`4(kQz(h|KvV!cabiwI?@`ZbXY zgKCbzQ&BFzf?q_ahkp=CLI?+cCGoOY6ID^wE1HfjTxtFuQYG3+h@~g5J2w^Yb>P-f4wjQ31YClrUCERw zlHR54lb{2Np3%n^1&TiF9`i5lYoGit#hOU z&f>4X+q+^If5*=1Dnnx*iu@A@W-t;NUS1QA=sxwRu1(MU&|s9AuMB3MQqO{(#Y)gC zL9fJ(k-aE0`;3S~Zk-yQ6WhFm_3w5-wd4oIL zJ*B56F`kb;0~|f0Re24VjBX$0>Y~uthaw+?;09s@e8e*uAY!IhVwPvK60=_!UOE4+ z=dcQMpUms;Z9ynI3T=ribC{H{d(3_fR+} zc0u$B2)s-v7L)@h@<$*Tz=@0#qHA(O=X6BphEL~YVZsbsqk+Kv@=VbD!VooRe|fv}G#T?w8g}k+ z`7BG)P8dI%_JgRyLYYRvw8KRBf(zNMR_FSrGXzMVRrQ!H~qgHppzRh-X8quQfmkYXqh@0?o1lb%uU)4yP2x zh=yu3Vh0p2!l~DA7G%Li7&yh_u)6m{qw>CyM`I&*+p^@@IAL6wcMm>N zRp`A8L>$IL3A@F!Nvg_^dXN3X2VG@;{K;cw-#gG9`=F<5=k6!H&vlDF=n8G#+Bi7& zWy(48pU#wpZ*P&@57A)@kx+%XNyK%0?!%NsUoyxJsgbM88zPm=t`|MB@XU5&--UOe zL*}N{t(C#)0u2J$b7|nbUn=zNGh^v5R(Dp0t!?s{%{u)kk-T~P(|4L5X~-~|L8fWm zY^KReE}D>TWhOh_kHF1{?cx~s`>u&Nf6~T=Rm}F5Yl&1 zG*IAPh^r`&3B)&0d>;j-|3awfJ;lT(FgJYf0x|PI+!J>x`aQ`Uz)l!BL?-C!@;3#Wp^1XgqI!hB0n4E@9$s$j$G^d*zz0Z61 zdmFCrXCjE@fQuC}Jk?%Ah6!z2KvvwMe}mFz=kWe7ln$n-E^3;cD7b^!y`Nj5o;$@2 zTp@;m_$G>Pq0k)D#1;}wA-`ji&W*Rb#dt>?C~G?#X#$wT(-MzZn@sJJ*|ma`eI-pl zgcqFCH2V3%#N}-ewza?$k-aA9yk9Q#o&O?XSHuqhl=vYEeU!Pj#XN8x*v8|c1yB7G zt07||ok$E019Fl}m+Za8VoUNC_`4$BLGdn%^?{+VkN+W0x8Z%CLb=G(SJpi33e=gk zI=~s7qlxUm?^QNP#CZLSHB3YJ85_TQ)F0pa#ZPaqDHQ2^O`#ZKLkQw0mrvlgX#u}X zXGB_a@)!Et!jz_n55kpj^v>kVFnbDr3bcJwk>d-&`lWj(0;cIFg`k0@0MYaUl9Jh=2h`Aj1KOi&=m~3PUi1CZpdHNt}4nG)R}xH8rM;xp8{~jRygBokG)T|)>Ca&)|#!|R=CcM zhYC0LRa^HAZf>gLJe1gCfao)Bf~Pt)tvTiGBwVD;sRA#u|9mIRnq?l9DKnk*I)X!ak(BfMRhCu*h}5 z5;p+Lab=?#*SJY5Hp;wkNONbn1vtx#fOEVASm$NH6TAZ0;8nnryaqVWX8;%C#eF() zDPHEY<5Sql$YnkUUh0E$cLG25-JU=2noqNpYhj?RLe>o2q{hy=AA6~Bzvs3$A6I}H z%&&!Uc+U-@SMPaS{>?DpUJ!X4O3)*0+Wkf254Zm|_~o_kZ+=bR=hss6E+)Bq@26(; zVA~bm+XM5~t>)dkcT?312BlwI8a8{O%RRoG(a* zaZ)4d_xw23CE9FwC5#hf|%ZwAgn!_k*spd)(Yhi#wjT8O5%M({i*P?l|7Z9=5bg zvUYsXWmo#b$C;B6?#7-I#d|$)({qFFHV(F{T`zW`y(sp!oOqC0vA^XF!T|D?i&GQV zVattM8bs^$I(8+(P4L6Ok<`~Fy-W*1DnvF~5JsPGedq* z`at0-j9DAJa@P&E-Cl368F_It0^iNPD_}CQC!%K9X~ye*G_mSB85$40s2PND)7$l< zc&%lm1`K>FBF4Gj2IFY~d%1Be1c^YL259Nx464-J+;K%WO0`XIFEu`Pd)uCrc?Oy^ zMZ@Cnpb<&ms?}ME)zlgrG@cOCpr1@I~b2t07Vh6u5S%4fP2IuPXJ8Y!7ZUu;Zgi&!pba z#45a4cyE87&$1-GkoStRX9YE)U}P*RadA-@7I+Dlt@tRTT3J>e=}93eqSoX(Hqz(u z%AcYWO4&|Haf&IAjKo|}lJbJ`NKHzQ*nx7u4%7qfK<^m5%qtJAxRez4*)3XM!I*wv zbTnSgMn=HOk!oDtsDQ32uN|@>QCQcIWwnz>Cj-xr|N^tA1JXgHu-Wk>qs3ol1fq^H)*#c#9PCY&>K+GL5=Nvl3J*(F)#r*hm%d~W=F0*!2(Pv(=w zMI~8~5N+5B+6ziY=PUd)KXV9&KArtSaw=KLHH1^SE;V!ZP>1G?@ry|#If-3q#mxAn zV@dKR_&Obz$1lS+TKqYjdtu`h?0)VLln>A3Bj0*v2eWOVw(i}IKpN2mEL3e+|z-VlPGx;*^(({UX1 ze)kReeQ~XeaeRNd)>0pncY92Wryhnp3n5ORM6UyM;r>3lApMEFKOe0O)e-J#0#CD` zjMR~qz`sDo>Sx-6*$4W)%;g~>GX(iV#1HD~rIhWZY!?q+brQu=Koq5wuJAcR6GStJ za-Qt%rDY0boII{7$&QS*jvf4$r7Jx=r0sC4e^n5{BomVj-uMbb3KgUT=oOX{Xbjm%8L^Dl5&Y+8>XcVW5VSzzN}1Er#COpW->2@}79zQI zheF1jm1FY7Wz5({$>^q3LX8K)0)_%wM6FR42|;cdPOqXQ{R~KF8%n}TNTv=MJryHmL*?pW&O}SYV@0`&t#MB8*LAd^HzQj2JFyHx z#4@2W7R3*;wtU_e(SC}fL!fd^h)ZZsB}1@eKeFz1>AzDKq;+MMu+|jMH#&IjgN#rNZYB7t9~QD#s9u0$VAs#DpCc%*GmiGcHHv= zGL5$}AXhvld8dXnKr)_q;0K*>ps)6W?x36}B-CkLN;RYlqE0L437jCXAeYN5CDj6N zM>Gh#1Yp-F2Z4P~O!_rB)fFP#!PIa^oT8~@8>uz9@aYVK&WTk(kAjR#QfSw&ia*(s|iMv@)M&7toaS(5OsuZ#Q(Y#WGwp35kd8WJ9N5aXcAd5_+C9&<_9iV;xZK~4(h>Y)_{wC1)vzqY?)a|q-M1mQYoZUY*wvl77{DM*0l=L)jIOi8mnkE z^eU{OR)ANTicHl)zN%v;@R*h1vOKn?TdaW{7N^(}o7HF8EY7R2dDg&h9;3^Y!f6e4 z7B$KzO0mHPXTQdWthLINQOY;RNlT8C<=n_FD~^LdL3;T}p%-?$u#dEeT;s=RdxD-A zs>O5QUc5|zEML4rV2i-9OO>rA;mBLlWsm4T8cQvy){<4i&yXWT%a-d0jx#tTwu1mC zHYpqSgC-t+{5jLZzYdfqd-A`ZRy8dk9S+-$V=v~MuEM6cCssS#f&33567SNvq$qiW y2&gqpnMIkpM2x5sptnZM5cmq};iWVAT%~9zA}6S;7IbITYM&^dD6d=4NbRHP18onLFyFksd410x zzqhd9F#Nt{fBDm2EHd_I>YV&+G_Ii}zXB1g&jc4n$lsyb42`kbH#s|OqGyFx-@3!1 zXDlWwdye`(XY`jtN7FS3W6b`sWY)@`R(oVRb^cE_=phSD9z%Dols9lmtk z4`n2L<-VojT{+Os^>}iqg3*q4w+~%^AcF+Nd4yN7F3_D}7}srI`3C zk;)AcH;T0zM2YspP>QGAw?gSB@?^xl8|aTRVX&V+&dVDPY>vlCqDy?YbeRLK_u&Q zD8(S9e9Zc$FolKM5*1NJT@es6>Z+&<2X##}AhKrO2q20|mAJbpIKKku%==a6zsq^8>GdGNV zA;ngAB{$+Ew@tdgwpf!N-_xpom<6lbr46xV1#P~0{qn-Nw$?Q zZsRs16;C7K4dO7Ks(xb_NBX2=Q-?0ouiqN`Bl#w}eOs%k)Q1z6N$qf~iXo&{wZ+?8IZaF$p$q z$Yf8)lMV6}7{bO})ElK6B`19{5J;Sa5I`@UcM;np7eJV?#;d$(R6(oU;!8!HuAI|Z z?_|+{6h=QXuL{Z!P?BpP2b&o`W)Im7_I~d@V`j`uGOk^|S5?nzw9qq;5McHlZ3>uS zW|YRV@7!U+fGwNp3qSOuDID|AO{8`cyw8Q>LUUTG#Eplp-hl^~?@E_Q-y)W!OUr{G z(Ocb0UV$Zz6MCfx26!bRfz-a%O0D6NiXPpy)HPdQ14V(N^d8ns|=Nm+xCPHR* zUKCjO3WolzD8O?n3bGU`MG&f@0c&8;Gf$tniFZKHZag77Ph9x_V8+33@qO*j+(+>>+%Uv(NZGyTkVXa);>)S+ReH(?#p&#&?-$i_XVv)*3OfXs}s( z);V}HbFkah*@9lp7U<1cO)Nnsi&;mnW$hylx_HD_*{f{U$vT<6hZEFR);?a!7U$<} z-CuzPJ4D9Qb6`@#FdlaICK~ad8z;hO?}4ZVclzCR(uiOX=mCGLp*INQRUy z3Vd@epgkfB&ds-Pey?jNve3LjSx2cF+K8$eLwD!3#z;iTRWwePzLQ=+5|7Hn=4zQ}g!Tj(J$-UZYG9;2 zcMwlQQQ$KK0VVyxjuh_ZbBeOev;p#`kA8=kzv+JX%53XY4kQ@5(ruKa1ybUt4EBD+ zDXW~ZlFL)tDp)C~6e3%iL0m8}duC+D=jMKs1a=l~x~6&&tT{i-`N7$+B9W_?K_ZkB zp4K9aUhc+=-BPPJiAHH-j*F<%y_}ms zHfo7j31TQRQ?&|`R|>F{n*hg(f^m5x%1Q)x@`|G9-(SLVsUie<{{ue={q0Z|2|TaA zaWIfY+EDnuVYzb#&w-~1=I1rsUj;JBtNvtyFNY%O=M^335R=JtJoeS0B5UZ^wLH+? zUFA=56CW9XfC~6Qb!cZZ(F%yn|3K!|!mg9>N2Z3s0MSSl=mnr2-0FP(SInis4C|05&5n_M63fgjal608rBRMQ+iR`xS8MB(Dua zDHTL8AWxSTWRHFy(AFt5?$CQ_)E=uNytIM8AbU9~}^06MMFJUEpud=(SPTOiC@ z=j+@ymw3mt_zKYBn%S||42L_WZCHlIJHSLu?pn6#ST=Vs(*Yk*+rldFw}6|7t7oq8 zbp2l&?N-+&+(wujxXtmr66vAc^t^ol!*WJFLAQQ}$g@PgNrdit&SeVhQn)C^NV2;E zw%CTT>!#I+JH)Zj$(p}7JfR*vU^ZIM^ zXY>>dOsd{+8WorwMh62H@wl)r^*Wu>xHX={N*4}QqEHI&h4~iOP(PwBAyY+RPSFRD tS|CF4Otp!efw9x4AtaOnx=L?JD4{i8}kNn=hRPqs4r7HPM`75XA-U|Zc zZlwYgx_f$hdS2Z#-Ge(_T`3Kp-kq=B|Kgga{Tmgc&ruMI_<8?sXd2UOjp@uN>1D$< zbfV3YX`8^YQtU}kj@xm?PuK~bSWDU#i`yOerSR)y2|JBn7fagR9Ncw7*vxbdX4yR) z5-6{Q$Jj|lkMdzY!ZQ8Zu*Oau)9f*RjE{!p(I_zC+oKh2L1Y4#a@M&Yyktit1bT;X&4oWc`) zLgDlLq@CqiK87|I_yvV8LPvJRurC2$0KN=eRGtLR3~7p<0!?+(A&=-8&=-McLmts{ z=%3oo1Cz`ZVA4VKRnR1JE#wh>9pfbV8^9!U6PWlfVcf*O1x);xfr)<`^C12LF!2|G ziT?^eulRR>iGLTE_)F|0JHyVhadwVPu=6a-F0hO261&VMi(U3THpQkt)9m|fhRp)M z%5JkcHvgG!KVVnvhy1mj-{G&bs~G>oUBiBZU9*=zyvpC$dBm>o>dYF^_!wXA*Vgqf z4e?L>A+xS&%~m&}R$m$)eDzdgH`z<*;Z1gny$t*of9r(?domwu*@gO_r=Ie>T;(ED zuCQ8(XI3gA^Uz)2ynHub;x5aJj8|Ea8+pMeQ>iDbJX5N@ZJG7AoaQXvn+knRhF-uwM0t{xkUv?p4ZA zSz-KCDs{I~-4sr7Rc4-TX7UB@cmSzAa@DNvcUOhu%G^rLEl}UfVCfg0-1kklvazQ_ zratu0b)=IoIiBMdGaJDiCnqPr(=!k@F*6{mly{4@e3ARHrHadICR+a2$J-(PG{ip( z@lQkiixB@j#D5avKMwI%A^s-Be-q-r4)H&P_-{k}%WR)*PR}raSpste<_X*Yn3*O( zwKG(4g^JTNF2F2-IRf(pZUD?o6QJ4|s<<-k7Ju<``uu94_)-5iul{TOtA#xrZrUDA zbuS4}#1EhUStzckPiir2G7u3b7sIOYh;uO{MrIa^bM*PE`AFt^MBG{|{`0r^yuP@& z$IwB6wuL^i@OKy3dj~*j4Vi;Ze5J`~j%(qIXkn~TzH=r44Z z9MZN-@GS72fM#|ava^TBw)2YC{y{MdvT%x+^Te6Z< zy-TR@dI2<}SMS#?eA5Q~#29$Z9V7#ypW49-ASCt=J8&BNXpG=wAsV|GBh2Dkx*KDO zExn;*Pm;?|1X;p&`eo4vY@32JKmH60vYs{keu-7*xk9B>sfnCdt5z#QiXjMQ4ZGjv zMVvLydE3Gz0%0}(0E|N1x1d+aeS(r_0ciS|o-ks%I0d>u6QB<{0{zrv-Ubm)=28RZ zhzVpG+77OM9J(0CH z)?>sfKtz4c15)%v%jJEOh?eThg!nc2?z*WcW5?Vj8?dPKWn!~e##oFZ7#U}A2LGiP zM;bc`Ns9#E-?4Tzc)hXHp*V(2?R4&HKi0m`*3vAA_`_N^MS~@y@-X}x7M0vG!Rcz4 zDUEe(>pR^n1%0t54`)LQKi=ebw(%29e!7jHY#2K|jo4Z*bXtmzE4o9`2}P$Aom6zE zJkrp2`Y`jZ5kya0X_T#&au>=SE#+>MQ!V8llsj9>z0h_P>q1%x_n|f6qi99AAJT*e zuv-0)9oW@&^_@XE^a6NmFys!mafjpxB#-UV_=Xids^}3#k16_CLti^ivF5hUdPlS$ z>*)VDW_4sl+Zt_)JrQ*lEqS6b%8pUI$VLY>$c)L8($6fJSt1$4 zE$I8W`E%P5YybyA*Yr<4vCBRhe1r{Q|X!9An6pMiT4+_Q>% zChYI)#&I^jbG9+It6zik=NkG(xNMG@`1Vuw25I9*R~CLyKR&cSkpeN=>mGX z&Z70h>NmRNqM9#qnwI&Jrg*67l|!12Lerf?n!4p(rK$UnrbMV|>5!&=Xu5YuQ;)o_ zH1!5XZ~c;gP518*-W5piFG*jH0uOKHE6G_DH_j zID_BWl^Dh9bUrHXTj0KRi2F9UZy(}52KR9*S3XgG5f|Ue-(7peEV(Sd2a9_u-vLy# z>MhA`ZJWC0s&V{ZQu1B-I?i%qYrHYOW6STemxplLz@CG?65;|RexM}IHO?uC+o439 zEzlkCRC8ralkcska69~&u5C@|TKx%bhQ;uPcqPPl8WS(*o`~*_ag2N!em{Yg#lDCB z`&-6?oM(wGZB6`e;vMZ>%{AUZ8Q1W=`uyFB>*5xrSnpAlyI~Mi&Q~+9y!kMbcUfkI z%ff1uFl2E1=Ix#^hKgb)Uwh(rBDTtTP=(;De!D$~x|s>Pah^MJGgDaQh4oA|?|GbE z%Dl>5E)c~aD?un&5 z7)5S&+^ceq%mCq{uOr%6zUS-reB&|DW1y$L{uIoodzVQU-Q#V+9L2Hp_~D%ZDB?~RogB2XLHa9pN3%^}iw#`87AEz*yJ%RfZDF*)t) zIgGDsUl7UJet`B}>K2kSiKMW4+o!%MFGy&HUO!z7mWbzq1-ezLAb|C5PwqFs0(C=N zP&DHF;SWGjELk_pQ=XuS*k-x9T92RqXnHH#3}0xL6t=6GQdsl_Vm-um2wj-5Ya*;b zSklneOdNHD5wsw+KxtINMME?=4Z`skdOz_H-=TyUZ;;ZE_)elh$w-1~fs-$EGXAX? zvx3JRmS$bSGtSqROg5m69a+Ss3DfLbcK!u6AZU!v$8W(YQqz;O)AMsTuFcKVyQU|n z=jN_ootwEad-aCezq&a+c_m07KmDT+hY9JYUx($L5dSj7e;VRnhxnVUrOZwBs@77O z;2!OSpfo^SB9M+i*7D)1(u@(Fn%Wryq61G@@J@_$%uB(20rBta1-$ag{ zjoUHitgMJT&|-Jc;{myh=Udf^hYY>qiW{iGhN@mEi4iJ(??xB7a;4(t)KkNMpu(d) z*YrNb@%?&QKZby|e(tv!OM7#2l$DArgPio+|6Ir#;vtkFpK?m2+=j#CYOpGw{4A{U zJ5?1jK)gbPb$@?9B)$xn@GrBb(j#6YWtON&HN8-U$bkEuJ|1EoC!&Lmg7s4R??-m3(q#8R$2`#Uq=*QJ)>qifqN|RN$SRXpTq)dt`1Q~ukc|Y%z zI6GAzzK3lTc$#S*bU}J}s&2i_^IpZhnL%%K6e+NreP3Llu9NwylUwJTzFFBQ+g*;A z!?BsGxFyHsc4wi)^CECsKdxSA?B4K%&E;i~^y1A0-c0*$chVMx^>&!}sgxy$ql6do z$b=WD(?m@c=;*kpMj*IKp2aiovAMvE@qPgs3+tyzGDju&p)z5=Q!PkYrGkDsTvg(Eet)#a z!I}lF?8F9k%9VafaXmb2l>FhAS4HVPvcu0ZDlE`n^ zF@m_|i6QROqW84~LXnll=sfVP&bs1%WV3jmD38`RCkDsY0%bYsl^hXj0m7@52JGlDlNj+XID~z}sH) z@IfRcYgIcLokdo3{@50sN4a9YYMa;}0<#3>2+Z5*NG?Z}t)wpX&jp2>>**(D-sLnic z1bZktJ{b23!cqI6D$;@D2XCBqcl$A5$EYkQWVO4?xVXF=-c;4AmUuwS4svA`9Uu%L z>r9i~(P1lO4#%-7;iVsRS2O};684d{qB1)@ctXRqrvi~%=%5*hsE9obM|V)+4bs(U zoYrFqLFkv#Ei+|Wdbi$d#LRwun7(EjK?=TRuO5CO5q`}m2FA zk1+kZ&2&e?>;s)PQz+vLNz?&$L%J8*NwQhnlprlMuCN|j6ME|ZQBqnB8YjNgn?7uG z2b3BCdN=y;I;>`|#!52c_pvg~kQ+4qY6>4$DOi`9`tONCULF71DCw4`%l+^Vfh1BS zwDr_Otu8)C>ntAA-}aNa9IF&^IXjiZKS1<&p34c6vg6fF6_?=7T5*asO0y7OE>Tr7 zyiV=pQt$>ZULp1o^)TNSBlHBU=FK6#2SM?az%v3ifk6O!xc!P&x0p(a#G6!YK6?6w zSSD$Uz#{_h5ukHZY!dhpfsYA%Lf~Bj^p}X;@ga^d#;^o-$7V!|9MvP+!EqU$tusw( zwn@#2k4UaTV2i*HsYMJ?z>H6DR?&0f`&9Qnf!`y*2;>QH0g#d-6VwJ!e0f)dk zff9i-0hd69K$XA;1Ox$(0R62XY6PAW*dRdBjtbJ$YrMKvZJfKV^qe{mZ=Cxm+LjbG zE;p;(ww5ch@;L7X;fjj5{UjnPY7rO`*~o9SChJxZ-`*x0^mYJZuvoI)UOf?u!H2_d z44w+F>ej7T0{#+w)3MNt$&*d^JN@>*L5X~u{wo1r{gh`YD)9Q>0O8e!)n#?0x?>ne Q%%Fs3(6D}_J+RFG1?ZR diff --git a/inkycal/modules/inkycal_rss.py b/inkycal/modules/inkycal_rss.py index 52bbd7e..763ddbc 100644 --- a/inkycal/modules/inkycal_rss.py +++ b/inkycal/modules/inkycal_rss.py @@ -5,7 +5,7 @@ RSS module for Inky-Calendar Project Copyright by aceisace """ -from inkycal.custom import * +from inkycal.render.functions import * from random import shuffle try: @@ -20,13 +20,7 @@ size = (384, 160) config = {'rss_urls': ['http://feeds.bbci.co.uk/news/world/rss.xml#']} -class rss: - """RSS class - parses rss feeds from given urls and writes them on the image - """ - - logger = logging.getLogger(__name__) - logging.basicConfig(level=logging.DEBUG) +class inkycal_rss: def __init__(self, section_size, section_config): """Initialize inkycal_rss module""" @@ -37,8 +31,8 @@ class rss: self.background_colour = 'white' self.font_colour = 'black' self.fontsize = 12 - self.font = ImageFont.truetype(fonts['NotoSans-SemiCondensed'], - size = self.fontsize) + self.font = ImageFont.truetype( + fonts['NotoSans-SemiCondensed'], size = self.fontsize) self.padding_x = 0.02 self.padding_y = 0.05 print('{0} loaded'.format(self.name)) @@ -72,20 +66,11 @@ class rss: im_width = int(self.width - (self.width * 2 * self.padding_x)) im_height = int(self.height - (self.height * 2 * self.padding_y)) im_size = im_width, im_height - logging.info('image size: {} x {} px'.format(im_width, im_height)) # Create an image for black pixels and one for coloured pixels im_black = Image.new('RGB', size = im_size, color = self.background_colour) im_colour = Image.new('RGB', size = im_size, color = 'white') - # Check if internet is available - if internet_available() == True: - logging.info('Connection test passed') - else: - logging.error('Network could not be reached :/') - raise Exception('Network could not be reached :(') - - # Set some parameters for formatting rss feeds line_spacing = 1 line_height = self.font.getsize('hg')[1] + line_spacing @@ -99,6 +84,11 @@ class rss: line_positions = [ (0, spacing_top + _ * line_height ) for _ in range(max_lines)] + if internet_available() == True: + print('Connection test passed') + else: + # write 'No network available :(' + raise Exception('Network could not be reached :(') try: # Create list containing all rss-feeds from all rss-feed urls diff --git a/inkycal/modules/inkycal_weather.py b/inkycal/modules/inkycal_weather.py deleted file mode 100644 index dc135e3..0000000 --- a/inkycal/modules/inkycal_weather.py +++ /dev/null @@ -1,479 +0,0 @@ -#!/usr/bin/python3 -# -*- coding: utf-8 -*- -""" -Weather module for Inky-Calendar software. -Copyright by aceisace -""" - -from inkycal.custom import * -import pyowm -import math, decimal -import arrow -from locale import getdefaultlocale as sys_locale - -config = {'api_key': 'top-secret', 'location': 'Stuttgart, DE'} -size = (384,80) - -class weather: - logger = logging.getLogger(__name__) - logging.basicConfig(level=logging.INFO) - - def __init__(self, section_size, section_config): - """Initialize inkycal_weather module""" - self.name = os.path.basename(__file__).split('.py')[0] - self.config = section_config - self.width, self.height = section_size - self.background_colour = 'white' - self.font_colour = 'black' - self.fontsize = 12 - self.font = ImageFont.truetype(fonts['NotoSans-SemiCondensed'], - size = self.fontsize) - self.padding_x = 0.02 - self.padding_y = 0.05 - - # Weather-specfic options - self.owm = pyowm.OWM(config['api_key']) - self.units = 'metric' # metric # imperial - self.hour_format = '12' # 12 #24 - self.timezone = get_system_tz() - self.round_temperature = True - self.round_windspeed = True - self.use_beaufort = True - self.show_wind_direction = False - self.use_wind_direction_icon = False - self.forecast_interval = 'hourly' # daily # hourly - self.locale = sys_locale()[0] - self.weatherfont = ImageFont.truetype(fonts['weathericons-regular-webfont'], - size = self.fontsize) - - print('{0} loaded'.format(self.name)) - - def set(self, **kwargs): - """Manually set some parameters of this module""" - - for key, value in kwargs.items(): - if key in self.__dict__: - setattr(self, key, value) - else: - print('{0} does not exist'.format(key)) - pass - - def get(self, **kwargs): - """Manually get some parameters of this module""" - - for key, value in kwargs.items(): - if key in self.__dict__: - getattr(self, key, value) - else: - print('{0} does not exist'.format(key)) - pass - - - def get_options(self): - """Get all options which can be changed""" - - return self.__dict__ - - - def generate_image(self): - """Generate image for this module""" - - # Define new image size with respect to padding - im_width = int(self.width - (self.width * 2 * self.padding_x)) - im_height = int(self.height - (self.height * 2 * self.padding_y)) - im_size = im_width, im_height - logging.info('image size: {} x {} px'.format(im_width, im_height)) - - # Create an image for black pixels and one for coloured pixels - im_black = Image.new('RGB', size = im_size, color = self.background_colour) - im_colour = Image.new('RGB', size = im_size, color = 'white') - - # Check if internet is available - if internet_available() == True: - logging.info('Connection test passed') - else: - raise Exception('Network could not be reached :(') - - def get_moon_phase(): - """Calculate the current (approximate) moon phase""" - - dec = decimal.Decimal - diff = now - arrow.get(2001, 1, 1) - days = dec(diff.days) + (dec(diff.seconds) / dec(86400)) - lunations = dec("0.20439731") + (days * dec("0.03386319269")) - position = lunations % dec(1) - index = math.floor((position * dec(8)) + dec("0.5")) - return {0: '\uf095',1: '\uf099',2: '\uf09c',3: '\uf0a0', - 4: '\uf0a3',5: '\uf0a7',6: '\uf0aa',7: '\uf0ae' }[int(index) & 7] - - - def is_negative(temp): - """Check if temp is below freezing point of water (0°C/30°F) - returns True if temp below freezing point, else False""" - answer = False - - if temp_unit == 'celsius' and round(float(temp.split('°')[0])) <= 0: - answer = True - elif temp_unit == 'fahrenheit' and round(float(temp.split('°')[0])) <= 0: - answer = True - return answer - - # Lookup-table for weather icons and weather codes - weathericons = { - '01d': '\uf00d', '02d': '\uf002', '03d': '\uf013', - '04d': '\uf012', '09d': '\uf01a ', '10d': '\uf019', - '11d': '\uf01e', '13d': '\uf01b', '50d': '\uf014', - '01n': '\uf02e', '02n': '\uf013', '03n': '\uf013', - '04n': '\uf013', '09n': '\uf037', '10n': '\uf036', - '11n': '\uf03b', '13n': '\uf038', '50n': '\uf023' - } - - - def draw_icon(image, xy, box_size, icon, rotation = None): - """Custom function to add icons of weather font on image - image = on which image should the text be added? - xy = xy-coordinates as tuple -> (x,y) - box_size = size of text-box -> (width,height) - icon = icon-unicode, looks this up in weathericons dictionary - """ - x,y = xy - box_width, box_height = box_size - text = icon - font = self.weatherfont - - # Increase fontsize to fit specified height and width of text box - size = 8 - font = ImageFont.truetype(font.path, size) - text_width, text_height = font.getsize(text) - while (text_width < int(box_width * 0.9) and - text_height < int(box_height * 0.9)): - size += 1 - font = ImageFont.truetype(font.path, size) - text_width, text_height = font.getsize(text) - - text_width, text_height = font.getsize(text) - - # Align text to desired position - x = int((box_width / 2) - (text_width / 2)) - y = int((box_height / 2) - (text_height / 2)) - - # Draw the text in the text-box - draw = ImageDraw.Draw(image) - space = Image.new('RGBA', (box_width, box_height)) - ImageDraw.Draw(space).text((x, y), text, fill='black', font=font) - - if rotation != None: - space.rotate(rotation, expand = True) - - # Update only region with text (add text with transparent background) - image.paste(space, xy, space) - - - -# column1 column2 column3 column4 column5 column6 column7 -# |----------|----------|----------|----------|----------|----------|----------| -# | time | temperat.| moonphase| forecast1| forecast2| forecast3| forecast4| -# | current |----------|----------|----------|----------|----------|----------| -# | weather | humidity | sunrise | icon1 | icon2 | icon3 | icon4 | -# | icon |----------|----------|----------|----------|----------|----------| -# | | windspeed| sunset | temperat.| temperat.| temperat.| temperat.| -# |----------|----------|----------|----------|----------|----------|----------| - - - # Calculate size rows and columns - col_width = im_width // 7 - - if (im_height // 3) > col_width//2: - row_height = (im_height // 4) - else: - row_height = (im_height // 3) - - - # Adjust the fontsize to make use of most free space - # self.font = auto_fontsize(self.font, row_height) - - # Calculate spacings for better centering - spacing_top = int( (im_width % col_width) / 2 ) - spacing_left = int( (im_height % row_height) / 2 ) - - # Define sizes for weather icons - icon_small = int(col_width / 3) - icon_medium = icon_small * 2 - icon_large = icon_small * 3 - - print('col_width=', col_width, 'row_height:', row_height) - print('small, medium ,large:', icon_small, icon_medium, icon_large) - - # Calculate the x-axis position of each col - col1 = spacing_top - col2 = col1 + col_width - col3 = col2 + col_width - col4 = col3 + col_width - col5 = col4 + col_width - col6 = col5 + col_width - col7 = col6 + col_width - - # Calculate the y-axis position of each row - row1 = spacing_left - row2 = row1 + row_height - row3 = row2 + row_height - - # Positions for current weather details - weather_icon_pos = (col1, row1) - temperature_icon_pos = (col2, row1) - temperature_pos = (col2+icon_small, row1) - - print('temp icon pos:', temperature_icon_pos) - print('temp:', temperature_pos) - - humidity_icon_pos = (col2, row2) - humidity_pos = (col2+icon_small, row2) - - print('hum icon pos:', humidity_icon_pos) - print('hum pos:', humidity_pos) - - windspeed_icon_pos = (col2, row3) - windspeed_pos = (col2+icon_small, row3) - - # Positions for sunrise, sunset, moonphase - moonphase_pos = (col3, row1) - sunrise_icon_pos = (col3, row2) - sunrise_time_pos = (col3+icon_small, row2) - sunset_icon_pos = (col3, row3) - sunset_time_pos = (col3+ icon_small, row3) - - # Positions for forecast 1 - stamp_fc1 = (col4, row1) - icon_fc1 = (col4, row2) - temp_fc1 = (col4, row3) - - # Positions for forecast 2 - stamp_fc2 = (col5, row1) - icon_fc2 = (col5, row2) - temp_fc2 = (col5, row3) - - # Positions for forecast 3 - stamp_fc3 = (col6, row1) - icon_fc3 = (col6, row2) - temp_fc3 = (col6, row3) - - # Positions for forecast 4 - stamp_fc4 = (col7, row1) - icon_fc4 = (col7, row2) - temp_fc4 = (col7, row3) - - # Create current-weather and weather-forecast objects - weather = self.owm.weather_at_place(self.config['location']).get_weather() - forecast = self.owm.three_hours_forecast(self.config['location']) - - # Set decimals - dec_temp = None if self.round_temperature == True else 1 - dec_wind = None if self.round_windspeed == True else 1 - - # Set correct temperature units - if self.units == 'metric': - temp_unit = 'celsius' - elif self.units == 'imperial': - temp_unit = 'fahrenheit' - - - # Get current time - now = arrow.utcnow() - - if self.forecast_interval == 'hourly': - - # Forecasts are provided for every 3rd full hour - # find out how many hours there are until the next 3rd full hour - if (now.hour % 3) != 0: - hour_gap = 3 - (now.hour % 3) - else: - hour_gap = 3 - - # Create timings for hourly forcasts - forecast_timings = [now.shift(hours = + hour_gap + _).floor('hour') - for _ in range(0,12,3)] - - # Create forecast objects for given timings - forecasts = [forecast.get_weather_at(forecast_time.datetime) for - forecast_time in forecast_timings] - - # Add forecast-data to fc_data dictionary - fc_data = {} - for forecast in forecasts: - temp = '{}°'.format(round( - forecast.get_temperature(unit=temp_unit)['temp'], ndigits=dec_temp)) - - icon = forecast.get_weather_icon_name() - fc_data['fc'+str(forecasts.index(forecast)+1)] = { - 'temp':temp, - 'icon':icon, - 'stamp': forecast_timings[forecasts.index(forecast)].format('H.00' - if self.hour_format == '24' else 'h a') - } - - elif self.forecast_interval == 'daily': - - def calculate_forecast(days_from_today): - """Get temperature range and most frequent icon code for forecast - days_from_today should be int from 1-4: e.g. 2 -> 2 days from today - """ - - # Create a list containing time-objects for every 3rd hour of the day - time_range = list(arrow.Arrow.range('hour', - now.shift(days=days_from_today).floor('day'), - now.shift(days=days_from_today).ceil('day') - ))[::3] - - # Get forecasts for each time-object - forecasts = [forecast.get_weather_at(_.datetime) for _ in time_range] - - - # Get all temperatures for this day - daily_temp = [round(_.get_temperature(unit=temp_unit)['temp'], - ndigits=dec_temp) for _ in forecasts] - # Calculate min. and max. temp for this day - temp_range = '{}°/{}°'.format(max(daily_temp), min(daily_temp)) - - - # Get all weather icon codes for this day - daily_icons = [_.get_weather_icon_name() for _ in forecasts] - # Find most common element from all weather icon codes - status = max(set(daily_icons), key=daily_icons.count) - - weekday = now.shift(days=days_from_today).format('ddd', locale= - self.locale) - return {'temp':temp_range, 'icon':status, 'stamp': weekday} - - fc_data = [calculate_forecast(days) for days in range (1,5)] - - for key,val in fc_data.items(): - logging.info((key,val)) - - # Get some current weather details - temperature = '{}°'.format(weather.get_temperature(unit=temp_unit)['temp']) - weather_icon = weather.get_weather_icon_name() - humidity = str(weather.get_humidity()) - windspeed = weather.get_wind(unit='meters_sec')['speed'] - wind_angle = weather.get_wind()['deg'] - wind_direction = ["N","NE","E","SE","S","SW","W","NW"][round( - wind_angle/45) % 8] - sunrise_raw = arrow.get(weather.get_sunrise_time()).to(self.timezone) - sunset_raw = arrow.get(weather.get_sunset_time()).to(self.timezone) - - if self.hour_format == '12': - sunrise = sunrise_raw.format('h:mm a') - sunset = sunset_raw.format('h:mm a') - elif self.hour_format == '24': - sunrise = sunrise_raw.format('H:mm') - sunset = sunset_raw.format('H:mm') - - # Format the windspeed to user preference - if self.use_beaufort == True: - windspeed_to_beaufort = [0.02, 1.5, 3.3, 5.4, 7.9, 10.7, 13.8, 17.1, - 20.7, 24.4, 28.4, 32.6, 100] - wind = str([windspeed_to_beaufort.index(_) for _ in windspeed_to_beaufort - if windspeed < _][0]) - - elif self.use_beaufort == False: - meters_sec = round(windspeed, ndigits = dec_wind) - miles_per_hour = round(windspeed * 2.23694, ndigits = dec_wind) - - if self.units == 'metric': - wind = str(meters_sec) + 'm/s' - - elif self.units == 'imperial': - wind = str(miles_per_hour) + 'mph' - - if self.show_wind_direction == True: - wind += '({0})'.format(wind_direction) - - - dec = decimal.Decimal - moonphase = get_moon_phase() - - # Fill weather details in col 1 (current weather icon) - # write(im_black, (col_width, row_height), now_str, text_now_pos, font = font) - draw_icon(im_colour, weather_icon_pos, (icon_large, icon_large), - weathericons[weather_icon]) - - # Fill weather details in col 2 (temp, humidity, wind) - draw_icon(im_colour, temperature_icon_pos, (row_height, row_height), - '\uf053') - - if is_negative(temperature): - write(im_black, temperature_pos, (col_width-icon_small, row_height), - temperature, font = self.font, fill_height = 0.9) - else: - write(im_black, temperature_pos, (col_width-icon_small, row_height), - temperature, font = self.font) - - draw_icon(im_colour, humidity_icon_pos, (row_height, row_height), - '\uf07a') - - write(im_black, humidity_pos, (col_width-icon_small, row_height), - humidity+'%', font = self.font, fill_height = 0.9) - - if self.use_wind_direction_icon == False: - draw_icon(im_colour, windspeed_icon_pos, (icon_small, icon_small), - '\uf050') - else: - draw_icon(im_colour, windspeed_icon_pos, (icon_small, icon_small), - '\uf0b1', rotation = -wind_degrees) - - write(im_black, windspeed_pos, (col_width-icon_small, row_height), - wind, font=self.font, fill_height = 0.9) - - # Fill weather details in col 3 (moonphase, sunrise, sunset) - draw_icon(im_colour, moonphase_pos, (col_width, row_height), moonphase) - - draw_icon(im_colour, sunrise_icon_pos, (icon_small, icon_small), '\uf051') - write(im_black, sunrise_time_pos, (col_width-icon_small, icon_small), sunrise, - font = self.font, autofit = True) - - draw_icon(im_colour, sunset_icon_pos, (icon_small, icon_small), '\uf052') - write(im_black, sunset_time_pos, (col_width-icon_small, icon_small), sunset, - font = self.font, autofit = True) - - # Add the forecast data to the correct places - for pos in range(1, len(fc_data)+1): - stamp = fc_data['fc'+str(pos)]['stamp'] - icon = weathericons[fc_data['fc'+str(pos)]['icon']] - temp = fc_data['fc'+str(pos)]['temp'] - - write(im_black, eval('stamp_fc'+str(pos)), (col_width, row_height), - stamp, font = self.font) - draw_icon(im_colour, eval('icon_fc'+str(pos)), (col_width, row_height), - icon) - write(im_black, eval('temp_fc'+str(pos)), (col_width, row_height), - temp, font = self.font) - - # Add borders around each sub-section - square_h = int((row_height*3)*0.9) - square_w = int((col_width*0.9)) - draw_square(im_colour, (col1, row1), (col_width*3, square_h)) - draw_square(im_colour, (col4, row1), (square_w, square_h)) - draw_square(im_colour, (col5, row1), (square_w, square_h)) - draw_square(im_colour, (col6, row1), (square_w, square_h)) - draw_square(im_colour, (col7, row1), (square_w, square_h)) - -## except Exception as e: -## """If something went wrong, print a Error message on the Terminal""" -## print('Failed!') -## print('Error in weather module!') -## print('Reason: ',e) -## clear_image('top_section') -## write(top_section_width, top_section_height, str(e), -## (0, 0), font = font) -## weather_image = crop_image(image, 'top_section') -## weather_image.save(image_path+'inkycal_weather.png') -## pass -## - # Save image of black and colour channel in image-folder - im_black.save(images+self.name+'.png') - im_colour.save(images+self.name+'_colour.png') - -if __name__ == '__main__': - print('running {0} in standalone mode'.format( - os.path.basename(__file__).split('.py')[0])) - a = weather(size, config) - a.generate_image()