arnaucube
arnaucube/exif-datesPublic Self-hosted repository
exif-dates/main.go
main.goRaw
  1package main
  2
  3import (
  4	"errors"
  5	"fmt"
  6	"io"
  7	"log"
  8	"os"
  9	"path"
 10	"time"
 11
 12	"github.com/rwcarlsen/goexif/exif"
 13)
 14
 15const version = "v0.0.1_2024-01-04"
 16const layout = "2006-01-02T15:04:05.000Z"
 17const outputDir = "output"
 18
 19func main() {
 20	fmt.Println("version:", version)
 21
 22	if err := os.Mkdir(outputDir, os.ModePerm); err != nil {
 23		log.Fatal("output directory already exists")
 24	}
 25
 26	dir := "."
 27	if len(os.Args) > 1 {
 28		dir = os.Args[1]
 29	}
 30
 31	entries, err := os.ReadDir(dir)
 32	if err != nil {
 33		log.Fatal(err)
 34	}
 35
 36	for _, e := range entries {
 37		// skip subdirectories
 38		if e.IsDir() {
 39			continue
 40		}
 41
 42		fileName := dir + "/" + e.Name()
 43		fileExtension := path.Ext(fileName)
 44		// get file
 45		fmt.Printf("---FileName: %s,", fileName)
 46		f, err := os.Open(fileName)
 47		if err != nil {
 48			fmt.Println("\ne", err)
 49		}
 50		defer f.Close()
 51
 52		// get camera date
 53		date, err := getExifDate(f)
 54		if err != nil && (err == io.EOF || err.Error() == "exif: failed to find exif intro marker") {
 55			fmt.Println("  not an img file, skipping file")
 56			continue
 57		}
 58		if err != nil {
 59			fmt.Println("err", err)
 60			continue
 61		}
 62		fmt.Println("\n  DATE", date)
 63
 64		newFileName := getValidFileName(outputDir+"/"+date.String(), fileExtension)
 65		newFileName = newFileName + fileExtension
 66
 67		fmt.Println("  storing the new img as", newFileName)
 68
 69		// duplicate the original file into newFileName
 70		f, err = os.Open(fileName)
 71		if err != nil {
 72			fmt.Println("\ne", err)
 73		}
 74		defer f.Close()
 75		fo, err := os.Create(newFileName)
 76		if err != nil {
 77			panic(err)
 78		}
 79		defer fo.Close()
 80		buf := make([]byte, 1024)
 81		for {
 82			n, err := f.Read(buf)
 83			if err != nil && err != io.EOF {
 84				panic(err)
 85			}
 86			if n == 0 {
 87				break
 88			}
 89
 90			if _, err := fo.Write(buf[:n]); err != nil {
 91				panic(err)
 92			}
 93		}
 94		// set the img date into the file date (file's access and modification times)
 95		os.Chtimes(newFileName, *date, *date)
 96
 97	}
 98
 99}
100
101func getExifDate(f *os.File) (*time.Time, error) {
102	x, err := exif.Decode(f)
103	if err != nil {
104		return nil, err
105	}
106
107	d, err := x.DateTime()
108	if err != nil {
109		return nil, err
110	}
111
112	return &d, nil
113}
114
115func getValidFileName(fileName, fileExtension string) string {
116	_, err := os.Open(fileName + fileExtension)
117	if !errors.Is(err, os.ErrNotExist) {
118		return getValidFileName(fileName+"_1", fileExtension)
119	}
120	return fileName
121}