1+ import aiohttp
12import lvgl as lv
23import json
34import requests
67import time
78import _thread
89
10+
911from mpos .apps import Activity , Intent
1012from mpos .app import App
13+ from mpos import TaskManager
1114import mpos .ui
1215from mpos .content .package_manager import PackageManager
1316
@@ -16,6 +19,7 @@ class AppStore(Activity):
1619 apps = []
1720 app_index_url = "https://apps.micropythonos.com/app_index.json"
1821 can_check_network = True
22+ aiohttp_session = None # one session for the whole app is more performant
1923
2024 # Widgets:
2125 main_screen = None
@@ -26,6 +30,7 @@ class AppStore(Activity):
2630 progress_bar = None
2731
2832 def onCreate (self ):
33+ self .aiohttp_session = aiohttp .ClientSession ()
2934 self .main_screen = lv .obj ()
3035 self .please_wait_label = lv .label (self .main_screen )
3136 self .please_wait_label .set_text ("Downloading app index..." )
@@ -43,38 +48,39 @@ def onResume(self, screen):
4348 if self .can_check_network and not network .WLAN (network .STA_IF ).isconnected ():
4449 self .please_wait_label .set_text ("Error: WiFi is not connected." )
4550 else :
46- _thread .stack_size (mpos .apps .good_stack_size ())
47- _thread .start_new_thread (self .download_app_index , (self .app_index_url ,))
51+ TaskManager .create_task (self .download_app_index (self .app_index_url ))
52+
53+ def onDestroy (self , screen ):
54+ await self .aiohttp_session .close ()
4855
49- def download_app_index (self , json_url ):
56+ async def download_app_index (self , json_url ):
57+ response = await self .download_url (json_url )
58+ if not response :
59+ self .please_wait_label .set_text (f"Could not download app index from\n { json_url } " )
60+ return
61+ print (f"Got response text: { response [0 :20 ]} " )
5062 try :
51- response = requests .get (json_url , timeout = 10 )
63+ for app in json .loads (response ):
64+ try :
65+ self .apps .append (App (app ["name" ], app ["publisher" ], app ["short_description" ], app ["long_description" ], app ["icon_url" ], app ["download_url" ], app ["fullname" ], app ["version" ], app ["category" ], app ["activities" ]))
66+ except Exception as e :
67+ print (f"Warning: could not add app from { json_url } to apps list: { e } " )
5268 except Exception as e :
53- print ("Download failed:" , e )
54- self .update_ui_threadsafe_if_foreground (self .please_wait_label .set_text , f"App index download \n { json_url } \n got error: { e } " )
69+ self .please_wait_label .set_text (f"ERROR: could not parse reponse.text JSON: { e } " )
5570 return
56- if response and response .status_code == 200 :
57- #print(f"Got response text: {response.text}")
58- try :
59- for app in json .loads (response .text ):
60- try :
61- self .apps .append (App (app ["name" ], app ["publisher" ], app ["short_description" ], app ["long_description" ], app ["icon_url" ], app ["download_url" ], app ["fullname" ], app ["version" ], app ["category" ], app ["activities" ]))
62- except Exception as e :
63- print (f"Warning: could not add app from { json_url } to apps list: { e } " )
64- except Exception as e :
65- print (f"ERROR: could not parse reponse.text JSON: { e } " )
66- finally :
67- response .close ()
68- # Remove duplicates based on app.name
69- seen = set ()
70- self .apps = [app for app in self .apps if not (app .fullname in seen or seen .add (app .fullname ))]
71- # Sort apps by app.name
72- self .apps .sort (key = lambda x : x .name .lower ()) # Use .lower() for case-insensitive sorting
73- time .sleep_ms (200 )
74- self .update_ui_threadsafe_if_foreground (self .please_wait_label .add_flag , lv .obj .FLAG .HIDDEN )
75- self .update_ui_threadsafe_if_foreground (self .create_apps_list )
76- time .sleep (0.1 ) # give the UI time to display the app list before starting to download
77- self .download_icons ()
71+ print ("Remove duplicates based on app.name" )
72+ seen = set ()
73+ self .apps = [app for app in self .apps if not (app .fullname in seen or seen .add (app .fullname ))]
74+ print ("Sort apps by app.name" )
75+ self .apps .sort (key = lambda x : x .name .lower ()) # Use .lower() for case-insensitive sorting
76+ print ("Hiding please wait label..." )
77+ self .update_ui_threadsafe_if_foreground (self .please_wait_label .add_flag , lv .obj .FLAG .HIDDEN )
78+ print ("Creating apps list..." )
79+ created_app_list_event = TaskManager .notify_event () # wait for the list to be shown before downloading the icons
80+ self .update_ui_threadsafe_if_foreground (self .create_apps_list , event = created_app_list_event )
81+ await created_app_list_event .wait ()
82+ print ("awaiting self.download_icons()" )
83+ await self .download_icons ()
7884
7985 def create_apps_list (self ):
8086 print ("create_apps_list" )
@@ -119,14 +125,15 @@ def create_apps_list(self):
119125 desc_label .set_style_text_font (lv .font_montserrat_12 , 0 )
120126 desc_label .add_event_cb (lambda e , a = app : self .show_app_detail (a ), lv .EVENT .CLICKED , None )
121127 print ("create_apps_list app done" )
122-
123- def download_icons (self ):
128+
129+ async def download_icons (self ):
130+ print ("Downloading icons..." )
124131 for app in self .apps :
125132 if not self .has_foreground ():
126133 print (f"App is stopping, aborting icon downloads." )
127134 break
128- if not app .icon_data :
129- app .icon_data = self .download_icon_data (app .icon_url )
135+ # if not app.icon_data:
136+ app .icon_data = await self .download_url (app .icon_url )
130137 if app .icon_data :
131138 print ("download_icons has icon_data, showing it..." )
132139 image_icon_widget = None
@@ -147,20 +154,16 @@ def show_app_detail(self, app):
147154 intent .putExtra ("app" , app )
148155 self .startActivity (intent )
149156
150- @ staticmethod
151- def download_icon_data ( url ):
152- print ( f"Downloading icon from { url } " )
157+ async def download_url ( self , url ):
158+ print ( f"Downloading { url } " )
159+ #await TaskManager.sleep(1 )
153160 try :
154- response = requests .get (url , timeout = 5 )
155- if response .status_code == 200 :
156- image_data = response .content
157- print ("Downloaded image, size:" , len (image_data ), "bytes" )
158- return image_data
159- else :
160- print ("Failed to download image: Status code" , response .status_code )
161+ async with self .aiohttp_session .get (url ) as response :
162+ if response .status >= 200 and response .status < 400 :
163+ return await response .read ()
164+ print (f"Done downloading { url } " )
161165 except Exception as e :
162- print (f"Exception during download of icon: { e } " )
163- return None
166+ print (f"download_url got exception { e } " )
164167
165168class AppDetail (Activity ):
166169
0 commit comments