Skip to content

Commit

Permalink
Enhance XMP file handling in folder read/write operations to support …
Browse files Browse the repository at this point in the history
…sidecar files
  • Loading branch information
simulot committed Nov 6, 2024
1 parent d421520 commit 8377d62
Show file tree
Hide file tree
Showing 2 changed files with 62 additions and 4 deletions.
37 changes: 37 additions & 0 deletions adapters/folder/readFolder.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ import (
"github.com/simulot/immich-go/internal/fileevent"
"github.com/simulot/immich-go/internal/filenames"
"github.com/simulot/immich-go/internal/filters"
"github.com/simulot/immich-go/internal/fshelper"
"github.com/simulot/immich-go/internal/groups"
"github.com/simulot/immich-go/internal/groups/burst"
"github.com/simulot/immich-go/internal/groups/epsonfastfoto"
Expand Down Expand Up @@ -142,6 +143,7 @@ func (la *LocalAssetBrowser) parseDir(ctx context.Context, fsys fs.FS, dir strin
continue
}
la.log.Record(ctx, fileevent.DiscoveredSidecar, fileevent.AsFileAndName(fsys, name))
continue
}

if !la.flags.InclusionFlags.IncludedExtensions.Include(ext) {
Expand Down Expand Up @@ -207,6 +209,14 @@ func (la *LocalAssetBrowser) parseDir(ctx context.Context, fsys fs.FS, dir strin
la.log.Record(ctx, fileevent.DiscoveredDiscarded, a, "reason", "asset outside date range")
continue
}

// check the presence of an XMP file
if b, xmp := detectXMP(fsys, a.FileName); b {
a.SideCar = metadata.SideCarFile{
FSys: fsys,
FileName: xmp,
}
}
select {
case in <- a:
case <-ctx.Done():
Expand Down Expand Up @@ -253,6 +263,33 @@ func (la *LocalAssetBrowser) parseDir(ctx context.Context, fsys fs.FS, dir strin
return nil
}

func detectXMP(fsys fs.FS, name string) (bool, string) {
xmp := name + ".xmp"
_, err := fshelper.Stat(fsys, xmp)
if err == nil {
return true, xmp
}
xmp = name + ".XMP"
_, err = fshelper.Stat(fsys, xmp)
if err == nil {
return true, xmp
}

name = strings.TrimSuffix(name, filepath.Ext(name))
xmp = name + ".xmp"
_, err = fshelper.Stat(fsys, xmp)
if err == nil {
return true, xmp
}
xmp = name + ".XMP"
_, err = fshelper.Stat(fsys, xmp)
if err == nil {
return true, xmp
}

return false, ""
}

func (la *LocalAssetBrowser) assetFromFile(_ context.Context, fsys fs.FS, name string) (*assets.Asset, error) {
a := &assets.Asset{
FileName: name,
Expand Down
29 changes: 25 additions & 4 deletions adapters/folder/writeFolder.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import (
"context"
"errors"
"fmt"
"io"
"io/fs"
"os"
"path"
Expand Down Expand Up @@ -77,14 +78,34 @@ func (w *LocalAssetWriter) WriteAsset(ctx context.Context, a *assets.Asset) erro
case <-ctx.Done():
return ctx.Err()
default:
err := fshelper.WriteFile(w.WriteToFS, path.Join(dir, base), r)
if err == nil {
f, err := fshelper.OpenFile(w.WriteToFS, path.Join(dir, base)+".xmp", os.O_RDWR|os.O_CREATE, 0o644)
err = fshelper.WriteFile(w.WriteToFS, path.Join(dir, base), r)
if err == nil && !a.SideCar.IsSet() {
// No sidecar file, write XMP data
var f fshelper.WFile
f, err = fshelper.OpenFile(w.WriteToFS, path.Join(dir, base)+".xmp", os.O_RDWR|os.O_CREATE, 0o644)
if err != nil {
return err
}
defer f.Close()
return xmp.WriteXMP(a, f)
err = xmp.WriteXMP(a, f)
if err != nil {
return err
}
} else if a.SideCar.IsSet() {
// Sidecar file is set, copy it
var scr fs.File
scr, err = a.FSys.Open(a.SideCar.FileName)
if err != nil {
return err
}
defer scr.Close()
var scw fshelper.WFile
scw, err = fshelper.OpenFile(w.WriteToFS, path.Join(dir, path.Base(a.SideCar.FileName)), os.O_RDWR|os.O_CREATE, 0o644)
if err != nil {
return err
}
defer scw.Close()
_, err = io.Copy(scw, scr)
}
return err
}
Expand Down

0 comments on commit 8377d62

Please sign in to comment.