From 4addf5bc85e03cb022c026f8fff145fe7bfe2b5d Mon Sep 17 00:00:00 2001 From: EMF Villager Date: Sat, 1 Sep 2018 17:52:37 +0200 Subject: [PATCH] Add TiNDA app --- tinda/main.py | 186 +++++++++++++++++++++++++ tinda/questions.json | 316 +++++++++++++++++++++++++++++++++++++++++++ tinda/splash.gif | Bin 0 -> 4103 bytes 3 files changed, 502 insertions(+) create mode 100644 tinda/main.py create mode 100644 tinda/questions.json create mode 100644 tinda/splash.gif diff --git a/tinda/main.py b/tinda/main.py new file mode 100644 index 0000000..7095b8c --- /dev/null +++ b/tinda/main.py @@ -0,0 +1,186 @@ +""" +TiNDA: A dating app for TiLDA. Find your perfect EMF match! +""" +___name___ = "tinda" +___license___ = "WTFPL" +___dependencies___ = ["app", "buttons", "database", "dialogs", "http", "sleep", "ugfx_helper"] +___categories___ = ["Other", "EMF"] + +import database +import dialogs +import http +import json +import sleep +import ugfx +import ugfx_helper + +from app import * +from buttons import is_pressed +from tilda import Buttons + +# +# CONFIGURATION +# + +ENABLE_SPLASH_SCREEN = True + +APP_TITLE = "TiNDA" +APP_COLOUR = ugfx.html_color(0x800080) +LOCAL_FOLDER = 'tinda/%s' +CARD_API_ENDPOINT = "http://d1obbkgck7qwwy.cloudfront.net" +QR_API_ENDPOINT = "http://api.qrserver.com/v1/create-qr-code/?size=231x231&format=gif&data=%s" + +DB_KEY_ANSWERS = "tinda_app_answers" +DB_KEY_CARD = "tinda_app_card" +DB_KEY_QR = "tinda_app_qr" + +# +# FUNCTIONS +# +def get_questions(): + with open(LOCAL_FOLDER % "questions.json", "r") as f: + data = json.load(f) + return data["questions"] + +def get_image_urls(answers): + try: + with dialogs.WaitingMessage("Sending data...", title=APP_TITLE): + response = http.post(CARD_API_ENDPOINT, json={"answers": answers}).raise_for_status() + + data = response.json() + url = json.loads(data["body"])["url"] + + database.set(DB_KEY_CARD, url) + database.set(DB_KEY_QR, QR_API_ENDPOINT % url) + + return True + except Exception as ex: + dialogs.notice(repr(ex), title="%s - Download failed" % APP_TITLE) + +# +# VIEWS +# + +def show_spash_screen(): + if ENABLE_SPLASH_SCREEN: + ugfx.display_image(0, 0, LOCAL_FOLDER % "splash.gif") + sleep.sleep_ms(1000) + +def show_menu(): + menu_items = [ + {"title": "Answer questions", "function": show_questions}, + {"title": "View emoji card", "function": show_card}, + {"title": "Share emoji card", "function": show_share}, + {"title": "Manual", "function": show_manual} + ] + + option = dialogs.prompt_option( + menu_items, none_text="Exit", text="Menu", title=APP_TITLE) + + if option: + option["function"]() + +def show_manual(): + ugfx.clear(APP_COLOUR) + window = ugfx.Container(0, 0, ugfx.width(), ugfx.height()) + window.show() + window.text(5, 10, "TiNDA: Dating app for TiLDA", ugfx.BLACK) + window.text(5, 30, "Find your perfect EMF match", ugfx.BLACK) + window.line(0, 50, ugfx.width(), 50, ugfx.BLACK) + + window.text(5, 60, "Step 1: Answer all questions", ugfx.BLACK) + window.text(5, 80, "and receive an emoji card.", ugfx.BLACK) + + window.text(5, 110, "Step 2: Compare cards with", ugfx.BLACK) + window.text(5, 130, "other people and count", ugfx.BLACK) + window.text(5, 150, "matching emoji.", ugfx.BLACK) + + window.text(5, 180, "Step 3: <3", ugfx.BLACK) + + while ((not Buttons.is_pressed(Buttons.BTN_B)) and (not Buttons.is_pressed(Buttons.BTN_Menu))): + sleep.wfi() + +def show_questions(): + answer_items = [] + answers = None + + questions = get_questions() + + if questions: + for i, question in enumerate(questions): + # add 3rd option "skip" to all questions + question["options"].append({"title": "Skip", "value": "0"}) + + title = "TiNDA - Question %i/%i" % (i + 1, len(questions)) + option = dialogs.prompt_option(question["options"], text=question["text"], select_text="OK", none_text="Skip", title=title) + + if option: + answer_items.append(option["value"]) + else: + answer_items.append("0") + + answers = "".join(answer_items) + + database.set(DB_KEY_ANSWERS, answers) + + if get_image_urls(answers): + show_card() + +def show_card(): + url = database.get(DB_KEY_CARD) + + if url: + try: + with dialogs.WaitingMessage("Loading data...", title=APP_TITLE): + image = http.get(url).raise_for_status().content + ugfx.display_image(0, 0, bytearray(image)) + + while ((not Buttons.is_pressed(Buttons.BTN_B)) and (not Buttons.is_pressed(Buttons.BTN_Menu))): + sleep.wfi() + except Exception as ex: + dialogs.notice(repr(ex), title="%s - Download failed" % APP_TITLE) + else: + dialogs.notice("Please answer the questions first", title=APP_TITLE) + show_menu() + +def show_share(): + ugfx.clear(APP_COLOUR) + url = database.get(DB_KEY_QR) + + if url: + dialogs.notice("Scan the QR code with your phone and share your emoji card online.", title=APP_TITLE) + + try: + with dialogs.WaitingMessage("Loading data...", title=APP_TITLE): + image = http.get(url).raise_for_status().content + ugfx.clear(APP_COLOUR) + ugfx.display_image(5, 45, bytearray(image)) + + while (not is_pressed(Buttons.BTN_B)) and (not is_pressed(Buttons.BTN_Menu)): + sleep.wfi() + except Exception as ex: + dialogs.notice(repr(ex), title="%s - Download failed" % APP_TITLE) + else: + dialogs.notice("Please answer the questions first", title=APP_TITLE) + show_menu() + +# +# INITIALIZATION +# + +ugfx_helper.init() +ugfx.clear(APP_COLOUR) + +# +# START +# + +show_spash_screen() + +while True: + show_menu() + + while (not is_pressed(Buttons.BTN_B)) and (not is_pressed(Buttons.BTN_Menu)): + sleep.wfi() + +restart_to_default() diff --git a/tinda/questions.json b/tinda/questions.json new file mode 100644 index 0000000..0d18c77 --- /dev/null +++ b/tinda/questions.json @@ -0,0 +1,316 @@ +{ + "questions":[ + { + "text":"Dogs or cats?", + "options":[ + { + "title":"Dogs", + "value":"1" + }, + { + "title":"Cats", + "value":"2" + } + ] + }, + { + "text":"iOS or Android?", + "options":[ + { + "title":"iOS", + "value":"1" + }, + { + "title":"Android", + "value":"2" + } + ] + }, + { + "text":"Beer or Club-Mate?", + "options":[ + { + "title":"Beer", + "value":"1" + }, + { + "title":"Club-Mate", + "value":"2" + } + ] + }, + { + "text":"Meat or vegan?", + "options":[ + { + "title":"Meat", + "value":"1" + }, + { + "title":"Vegan", + "value":"2" + } + ] + }, + { + "text":"Fantasy or sci-fi?", + "options":[ + { + "title":"Fantasy", + "value":"1" + }, + { + "title":"Sci-fi", + "value":"2" + } + ] + }, + { + "text":"Breakfast...?", + "options":[ + { + "title":"English breakfast", + "value":"1" + }, + { + "title":"Continental breakfast", + "value":"2" + } + ] + }, + { + "text":"Cash or card?", + "options":[ + { + "title":"Cash", + "value":"1" + }, + { + "title":"Card", + "value":"2" + } + ] + }, + { + "text":"Tent or caravan/camper?", + "options":[ + { + "title":"Tent", + "value":"1" + }, + { + "title":"Caravan/camper", + "value":"2" + } + ] + }, + { + "text":"Twitter or Facebook?", + "options":[ + { + "title":"Twitter", + "value":"1" + }, + { + "title":"Facebook", + "value":"2" + } + ] + }, + { + "text":"Music or podcasts?", + "options":[ + { + "title":"Music", + "value":"1" + }, + { + "title":"Podcasts", + "value":"2" + } + ] + }, + { + "text":"Early bird or night owl?", + "options":[ + { + "title":"Early bird", + "value":"1" + }, + { + "title":"Night owl", + "value":"2" + } + ] + }, + { + "text":"Eastnor Castle or Obelisk?", + "options":[ + { + "title":"Eastnor Castle", + "value":"1" + }, + { + "title":"Eastnor Obelisk", + "value":"2" + } + ] + }, + { + "text":"Doctor Who or Black Mirror?", + "options":[ + { + "title":"Doctor Who", + "value":"1" + }, + { + "title":"Black Mirror", + "value":"2" + } + ] + }, + { + "text":"Coffee or tea?", + "options":[ + { + "title":"Coffee", + "value":"1" + }, + { + "title":"Tea", + "value":"2" + } + ] + }, + { + "text":"Orwell or Douglas Adams?", + "options":[ + { + "title":"George Orwell", + "value":"1" + }, + { + "title":"Douglas Adams", + "value":"2" + } + ] + }, + { + "text":"Beach or mountains?", + "options":[ + { + "title":"Beach", + "value":"1" + }, + { + "title":"Mountains", + "value":"2" + } + ] + }, + { + "text":"Video or board games?", + "options":[ + { + "title":"Video games", + "value":"1" + }, + { + "title":"Board games", + "value":"2" + } + ] + }, + { + "text":"Talks or Null Sector?", + "options":[ + { + "title":"Talks", + "value":"1" + }, + { + "title":"Null Sector", + "value":"2" + } + ] + }, + { + "text":"Doughmain or Grazing Shed?", + "options":[ + { + "title":"Pizza Doughmain", + "value":"1" + }, + { + "title":"Grazing Shed", + "value":"2" + } + ] + }, + { + "text":"Leave or remain?", + "options":[ + { + "title":"Leave", + "value":"1" + }, + { + "title":"Remain", + "value":"2" + } + ] + }, + { + "text":"Netflix or YouTube?", + "options":[ + { + "title":"Netflix", + "value":"1" + }, + { + "title":"YouTube", + "value":"2" + } + ] + }, + { + "text":"Hardware or software?", + "options":[ + { + "title":"Hardware", + "value":"1" + }, + { + "title":"Software", + "value":"2" + } + ] + }, + { + "text":"Year-round...", + "options":[ + { + "title":"Summer Time", + "value":"1" + }, + { + "title":"Standard Time", + "value":"2" + } + ] + }, + { + "text":"Is this your first EMF camp?", + "options":[ + { + "title":"Yes", + "value":"1" + }, + { + "title":"No", + "value":"2" + } + ] + } + ] +} \ No newline at end of file diff --git a/tinda/splash.gif b/tinda/splash.gif new file mode 100644 index 0000000000000000000000000000000000000000..65116cb76989b604adde90b7270a875a2debbd6e GIT binary patch literal 4103 zcmb7>?hBuL_c3XfJI0pQeUr#)LJGuRKdH(yE|E6c) zrVnn*CuqwDyXhagcX*_6XIcRA;c-MZ|+J4yHb=cK+)IW6eapd^(*zwoNlj+%$Z}X>% zOQ$Pqe}8WL-P}6c+dDfrq|s>qH|PIX7mlEe03Z*@{)heN1klr{I5z`XL1J%#N1v;D z&TxsBQN@F*iE^KTUjZNHs{M@RGC!@>2Mj%@eBXNe(xhs7^YC5Jr_B=@7KaZB4GWKm zBt%8W#KsZh6B3h>Q&LH3=^2?>ud{Q=xq0~og+;|BrDbo*D=Mq1YijH28ycJ5Hn&jT zy>It)wR{djbFc~ zf2{B9?k#T~9ByUrpZ+~N0;aom^{dJ6vG6ul<=*NG^`RV;%U%W}=+0jY4G}_SdIY0nB_z_gblVh2=q7&eYcAU}=)%AWF?a9z?@)$P z^dBK!T~U5IP+%3|_4?S=byCPF@Dk{?!b^|01Z0 zh||vTpr36Tnu%h64fogtL*=B*LQZ1qvqJZUEpuLN+4a&Af>zy2$PohgRa<;~yyXIt zZHHk#5|Q^f4@=k1k5T6dpGfyrT|kQARf;C^iL&O77l=1n?iIvo9Fvx`7wXf@yzbcU zE{0!ZvU+mWLKB%4`|xx95yz%QU+RQeK7B)ijg!q)fOS09w+y?R5_=tc}*;z zzCkj}z1FG_Sr*i>g3MsL^fcxhy#KaR;gmqx#p}P1Q6Pgb^^4hit}+f)m~6Ec9jh$$ zdj<1z&r&)*F9iq_qJ#=zMv&1ua6uFbsG1)Xq?yp2bJKz}-G3F0hw~%nV&9B0QGY^3 z$-`qGObBRP^t#U?z#svXS2IgIMqxRQ$x*qjAO{)uf%)kMo=I3%ROZdJWqfrva~-v< zBgjKArvZFShV&`ak#VZ)W(rpZ1?sS1Cl~E$1)b!atQQlfg3Dv@B0RQ^k(K|rlZO4^1`yGmkVI!(iunYP*oapMH+tnp{T%wZgi z6Zuf9ju}O6gFE;>X@|&o73wft$_F6yuf%x$7^EFpAhQwWGsbX%d~zFPLRi#eC5$u! zLO1WZDN!$=Z6lY3WwY=w9)@9BoDvVZ+}lFvEz$&LMK^={l1?g?hcO3h)l?^}Q*Lii z7VqJEUNTaf+XV`&ulXE{pju$7l^sLSLYEosr)Dz3xIb0F#hd%Io9Mt_3opKCZ6QC+ zi~#4P%5`$XoO8VP&Vga3RG+=AZpc<~O_?23q?cRdguX_E3oxdG8WCya=v#<964g2=CCqy?l-F4nQng13jHTZ&bbCKx{u$VHJK7bpeO>GAavQ%B1k zkjZLT#?t}lbZ6{ukDZ~@$fSS9g|X*6@p!L(hu26aN$Ky5cWnE2AMF>Ay;@2?z1s22 zI#Vv5-{=!`T-J?eQ7cg)V26TL%*cb=)DH^qk8VcFN!Kt%vH}kTSx;|4zwE8*FE$(4 zC+;cHGCLWWvQ|D4jY9K++KZW`w#)`E0chKek{H)1$!mf;kC<1b9lWA&$!sYlsz0pY zlq+`&jU3{11#owBn8q}U$_wQjU*G5BzFTEbTZHNolc8KSZ?CQ`)v0)7;hSFTx~>bx z$+B7MHQ#rwcCDmr6zbLWGH|DkWxgt8tP)0pEa*9i4%7g~L153;u9e{v-4N;D?Mad_ zw`lCZn%o^$eA#L8R3Y6?@ci<9;S7aTjnj=A8QQr1C&th}&OP_sbs+t%7@+)}wTq1g z6%ba5s@=Z_px-FY#O0Tl4D|rU&YkmT7c|k{Ap2rjEKqRA>0+d-YRN!LKQ9o!I!fDc znB~I`IH)v3V?;Wx%wg$}qIBx86rJ8%$(2?IE!zShm8ooEw|^Yrkso6WI!5lV4!l=W z1ARM4vvl&tu+md{R>e2A!C$pKC&S*PK-?^uoZfW+{3_t<^;X%A?;wa2n7DLP_2!(J%BNDP17~Soo3en${j3ShZ72>)$nD7MSZG@wVf|49;|zzM>s-9Md06=33}62E%d&AZTV(L+3~yZ9zPy*HysVhfpC5a041}RYz~y%9CD7 z*vRT;*%V_#29wmxOx9o5p_H`z=bw}Qxvl2H8+=>m__Gw14Qc0Itou;|s^TtbuKOMc z6loEzyVZPs(-}q{0Xp0~Fe+Sdslo7_-%THGS+C(99gEX{Rd%_*{Nk*2d_G&y@IB>X zrvXdfkR1AA_sV#Jp)ZV1^i@VwR+D?4o7N|fFu3_;!}08jYXB#0oF2_49!Wh(Hf=Z> z5*UVrwKdEN+=(QTxOwb)N#);Jjj^ZsN}n}6xBr?$S!=Jq)`C#v(2u|H|e$9hd>3z;C{3+{Nf z9Vl(ysO4SoZ5eyn8$fKtzg)^3@yj}V@BcgPsBdLt&?9b(W4a5e%?WxF}q8Hsi zXkE`Aw9<_un>E%{{`Hycv01-#Ucbm)htj{(dH`~~3NF;l5n|vH4GX@nl>EXsn~1?N zV<=uk`M<#6*^&ZZ1YN%>?%xY}ckLcdjEwBZ!jt1*&A-?_>?@Rgk&ns$cyg1V%1i5{ zV$S^I5jnO!toMn z2^lNEmDcLKjNmrA1e8lc7Ig9Aj+Z6*%^9$P7Y-G!INV#gr zlSUWiOaCr4cv|y7C_W@0k%Wa|Jw>@Wv5@I~O{6wJ-t!nq-m==c_0E(>Yu5(7Ju2@TGr5pf;1YZa~+^d9c@kxE98NqjbsHdB1f-> zznEYx6Xr~_Y`RD++JJC;8mMrk-|-oURsF6Uj-V3R8FQSxvq}wZAmfQQYN9bE+);hv zkd`p0vmouhQ_4n@npC9LZl?t(n7v>a>{bITEkjmzS!#4+IRE#bj>OHrT=B_gX4DKcd{hf6cHB3Xe z5p#M_l$r*q0M>Zkcq;#^+PQaJARnN{vumT{A5l@96qQJ_alXr0Mi@c6%K&Pf#YJB2 zMX_sXZYaT7YzqFVlFhb%^4kLc<03c3AY?A_5^o+mx)_fy4qGpHSq9?oY4~}X%k&re zmleyKTjwV$*Dz*h2$nuV2#hYX6zL}9t@A%yFG`I1=j`I^HxGC#qB32rMA%Regz_6& zgz1~HQa#v3qJ~jP!Ft|cZs8xGw2P_S!~oGhl~y%X4%aPdoyuF3uBg+i7zn7Ch$3e^ zsHp2LpH(-SVyY+%2<0PaO}E%C8dZL8DP1|n`!Q9{_gDVPs2splHceF=s^hku%1tJ! z_SEq}bmgvkbzpPV1fu$}T2}FAwd%uXIZkyNCv{pv^*S2$x)1Ab z2G$#7)*Dgkji>8PPU=xY4Q3h*_Z~Kw2R2w{Haws-SWh?Do;09^8tpY2A3too^@#e16jCCe-Ai(d6~8$tSSMFS99t(!|UK1vLH#DKV2x literal 0 HcmV?d00001