diff --git a/internal/filenames/infoCollector.go b/internal/filenames/infoCollector.go index bd804ad..2721c09 100644 --- a/internal/filenames/infoCollector.go +++ b/internal/filenames/infoCollector.go @@ -28,7 +28,7 @@ type nameMatcher func(name string) (bool, NameInfo) // GetInfo analyze the name and return the information extracted from the name func (ic InfoCollector) GetInfo(name string) NameInfo { - for _, m := range []nameMatcher{ic.Pixel, ic.Samsung, ic.Nexus, ic.Huawei} { + for _, m := range []nameMatcher{ic.Pixel, ic.Samsung, ic.Nexus, ic.Huawei, ic.SonyXperia} { if ok, i := m(name); ok { return i } diff --git a/internal/filenames/info_test.go b/internal/filenames/info_test.go index 0b250cc..6e9716b 100644 --- a/internal/filenames/info_test.go +++ b/internal/filenames/info_test.go @@ -69,6 +69,21 @@ func TestGetInfo(t *testing.T) { Taken: time.Date(2017, 11, 11, 3, 1, 28, 0, time.Local), }, }, + { + name: "Sony Xperia", + filename: "DSC_0002_BURST20230709220904977.JPG", + expected: true, + info: NameInfo{ + Radical: "BURST20230709220904977", + Base: "DSC_0002_BURST20230709220904977.JPG", + IsCover: false, + Ext: ".JPG", + Type: metadata.TypeImage, + Kind: KindBurst, + Index: 2, + Taken: time.Date(2023, 7, 9, 22, 9, 4, int(977*time.Millisecond), time.Local), + }, + }, { name: "InvalidFilename", filename: "IMG_1123.jpg", diff --git a/internal/filenames/sony_xperia.go b/internal/filenames/sony_xperia.go new file mode 100644 index 0000000..4b9c1a5 --- /dev/null +++ b/internal/filenames/sony_xperia.go @@ -0,0 +1,30 @@ +package filenames + +import ( + "regexp" + "strconv" + "strings" + "time" +) + +var sonyXperiaRE = regexp.MustCompile(`^DSC_(\d+)_BURST(\d+)(\D+)?(\..+)$`) + +func (ic InfoCollector) SonyXperia(name string) (bool, NameInfo) { + parts := sonyXperiaRE.FindStringSubmatch(name) + if len(parts) == 0 { + return false, NameInfo{} + } + ext := parts[4] + info := NameInfo{ + Radical: "BURST" + parts[2], + Base: name, + IsCover: strings.Contains(parts[3], "COVER"), + Ext: strings.ToLower(ext), + Type: ic.SM.TypeFromExt(ext), + Kind: KindBurst, + } + info.Index, _ = strconv.Atoi(parts[1]) + + info.Taken, _ = time.ParseInLocation("20060102150405.000", parts[2][:14]+"."+parts[2][14:], ic.TZ) + return true, info +} diff --git a/internal/filenames/sony_xperia_test.go b/internal/filenames/sony_xperia_test.go new file mode 100644 index 0000000..9ba275a --- /dev/null +++ b/internal/filenames/sony_xperia_test.go @@ -0,0 +1,70 @@ +package filenames + +import ( + "testing" + "time" + + "github.com/simulot/immich-go/internal/metadata" +) + +func TestSonyXperia(t *testing.T) { + tests := []struct { + name string + filename string + expected bool + info NameInfo + }{ + { + name: "Sony Xperia BURST", + filename: "DSC_0001_BURST20230709220904977.JPG", + expected: true, + info: NameInfo{ + Radical: "BURST20230709220904977", + Base: "DSC_0001_BURST20230709220904977.JPG", + IsCover: false, + Ext: ".jpg", + Type: metadata.TypeImage, + Kind: KindBurst, + Index: 1, + Taken: time.Date(2023, 7, 9, 22, 9, 4, int(977*time.Millisecond), time.Local), + }, + }, + { + name: "Sony Xperia BURST cover", + filename: "DSC_0052_BURST20230709220904977_COVER.JPG", + expected: true, + info: NameInfo{ + Radical: "BURST20230709220904977", + Base: "DSC_0052_BURST20230709220904977_COVER.JPG", + IsCover: true, + Ext: ".jpg", + Type: metadata.TypeImage, + Kind: KindBurst, + Index: 52, + Taken: time.Date(2023, 7, 9, 22, 9, 4, int(977*time.Millisecond), time.Local), + }, + }, + { + name: "InvalidFilename", + filename: "IMG_1123.jpg", + expected: false, + info: NameInfo{}, + }, + } + + ic := InfoCollector{ + TZ: time.Local, + SM: metadata.DefaultSupportedMedia, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got, info := ic.SonyXperia(tt.filename) + if got != tt.expected { + t.Errorf("expected %v, got %v", tt.expected, got) + } + if got && info != tt.info { + t.Errorf("expected \n%+v,\n got \n%+v", tt.info, info) + } + }) + } +}