@@ -159,7 +159,6 @@ def getFileSize(self):
159159 self .file_header = {}
160160 response = self .requests_session .head (self .link , allow_redirects = True , timeout = self .timeout , verify = self .check_certificate )
161161# response.raise_for_status()
162- print (response .headers )
163162 self .file_header = response .headers
164163
165164 self .file_size = int (self .file_header ['content-length' ])
@@ -392,7 +391,7 @@ def definePartSizes(self):
392391
393392 else :
394393 # Calculate how many parts of one MiB we need.
395- self .number_of_parts = int (self .file_size // (1024 ** 2 )) + 1
394+ self .number_of_parts = int (( self .file_size - 1 ) // (1024 ** 2 )) + 1
396395 self .number_of_threads = self .number_of_parts
397396 for i in range (0 , self .number_of_parts ):
398397 self .download_infromation_list [i ] = [i * 1024 * 1024 , 0 , 'pending' , - 1 ]
@@ -401,7 +400,7 @@ def definePartSizes(self):
401400 # The size of the file is equal to the last byte of the file.
402401 # The status of these parts is complete. Because we have nothing to download.
403402 for i in range (self .number_of_parts , 64 ):
404- self .download_infromation_list [i ] = [self .file_size , 0 , 'complete' , - 1 ]
403+ self .download_infromation_list [i ] = [self .file_size - 1 , 0 , 'complete' , - 1 ]
405404 else :
406405 # create new list.
407406 self .download_infromation_list = [[]] * 64
@@ -463,25 +462,29 @@ def askForNewPart(self):
463462 # Check that this part is not being downloaded or it is not complete.
464463 # Check that the number of retries of this part has not reached the set limit.
465464 if (self .download_infromation_list [i ][2 ] not in ['complete' , 'downloading' ]) and (self .download_infromation_list [i ][3 ] != self .retry ):
465+
466466 # set 'downloding' status for this part
467467 self .download_infromation_list [i ][2 ] = 'downloading'
468+
468469 # add 1 to retry number for this part
469470 self .download_infromation_list [i ][3 ] += 1
470- break
471471
472- # no part found
473- if i == (self .number_of_parts - 1 ):
474- i = None
472+ # number of retries can't be less than 0
473+ if self .download_infromation_list [i ][3 ] < 0 :
474+ self .download_infromation_list [i ][3 ] = 0
475+
476+ self .lock = False
477+ return i
475478
476479 self .lock = False
477- return i
480+ return None
478481
479482 # The below code is used for each chunk of file handled
480483 # by each thread for downloading the content from specified
481484 # location to storage
482485 def threadHandler (self , thread_number ):
483486 while self .download_status in ['downloading' , 'paused' ]:
484-
487+ is_break = False
485488 # Wait for the lock to be released.
486489 while self .lock is True :
487490 # Random sleep prevents two threads from downloading the same part at the same time.
@@ -491,6 +494,7 @@ def threadHandler(self, thread_number):
491494
492495 # If part_number is None, no part is available for download. So exit the loop.
493496 if part_number is None :
497+ is_break = True
494498 break
495499 error_message = None
496500 error_message2 = None
@@ -503,7 +507,7 @@ def threadHandler(self, thread_number):
503507 part_size = self .download_infromation_list [part_number + 1 ][0 ] - self .download_infromation_list [part_number ][0 ]
504508 else :
505509 # for last part
506- part_size = self .file_size - self .download_infromation_list [part_number ][0 ]
510+ part_size = self .file_size - 1 - self .download_infromation_list [part_number ][0 ]
507511
508512 # get start byte number of this part and add it to downloaded size. download resume from this byte number
509513 downloaded_part = self .download_infromation_list [part_number ][1 ]
@@ -512,9 +516,9 @@ def threadHandler(self, thread_number):
512516
513517 # end of part is equal to start of the next part
514518 if part_number != (self .number_of_parts - 1 ):
515- end = self .download_infromation_list [part_number + 1 ][0 ]
519+ end = self .download_infromation_list [part_number + 1 ][0 ] - 1
516520 else :
517- end = self .file_size
521+ end = self .file_size - 1
518522
519523 # download from begining!
520524 if self .resuming_suppurt is False :
@@ -561,6 +565,7 @@ def threadHandler(self, thread_number):
561565 # This loop does not end due to an error in the request.
562566 # Therefore, no number should be added to the number of retries.
563567 self .download_infromation_list [part_number ][3 ] -= 1
568+ is_break = True
564569 break
565570
566571 # maybe the last chunk is less than default chunk size
@@ -602,6 +607,7 @@ def threadHandler(self, thread_number):
602607
603608 else :
604609 self .download_infromation_list [part_number ][2 ] = 'stopped'
610+ is_break = True
605611 break
606612 # If file_size is unspecified.
607613 else :
@@ -673,6 +679,7 @@ def threadHandler(self, thread_number):
673679
674680 else :
675681 self .download_infromation_list [part_number ][2 ] = 'stopped'
682+ is_break = True
676683 break
677684 download_finished_successfully = True
678685
@@ -710,15 +717,15 @@ def threadHandler(self, thread_number):
710717 if (downloaded_part == part_size ):
711718 self .download_infromation_list [part_number ][2 ] = 'complete'
712719 self .part_thread_dict [part_number ] = None
713- else :
720+ elif not ( is_break ) :
714721 self .download_infromation_list [part_number ][2 ] = 'error'
715722 self .part_thread_dict [part_number ] = None
716723 else :
717724 if download_finished_successfully :
718725 self .file_size = self .downloaded_size
719726 self .download_infromation_list [part_number ][2 ] = 'complete'
720727 self .part_thread_dict [part_number ] = None
721- else :
728+ elif not ( is_break ) :
722729 self .download_infromation_list [part_number ][2 ] = 'error'
723730 self .part_thread_dict [part_number ] = None
724731 # This thread is finished.
@@ -772,7 +779,7 @@ def checkDownloadProgress(self):
772779 logger .sendToLog ("Download starts! - GID:" + self .gid , "DOWNLOADS" )
773780
774781 # Run this loop until the download is finished.
775- while (self .file_size != self . downloaded_size ) and ( self . download_status == 'downloading' or self .download_status == 'paused' ) and \
782+ while (self .download_status == 'downloading' or self .download_status == 'paused' ) and \
776783 (self .finished_threads != self .number_of_threads ):
777784
778785 # Calculate download percent
@@ -785,6 +792,15 @@ def checkDownloadProgress(self):
785792 self .number_of_active_connections = self .number_of_threads - self .finished_threads
786793 time .sleep (1 )
787794
795+ # Check if all parts downloaded completely.
796+ number_of_completed_parts = 0
797+ for i in range (0 , self .number_of_parts ):
798+ if self .download_infromation_list [i ][2 ] == 'complete' :
799+ number_of_completed_parts += 1
800+ if number_of_completed_parts == self .number_of_parts :
801+ # Download complete!
802+ self .download_status = 'complete'
803+
788804 # Calculate download percent
789805 if self .file_size :
790806 self .download_percent = int ((self .downloaded_size / self .file_size ) * 100 )
@@ -793,9 +809,8 @@ def checkDownloadProgress(self):
793809
794810 self .number_of_active_connections = 0
795811 # If the downloaded size is the same as the file size, then the download has been completed successfully.
796- if self .file_size == self . downloaded_size :
812+ if self .download_status == 'complete' :
797813
798- self .download_status = 'complete'
799814 logger .sendToLog ('Download complete. - GID: ' + self .gid , 'DOWNLOADS' )
800815
801816 # If the download is not complete and the user has not stopped the download, then the download has encountered an error.
0 commit comments