Thursday, November 5, 2015

Fix Whatsapp picture capture time

Whatsapp strips all EXIF info from any pictures sent through it. Without any EXIF info, Lightroom uses the file modification time as the capture time. If for some reason, the file modification time is wrong, then Lightroom gets confused. Luckily, Whatsapp puts the date in the filename. But Lightroom doesn't know about it.

So, here's a little Go program that changes the file modification time of files to the date in the filenames. Since the exact time is unknown, it is set to 3am local time.

Public domain.

UPDATE 2017/01/10: In addition to updating the file timestamp, also runs "exiftool" to update the EXIF dates in the jpg file. Overwrites the original jpeg file.

Use at your own risk!

package main

import (
        "flag"
        "fmt"
        "os"
        "os/exec"
        "regexp"
        "strconv"
        "time"
)

var trial = flag.Bool("n", true, "trail run")

func main() {
        flag.Parse()
        for _, f := range flag.Args() {
                fix(f)
        }
}

var re = regexp.MustCompile(`^([^-]*-)([0-9][0-9][0-9][0-9])([0-9][0-9])([0-9][0-9])(-WA.*)$`)

func fix(f string) {
        match := re.FindStringSubmatch(f)
        if len(match) > 0 {
                y, _ := strconv.Atoi(match[2])
                m, _ := strconv.Atoi(match[3])
                d, _ := strconv.Atoi(match[4])
                update(f, y, m, d)
        }
}

func update(f string, y int, m int, d int) {
        s, err := os.Stat(f)
        if err != nil {
                fmt.Printf("Unable to stat file %v\n", f)
                return
        }
        oldy, oldm, oldd := s.ModTime().Date()
        oldhh, oldmm, oldss := s.ModTime().Clock()
        hh, mm, ss := 3, 3, 3
        if y != oldy || time.Month(m) != oldm || d != oldd ||
                oldhh != hh || oldmm != mm || oldss != ss {
                t := time.Date(y, time.Month(m), d, hh, mm, ss, 0, time.Local)
                fmt.Printf("%v: %v -> %v\n", f, s.ModTime(), t)
                if !*trial {
                        err := os.Chtimes(f, time.Now(), t)
                        if err != nil {
                                fmt.Printf("Failed to change time on %v\n", f)
                                return
                        }
                        err = exec.Command("exiftool", "-overwrite_original_in_place", "-FileModifyDate>AllDates", f).Run()
                        if err != nil {
                                fmt.Printf("Failed to update exif of %v\n", f)
                                return
                        }
                        err = os.Chtimes(f, time.Now(), t)
                        if err != nil {
                                fmt.Printf("Failed to change time on %v\n", f)
                                return
                        }
                }
        }
}

No comments:

Post a Comment