Toggle Navigation
Hatchery
Eggs
Installer cached
__init__.py
Users
Badges
Login
Register
MCH2022 badge?
go to mch2022.badge.team
__init__.py
raw
Content
import ugfx, badge, network, gc, time, urequests, appglue import uos import utime # SHA2017 Badge installer # V3 Edwin Eefting (psy0rz) # V2 Thomas Roos # V1 Niek Blankers def draw_progress(msg): """draw progress data (downloading/errors etc). will also flush""" ugfx.area(148,110,148,18, ugfx.BLACK) ugfx.string_box(148,110,148,18, str(msg), "Roboto_Regular12", ugfx.WHITE, ugfx.justifyLeft) ugfx.flush() return def draw_status(msg): """update status text (e.g. 'ready') will not flush. uses same area as draw progress""" ugfx.area(148,110,148,18, ugfx.WHITE) ugfx.string_box(148,110,148,18, str(msg), "Roboto_Regular12", ugfx.BLACK, ugfx.justifyLeft) return def connectWiFi(): """makes sure wifi is connected, otherwise raises exception""" nw = network.WLAN(network.STA_IF) if not nw.isconnected(): nw.active(True) ssid = badge.nvs_get_str('badge', 'wifi.ssid', 'SHA2017-insecure') password = badge.nvs_get_str('badge', 'wifi.password') nw.connect(ssid, password) if password else nw.connect(ssid) draw_progress("Connecting...") timeout = 150 while not nw.isconnected(): time.sleep(0.1) timeout = timeout - 1 if (timeout<1): raise("Timeout!") nw.active(True) def show_description(active): if active: global text if options.selected_index()>0 and options.selected_index()<len(packages): text.text(packages[options.selected_index()]["description"]) ugfx.flush() def select_category(active): if active: global categories global options index = options.selected_index() if categories[index]["eggs"] > 0: category = categories[index]["slug"] list_apps(category) def list_apps(slug, refresh=False): global options global text global packages if refresh: cache_clear() ugfx.input_attach(ugfx.JOY_UP, 0) ugfx.input_attach(ugfx.JOY_DOWN, 0) ugfx.input_attach(ugfx.BTN_A, 0) ugfx.input_attach(ugfx.BTN_B, 0) ugfx.input_attach(ugfx.BTN_START, 0) while options.count() > 0: options.remove_item(0) try: age=None url="https://badge.sha2017.org/eggs/category/%s/json" % slug packages = cache_get_json(url) age = cache_get_age(url) except Exception as e: draw_progress(e) packages = [] for package in packages: options.add_item("%s rev. %s" % (package["name"], package["revision"])) if packages: options.selected_index(0) ugfx.input_attach(ugfx.JOY_UP, show_description) ugfx.input_attach(ugfx.JOY_DOWN, show_description) ugfx.input_attach(ugfx.BTN_A, install_app) ugfx.input_attach(ugfx.BTN_B, lambda pushed: list_categories() if pushed else False) ugfx.input_attach(ugfx.BTN_START, lambda pushed: appglue.start_app('') if pushed else False) ugfx.input_attach(ugfx.BTN_SELECT, lambda pushed: list_apps(slug,True) if pushed else False) #no download error? if age!=None: show_description(True) if age: draw_status("cached: "+str(age)+"m (SEL=refresh)") else: draw_status("Ready") ugfx.flush(ugfx.LUT_NORMAL) gc.collect() def start_categories(pushed): if pushed: list_categories() def start_app(pushed): if pushed: global selected_app appglue.start_app(selected_app) def install_app(active): if active: global options global text global packages global selected_app connectWiFi() index = options.selected_index() ugfx.input_attach(ugfx.JOY_UP, 0) ugfx.input_attach(ugfx.JOY_DOWN, 0) ugfx.input_attach(ugfx.BTN_A, 0) ugfx.input_attach(ugfx.BTN_B, 0) ugfx.input_attach(ugfx.BTN_START, 0) ugfx.clear(ugfx.BLACK) ugfx.string(40,25,"Installing:","Roboto_BlackItalic24",ugfx.WHITE) ugfx.string(100,55, packages[index]["name"],"PermanentMarker22",ugfx.WHITE) ugfx.flush() import woezel selected_app = packages[index]["slug"] woezel.install(selected_app) ugfx.clear(ugfx.WHITE) ugfx.string(40,25,"Installed:","Roboto_BlackItalic24",ugfx.BLACK) ugfx.string(100,55, packages[index]["name"],"PermanentMarker22",ugfx.BLACK) ugfx.string(0, 115, "[ A: START | B: BACK ]", "Roboto_Regular12", ugfx.BLACK) ugfx.input_attach(ugfx.BTN_A, start_app) ugfx.input_attach(ugfx.BTN_B, start_categories) ugfx.input_attach(ugfx.BTN_START, lambda pushed: appglue.start_app("") if pushed else False) ugfx.flush(ugfx.LUT_NORMAL) gc.collect() def list_categories(refresh=False): global options global text global categories if refresh: cache_clear() ugfx.input_init() try: url="https://badge.sha2017.org/eggs/categories/json" age=None categories=cache_get_json(url) age=cache_get_age(url) except Exception as e: draw_progress(e) categories=[] options = ugfx.List(0,0,int(ugfx.width()/2),ugfx.height()) text = ugfx.Textbox(int(ugfx.width()/2),0, int(ugfx.width()/2), ugfx.height()) ugfx.input_attach(ugfx.JOY_UP, lambda pushed: ugfx.flush() if pushed else False) ugfx.input_attach(ugfx.JOY_DOWN, lambda pushed: ugfx.flush() if pushed else False) ugfx.input_attach(ugfx.BTN_A, select_category) ugfx.input_attach(ugfx.BTN_B, lambda pushed: appglue.start_app("launcher", False) if pushed else False) ugfx.input_attach(ugfx.BTN_START, lambda pushed: appglue.start_app("") if pushed else False) ugfx.input_attach(ugfx.BTN_SELECT, lambda pushed: list_categories(True) if pushed else False) #ugfx.clear(ugfx.WHITE) #ugfx.flush() while options.count() > 0: options.remove_item(0) for category in categories: options.add_item("%s (%d) >" % (category["name"], category["eggs"])) options.selected_index(0) text.text("Install or update eggs from the hatchery here\n\n\n\n") ugfx.string_box(148,0,148,26, "Hatchery", "Roboto_BlackItalic24", ugfx.BLACK, ugfx.justifyCenter) ugfx.line(148, 64, 296, 64, ugfx.BLACK) ugfx.string_box(148,64,148,18, " A : Open category", "Roboto_Regular12", ugfx.BLACK, ugfx.justifyLeft) ugfx.string_box(148,78,148,18, " B : Return to home", "Roboto_Regular12", ugfx.BLACK, ugfx.justifyLeft) ugfx.string_box(148,92,148,18, " SEL: Refresh", "Roboto_Regular12", ugfx.BLACK, ugfx.justifyLeft) ugfx.line(148, 110, 296, 110, ugfx.BLACK) #ugfx.string_box(148,110,148,18, " badge.sha2017.org", "Roboto_Regular12", ugfx.BLACK, ugfx.justifyLeft) if age!=None: if age: draw_status("cached: "+str(age)+"m (SEL=refresh)") else: draw_status("Ready") ugfx.flush(ugfx.LUT_NORMAL) gc.collect() def cache_get_filename(url): global installer_cache_dir return(installer_cache_dir+"/"+url.replace("/","_").replace(":","_")) def cache_get(url, refresh=False): """get cached contents of url, or redownloads if it doenst exist, of if refresh=True """ global installer_cache_dir global installer_cache url_filename=cache_get_filename(url) #use cache if refresh==False: try: with open(url_filename,'r') as fh: return(fh.read()) except: refresh=True #reload/dont use cache if refresh: connectWiFi() draw_progress('Downloading...') url_fh=urequests.get(url) content=url_fh.content url_fh.close() #cache content with open(url_filename,'w') as fh: fh.write(content) #uos.stat seemed buggy, so just store time.. with open(url_filename+".time",'w') as fh: fh.write(str(utime.time())) return(content) def cache_get_age(url): """get age of cached data in minutes""" #note: uos.stat seemed buggy url_filename=cache_get_filename(url)+".time" with open(url_filename,'r') as fh: delta=utime.time()-int(fh.read()) return(int(delta/60)) def cache_get_json(url, refresh=False): """uses cache_get and parses json data""" import ujson return ujson.loads(cache_get(url, refresh)) def cache_prepare(): global installer_cache_dir installer_cache_dir="/media/installer_cache" try: #we dont have os.path.exists, so just yolooo uos.mkdir(installer_cache_dir) except: pass def cache_clear(): global installer_cache_dir draw_progress("Clearing cache..") for file in uos.listdir(installer_cache_dir): uos.remove(installer_cache_dir+"/"+file) try: cache_prepare() ugfx.clear(ugfx.WHITE) ugfx.set_lut(ugfx.LUT_FASTER) list_categories() except Exception as e: #probably a bug: draw_progress(str(e)) #dont re-raise it in the hope the user can continue #raise e