package main import ( "fmt" "io" "net/http" "os" "path/filepath" "strings" ) func downloadImage(config *Config) error { filename := getFilenameFromURL(config.ImageURL) filepath := filepath.Join("/tmp", filename) if _, err := os.Stat(filepath); err == nil { fmt.Printf("Image already exists at %s, skipping download\n", filepath) config.ImageURL = filepath return nil } fmt.Printf("Downloading image from %s...\n", config.ImageURL) resp, err := http.Get(config.ImageURL) if err != nil { return fmt.Errorf("failed to download image: %w", err) } defer resp.Body.Close() if resp.StatusCode != http.StatusOK { return fmt.Errorf("bad status: %s", resp.Status) } out, err := os.Create(filepath) if err != nil { return fmt.Errorf("failed to create file: %w", err) } defer out.Close() counter := &WriteCounter{Total: resp.ContentLength} _, err = io.Copy(out, io.TeeReader(resp.Body, counter)) if err != nil { return fmt.Errorf("failed to save image: %w", err) } fmt.Println("\nDownload completed!") config.ImageURL = filepath return nil } func getFilenameFromURL(url string) string { parts := strings.Split(url, "/") return parts[len(parts)-1] } type WriteCounter struct { Total int64 Downloaded int64 } func (wc *WriteCounter) Write(p []byte) (int, error) { n := len(p) wc.Downloaded += int64(n) wc.printProgress() return n, nil } func (wc *WriteCounter) printProgress() { fmt.Printf("\r") if wc.Total > 0 { percent := float64(wc.Downloaded) / float64(wc.Total) * 100 fmt.Printf("Downloading... %.0f%% (%d/%d MB)", percent, wc.Downloaded/1024/1024, wc.Total/1024/1024) } else { fmt.Printf("Downloading... %d MB", wc.Downloaded/1024/1024) } }