22import json
33import urequests
44import gc
5+ import os
6+ import time
7+
8+ mainscreen = lv .screen_active ()
59
610apps = []
711app_detail_screen = None
812install_button = None
913please_wait_label = None
1014app_detail_screen = None
1115progress_bar = None
16+ action_label_install = "Install Latest Version"
17+ action_label_uninstall = "Uninstall"
1218
1319class App :
1420 def __init__ (self , name , publisher , short_description , long_description , icon_url , download_url , fullname , version ):
@@ -22,6 +28,21 @@ def __init__(self, name, publisher, short_description, long_description, icon_ur
2228 self .fullname = fullname
2329 self .version = version
2430
31+
32+ def is_installed_by_path (dir_path ):
33+ try :
34+ if os .stat (dir_path )[0 ] & 0x4000 :
35+ manifest = f"{ dir_path } /META-INF/MANIFEST.MF"
36+ if os .stat (manifest )[0 ] & 0x8000 :
37+ return True
38+ except OSError :
39+ pass # Skip if directory or manifest doesn't exist
40+ return False
41+
42+ def is_installed_by_name (app_fullname ):
43+ print (f"Checking if app { app_fullname } is installed..." )
44+ return is_installed_by_path (f"/apps/{ app_fullname } " ) or is_installed_by_path (f"/builtin/apps/{ app_fullname } " )
45+
2546def load_icon (url ):
2647 print (f"downloading icon from { url } " )
2748 response = urequests .get (url , timeout = 5 )
@@ -37,7 +58,7 @@ def load_icon(url):
3758 print ("Failed to download image: Status code" , response .status_code )
3859 return None
3960
40- import os
61+
4162try :
4263 import zipfile
4364except ImportError :
@@ -46,7 +67,7 @@ def load_icon(url):
4667def download_and_unzip (zip_url , dest_folder ):
4768 try :
4869 # Step 1: Download the .zip file
49- print ("Downloading .zip file from:" , zip_url )
70+ print (f "Downloading .zip file from: { zip_url } " )
5071 response = urequests .get (zip_url , timeout = 10 )
5172 if response .status_code != 200 :
5273 print ("Download failed: Status code" , response .status_code )
@@ -100,7 +121,7 @@ def download_apps(json_url):
100121def create_apps_list ():
101122 global apps
102123 print ("create_apps_list" )
103- apps_list = lv .list (subwindow )
124+ apps_list = lv .list (mainscreen )
104125 apps_list .set_style_pad_all (0 , 0 )
105126 apps_list .set_size (lv .pct (100 ), lv .pct (100 ))
106127 print ("create_apps_list iterating" )
@@ -139,7 +160,7 @@ def create_apps_list():
139160
140161
141162def show_app_detail (app ):
142- global app_detail_screen , install_button , progress_bar
163+ global app_detail_screen , install_button , progress_bar , action_label_install , action_label_uninstall
143164 app_detail_screen = lv .obj ()
144165 app_detail_screen .set_size (lv .pct (100 ), lv .pct (100 ))
145166 back_button = lv .button (app_detail_screen )
@@ -176,16 +197,21 @@ def show_app_detail(app):
176197 publisher_label .set_style_text_font (lv .font_montserrat_16 , 0 )
177198 #
178199 progress_bar = lv .bar (cont )
179- progress_bar .add_flag (lv .obj .FLAG .HIDDEN )
180200 progress_bar .set_width (lv .pct (100 ))
181201 progress_bar .set_range (0 , 100 )
202+ progress_bar .add_flag (lv .obj .FLAG .HIDDEN )
182203 install_button = lv .button (cont )
183204 install_button .align_to (detail_cont , lv .ALIGN .OUT_BOTTOM_MID , 0 , lv .pct (5 ))
184205 install_button .set_size (lv .pct (100 ), 40 )
185206 install_button .add_flag (lv .obj .FLAG .CLICKABLE )
207+ print (f"Adding install button for url: { app .download_url } " )
186208 install_button .add_event_cb (lambda e , d = app .download_url , f = app .fullname : toggle_install (d ,f ), lv .EVENT .CLICKED , None )
187209 install_label = lv .label (install_button )
188- install_label .set_text ("(Re)Install Latest Version" ) # TODO: check if already installed and if yes, change to "Uninstall" and "Open"
210+ if is_installed_by_name (app .fullname ):
211+ action_label = action_label_uninstall # Maybe show "restore builtin version" for builtin apps...
212+ else :
213+ action_label = action_label_install
214+ install_label .set_text (action_label )
189215 install_label .center ()
190216 version_label = lv .label (cont )
191217 version_label .set_width (lv .pct (100 ))
@@ -201,25 +227,33 @@ def show_app_detail(app):
201227
202228
203229def toggle_install (download_url , fullname ):
204- global install_button , progress_bar
230+ global install_button , progress_bar , action_label_install , action_label_uninstall
231+ print (f"Install button clicked for { download_url } and fullname { fullname } " )
205232 label = install_button .get_child (0 )
206- if label .get_text () == "(Re)Install Latest Version" :
233+ if label .get_text () == action_label_install :
207234 install_button .remove_flag (lv .obj .FLAG .CLICKABLE ) # TODO: change color so it's clear the button is not clickable
208235 label .set_text ("Please wait..." ) # TODO: Put "Cancel" if cancellation is possible
209236 progress_bar .remove_flag (lv .obj .FLAG .HIDDEN )
210237 progress_bar .set_value (40 , lv .ANIM .OFF )
211238 # TODO: do the download and install in a new thread with a few sleeps so it can be cancelled...
239+ #try:
240+ # _thread.stack_size(16384)
241+ # _thread.start_new_thread(execute_script, (scriptname, is_file, is_launcher, is_graphical))
242+ #except Exception as e:
243+ # print("Could not start download_and_unzip thread: ", e)
212244 download_and_unzip (download_url , f"/apps/{ fullname } " )
213245 progress_bar .set_value (80 , lv .ANIM .OFF )
214- time .sleep_ms ( 500 )
246+ time .sleep ( 1 )
215247 progress_bar .set_value (100 , lv .ANIM .OFF )
216- time .sleep (500 )
217- label .set_text ("Installed! " ) # Opening doesn't work because it races along with the launcher to use the screen...
248+ time .sleep (1 )
249+ label .set_text ("Uninstall " ) # Opening doesn't work because it races along with the launcher to use the screen...
218250 progress_bar .add_flag (lv .obj .FLAG .HIDDEN )
219- # install_button.add_flag(lv.obj.FLAG.CLICKABLE)
251+ install_button .add_flag (lv .obj .FLAG .CLICKABLE )
220252 elif label .get_text () == "Open" :
221253 print ("Open button clicked, starting app..." )
222254 start_app (f"/apps/{ fullname } " )
255+ elif label .get_text () == action_label_uninstall :
256+ print ("Uninstalling app...." )
223257 else : # if the button text was "Please wait..." or "Uninstall" or "Installed!"
224258 label .set_text ("Install" )
225259
@@ -229,12 +263,12 @@ def back_to_main(event):
229263 if app_detail_screen :
230264 app_detail_screen .delete ()
231265 app_detail_screen = None
232- lv .screen_load (appscreen )
266+ lv .screen_load (mainscreen )
233267
234268
235269print ("appstore.py starting" )
236270
237- please_wait_label = lv .label (subwindow )
271+ please_wait_label = lv .label (mainscreen )
238272please_wait_label .set_text ("Downloading app index..." )
239273please_wait_label .center ()
240274
@@ -247,7 +281,7 @@ def back_to_main(event):
247281 download_apps ("http://demo.lnpiggy.com:2121/apps.json" )
248282 # Wait until the user stops the app
249283 import time
250- while appscreen == lv .screen_active () or app_detail_screen == lv .screen_active ():
284+ while mainscreen == lv .screen_active () or app_detail_screen == lv .screen_active ():
251285 time .sleep_ms (100 )
252286
253287print ("appstore.py ending" )
0 commit comments