MCPcopy
hub / github.com/perkeep/perkeep / FileTime

Function FileTime

pkg/schema/schema.go:989–1040  ·  view source on GitHub ↗

FileTime returns the best guess of the file's creation time (or modtime). If the file doesn't have its own metadata indication the creation time (such as in EXIF), FileTime uses the modification time from the file system. It there was a valid EXIF but an error while trying to get a date from it, it

(f io.ReaderAt)

Source from the content-addressed store, hash-verified

987// It there was a valid EXIF but an error while trying to get a date from it,
988// it logs the error and tries the other methods.
989func FileTime(f io.ReaderAt) (time.Time, error) {
990 var ct time.Time
991 defaultTime := func() (time.Time, error) {
992 if osf, ok := f.(*os.File); ok {
993 fi, err := osf.Stat()
994 if err != nil {
995 return ct, fmt.Errorf("Failed to find a modtime: stat: %w", err)
996 }
997 return fi.ModTime(), nil
998 }
999 return ct, errors.New("all methods failed to find a creation time or modtime")
1000 }
1001
1002 size, ok := findSize(f)
1003 if !ok {
1004 size = 256 << 10 // enough to get the EXIF
1005 }
1006 r := io.NewSectionReader(f, 0, size)
1007 var tiffErr error
1008 ex, err := exif.Decode(r)
1009 if err != nil {
1010 tiffErr = err
1011 if exif.IsShortReadTagValueError(err) {
1012 return ct, io.ErrUnexpectedEOF
1013 }
1014 if exif.IsCriticalError(err) || exif.IsExifError(err) {
1015 return defaultTime()
1016 }
1017 }
1018 ct, err = ex.DateTime()
1019 if err != nil {
1020 return defaultTime()
1021 }
1022 // If the EXIF file only had local timezone, but it did have
1023 // GPS, then lookup the timezone and correct the time.
1024 if ct.Location() == time.Local {
1025 if exif.IsGPSError(tiffErr) {
1026 log.Printf("Invalid EXIF GPS data: %v", tiffErr)
1027 return ct, nil
1028 }
1029 if lat, long, err := ex.LatLong(); err == nil {
1030 if loc := lookupLocation(latlong.LookupZoneName(lat, long)); loc != nil {
1031 if t, err := exifDateTimeInLocation(ex, loc); err == nil {
1032 return t, nil
1033 }
1034 }
1035 } else if !exif.IsTagNotPresentError(err) {
1036 log.Printf("Invalid EXIF GPS data: %v", err)
1037 }
1038 }
1039 return ct, nil
1040}
1041
1042// This is basically a copy of the exif.Exif.DateTime() method, except:
1043// - it takes a *time.Location to assume

Callers 3

populateFileMethod · 0.92
uploadNodeRegularFileMethod · 0.92

Calls 7

findSizeFunction · 0.85
lookupLocationFunction · 0.85
exifDateTimeInLocationFunction · 0.85
PrintfMethod · 0.80
StatMethod · 0.65
LatLongMethod · 0.65
ModTimeMethod · 0.45

Tested by 1