From 3b595fe57607947a686e7704800cc960a807e592 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Andre=20Kl=C3=A4rner?= Date: Thu, 5 Sep 2024 00:02:52 +0200 Subject: [PATCH] apply the mtime given by the gopro to the written files (#126) This allows applications like Google Photos to have the actual timestamp available, when the file was written, instead of reading the timestamp when the files were downloaded from the camera. --- pkg/gopro/connect.go | 20 ++++++++++++-------- pkg/gopro/update.go | 2 +- pkg/insta360/update.go | 2 +- pkg/utils/cameras.go | 9 ++++++++- 4 files changed, 22 insertions(+), 11 deletions(-) diff --git a/pkg/gopro/connect.go b/pkg/gopro/connect.go index 27dd802..9d270f2 100644 --- a/pkg/gopro/connect.go +++ b/pkg/gopro/connect.go @@ -234,7 +234,7 @@ func ImportConnect(params utils.ImportParams) (*utils.Result, error) { switch fileTypeMatch.Type { case Video, ChapteredVideo: - go func(in, folder, origFilename, unsorted string, origSize int64, lrvSize int, bar *mpb.Bar) { + go func(in, folder, origFilename, unsorted string, origSize int64, lrvSize int, bar *mpb.Bar, mtime time.Time) { defer wg.Done() x := origFilename filename := origFilename @@ -249,7 +249,8 @@ func ImportConnect(params utils.ImportParams) (*utils.Result, error) { err := utils.DownloadFile( filepath.Join(unsorted, origFilename), fmt.Sprintf("http://%s:8080/videos/DCIM/%s/%s", in, folder, origFilename), - bar) + bar, + &mtime) if err != nil { bar.EwmaSetCurrent(origSize, 1*time.Millisecond) bar.EwmaIncrInt64(origSize, 1*time.Millisecond) @@ -304,7 +305,8 @@ func ImportConnect(params utils.ImportParams) (*utils.Result, error) { err := utils.DownloadFile( filepath.Join(unsorted, proxyVideoName), fmt.Sprintf("http://%s:8080/videos/DCIM/%s/%s", in, folder, proxyVideoName), - proxyVideoBar) + proxyVideoBar, + &mtime) if err != nil { proxyVideoBar.EwmaSetCurrent(int64(lrvSize), 1*time.Millisecond) proxyVideoBar.EwmaIncrInt64(int64(lrvSize), 1*time.Millisecond) @@ -323,7 +325,7 @@ func ImportConnect(params utils.ImportParams) (*utils.Result, error) { } inlineCounter.SetSuccess() } - }(params.Input, folder.D, goprofile.N, unsorted, goprofile.S, goprofile.Glrv, bar) + }(params.Input, folder.D, goprofile.N, unsorted, goprofile.S, goprofile.Glrv, bar, tm) case Photo: type photo struct { @@ -363,13 +365,14 @@ func ImportConnect(params utils.ImportParams) (*utils.Result, error) { } for _, item := range totalPhotos { - go func(in string, nowPhoto photo, unsorted string) { + go func(in string, nowPhoto photo, unsorted string, mtime time.Time) { defer wg.Done() err := utils.DownloadFile( filepath.Join(unsorted, nowPhoto.Name), fmt.Sprintf("http://%s:8080/videos/DCIM/%s/%s", in, nowPhoto.Folder, nowPhoto.Name), nowPhoto.Bar, + &mtime, ) if err != nil { nowPhoto.Bar.EwmaSetCurrent(int64(nowPhoto.Size), 1*time.Millisecond) @@ -396,7 +399,7 @@ func ImportConnect(params utils.ImportParams) (*utils.Result, error) { return } } - }(params.Input, item, unsorted) + }(params.Input, item, unsorted, tm) } case Multishot: @@ -415,13 +418,14 @@ func ImportConnect(params utils.ImportParams) (*utils.Result, error) { } multiShotBar := utils.GetNewBar(progressBar, gpFileInfo.S, filename, utils.IoTX) - go func(in, folder, origFilename, unsorted string, origSize int64) { + go func(in, folder, origFilename, unsorted string, origSize int64, mtime time.Time) { defer wg.Done() err := utils.DownloadFile( filepath.Join(unsorted, origFilename), fmt.Sprintf("http://%s:8080/videos/DCIM/%s/%s", in, folder, origFilename), multiShotBar, + &mtime, ) if err != nil { bar.EwmaSetCurrent(origSize, 1*time.Millisecond) @@ -442,7 +446,7 @@ func ImportConnect(params utils.ImportParams) (*utils.Result, error) { return } } - }(params.Input, folder.D, filename, unsorted, gpFileInfo.S) + }(params.Input, folder.D, filename, unsorted, gpFileInfo.S, tm) } default: diff --git a/pkg/gopro/update.go b/pkg/gopro/update.go index 28b17f6..ef9c984 100644 --- a/pkg/gopro/update.go +++ b/pkg/gopro/update.go @@ -57,7 +57,7 @@ func UpdateCamera(sdcard string) error { color.Yellow(">> Firmware release date: %s", camera.ReleaseDate) color.Yellow(html2text.HTML2Text(camera.ReleaseHTML)) - err = utils.DownloadFile(filepath.Join(sdcard, "UPDATE.zip"), camera.URL, nil) + err = utils.DownloadFile(filepath.Join(sdcard, "UPDATE.zip"), camera.URL, nil, nil) if err != nil { return err } diff --git a/pkg/insta360/update.go b/pkg/insta360/update.go index b090975..99b591f 100644 --- a/pkg/insta360/update.go +++ b/pkg/insta360/update.go @@ -42,7 +42,7 @@ func UpdateCamera(sdcard string, model string) error { color.White(html2text.HTML2Text(item.Description)) fwURL := item.Channels[0].DownloadURL - err = utils.DownloadFile(filepath.Join(sdcard, strings.Split(fwURL, "/")[len(strings.Split(fwURL, "/"))-1]), fwURL, nil) + err = utils.DownloadFile(filepath.Join(sdcard, strings.Split(fwURL, "/")[len(strings.Split(fwURL, "/"))-1]), fwURL, nil, nil) if err != nil { return err } diff --git a/pkg/utils/cameras.go b/pkg/utils/cameras.go index 146c330..46f6e26 100644 --- a/pkg/utils/cameras.go +++ b/pkg/utils/cameras.go @@ -172,7 +172,7 @@ func (wc WriteCounter) PrintProgress() { fmt.Printf("\rDownloading... %s complete", humanize.Bytes(wc.Total)) } -func DownloadFile(filepath string, url string, progressbar *mpb.Bar) error { +func DownloadFile(filepath string, url string, progressbar *mpb.Bar, mtime *time.Time) error { // Create the file, but give it a tmp file extension, this means we won't overwrite a // file until it's downloaded, but we'll remove the tmp extension once downloaded. out, err := os.Create(filepath + ".tmp") @@ -209,6 +209,13 @@ func DownloadFile(filepath string, url string, progressbar *mpb.Bar) error { // Close the file without defer so it can happen before Rename() out.Close() + if mtime != nil { + // set file mtime to what was given to us + if err := os.Chtimes(filepath+".tmp", time.Time{}, *mtime); err != nil { + return err + } + } + return os.Rename(filepath+".tmp", filepath) }