You've already forked MicroPythonOS
mirror of
https://github.com/m5stack/MicroPythonOS.git
synced 2026-05-20 11:51:27 -07:00
appstore: uninstall button and progress bar
This commit is contained in:
@@ -2,6 +2,10 @@ import lvgl as lv
|
||||
import json
|
||||
import urequests
|
||||
import gc
|
||||
import os
|
||||
import time
|
||||
|
||||
mainscreen = lv.screen_active()
|
||||
|
||||
apps = []
|
||||
app_detail_screen = None
|
||||
@@ -9,6 +13,8 @@ install_button = None
|
||||
please_wait_label = None
|
||||
app_detail_screen = None
|
||||
progress_bar = None
|
||||
action_label_install = "Install Latest Version"
|
||||
action_label_uninstall = "Uninstall"
|
||||
|
||||
class App:
|
||||
def __init__(self, name, publisher, short_description, long_description, icon_url, download_url, fullname, version):
|
||||
@@ -22,6 +28,21 @@ class App:
|
||||
self.fullname = fullname
|
||||
self.version = version
|
||||
|
||||
|
||||
def is_installed_by_path(dir_path):
|
||||
try:
|
||||
if os.stat(dir_path)[0] & 0x4000:
|
||||
manifest = f"{dir_path}/META-INF/MANIFEST.MF"
|
||||
if os.stat(manifest)[0] & 0x8000:
|
||||
return True
|
||||
except OSError:
|
||||
pass # Skip if directory or manifest doesn't exist
|
||||
return False
|
||||
|
||||
def is_installed_by_name(app_fullname):
|
||||
print(f"Checking if app {app_fullname} is installed...")
|
||||
return is_installed_by_path(f"/apps/{app_fullname}") or is_installed_by_path(f"/builtin/apps/{app_fullname}")
|
||||
|
||||
def load_icon(url):
|
||||
print(f"downloading icon from {url}")
|
||||
response = urequests.get(url, timeout=5)
|
||||
@@ -37,7 +58,7 @@ def load_icon(url):
|
||||
print("Failed to download image: Status code", response.status_code)
|
||||
return None
|
||||
|
||||
import os
|
||||
|
||||
try:
|
||||
import zipfile
|
||||
except ImportError:
|
||||
@@ -46,7 +67,7 @@ except ImportError:
|
||||
def download_and_unzip(zip_url, dest_folder):
|
||||
try:
|
||||
# Step 1: Download the .zip file
|
||||
print("Downloading .zip file from:", zip_url)
|
||||
print(f"Downloading .zip file from: {zip_url}")
|
||||
response = urequests.get(zip_url, timeout=10)
|
||||
if response.status_code != 200:
|
||||
print("Download failed: Status code", response.status_code)
|
||||
@@ -100,7 +121,7 @@ def download_apps(json_url):
|
||||
def create_apps_list():
|
||||
global apps
|
||||
print("create_apps_list")
|
||||
apps_list = lv.list(subwindow)
|
||||
apps_list = lv.list(mainscreen)
|
||||
apps_list.set_style_pad_all(0, 0)
|
||||
apps_list.set_size(lv.pct(100), lv.pct(100))
|
||||
print("create_apps_list iterating")
|
||||
@@ -139,7 +160,7 @@ def create_apps_list():
|
||||
|
||||
|
||||
def show_app_detail(app):
|
||||
global app_detail_screen, install_button, progress_bar
|
||||
global app_detail_screen, install_button, progress_bar, action_label_install, action_label_uninstall
|
||||
app_detail_screen = lv.obj()
|
||||
app_detail_screen.set_size(lv.pct(100), lv.pct(100))
|
||||
back_button = lv.button(app_detail_screen)
|
||||
@@ -176,16 +197,21 @@ def show_app_detail(app):
|
||||
publisher_label.set_style_text_font(lv.font_montserrat_16, 0)
|
||||
#
|
||||
progress_bar = lv.bar(cont)
|
||||
progress_bar.add_flag(lv.obj.FLAG.HIDDEN)
|
||||
progress_bar.set_width(lv.pct(100))
|
||||
progress_bar.set_range(0, 100)
|
||||
progress_bar.add_flag(lv.obj.FLAG.HIDDEN)
|
||||
install_button = lv.button(cont)
|
||||
install_button.align_to(detail_cont, lv.ALIGN.OUT_BOTTOM_MID, 0, lv.pct(5))
|
||||
install_button.set_size(lv.pct(100), 40)
|
||||
install_button.add_flag(lv.obj.FLAG.CLICKABLE)
|
||||
print(f"Adding install button for url: {app.download_url}")
|
||||
install_button.add_event_cb(lambda e, d=app.download_url, f=app.fullname: toggle_install(d,f), lv.EVENT.CLICKED, None)
|
||||
install_label = lv.label(install_button)
|
||||
install_label.set_text("(Re)Install Latest Version") # TODO: check if already installed and if yes, change to "Uninstall" and "Open"
|
||||
if is_installed_by_name(app.fullname):
|
||||
action_label = action_label_uninstall # Maybe show "restore builtin version" for builtin apps...
|
||||
else:
|
||||
action_label = action_label_install
|
||||
install_label.set_text(action_label)
|
||||
install_label.center()
|
||||
version_label = lv.label(cont)
|
||||
version_label.set_width(lv.pct(100))
|
||||
@@ -201,25 +227,33 @@ def show_app_detail(app):
|
||||
|
||||
|
||||
def toggle_install(download_url, fullname):
|
||||
global install_button, progress_bar
|
||||
global install_button, progress_bar, action_label_install, action_label_uninstall
|
||||
print(f"Install button clicked for {download_url} and fullname {fullname}")
|
||||
label = install_button.get_child(0)
|
||||
if label.get_text() == "(Re)Install Latest Version":
|
||||
if label.get_text() == action_label_install:
|
||||
install_button.remove_flag(lv.obj.FLAG.CLICKABLE) # TODO: change color so it's clear the button is not clickable
|
||||
label.set_text("Please wait...") # TODO: Put "Cancel" if cancellation is possible
|
||||
progress_bar.remove_flag(lv.obj.FLAG.HIDDEN)
|
||||
progress_bar.set_value(40, lv.ANIM.OFF)
|
||||
# TODO: do the download and install in a new thread with a few sleeps so it can be cancelled...
|
||||
#try:
|
||||
# _thread.stack_size(16384)
|
||||
# _thread.start_new_thread(execute_script, (scriptname, is_file, is_launcher, is_graphical))
|
||||
#except Exception as e:
|
||||
# print("Could not start download_and_unzip thread: ", e)
|
||||
download_and_unzip(download_url, f"/apps/{fullname}")
|
||||
progress_bar.set_value(80, lv.ANIM.OFF)
|
||||
time.sleep_ms(500)
|
||||
time.sleep(1)
|
||||
progress_bar.set_value(100, lv.ANIM.OFF)
|
||||
time.sleep(500)
|
||||
label.set_text("Installed!") # Opening doesn't work because it races along with the launcher to use the screen...
|
||||
time.sleep(1)
|
||||
label.set_text("Uninstall") # Opening doesn't work because it races along with the launcher to use the screen...
|
||||
progress_bar.add_flag(lv.obj.FLAG.HIDDEN)
|
||||
#install_button.add_flag(lv.obj.FLAG.CLICKABLE)
|
||||
install_button.add_flag(lv.obj.FLAG.CLICKABLE)
|
||||
elif label.get_text() == "Open":
|
||||
print("Open button clicked, starting app...")
|
||||
start_app(f"/apps/{fullname}")
|
||||
elif label.get_text() == action_label_uninstall:
|
||||
print("Uninstalling app....")
|
||||
else: # if the button text was "Please wait..." or "Uninstall" or "Installed!"
|
||||
label.set_text("Install")
|
||||
|
||||
@@ -229,12 +263,12 @@ def back_to_main(event):
|
||||
if app_detail_screen:
|
||||
app_detail_screen.delete()
|
||||
app_detail_screen = None
|
||||
lv.screen_load(appscreen)
|
||||
lv.screen_load(mainscreen)
|
||||
|
||||
|
||||
print("appstore.py starting")
|
||||
|
||||
please_wait_label = lv.label(subwindow)
|
||||
please_wait_label = lv.label(mainscreen)
|
||||
please_wait_label.set_text("Downloading app index...")
|
||||
please_wait_label.center()
|
||||
|
||||
@@ -247,7 +281,7 @@ else:
|
||||
download_apps("http://demo.lnpiggy.com:2121/apps.json")
|
||||
# Wait until the user stops the app
|
||||
import time
|
||||
while appscreen == lv.screen_active() or app_detail_screen == lv.screen_active():
|
||||
while mainscreen == lv.screen_active() or app_detail_screen == lv.screen_active():
|
||||
time.sleep_ms(100)
|
||||
|
||||
print("appstore.py ending")
|
||||
|
||||
Reference in New Issue
Block a user