Add TiNDA app
parent
3fd67bc82a
commit
4addf5bc85
|
@ -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()
|
|
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
Binary file not shown.
After Width: | Height: | Size: 4.0 KiB |
Loading…
Reference in New Issue