Convert: Case-insensitive related file search

Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
Michael Mayer 2020-04-22 16:39:45 +02:00
parent 606e416e2a
commit f43154be93
3 changed files with 91 additions and 19 deletions

View file

@ -14,6 +14,7 @@ import (
"github.com/photoprism/photoprism/internal/event"
"github.com/photoprism/photoprism/internal/mutex"
"github.com/photoprism/photoprism/internal/thumb"
"github.com/photoprism/photoprism/pkg/fs"
)
// Convert represents a converter that can convert RAW/HEIF images to JPEG.
@ -123,9 +124,7 @@ func (c *Convert) ToJpeg(image *MediaFile) (*MediaFile, error) {
return image, nil
}
base := image.AbsBase(c.conf.Settings().Library.GroupRelated)
jpegName := base + ".jpg"
jpegName := fs.TypeJpeg.Find(image.FileName(), c.conf.Settings().Library.GroupRelated)
mediaFile, err := NewMediaFile(jpegName)
@ -133,6 +132,8 @@ func (c *Convert) ToJpeg(image *MediaFile) (*MediaFile, error) {
return mediaFile, nil
}
jpegName = image.AbsBase(c.conf.Settings().Library.GroupRelated) + ".jpg"
if c.conf.ReadOnly() {
return nil, fmt.Errorf("convert: disabled in read only mode (%s)", image.FileName())
}
@ -141,11 +142,7 @@ func (c *Convert) ToJpeg(image *MediaFile) (*MediaFile, error) {
log.Infof("convert: %s -> %s", fileName, jpegName)
xmpName := base + ".xmp"
if _, err := os.Stat(xmpName); err != nil {
xmpName = ""
}
xmpName := fs.TypeXMP.Find(image.FileName(), c.conf.Settings().Library.GroupRelated)
event.Publish("index.converting", event.Data{
"fileType": image.FileType(),

View file

@ -4,6 +4,7 @@ import (
_ "image/gif" // Import for image.
_ "image/jpeg"
_ "image/png"
"os"
"path/filepath"
"strings"
)
@ -29,11 +30,14 @@ const (
TypeJson FileType = "json" // JSON metadata / config / sidecar file.
TypeText FileType = "txt" // Text config / sidecar file.
TypeMarkdown FileType = "md" // Markdown text sidecar file.
TypeOther FileType = "unknown" // Unknown file format.
TypeOther FileType = "" // Unknown file format.
)
type FileExtensions map[string]FileType
type TypeExtensions map[FileType][]string
// FileExt contains the filename extensions of file formats known to PhotoPrism.
var FileExt = map[string]FileType{
var FileExt = FileExtensions{
".bmp": TypeBitmap,
".gif": TypeGif,
".tif": TypeTiff,
@ -48,9 +52,14 @@ var FileExt = map[string]FileType{
".avi": TypeAvi,
".mp4": TypeMP4,
".yml": TypeYaml,
".yaml": TypeYaml,
".jpg": TypeJpeg,
".thm": TypeJpeg,
".jpeg": TypeJpeg,
".jpe": TypeJpeg,
".jif": TypeJpeg,
".jfif": TypeJpeg,
".jfi": TypeJpeg,
".thm": TypeJpeg,
".xmp": TypeXMP,
".aae": TypeAAE,
".heif": TypeHEIF,
@ -97,6 +106,50 @@ var FileExt = map[string]FileType{
".json": TypeJson,
}
func (m FileExtensions) TypeExt() TypeExtensions {
result := make(TypeExtensions)
for ext, t := range m {
extUpper := strings.ToUpper(ext)
if _, ok := result[t]; ok {
result[t] = append(result[t], ext, extUpper)
} else {
result[t] = []string{ext, extUpper}
}
}
return result
}
var TypeExt = FileExt.TypeExt()
// Find returns the first filename with the same base name and a given type.
func (t FileType) Find(fileName string, stripSequence bool) string {
base := Base(fileName, stripSequence)
dir := filepath.Dir(fileName)
prefix := filepath.Join(dir, base)
prefixLower := filepath.Join(dir, strings.ToLower(base))
prefixUpper := filepath.Join(dir, strings.ToUpper(base))
for _, ext := range TypeExt[t] {
if info, err := os.Stat(prefix + ext); err == nil && info.Mode().IsRegular() {
return filepath.Join(dir, info.Name())
}
if info, err := os.Stat(prefixLower + ext); err == nil && info.Mode().IsRegular() {
return filepath.Join(dir, info.Name())
}
if info, err := os.Stat(prefixUpper + ext); err == nil && info.Mode().IsRegular() {
return filepath.Join(dir, info.Name())
}
}
return ""
}
// GetFileType returns the (expected) type for a given file name.
func GetFileType(fileName string) FileType {
fileExt := strings.ToLower(filepath.Ext(fileName))
result, ok := FileExt[fileExt]

View file

@ -22,3 +22,25 @@ func TestGetFileType(t *testing.T) {
assert.Equal(t, TypeOther, result)
})
}
func TestFileType_Find(t *testing.T) {
t.Run("find jpg", func(t *testing.T) {
result := TypeJpeg.Find("testdata/test.xmp", false)
assert.Equal(t, "testdata/test.jpg", result)
})
t.Run("upper ext", func(t *testing.T) {
result := TypeJpeg.Find("testdata/test.XMP", false)
assert.Equal(t, "testdata/test.jpg", result)
})
t.Run("with sequence", func(t *testing.T) {
result := TypeJpeg.Find("testdata/test (2).xmp", false)
assert.Equal(t, "", result)
})
t.Run("strip sequence", func(t *testing.T) {
result := TypeJpeg.Find("testdata/test (2).xmp", true)
assert.Equal(t, "testdata/test.jpg", result)
})
}