Index: Refactor mime type detection #391
Signed-off-by: Michael Mayer <michael@liquidbytes.net>
This commit is contained in:
parent
c704642f2e
commit
7d00e68d92
18 changed files with 169 additions and 99 deletions
|
@ -1,4 +1,4 @@
|
|||
FROM photoprism/development:20200715
|
||||
FROM photoprism/development:20200721
|
||||
|
||||
# Set up project directory
|
||||
WORKDIR "/go/src/github.com/photoprism/photoprism"
|
||||
|
|
BIN
assets/examples/earth.avi
Normal file
BIN
assets/examples/earth.avi
Normal file
Binary file not shown.
BIN
assets/examples/earth.mov
Normal file
BIN
assets/examples/earth.mov
Normal file
Binary file not shown.
|
@ -1,4 +1,4 @@
|
|||
FROM photoprism/development:20200715 as build
|
||||
FROM photoprism/development:20200721 as build
|
||||
|
||||
# Set up project directory
|
||||
WORKDIR "/go/src/github.com/photoprism/photoprism"
|
||||
|
|
|
@ -41,6 +41,7 @@ RUN apt-get update && apt-get upgrade && \
|
|||
make \
|
||||
wget \
|
||||
git \
|
||||
gettext \
|
||||
tzdata \
|
||||
gconf-service
|
||||
|
||||
|
|
2
go.mod
2
go.mod
|
@ -18,13 +18,13 @@ require (
|
|||
github.com/dsoprea/go-utility v0.0.0-20200717064901-2fccff4aa15e // indirect
|
||||
github.com/dustin/go-humanize v1.0.0
|
||||
github.com/gin-gonic/gin v1.6.3
|
||||
github.com/go-errors/errors v1.1.1 // indirect
|
||||
github.com/go-playground/validator/v10 v10.3.0 // indirect
|
||||
github.com/golang/geo v0.0.0-20200319012246-673a6f80352d
|
||||
github.com/golang/protobuf v1.4.2 // indirect
|
||||
github.com/google/open-location-code/go v0.0.0-20200603075809-e28188e71340
|
||||
github.com/gorilla/websocket v1.4.2
|
||||
github.com/gosimple/slug v1.9.0
|
||||
github.com/h2non/filetype v1.1.0
|
||||
github.com/jinzhu/gorm v1.9.14
|
||||
github.com/jinzhu/inflection v1.0.0
|
||||
github.com/json-iterator/go v1.1.10 // indirect
|
||||
|
|
14
go.sum
14
go.sum
|
@ -46,29 +46,17 @@ github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4 h1:bVaiYo8amn7L
|
|||
github.com/dsoprea/go-exif/v2 v2.0.0-20200321225314-640175a69fe4/go.mod h1:Lm2lMM2zx8p4a34ZemkaUV95AnMl4ZvLbCUbwOvLC2E=
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200520183328-015129a9efd5/go.mod h1:9EXlPeHfblFFnwu5UOqmP2eoZfJyAZ2Ri/Vki33ajO0=
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200604193436-ca8584a0e1c4/go.mod h1:9EXlPeHfblFFnwu5UOqmP2eoZfJyAZ2Ri/Vki33ajO0=
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200717063959-46b1a0cd1772 h1:M49UNOTa5sLju107lAoMsm93B/fHD02vWIoskmXMBm8=
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200717063959-46b1a0cd1772/go.mod h1:oKrjk2kb3rAR5NbtSTLUMvMSbc+k8ZosI3MaVH47noc=
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200717071058-9393e7afd446 h1:ruDG+2wFz+k/mDNy8x1UqWEItWNLXpvGlLv05+TlZt4=
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200717071058-9393e7afd446/go.mod h1:oKrjk2kb3rAR5NbtSTLUMvMSbc+k8ZosI3MaVH47noc=
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200721051611-3a80916d1fb8 h1:CDv1mPzK6J1vdCeXGoVdFKJqKKTTfnbsPIu9VcWkurM=
|
||||
github.com/dsoprea/go-exif/v2 v2.0.0-20200721051611-3a80916d1fb8/go.mod h1:oKrjk2kb3rAR5NbtSTLUMvMSbc+k8ZosI3MaVH47noc=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20200717053412-08f1b6708903/go.mod h1:0nsO1ce0mh5czxGeLo4+OCZ/C6Eo6ZlMWsz7rH/Gxv8=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20200717063959-46b1a0cd1772 h1:l/wfrK3wEH7sYpJe+Y8ZdFJW3AmsDgPoAQq2RLgKPSQ=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20200717063959-46b1a0cd1772/go.mod h1:0nsO1ce0mh5czxGeLo4+OCZ/C6Eo6ZlMWsz7rH/Gxv8=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20200717071058-9393e7afd446 h1:96yylb+JH415u6V7ykNtnEBLaZUwS1S31TnAezcvnNE=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20200717071058-9393e7afd446/go.mod h1:cg5SNYKHMmzxsr9X6ZeLh/nfBRHHp5PngtEPcujONtk=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20200721051611-3a80916d1fb8 h1:xMu5i9w1hAuS+0v7pw44wd4Y7eJoxfYiCkRQnEEvGd4=
|
||||
github.com/dsoprea/go-exif/v3 v3.0.0-20200721051611-3a80916d1fb8/go.mod h1:cg5SNYKHMmzxsr9X6ZeLh/nfBRHHp5PngtEPcujONtk=
|
||||
github.com/dsoprea/go-heic-exif-extractor v0.0.0-20200520190950-3ae4ff88a0d1 h1:8Tbo+OYgg7i2G3fltmpWq1if1e752aMX7Zv/sNWWJUk=
|
||||
github.com/dsoprea/go-heic-exif-extractor v0.0.0-20200520190950-3ae4ff88a0d1/go.mod h1:UwRKreeVikXn5OarSnt4OqovcEjsIgZVuc5svj7G5w4=
|
||||
github.com/dsoprea/go-heic-exif-extractor v0.0.0-20200717090456-b3d9dcddffd1 h1:R/EEzpxqQxeEcJ/z0EFTI1U6XsuOnepyp5o1uZg5c2E=
|
||||
github.com/dsoprea/go-heic-exif-extractor v0.0.0-20200717090456-b3d9dcddffd1/go.mod h1:UwRKreeVikXn5OarSnt4OqovcEjsIgZVuc5svj7G5w4=
|
||||
github.com/dsoprea/go-iptc v0.0.0-20200609062250-162ae6b44feb h1:gwjJjUr6FY7zAWVEueFPrcRHhd9+IK81TcItbqw2du4=
|
||||
github.com/dsoprea/go-iptc v0.0.0-20200609062250-162ae6b44feb/go.mod h1:kYIdx9N9NaOyD7U6D+YtExN7QhRm+5kq7//yOsRXQtM=
|
||||
github.com/dsoprea/go-iptc v0.0.0-20200610044640-bc9ca208b413 h1:YDRiMEm32T60Kpm35YzOK9ZHgjsS1Qrid+XskNcsdp8=
|
||||
github.com/dsoprea/go-iptc v0.0.0-20200610044640-bc9ca208b413/go.mod h1:kYIdx9N9NaOyD7U6D+YtExN7QhRm+5kq7//yOsRXQtM=
|
||||
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20200615034914-d40a386309d2 h1:8HmMqu64P4ZDGtcVwZDfmS4xuLXYjf2iery8teY7d9c=
|
||||
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20200615034914-d40a386309d2/go.mod h1:ZoOP3yUG0HD1T4IUjIFsz/2OAB2yB4YX6NSm4K+uJRg=
|
||||
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20200717085400-dd2ba56ee6b8 h1:cXCR9FOOkTEZ3t+asmy3lLv2AKYAah2igfx7WnNnVMc=
|
||||
github.com/dsoprea/go-jpeg-image-structure v0.0.0-20200717085400-dd2ba56ee6b8/go.mod h1:ZoOP3yUG0HD1T4IUjIFsz/2OAB2yB4YX6NSm4K+uJRg=
|
||||
github.com/dsoprea/go-logging v0.0.0-20190624164917-c4f10aab7696 h1:VGFnZAcLwPpt1sHlAxml+pGLZz9A2s+K/s1YNhPC91Y=
|
||||
|
@ -175,6 +163,8 @@ github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0U
|
|||
github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE=
|
||||
github.com/gosimple/slug v1.9.0 h1:r5vDcYrFz9BmfIAMC829un9hq7hKM4cHUrsv36LbEqs=
|
||||
github.com/gosimple/slug v1.9.0/go.mod h1:AMZ+sOVe65uByN3kgEyf9WEBKBCSS+dJjMX9x4vDJbg=
|
||||
github.com/h2non/filetype v1.1.0 h1:Or/gjocJrJRNK/Cri/TDEKFjAR+cfG6eK65NGYB6gBA=
|
||||
github.com/h2non/filetype v1.1.0/go.mod h1:319b3zT68BvV+WRj7cwy856M2ehB3HqNOt6sy1HndBY=
|
||||
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
|
||||
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
|
||||
|
|
|
@ -61,8 +61,6 @@ func NewTestParams() *Params {
|
|||
DetectNSFW: true,
|
||||
UploadNSFW: false,
|
||||
SidecarPath: fs.HiddenPath,
|
||||
DarktableBin: "/usr/bin/darktable-cli",
|
||||
ExifToolBin: "/usr/bin/exiftool",
|
||||
AssetsPath: assetsPath,
|
||||
StoragePath: testDataPath,
|
||||
CachePath: testDataPath + "/cache",
|
||||
|
|
|
@ -11,6 +11,10 @@ func TestMain(m *testing.M) {
|
|||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.DebugLevel)
|
||||
|
||||
if err := os.Remove(".test.db"); err == nil {
|
||||
log.Debugln("removed .test.db")
|
||||
}
|
||||
|
||||
db := InitTestDb(os.Getenv("PHOTOPRISM_TEST_DRIVER"), os.Getenv("PHOTOPRISM_TEST_DSN"))
|
||||
defer db.Close()
|
||||
|
||||
|
|
|
@ -1,19 +1,21 @@
|
|||
package photoprism
|
||||
|
||||
import (
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestFileName(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
t.Run("sidecar", func(t *testing.T) {
|
||||
assert.Equal(t, ".photoprism/test.jpg", FileName("sidecar", "test.jpg"))
|
||||
})
|
||||
t.Run("import", func(t *testing.T) {
|
||||
assert.Equal(t, "/go/src/github.com/photoprism/photoprism/storage/testdata/import/test.jpg", FileName("import", "test.jpg"))
|
||||
assert.Equal(t, conf.ImportPath()+"/test.jpg", FileName("import", "test.jpg"))
|
||||
})
|
||||
t.Run("examples", func(t *testing.T) {
|
||||
assert.Equal(t, "/go/src/github.com/photoprism/photoprism/assets/examples/test.jpg", FileName("examples", "test.jpg"))
|
||||
assert.Equal(t, conf.ExamplesPath()+"/test.jpg", FileName("examples", "test.jpg"))
|
||||
})
|
||||
|
||||
}
|
||||
|
|
|
@ -294,32 +294,44 @@ func (m *MediaFile) RelatedFiles(stripSequence bool) (result RelatedFiles, err e
|
|||
matches = append(matches, name)
|
||||
}
|
||||
|
||||
for _, filename := range matches {
|
||||
resultFile, err := NewMediaFile(filename)
|
||||
for _, fileName := range matches {
|
||||
f, err := NewMediaFile(fileName)
|
||||
|
||||
if err != nil {
|
||||
log.Warnf("mediafile: %s in %s", err, txt.Quote(filepath.Base(fileName)))
|
||||
continue
|
||||
}
|
||||
|
||||
if result.Main == nil && resultFile.IsJpeg() {
|
||||
result.Main = resultFile
|
||||
} else if resultFile.IsRaw() {
|
||||
result.Main = resultFile
|
||||
} else if resultFile.IsHEIF() {
|
||||
result.Main = resultFile
|
||||
} else if resultFile.IsJpeg() && len(result.Main.FileName()) > len(resultFile.FileName()) {
|
||||
result.Main = resultFile
|
||||
} else if resultFile.IsImageOther() {
|
||||
result.Main = resultFile
|
||||
} else if resultFile.IsVideo() {
|
||||
result.Main = resultFile
|
||||
if f.FileSize() == 0 {
|
||||
log.Warnf("mediafile: %s is empty", txt.Quote(filepath.Base(fileName)))
|
||||
continue
|
||||
}
|
||||
|
||||
result.Files = append(result.Files, resultFile)
|
||||
if result.Main == nil && f.IsJpeg() {
|
||||
result.Main = f
|
||||
} else if f.IsRaw() {
|
||||
result.Main = f
|
||||
} else if f.IsHEIF() {
|
||||
result.Main = f
|
||||
} else if f.IsJpeg() && len(result.Main.FileName()) > len(f.FileName()) {
|
||||
result.Main = f
|
||||
} else if f.IsImageOther() {
|
||||
result.Main = f
|
||||
} else if f.IsVideo() {
|
||||
result.Main = f
|
||||
}
|
||||
|
||||
result.Files = append(result.Files, f)
|
||||
}
|
||||
|
||||
if result.Main == nil {
|
||||
return result, fmt.Errorf("no main file found for %s", txt.Quote(m.BaseName()))
|
||||
if len(result.Files) == 0 || result.Main == nil {
|
||||
t := m.MimeType()
|
||||
|
||||
if t == "" {
|
||||
t = "unknown type"
|
||||
}
|
||||
|
||||
return result, fmt.Errorf("no supported files found for %s (%s)", txt.Quote(m.BaseName()), t)
|
||||
}
|
||||
|
||||
// Add hidden JPEG if exists.
|
||||
|
@ -622,11 +634,26 @@ func (m *MediaFile) IsGif() bool {
|
|||
return m.MimeType() == fs.MimeTypeGif
|
||||
}
|
||||
|
||||
// IsTiff returns true if this is a TIFF file.
|
||||
func (m *MediaFile) IsTiff() bool {
|
||||
return m.HasFileType(fs.TypeTiff) && m.MimeType() == fs.MimeTypeTiff
|
||||
}
|
||||
|
||||
// IsHEIF returns true if this is a High Efficiency Image File Format file.
|
||||
func (m *MediaFile) IsHEIF() bool {
|
||||
return m.MimeType() == fs.MimeTypeHEIF
|
||||
}
|
||||
|
||||
// IsBitmap returns true if this is a bitmap file.
|
||||
func (m *MediaFile) IsBitmap() bool {
|
||||
return m.MimeType() == fs.MimeTypeBitmap
|
||||
}
|
||||
|
||||
// IsVideo returns true if this is a video file.
|
||||
func (m *MediaFile) IsVideo() bool {
|
||||
return strings.HasPrefix(m.MimeType(), "video/")
|
||||
}
|
||||
|
||||
// IsJson return true if this media file is a json sidecar file.
|
||||
func (m *MediaFile) IsJson() bool {
|
||||
return m.HasFileType(fs.TypeJson)
|
||||
|
@ -641,6 +668,8 @@ func (m *MediaFile) FileType() fs.FileType {
|
|||
return fs.TypePng
|
||||
case m.IsGif():
|
||||
return fs.TypeGif
|
||||
case m.IsHEIF():
|
||||
return fs.TypeHEIF
|
||||
case m.IsBitmap():
|
||||
return fs.TypeBitmap
|
||||
default:
|
||||
|
@ -667,11 +696,6 @@ func (m *MediaFile) IsRaw() bool {
|
|||
return m.HasFileType(fs.TypeRaw)
|
||||
}
|
||||
|
||||
// IsTiff returns true if this is a TIFF file.
|
||||
func (m *MediaFile) IsTiff() bool {
|
||||
return m.HasFileType(fs.TypeTiff)
|
||||
}
|
||||
|
||||
// IsImageOther returns true if this is a PNG, GIF, BMP or TIFF file.
|
||||
func (m *MediaFile) IsImageOther() bool {
|
||||
switch {
|
||||
|
@ -682,11 +706,6 @@ func (m *MediaFile) IsImageOther() bool {
|
|||
}
|
||||
}
|
||||
|
||||
// IsHEIF returns true if this is a High Efficiency Image File Format file.
|
||||
func (m *MediaFile) IsHEIF() bool {
|
||||
return m.HasFileType(fs.TypeHEIF)
|
||||
}
|
||||
|
||||
// IsXMP returns true if this is a XMP sidecar file.
|
||||
func (m *MediaFile) IsXMP() bool {
|
||||
return m.FileType() == fs.TypeXMP
|
||||
|
@ -697,14 +716,9 @@ func (m *MediaFile) IsSidecar() bool {
|
|||
return m.MediaType() == fs.MediaSidecar
|
||||
}
|
||||
|
||||
// IsVideo returns true if this is a video file.
|
||||
func (m *MediaFile) IsVideo() bool {
|
||||
return m.MediaType() == fs.MediaVideo
|
||||
}
|
||||
|
||||
// IsPlayableVideo returns true if this is a supported video file format.
|
||||
func (m *MediaFile) IsPlayableVideo() bool {
|
||||
return m.MediaType() == fs.MediaVideo && m.HasFileType(fs.TypeMP4)
|
||||
return m.IsVideo() && m.HasFileType(fs.TypeMP4)
|
||||
}
|
||||
|
||||
// IsPhoto returns true if this file is a photo / image.
|
||||
|
|
|
@ -3,6 +3,7 @@ package photoprism
|
|||
import (
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
|
@ -522,6 +523,8 @@ func TestMediaFile_RelatedFiles(t *testing.T) {
|
|||
t.Fatalf("length is %d, should be 4", len(related.Files))
|
||||
}
|
||||
|
||||
t.Logf("FILE: %s, %s", related.Main.FileType(), related.Main.MimeType())
|
||||
|
||||
assert.Equal(t, "2015-02-04.jpg", related.Main.BaseName())
|
||||
|
||||
assert.Equal(t, "2015-02-04.jpg", related.Files[0].BaseName())
|
||||
|
@ -650,12 +653,12 @@ func TestMediaFile_RelName(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("directory with end slash", func(t *testing.T) {
|
||||
filename := mediaFile.RelName("/go/src/github.com/photoprism/photoprism/assets/")
|
||||
filename := mediaFile.RelName(conf.AssetsPath())
|
||||
assert.Equal(t, "examples/tree_white.jpg", filename)
|
||||
})
|
||||
|
||||
t.Run("directory without end slash", func(t *testing.T) {
|
||||
filename := mediaFile.RelName("/go/src/github.com/photoprism/photoprism/assets")
|
||||
filename := mediaFile.RelName(conf.AssetsPath())
|
||||
assert.Equal(t, "examples/tree_white.jpg", filename)
|
||||
})
|
||||
t.Run("directory not part of filename", func(t *testing.T) {
|
||||
|
@ -663,7 +666,7 @@ func TestMediaFile_RelName(t *testing.T) {
|
|||
assert.Equal(t, conf.ExamplesPath()+"/tree_white.jpg", filename)
|
||||
})
|
||||
t.Run("directory equals example path", func(t *testing.T) {
|
||||
filename := mediaFile.RelName("/go/src/github.com/photoprism/photoprism/assets/examples")
|
||||
filename := mediaFile.RelName(conf.ExamplesPath())
|
||||
assert.Equal(t, "tree_white.jpg", filename)
|
||||
})
|
||||
}
|
||||
|
@ -679,11 +682,11 @@ func TestMediaFile_RelativePath(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("directory with end slash", func(t *testing.T) {
|
||||
path := mediaFile.RelPath("/go/src/github.com/photoprism/photoprism/assets/")
|
||||
path := mediaFile.RelPath(conf.AssetsPath() + "/")
|
||||
assert.Equal(t, "examples", path)
|
||||
})
|
||||
t.Run("directory without end slash", func(t *testing.T) {
|
||||
path := mediaFile.RelPath("/go/src/github.com/photoprism/photoprism/assets")
|
||||
path := mediaFile.RelPath(conf.AssetsPath())
|
||||
assert.Equal(t, "examples", path)
|
||||
})
|
||||
t.Run("directory equals filepath", func(t *testing.T) {
|
||||
|
@ -692,7 +695,7 @@ func TestMediaFile_RelativePath(t *testing.T) {
|
|||
})
|
||||
t.Run("directory does not match filepath", func(t *testing.T) {
|
||||
path := mediaFile.RelPath("xxx")
|
||||
assert.Equal(t, "/go/src/github.com/photoprism/photoprism/assets/examples", path)
|
||||
assert.Equal(t, conf.ExamplesPath(), path)
|
||||
})
|
||||
|
||||
mediaFile, err = NewMediaFile(conf.ExamplesPath() + "/.photoprism/example.jpg")
|
||||
|
@ -724,15 +727,15 @@ func TestMediaFile_RelativeBasename(t *testing.T) {
|
|||
}
|
||||
|
||||
t.Run("directory with end slash", func(t *testing.T) {
|
||||
basename := mediaFile.RelPrefix("/go/src/github.com/photoprism/photoprism/assets/", true)
|
||||
basename := mediaFile.RelPrefix(conf.AssetsPath()+"/", true)
|
||||
assert.Equal(t, "examples/tree_white", basename)
|
||||
})
|
||||
t.Run("directory without end slash", func(t *testing.T) {
|
||||
basename := mediaFile.RelPrefix("/go/src/github.com/photoprism/photoprism/assets", true)
|
||||
basename := mediaFile.RelPrefix(conf.AssetsPath(), true)
|
||||
assert.Equal(t, "examples/tree_white", basename)
|
||||
})
|
||||
t.Run("directory equals example path", func(t *testing.T) {
|
||||
basename := mediaFile.RelPrefix("/go/src/github.com/photoprism/photoprism/assets/examples/", true)
|
||||
basename := mediaFile.RelPrefix(conf.ExamplesPath(), true)
|
||||
assert.Equal(t, "tree_white", basename)
|
||||
})
|
||||
|
||||
|
@ -796,7 +799,7 @@ func TestMediaFile_MimeType(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, "application/octet-stream", mediaFile.MimeType())
|
||||
assert.Equal(t, "image/tiff", mediaFile.MimeType())
|
||||
|
||||
})
|
||||
|
||||
|
@ -805,7 +808,7 @@ func TestMediaFile_MimeType(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, "text/plain; charset=utf-8", mediaFile.MimeType())
|
||||
assert.Equal(t, "", mediaFile.MimeType())
|
||||
})
|
||||
|
||||
t.Run("iphone_7.json", func(t *testing.T) {
|
||||
|
@ -813,7 +816,7 @@ func TestMediaFile_MimeType(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, "text/plain; charset=utf-8", mediaFile.MimeType())
|
||||
assert.Equal(t, "", mediaFile.MimeType())
|
||||
})
|
||||
|
||||
t.Run("iphone_7.heic", func(t *testing.T) {
|
||||
|
@ -821,7 +824,7 @@ func TestMediaFile_MimeType(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, "application/octet-stream", mediaFile.MimeType())
|
||||
assert.Equal(t, "image/heif", mediaFile.MimeType())
|
||||
})
|
||||
|
||||
t.Run("IMG_4120.AAE", func(t *testing.T) {
|
||||
|
@ -829,7 +832,31 @@ func TestMediaFile_MimeType(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, "text/xml; charset=utf-8", mediaFile.MimeType())
|
||||
assert.Equal(t, "", mediaFile.MimeType())
|
||||
})
|
||||
|
||||
t.Run("earth.mov", func(t *testing.T) {
|
||||
if f, err := NewMediaFile(filepath.Join(conf.ExamplesPath(), "earth.mov")); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
assert.Equal(t, "video/quicktime", f.MimeType())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("blue-go-video.mp4", func(t *testing.T) {
|
||||
if f, err := NewMediaFile(filepath.Join(conf.ExamplesPath(), "blue-go-video.mp4")); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
assert.Equal(t, "video/mp4", f.MimeType())
|
||||
}
|
||||
})
|
||||
|
||||
t.Run("earth.avi", func(t *testing.T) {
|
||||
if f, err := NewMediaFile(filepath.Join(conf.ExamplesPath(), "earth.avi")); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
assert.Equal(t, "video/x-msvideo", f.MimeType())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1087,6 +1114,7 @@ func TestMediaFile_IsRaw(t *testing.T) {
|
|||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.Equal(t, true, mediaFile.IsRaw())
|
||||
})
|
||||
t.Run("/elephants.jpg", func(t *testing.T) {
|
||||
|
@ -1134,7 +1162,7 @@ func TestMediaFile_IsTiff(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, fs.TypeJson, mediaFile.FileType())
|
||||
assert.Equal(t, "text/plain; charset=utf-8", mediaFile.MimeType())
|
||||
assert.Equal(t, "", mediaFile.MimeType())
|
||||
assert.Equal(t, false, mediaFile.IsTiff())
|
||||
})
|
||||
t.Run("/purple.tiff", func(t *testing.T) {
|
||||
|
@ -1145,7 +1173,7 @@ func TestMediaFile_IsTiff(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, fs.TypeTiff, mediaFile.FileType())
|
||||
assert.Equal(t, "application/octet-stream", mediaFile.MimeType())
|
||||
assert.Equal(t, "image/tiff", mediaFile.MimeType())
|
||||
assert.Equal(t, true, mediaFile.IsTiff())
|
||||
})
|
||||
t.Run("/example.tiff", func(t *testing.T) {
|
||||
|
@ -1156,7 +1184,7 @@ func TestMediaFile_IsTiff(t *testing.T) {
|
|||
t.Fatal(err)
|
||||
}
|
||||
assert.Equal(t, fs.TypeTiff, mediaFile.FileType())
|
||||
assert.Equal(t, "application/octet-stream", mediaFile.MimeType())
|
||||
assert.Equal(t, "image/tiff", mediaFile.MimeType())
|
||||
assert.Equal(t, true, mediaFile.IsTiff())
|
||||
})
|
||||
}
|
||||
|
@ -1285,7 +1313,7 @@ func TestMediaFile_IsSidecar(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMediaFile_IsPhoto(t *testing.T) {
|
||||
t.Run("/iphone_7.json", func(t *testing.T) {
|
||||
t.Run("iphone_7.json", func(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
mediaFile, err := NewMediaFile(conf.ExamplesPath() + "/iphone_7.json")
|
||||
|
@ -1294,14 +1322,14 @@ func TestMediaFile_IsPhoto(t *testing.T) {
|
|||
}
|
||||
assert.Equal(t, false, mediaFile.IsPhoto())
|
||||
})
|
||||
t.Run("/iphone_7.xmp", func(t *testing.T) {
|
||||
t.Run("iphone_7.xmp", func(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
mediaFile, err := NewMediaFile(conf.ExamplesPath() + "/iphone_7.xmp")
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, false, mediaFile.IsPhoto())
|
||||
})
|
||||
t.Run("/iphone_7.heic", func(t *testing.T) {
|
||||
t.Run("iphone_7.heic", func(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
mediaFile, err := NewMediaFile(conf.ExamplesPath() + "/iphone_7.heic")
|
||||
|
@ -1310,7 +1338,7 @@ func TestMediaFile_IsPhoto(t *testing.T) {
|
|||
}
|
||||
assert.Equal(t, true, mediaFile.IsPhoto())
|
||||
})
|
||||
t.Run("/canon_eos_6d.dng", func(t *testing.T) {
|
||||
t.Run("canon_eos_6d.dng", func(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
mediaFile, err := NewMediaFile(conf.ExamplesPath() + "/canon_eos_6d.dng")
|
||||
|
@ -1319,7 +1347,7 @@ func TestMediaFile_IsPhoto(t *testing.T) {
|
|||
}
|
||||
assert.Equal(t, true, mediaFile.IsPhoto())
|
||||
})
|
||||
t.Run("/elephants.jpg", func(t *testing.T) {
|
||||
t.Run("elephants.jpg", func(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
mediaFile, err := NewMediaFile(conf.ExamplesPath() + "/elephants.jpg")
|
||||
|
@ -1329,25 +1357,37 @@ func TestMediaFile_IsPhoto(t *testing.T) {
|
|||
}
|
||||
|
||||
func TestMediaFile_IsVideo(t *testing.T) {
|
||||
t.Run("/christmas.mp4", func(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
conf := config.TestConfig()
|
||||
|
||||
mediaFile, err := NewMediaFile(conf.ExamplesPath() + "/christmas.mp4")
|
||||
if err != nil {
|
||||
t.Run("christmas.mp4", func(t *testing.T) {
|
||||
if f, err := NewMediaFile(filepath.Join(conf.ExamplesPath(), "christmas.mp4")); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
assert.Equal(t, false, f.IsPhoto())
|
||||
assert.Equal(t, true, f.IsVideo())
|
||||
assert.Equal(t, false, f.IsJson())
|
||||
assert.Equal(t, false, f.IsSidecar())
|
||||
}
|
||||
assert.Equal(t, false, mediaFile.IsPhoto())
|
||||
})
|
||||
t.Run("/canon_eos_6d.dng", func(t *testing.T) {
|
||||
conf := config.TestConfig()
|
||||
|
||||
mediaFile, err := NewMediaFile(conf.ExamplesPath() + "/canon_eos_6d.dng")
|
||||
|
||||
if err != nil {
|
||||
t.Run("canon_eos_6d.dng", func(t *testing.T) {
|
||||
if f, err := NewMediaFile(filepath.Join(conf.ExamplesPath(), "canon_eos_6d.dng")); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
assert.Equal(t, true, f.IsPhoto())
|
||||
assert.Equal(t, false, f.IsVideo())
|
||||
assert.Equal(t, false, f.IsJson())
|
||||
assert.Equal(t, false, f.IsSidecar())
|
||||
}
|
||||
})
|
||||
t.Run("iphone_7.json", func(t *testing.T) {
|
||||
if f, err := NewMediaFile(filepath.Join(conf.ExamplesPath(), "iphone_7.json")); err != nil {
|
||||
t.Fatal(err)
|
||||
} else {
|
||||
assert.Equal(t, false, f.IsPhoto())
|
||||
assert.Equal(t, false, f.IsVideo())
|
||||
assert.Equal(t, true, f.IsJson())
|
||||
assert.Equal(t, true, f.IsSidecar())
|
||||
}
|
||||
|
||||
assert.Equal(t, true, mediaFile.IsPhoto())
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1844,7 +1884,7 @@ func TestMediaFile_JsonName(t *testing.T) {
|
|||
}
|
||||
|
||||
name := mediaFile.JsonName()
|
||||
assert.Equal(t, "/go/src/github.com/photoprism/photoprism/assets/examples/blue-go-video.mp4.json", name)
|
||||
assert.True(t, strings.HasSuffix(name, "/assets/examples/blue-go-video.mp4.json"))
|
||||
})
|
||||
}
|
||||
|
||||
|
@ -1941,7 +1981,7 @@ func TestMediaFile_SubDirectory(t *testing.T) {
|
|||
}
|
||||
|
||||
subdir := mediaFile.SubDir("xxx")
|
||||
assert.Equal(t, "/go/src/github.com/photoprism/photoprism/assets/examples/xxx", subdir)
|
||||
assert.True(t, strings.HasSuffix(subdir, "/assets/examples/xxx"))
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
@ -12,6 +12,10 @@ func TestMain(m *testing.M) {
|
|||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.DebugLevel)
|
||||
|
||||
if err := os.Remove(".test.db"); err == nil {
|
||||
log.Debugln("removed .test.db")
|
||||
}
|
||||
|
||||
c := config.TestConfig()
|
||||
SetConfig(c)
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package photoprism
|
|||
|
||||
import (
|
||||
"os"
|
||||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
|
@ -60,11 +61,16 @@ func TestThumb_Filename(t *testing.T) {
|
|||
|
||||
t.Run("", func(t *testing.T) {
|
||||
filename, err := thumb.Filename("99988", thumbsPath, 150, 150, thumb.ResampleFit, thumb.ResampleNearestNeighbor)
|
||||
assert.Nil(t, err)
|
||||
assert.Equal(t, "/go/src/github.com/photoprism/photoprism/storage/testdata/cache/_tmp/9/9/9/99988_150x150_fit.jpg", filename)
|
||||
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
assert.True(t, strings.HasSuffix(filename, "/storage/testdata/cache/_tmp/9/9/9/99988_150x150_fit.jpg"))
|
||||
})
|
||||
t.Run("hash too short", func(t *testing.T) {
|
||||
_, err := thumb.Filename("999", thumbsPath, 150, 150, thumb.ResampleFit, thumb.ResampleNearestNeighbor)
|
||||
|
||||
if err == nil {
|
||||
t.FailNow()
|
||||
}
|
||||
|
|
0
internal/photoprism/testdata/2018-04-12 19:24:49.mov
vendored
Normal file
0
internal/photoprism/testdata/2018-04-12 19:24:49.mov
vendored
Normal file
|
@ -13,6 +13,10 @@ func TestMain(m *testing.M) {
|
|||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.DebugLevel)
|
||||
|
||||
if err := os.Remove(".test.db"); err == nil {
|
||||
log.Debugln("removed .test.db")
|
||||
}
|
||||
|
||||
db := entity.InitTestDb(os.Getenv("PHOTOPRISM_TEST_DRIVER"), os.Getenv("PHOTOPRISM_TEST_DSN"))
|
||||
defer db.Close()
|
||||
|
||||
|
|
|
@ -12,6 +12,10 @@ func TestMain(m *testing.M) {
|
|||
log = logrus.StandardLogger()
|
||||
log.SetLevel(logrus.DebugLevel)
|
||||
|
||||
if err := os.Remove(".test.db"); err == nil {
|
||||
log.Debugln("removed .test.db")
|
||||
}
|
||||
|
||||
c := config.TestConfig()
|
||||
|
||||
code := m.Run()
|
||||
|
|
|
@ -1,8 +1,9 @@
|
|||
package fs
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"os"
|
||||
|
||||
"github.com/h2non/filetype"
|
||||
)
|
||||
|
||||
const (
|
||||
|
@ -10,6 +11,8 @@ const (
|
|||
MimeTypePng = "image/png"
|
||||
MimeTypeGif = "image/gif"
|
||||
MimeTypeBitmap = "image/bmp"
|
||||
MimeTypeTiff = "image/tiff"
|
||||
MimeTypeHEIF = "image/heif"
|
||||
)
|
||||
|
||||
// MimeType returns the mime type of a file, empty string if unknown.
|
||||
|
@ -22,14 +25,14 @@ func MimeType(filename string) string {
|
|||
|
||||
defer handle.Close()
|
||||
|
||||
// Only the first 512 bytes are used to sniff the content type.
|
||||
buffer := make([]byte, 512)
|
||||
// Only the first 261 bytes are used to sniff the content type.
|
||||
buffer := make([]byte, 261)
|
||||
|
||||
_, err = handle.Read(buffer)
|
||||
|
||||
if err != nil {
|
||||
if _, err := handle.Read(buffer); err != nil {
|
||||
return ""
|
||||
} else if t, err := filetype.Get(buffer); err != nil {
|
||||
return ""
|
||||
} else {
|
||||
return t.MIME.Value
|
||||
}
|
||||
|
||||
return http.DetectContentType(buffer)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue