77 "os"
88 "path/filepath"
99 "sync"
10+ "time"
1011
1112 "github.com/kataras/golog"
1213)
@@ -33,6 +34,8 @@ func main() {
3334 config_path := flag .String ("config" , "./config.json" , "A config file for download extensions and skins." )
3435 target_path := flag .String ("target" , "./downloaded" , "A target folder for downloaded extensions and skins." )
3536 force_rm_target := flag .Bool ("force-rm-target" , false , "Turn this on to delete target directory if exist. Be careful to use!" )
37+ retry_count := flag .Int ("retry-count" , 3 , "Number of retries for download and extraction process." )
38+ retry_delay := flag .Int ("retry-delay" , 2 , "Delay in seconds between retries for download and extraction process." )
3639 flag .Parse ()
3740
3841 // Set flags to each variables.
@@ -92,7 +95,7 @@ func main() {
9295 wg .Add (len (DownloadTargets ))
9396 for _ , opts := range DownloadTargets {
9497 log .Debugf ("Start download %s \" %s\" " , opts .Type , opts .Name )
95- go opts .StartDownload (& wg )
98+ go opts .StartDownload (& wg , * retry_count , time . Duration ( * retry_delay ) * time . Second )
9699 }
97100 wg .Wait ()
98101
@@ -107,34 +110,60 @@ func main() {
107110 log .Info ("Download Finished." )
108111}
109112
110- func (o DownloadOption ) StartDownload (wg * sync.WaitGroup ) {
113+ func (o DownloadOption ) StartDownload (wg * sync.WaitGroup , retryCount int , retryDelay time. Duration ) {
111114 defer wg .Done ()
112115
113- // remove "s" suffix
114- target_name := o .Type [:len (o .Type )- 1 ]
116+ err := retry (func () error {
117+ // remove "s" suffix
118+ log .Info (o .Type )
119+ targetName := o .Type [:len (o .Type )- 1 ]
120+
121+ // Step 1: Download file from URL
122+ filename , err := downloadUrl (o .Name , o .Url )
123+ if err != nil {
124+ return fmt .Errorf ("Failed to download %s \" %s\" : %w" , targetName , o .Name , err )
125+ }
126+
127+ // Step 2: Check if the file is a valid archive
128+ if ! isValidArchiveFile (filename ) {
129+ return fmt .Errorf ("Downloaded file is not an archive: %s \" %s\" " , targetName , o .Name )
130+ }
131+
132+ // Step 3: Extract the file to a temporary directory
133+ dirpath , err := unArchive (o .Name , filename )
134+ if err != nil {
135+ return fmt .Errorf ("Failed to extract %s \" %s\" : %w" , targetName , o .Name , err )
136+ }
137+
138+ // Step 4: Move the extracted directory to the target location
139+ dest := fmt .Sprintf ("%s/%s/%s" , targetDir , o .Type , o .Name )
140+ err = os .Rename (dirpath , dest )
141+ if err != nil {
142+ return fmt .Errorf ("Failed to move %s \" %s\" to \" %s\" : %w" , targetName , o .Name , dest , err )
143+ }
144+
145+ return nil
146+ }, retryCount , retryDelay , fmt .Sprintf ("Complete download and extraction process for \" %s\" " , o .Name ))
115147
116- // Download file from url.
117- filename , err := downloadUrl (o .Name , o .Url )
118148 if err != nil {
119- msg := fmt .Sprintf ("Failed to download %s \" %s\" " , target_name , o .Name )
120- log .Error (msg , err )
121- hasError = true
122- }
123-
124- // Extract to temp directory.
125- dirpath , err := unArchive (o .Name , filename )
126- if err != nil {
127- msg := fmt .Sprintf ("Failed to extract %s \" %s\" to \" %s\" " , target_name , o .Name , dirpath )
128- log .Error (msg , err )
149+ log .Error (err )
129150 hasError = true
130151 }
152+ }
131153
132- // And move to target.
133- dest := fmt .Sprintf ("%s/%s/%s" , targetDir , o .Type , o .Name )
134- err = os .Rename (dirpath , dest )
135- if err != nil {
136- msg := fmt .Sprintf ("Failed to move %s \" %s\" from \" %s\" to \" %s\" " , target_name , o .Name , dirpath , dest )
137- log .Error (msg , err )
138- hasError = true
154+ // retry function to handle retries with delay for entire process
155+ func retry (operation func () error , attempts int , delay time.Duration , description string ) error {
156+ for i := 0 ; i < attempts ; i ++ {
157+ err := operation ()
158+ if err == nil {
159+ return nil
160+ }
161+ if i < attempts - 1 {
162+ log .Warnf ("Retrying %s... attempt %d" , description , i + 2 )
163+ time .Sleep (delay )
164+ } else {
165+ return fmt .Errorf ("failed to %s after %d attempts: %w" , description , attempts , err )
166+ }
139167 }
168+ return nil
140169}
0 commit comments