@@ -179,16 +179,39 @@ def show_app_detail(self, app):
179179 intent .putExtra ("appstore" , self )
180180 self .startActivity (intent )
181181
182- async def download_url (self , url ):
182+ async def download_url (self , url , outfile = None ):
183183 print (f"Downloading { url } " )
184184 #await TaskManager.sleep(4) # test slowness
185185 try :
186186 async with self .aiohttp_session .get (url ) as response :
187- if response .status >= 200 and response .status < 400 :
187+ if response .status < 200 or response .status >= 400 :
188+ return None
189+ if not outfile :
188190 return await response .read ()
189- print (f"Done downloading { url } " )
191+ else :
192+ # Would be good to check free available space first
193+ chunk_size = 1024
194+ print ("headers:" ) ; print (response .headers )
195+ total_size = response .headers .get ('Content-Length' ) # some servers don't send this
196+ print (f"download_url writing to { outfile } of { total_size } bytes in chunks of size { chunk_size } " )
197+ with open (outfile , 'wb' ) as fd :
198+ print ("opened file..." )
199+ print (dir (response .content ))
200+ while True :
201+ #print("reading next chunk...")
202+ # Would be better to use wait_for() to handle timeouts:
203+ chunk = await response .content .read (chunk_size )
204+ #print(f"got chunk: {chunk}")
205+ if not chunk :
206+ break
207+ #print("writing chunk...")
208+ fd .write (chunk )
209+ #print("wrote chunk")
210+ print (f"Done downloading { url } " )
211+ return True
190212 except Exception as e :
191213 print (f"download_url got exception { e } " )
214+ return False
192215
193216 @staticmethod
194217 def badgehub_app_to_mpos_app (bhapp ):
@@ -435,8 +458,7 @@ def toggle_install(self, app_obj):
435458 label_text = self .install_label .get_text ()
436459 if label_text == self .action_label_install :
437460 try :
438- _thread .stack_size (mpos .apps .good_stack_size ())
439- _thread .start_new_thread (self .download_and_install , (download_url , f"apps/{ fullname } " , fullname ))
461+ TaskManager .create_task (self .download_and_install (download_url , f"apps/{ fullname } " , fullname ))
440462 except Exception as e :
441463 print ("Could not start download_and_install thread: " , e )
442464 elif label_text == self .action_label_uninstall or label_text == self .action_label_restore :
@@ -478,48 +500,38 @@ def uninstall_app(self, app_fullname):
478500 self .update_button .remove_flag (lv .obj .FLAG .HIDDEN )
479501 self .install_button .set_size (lv .pct (47 ), 40 ) # if a builtin app was removed, then it was overridden, and a new version is available, so make space for update button
480502
481- def download_and_install (self , zip_url , dest_folder , app_fullname ):
503+ async def download_and_install (self , zip_url , dest_folder , app_fullname ):
482504 self .install_button .add_state (lv .STATE .DISABLED )
483505 self .install_label .set_text ("Please wait..." )
484506 self .progress_bar .remove_flag (lv .obj .FLAG .HIDDEN )
485507 self .progress_bar .set_value (20 , True )
486- time .sleep (1 ) # seems silly but otherwise it goes so quickly that the user can't tell something happened and gets confused
508+ TaskManager .sleep (1 ) # seems silly but otherwise it goes so quickly that the user can't tell something happened and gets confused
509+ # Download the .mpk file to temporary location
510+ try :
511+ os .remove (temp_zip_path )
512+ except Exception :
513+ pass
487514 try :
488- # Step 1: Download the .mpk file
489- print (f"Downloading .mpk file from: { zip_url } " )
490- response = requests .get (zip_url , timeout = 10 ) # TODO: use stream=True and do it in chunks like in OSUpdate
491- if response .status_code != 200 :
492- print ("Download failed: Status code" , response .status_code )
493- response .close ()
515+ os .mkdir ("tmp" )
516+ except Exception :
517+ pass
518+ self .progress_bar .set_value (40 , True )
519+ temp_zip_path = "tmp/temp.mpk"
520+ print (f"Downloading .mpk file from: { zip_url } to { temp_zip_path } " )
521+ try :
522+ result = await self .appstore .download_url (zip_url , outfile = temp_zip_path )
523+ if result is not True :
524+ print ("Download failed..." )
494525 self .set_install_label (app_fullname )
495- self .progress_bar .set_value (40 , True )
496- # Save the .mpk file to a temporary location
497- try :
498- os .remove (temp_zip_path )
499- except Exception :
500- pass
501- try :
502- os .mkdir ("tmp" )
503- except Exception :
504- pass
505- temp_zip_path = "tmp/temp.mpk"
506- print (f"Writing to temporary mpk path: { temp_zip_path } " )
507- # TODO: check free available space first!
508- with open (temp_zip_path , "wb" ) as f :
509- f .write (response .content )
510526 self .progress_bar .set_value (60 , True )
511- response .close ()
512527 print ("Downloaded .mpk file, size:" , os .stat (temp_zip_path )[6 ], "bytes" )
513528 except Exception as e :
514529 print ("Download failed:" , str (e ))
515530 # Would be good to show error message here if it fails...
516- finally :
517- if 'response' in locals ():
518- response .close ()
519531 # Step 2: install it:
520532 PackageManager .install_mpk (temp_zip_path , dest_folder ) # ERROR: temp_zip_path might not be set if download failed!
521533 # Success:
522- time .sleep (1 ) # seems silly but otherwise it goes so quickly that the user can't tell something happened and gets confused
534+ TaskManager .sleep (1 ) # seems silly but otherwise it goes so quickly that the user can't tell something happened and gets confused
523535 self .progress_bar .set_value (100 , False )
524536 self .progress_bar .add_flag (lv .obj .FLAG .HIDDEN )
525537 self .progress_bar .set_value (0 , False )
0 commit comments