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}