add overwrite arg

This commit is contained in:
Aurélie Delhaie
2023-07-23 14:04:43 +02:00
parent 10867d2d85
commit ab31e2e3ff

111
main.go
View File

@@ -33,7 +33,10 @@ func usage() {
func main() { func main() {
go func() { go func() {
if r := recover(); r != nil { if r := recover(); r != nil {
fmt.Fprintln(os.Stderr, "E: ", r) _, err := fmt.Fprintln(os.Stderr, "E: ", r)
if err != nil {
os.Exit(-255)
}
os.Exit(-1) os.Exit(-1)
} }
}() }()
@@ -43,6 +46,7 @@ func main() {
jpegQuality := flag.Int("q", jpeg.DefaultQuality, "Define the jpeg quality") jpegQuality := flag.Int("q", jpeg.DefaultQuality, "Define the jpeg quality")
ignoreErr := flag.Bool("ignore-errors", false, "Continue to convert when the converter encounter an error") ignoreErr := flag.Bool("ignore-errors", false, "Continue to convert when the converter encounter an error")
removeOrig := flag.Bool("remove-original", false, "Remove the heic file after conversion") removeOrig := flag.Bool("remove-original", false, "Remove the heic file after conversion")
overwriteOut := flag.Bool("overwrite", false, "Overwrite file if already exists")
outPath := flag.String("o", "", "Output directory") outPath := flag.String("o", "", "Output directory")
flag.Parse() flag.Parse()
@@ -54,15 +58,22 @@ func main() {
var files []string var files []string
if len(*dir) == 0 { if len(*dir) == 0 {
if len(os.Args) == 1 { if len(os.Args) == 1 {
fmt.Fprintln(os.Stderr, "E: Missing file path") _, err := fmt.Fprintln(os.Stderr, "E: Missing file path")
if err != nil {
panic(err)
}
os.Exit(-1) os.Exit(-1)
} }
files = append(files, os.Args[len(os.Args)-1]) files = append(files, os.Args[len(os.Args)-1])
} else { } else {
fmt.Printf("Analyzing folder %s\n", *dir)
var err error var err error
files, err = getHEICFiles(*dir, *recursive) files, err = getHEICFiles(*dir, *recursive)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "E: Failed to analyse directory: %v\n", err) _, err := fmt.Fprintf(os.Stderr, "E: Failed to analyse directory: %v\n", err)
if err != nil {
panic(err)
}
os.Exit(-1) os.Exit(-1)
} }
} }
@@ -79,19 +90,22 @@ func main() {
if askForConfirmation("Do you want to start the conversion?") { if askForConfirmation("Do you want to start the conversion?") {
out := *dir out := *dir
overwritePath := false rewritePath := false
if len(*outPath) > 0 { if len(*outPath) > 0 {
out = *outPath out = *outPath
overwritePath = true rewritePath = true
} }
start := time.Now() start := time.Now()
converted := convert(out, files, *ignoreErr, *jpegQuality, overwritePath) converted := convert(out, files, *ignoreErr, *jpegQuality, rewritePath, *overwriteOut)
if *removeOrig { if *removeOrig {
for _, file := range converted { for _, file := range converted {
err := os.Remove(file) err := os.Remove(file)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "E: Failed to remove %s: %v\n", file, err) _, err := fmt.Fprintf(os.Stderr, "E: Failed to remove %s: %v\n", file, err)
if err != nil {
panic(err)
}
} }
} }
} }
@@ -140,7 +154,7 @@ func isHEIC(f filer) bool {
return !f.IsDir() && strings.HasSuffix(f.Name(), ".heic") return !f.IsDir() && strings.HasSuffix(f.Name(), ".heic")
} }
func convert(out string, files []string, ignoreErr bool, jpegQuality int, overwritePath bool) []string { func convert(out string, files []string, ignoreErr bool, jpegQuality int, rewritePath, overwrite bool) []string {
var success []string var success []string
wg := new(sync.WaitGroup) wg := new(sync.WaitGroup)
chunk := chunkWork(files) chunk := chunkWork(files)
@@ -148,60 +162,103 @@ func convert(out string, files []string, ignoreErr bool, jpegQuality int, overwr
wg.Add(1) wg.Add(1)
go func(files []string, wg *sync.WaitGroup) { go func(files []string, wg *sync.WaitGroup) {
for _, file := range files { for _, file := range files {
// Generate new path
fout := strings.TrimSuffix(file, ".heic") + ".jpg"
if rewritePath {
fout = filepath.Join(out, filepath.Base(fout))
}
// Ignore if file exists and overwirte arg not true
if !overwrite {
if _, err := os.Stat(fout); err == nil {
continue
}
}
// Open source file
fi, err := os.Open(file) fi, err := os.Open(file)
if err != nil { if err != nil {
fmt.Fprintf(os.Stderr, "E: Failed to open %s: %v\n", file, err) _, err := fmt.Fprintf(os.Stderr, "E: Failed to open %s: %v\n", file, err)
if err != nil {
panic(err)
}
if ignoreErr { if ignoreErr {
continue continue
} }
os.Exit(-1) os.Exit(-1)
} }
// Extract exif
ex, err := goheif.ExtractExif(fi) ex, err := goheif.ExtractExif(fi)
if err != nil { if err != nil {
fmt.Printf("W: no EXIF from %s: %v\n", file, err) fmt.Printf("W: no EXIF from %s: %v\n", file, err)
} }
// Parse jpg to bitmap
img, err := goheif.Decode(fi) img, err := goheif.Decode(fi)
if err != nil { if err != nil {
fi.Close() err := fi.Close()
fmt.Fprintf(os.Stderr, "E: Failed to decode %s: %v\n", file, err) if err != nil {
panic(err)
}
_, err = fmt.Fprintf(os.Stderr, "E: Failed to decode %s: %v\n", file, err)
if err != nil {
panic(err)
}
if ignoreErr { if ignoreErr {
continue continue
} }
os.Exit(-1) os.Exit(-1)
} }
fout := strings.TrimSuffix(file, ".heic") + ".jpg" // Open out file
if overwritePath {
fout = filepath.Join(out, filepath.Base(fout))
}
fo, err := os.OpenFile(fout, os.O_RDWR|os.O_CREATE, 0644) fo, err := os.OpenFile(fout, os.O_RDWR|os.O_CREATE, 0644)
if err != nil { if err != nil {
fi.Close() err := fi.Close()
fmt.Fprintf(os.Stderr, "E: Failed to create output file %s: %v\n", fout, err) if err != nil {
panic(err)
}
_, err = fmt.Fprintf(os.Stderr, "E: Failed to create output file %s: %v\n", fout, err)
if err != nil {
panic(err)
}
if ignoreErr { if ignoreErr {
continue continue
} }
os.Exit(-1) os.Exit(-1)
} }
// Convert and write to jpg file
w, _ := exif.NewWriterExif(fo, ex) w, _ := exif.NewWriterExif(fo, ex)
err = jpeg.Encode(w, img, &jpeg.Options{ err = jpeg.Encode(w, img, &jpeg.Options{
Quality: jpegQuality, Quality: jpegQuality,
}) })
if err != nil { if err != nil {
fi.Close() err := fi.Close()
fo.Close() if err != nil {
fmt.Fprintf(os.Stderr, "E: Failed to encode %s: %v\n", fout, err) panic(err)
}
err = fo.Close()
if err != nil {
panic(err)
}
_, err = fmt.Fprintf(os.Stderr, "E: Failed to encode %s: %v\n", fout, err)
if err != nil {
panic(err)
}
if ignoreErr { if ignoreErr {
continue continue
} }
os.Exit(-1) os.Exit(-1)
} }
fi.Close() err = fi.Close()
fo.Close() if err != nil {
panic(err)
}
err = fo.Close()
if err != nil {
panic(err)
}
success = append(success, file) success = append(success, file)
} }
wg.Done() wg.Done()
@@ -228,9 +285,7 @@ func chunkWork(files []string) [][]string {
func askForConfirmation(s string) bool { func askForConfirmation(s string) bool {
reader := bufio.NewReader(os.Stdin) reader := bufio.NewReader(os.Stdin)
fmt.Printf("%s [y/N]: ", s)
for {
fmt.Printf("%s [y/n]: ", s)
response, err := reader.ReadString('\n') response, err := reader.ReadString('\n')
if err != nil { if err != nil {
@@ -241,8 +296,6 @@ func askForConfirmation(s string) bool {
if response == "y" || response == "yes" { if response == "y" || response == "yes" {
return true return true
} else if response == "n" || response == "no" { }
return false return false
} }
}
}