Add support for local image files (URL or local path)
This commit is contained in:
126
download.go
126
download.go
@@ -12,6 +12,132 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
func isURL(path string) bool {
|
||||
return strings.HasPrefix(path, "http://") || strings.HasPrefix(path, "https://")
|
||||
}
|
||||
|
||||
func downloadOrCopyImage(config *Config) error {
|
||||
// Check if it's a local file
|
||||
if !isURL(config.ImageURL) {
|
||||
return handleLocalImage(config)
|
||||
}
|
||||
|
||||
// It's a URL, download it
|
||||
return downloadImage(config)
|
||||
}
|
||||
|
||||
func handleLocalImage(config *Config) error {
|
||||
localPath := config.ImageURL
|
||||
|
||||
// Check if file exists
|
||||
if _, err := os.Stat(localPath); os.IsNotExist(err) {
|
||||
return fmt.Errorf("local image file not found: %s", localPath)
|
||||
}
|
||||
|
||||
fmt.Printf("Using local image: %s\n", localPath)
|
||||
|
||||
// Verify image
|
||||
if err := verifyImage(localPath); err != nil {
|
||||
return fmt.Errorf("local image verification failed: %w", err)
|
||||
}
|
||||
|
||||
fmt.Println("Local image verification passed!")
|
||||
|
||||
// Check if it's already in /tmp, if not copy it
|
||||
filename := filepath.Base(localPath)
|
||||
tmpPath := filepath.Join("/tmp", filename)
|
||||
|
||||
absLocal, _ := filepath.Abs(localPath)
|
||||
absTmp, _ := filepath.Abs(tmpPath)
|
||||
|
||||
if absLocal != absTmp {
|
||||
// Check if already exists in /tmp
|
||||
if _, err := os.Stat(tmpPath); err == nil {
|
||||
fmt.Printf("Image already exists in /tmp, verifying...\n")
|
||||
if err := verifyImage(tmpPath); err != nil {
|
||||
fmt.Println("Cached image corrupted, copying fresh...")
|
||||
if err := copyFile(localPath, tmpPath); err != nil {
|
||||
return fmt.Errorf("failed to copy image to /tmp: %w", err)
|
||||
}
|
||||
} else {
|
||||
fmt.Println("Using cached image from /tmp")
|
||||
}
|
||||
} else {
|
||||
fmt.Printf("Copying image to /tmp...\n")
|
||||
if err := copyFile(localPath, tmpPath); err != nil {
|
||||
return fmt.Errorf("failed to copy image to /tmp: %w", err)
|
||||
}
|
||||
fmt.Println("Image copied successfully!")
|
||||
}
|
||||
config.ImageURL = tmpPath
|
||||
} else {
|
||||
// Already in /tmp, ensure config path is normalized
|
||||
config.ImageURL = tmpPath
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func copyFile(src, dst string) error {
|
||||
sourceFile, err := os.Open(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer sourceFile.Close()
|
||||
|
||||
destFile, err := os.Create(dst)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer destFile.Close()
|
||||
|
||||
// Get file size for progress
|
||||
fileInfo, err := sourceFile.Stat()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fileSize := fileInfo.Size()
|
||||
|
||||
fmt.Printf("Copying %s (%.2f MB)...\n", filepath.Base(src), float64(fileSize)/(1024*1024))
|
||||
|
||||
// Copy with progress
|
||||
buf := make([]byte, 1024*1024) // 1MB buffer
|
||||
var written int64
|
||||
lastProgress := 0
|
||||
|
||||
for {
|
||||
nr, err := sourceFile.Read(buf)
|
||||
if nr > 0 {
|
||||
nw, err := destFile.Write(buf[0:nr])
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
if nr != nw {
|
||||
return fmt.Errorf("short write")
|
||||
}
|
||||
written += int64(nw)
|
||||
|
||||
// Show progress every 10%
|
||||
if fileSize > 0 {
|
||||
progress := int(float64(written) / float64(fileSize) * 100)
|
||||
if progress >= lastProgress+10 {
|
||||
fmt.Printf("Progress: %d%%\n", progress)
|
||||
lastProgress = progress
|
||||
}
|
||||
}
|
||||
}
|
||||
if err == io.EOF {
|
||||
break
|
||||
}
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
fmt.Println("Progress: 100%")
|
||||
return nil
|
||||
}
|
||||
|
||||
func downloadImage(config *Config) error {
|
||||
filename := getFilenameFromURL(config.ImageURL)
|
||||
filepath := filepath.Join("/tmp", filename)
|
||||
|
||||
Reference in New Issue
Block a user