diff --git a/badge_store/main.py b/badge_store/main.py index 2a287dc..98fa085 100644 --- a/badge_store/main.py +++ b/badge_store/main.py @@ -6,38 +6,68 @@ To publish apps use https://badge.emfcamp.org""" ___license___ = "MIT" ___title___ = "Badge Store" -___dependencies___ = ["wifi", "dialogs"] +___dependencies___ = ["app", "badge_store", "dialogs"] ___categories___ = ["System"] ___bootstrapped___ = True -import pyb import ugfx import os -#import http_client import wifi -import dialogs -#from app import App, get_local_apps, get_public_apps, get_public_app_categories, empty_local_app_cache -#import filesystem - -TEMP_FILE = ".temp_download" +from dialogs import * +import app +from lib.badge_store import BadgeStore ugfx.init() ### VIEWS ### +store = BadgeStore() +title = "TiLDA Badge Store" + def clear(): ugfx.clear(ugfx.html_color(0x7c1143)) -def store(): +def show_categories(): + with WaitingMessage(): + menu_items = [{"title": c, "category": c} for c in store.get_categories()] + + option = prompt_option(menu_items, none_text="Back", text="Categories", title=title) + + if option: + show_apps(option["category"]) + else: + return + +def show_apps(c): + menu_items = [{"title": a, "app": a} for a in store.get_apps(c)] + + option = prompt_option(menu_items, none_text="Back", title=title) + + if option: + show_app(option["app"]) + else: + return + +def show_app(a): + with WaitingMessage(): + app_info = store.get_app(a) + + install = prompt_boolean(app_info["description"], title=a, true_text="Install", false_text="Back") + + if install: + with WaitingMessage(title="Installing %s" % a, text="Please wait...") as message: + installers = store.install(a) + n = len(installers) + for i, installer in enumerate(installers): + message.text = "%s (%s/%s)" % (installer.path, i + 1, n) + installer.download() + + notice("App %s has been successfully installed" % a, title=title, close_text="Back") + +def show_update(): None -def update(): - None - -def remove(): - None - -def settings(): +def show_remove(): None def main_menu(): @@ -47,13 +77,12 @@ def main_menu(): print() menu_items = [ - {"title": "Install Apps", "function": store}, - {"title": "Update", "function": update}, - {"title": "Manage Apps", "function": remove}, - {"title": "Settings", "function": settings} + {"title": "Install Apps", "function": show_categories}, + {"title": "Update", "function": show_update}, + {"title": "Manage Apps", "function": show_remove} ] - option = dialogs.prompt_option(menu_items, none_text="Exit", text="What do you want to do?", title="TiLDA App Library") + option = prompt_option(menu_items, none_text="Exit", text="What do you want to do?", title=title) if option: option["function"]() @@ -61,10 +90,4 @@ def main_menu(): return main_menu() - -#if App("home").loadable: -# main_menu() -#else: -# for app_name in ["changename", "snake", "alistair~selectwifi", "sponsors", "home"]: -# install(App(app_name)) -# pyb.hard_reset() +#show_app("launcher") diff --git a/lib/app.py b/lib/app.py index c8758e5..9274f40 100644 --- a/lib/app.py +++ b/lib/app.py @@ -57,6 +57,12 @@ class App: return self.attributes[attribute] return default + def uninstall(self): + try: + os.remove(self.name) + except Exception as e: + pass + def __str__(self): return self.title diff --git a/lib/badge_store.py b/lib/badge_store.py index 44bcd3e..cef6100 100644 --- a/lib/badge_store.py +++ b/lib/badge_store.py @@ -1,11 +1,11 @@ """Library to interact with the badge store""" ___license___ = "MIT" -___dependencies___ = ["http", "ospath"] +___dependencies___ = ["http", "ospath", "app"] from ospath import * from http import * -import hashlib, binascii +import hashlib, binascii, app class BadgeStore: def __init__(self, url = "http://badge.marekventur.com", repo="emfcamp/Mk4-Apps", ref="master"): @@ -14,18 +14,21 @@ class BadgeStore: self.ref = ref self._apps = None - def get_apps(self): + def get_all_apps(self): if not self._apps: self._apps = self._call("apps") return self._apps + def get_apps(self, category): + return self.get_all_apps()[category] + def get_categories(self): - return self.get_apps().keys() + return self.get_all_apps().keys() def get_app(self, app): return self._call("app", {"app": app}) - def install(self, apps): + def call_install(self, apps): files = self._call("install", {"apps": ",".join(apps)}) installers = [] url = "%s/download" % (self.url) @@ -36,6 +39,12 @@ class BadgeStore: installers.append(Installer(path, url, params, hash)) return installers + def install(self, app): + return self.call_install(self._get_current_apps() + [app]) + + def update(self): + return self.call_install(self._get_current_apps()) + def _call(self, command, params = {}): params["repo"] = self.repo params["ref"] = self.ref @@ -45,6 +54,8 @@ class BadgeStore: def _is_file_up_to_date(self, path, hash): return hash == _get_hash(path) + def _get_current_apps(self): + return [a.name for a in app.get_apps()] TEMP_FILE = ".tmp.download" @@ -70,6 +81,8 @@ class Installer: os.remove(self.path) except OSError: pass + makedirs(dirname(self.path)) + os.rename(TEMP_FILE, self.path) def get_hash(path): diff --git a/lib/ospath.py b/lib/ospath.py index 9e59237..47b366a 100644 --- a/lib/ospath.py +++ b/lib/ospath.py @@ -61,3 +61,12 @@ def isfile(path): return stat.S_ISREG(mode) except OSError: return False + +# not normally in os.path +def makedirs(path): + """recursively creates a given path""" + sub_path = dirname(path) + if sub_path and (not exists(sub_path)): + makedirs(sub_path) + if not exists(path): + os.mkdir(path) diff --git a/lib/test_badge_store.py b/lib/test_badge_store.py index dca843d..cdfb6b6 100644 --- a/lib/test_badge_store.py +++ b/lib/test_badge_store.py @@ -16,15 +16,19 @@ class TestBadgeStore(unittest.TestCase): def tearDownClass(self): self._remove_download_file() - def test_apps(self): - response = self.store.get_apps() + def test_get_all_apps(self): + response = self.store.get_all_apps() self.assertEqual(response["System"], ['badge_store', 'launcher', 'settings']) def test_categories(self): categories = self.store.get_categories() self.assertEqual(set(categories), set(["System", "homescreen"])) - def test_app(self): + def test_get_apps(self): + apps = self.store.get_apps("System") + self.assertEqual(set(apps), set(['badge_store', 'settings', 'launcher'])) + + def test_get_app(self): response = self.store.get_app("launcher") self.assertEqual(response["description"], "Launcher for apps currently installed") @@ -35,7 +39,7 @@ class TestBadgeStore(unittest.TestCase): def test_install_integration(self): self._remove_download_file() store = BadgeStore(url="http://badge.marekventur.com", repo="emfcamp/Mk4-Apps", ref="dont-delete-test-download-branch") - for installer in store.install(["launcher"]): + for installer in store.call_install(["launcher"]): if installer.path == "shared/test/download.txt": installer.download()