Skip to content

Instantly share code, notes, and snippets.

@vyachin
Created April 5, 2025 20:04
Show Gist options
  • Save vyachin/a723e8e9892b2b5a41653e037d5b9f17 to your computer and use it in GitHub Desktop.
Save vyachin/a723e8e9892b2b5a41653e037d5b9f17 to your computer and use it in GitHub Desktop.
golfing mass photo renamer
package main
import (
"errors"
"fmt"
"github.com/rwcarlsen/goexif/exif"
"io/fs"
"log"
"os"
"path/filepath"
"strconv"
"strings"
)
func fileExt(filename string) string {
ext := filepath.Ext(filename)
return strings.ToLower(ext)
}
func generateFileName(fileName string) (string, error) {
f, err := os.Open(fileName)
if err != nil {
return "", err
}
defer f.Close()
x, err := exif.Decode(f)
if err != nil {
return "", err
}
t, err := x.DateTime()
if err != nil {
return "", err
}
buf := strings.Builder{}
buf.WriteString(t.Format("2006-01-02_15:04:05"))
imageUniqueID, err := x.Get("ImageUniqueID")
if err == nil {
idStr, err := imageUniqueID.StringVal()
if err == nil {
buf.WriteString("_")
buf.WriteString(idStr)
}
} else {
if stat, err := os.Stat(fileName); err == nil {
buf.WriteString("_")
buf.WriteString(strconv.FormatInt(stat.Size(), 10))
}
}
buf.WriteString(fileExt(fileName))
newFileName := buf.String()
return filepath.Join(filepath.Dir(fileName), newFileName), nil
}
func walkFunc(path string, info fs.FileInfo, err0 error) error {
if info.IsDir() {
return nil
}
if fileExt(path) != ".jpg" {
return nil
}
newFilePath, err := generateFileName(path)
if err != nil {
return nil
}
if _, err := os.Stat(newFilePath); errors.Is(err, os.ErrNotExist) {
err = os.Rename(path, newFilePath)
if err != nil {
return nil
}
fmt.Printf("%s -> %s\n", path, newFilePath)
}
return nil
}
func main() {
err := filepath.Walk(".", walkFunc)
if err != nil {
log.Fatal(err)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment