Convert: Case-insensitive related file search
Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
parent
606e416e2a
commit
f43154be93
3 changed files with 91 additions and 19 deletions
|
@ -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(),
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
_ "image/gif" // Import for image.
|
||||
_ "image/jpeg"
|
||||
_ "image/png"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
@ -21,19 +22,22 @@ const (
|
|||
TypeMov FileType = "mov" // Video files.
|
||||
TypeMP4 FileType = "mp4"
|
||||
TypeAvi FileType = "avi"
|
||||
TypeXMP FileType = "xmp" // Adobe XMP sidecar file (XML).
|
||||
TypeAAE FileType = "aae" // Apple sidecar file (XML).
|
||||
TypeXML FileType = "xml" // XML metadata / config / sidecar file.
|
||||
TypeYaml FileType = "yml" // YAML metadata / config / sidecar file.
|
||||
TypeToml FileType = "toml" // Tom's Obvious, Minimal Language sidecar file.
|
||||
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.
|
||||
TypeXMP FileType = "xmp" // Adobe XMP sidecar file (XML).
|
||||
TypeAAE FileType = "aae" // Apple sidecar file (XML).
|
||||
TypeXML FileType = "xml" // XML metadata / config / sidecar file.
|
||||
TypeYaml FileType = "yml" // YAML metadata / config / sidecar file.
|
||||
TypeToml FileType = "toml" // Tom's Obvious, Minimal Language sidecar file.
|
||||
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 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]
|
||||
|
|
|
@ -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)
|
||||
})
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue