mirror of
https://github.com/photoprism/photoprism.git
synced 2026-07-17 16:49:04 +00:00
Videos: Refactor codec, content and file type specifications #4770
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
parent
30a6ff248b
commit
6a89519e63
254 changed files with 1193 additions and 1032 deletions
2
Makefile
2
Makefile
|
|
@ -780,7 +780,7 @@ fmt-js:
|
|||
fmt-go:
|
||||
go fmt ./pkg/... ./internal/... ./cmd/...
|
||||
gofmt -w -s pkg internal cmd
|
||||
goimports -w pkg internal cmd
|
||||
goimports -w -local "github.com/photoprism" pkg internal cmd
|
||||
tidy:
|
||||
go mod tidy
|
||||
users:
|
||||
|
|
|
|||
|
|
@ -11,9 +11,10 @@ import (
|
|||
"text/template"
|
||||
"unicode"
|
||||
|
||||
"gopkg.in/yaml.v2"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"gopkg.in/yaml.v2"
|
||||
)
|
||||
|
||||
// LabelRule defines the rule for a given Label
|
||||
|
|
|
|||
|
|
@ -13,9 +13,9 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
tf "github.com/tensorflow/tensorflow/tensorflow/go"
|
||||
|
||||
"github.com/disintegration/imaging"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,7 @@ import (
|
|||
"sort"
|
||||
|
||||
pigo "github.com/esimov/pigo/core"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -6,9 +6,9 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/dustin/go-humanize/english"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/fs/fastwalk"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestDetect(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ import (
|
|||
"path/filepath"
|
||||
"sync"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
tf "github.com/tensorflow/tensorflow/tensorflow/go"
|
||||
"github.com/tensorflow/tensorflow/tensorflow/go/op"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
// Detector uses TensorFlow to label drawing, hentai, neutral, porn and sexy images.
|
||||
|
|
@ -29,7 +30,7 @@ func New(modelPath string) *Detector {
|
|||
|
||||
// File returns matching labels for a jpeg media file.
|
||||
func (t *Detector) File(filename string) (result Labels, err error) {
|
||||
if fs.MimeType(filename) != fs.MimeTypeJPEG {
|
||||
if fs.MimeType(filename) != fs.MimeTypeJpeg {
|
||||
return result, fmt.Errorf("nsfw: %s is not a jpeg file", clean.Log(filepath.Base(filename)))
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
//go:embed embed/video.mp4
|
||||
|
|
@ -128,6 +128,6 @@ func AbortVideo(c *gin.Context) {
|
|||
|
||||
func AbortVideoWithStatus(c *gin.Context, code int) {
|
||||
if c != nil {
|
||||
c.Data(code, header.ContentTypeAVC32, brokenVideo)
|
||||
c.Data(code, header.ContentTypeMp4Avc720, brokenVideo)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
// Auth checks if the user is authorized to access a resource with the given permission
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
"github.com/photoprism/photoprism/internal/auth/acl"
|
||||
"github.com/photoprism/photoprism/internal/auth/session"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
func TestAuth(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@ package api
|
|||
import (
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
// ClientIP returns the client IP address from the request context or a placeholder if it is unknown.
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/photoprism/get"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
// AddCountHeader adds the actual result count to the response.
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/internal/photoprism/get"
|
||||
"github.com/photoprism/photoprism/internal/server/limiter"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
type CloseableResponseRecorder struct {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/photoprism/get"
|
||||
"github.com/photoprism/photoprism/internal/thumb"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ func RemoveFromAlbumCoverCache(uid string) {
|
|||
}
|
||||
|
||||
// Delete share preview, if exists.
|
||||
if sharePreview := path.Join(get.Config().ThumbCachePath(), "share", uid+fs.ExtJPEG); fs.FileExists(sharePreview) {
|
||||
if sharePreview := path.Join(get.Config().ThumbCachePath(), "share", uid+fs.ExtJpeg); fs.FileExists(sharePreview) {
|
||||
_ = os.Remove(sharePreview)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -7,7 +7,7 @@ import (
|
|||
"github.com/gin-gonic/gin"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
func TestAddVideoCacheHeader(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import (
|
|||
swagger "github.com/swaggo/gin-swagger"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/photoprism/get"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
//go:embed swagger.json
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/photoprism/get"
|
||||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
// OAuthAuthorize should gather consent and authorization from resource owners when using the
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -16,7 +16,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/server/limiter"
|
||||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
// OAuthToken creates a new access token for clients that authenticate with valid OAuth2 client credentials.
|
||||
|
|
|
|||
|
|
@ -11,7 +11,7 @@ import (
|
|||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
func TestOAuthToken(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/photoprism/get"
|
||||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
// OAuthUserinfo should return information about the authenticated user,
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/server/limiter"
|
||||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
// OIDCLogin redirects a browser to the login page of the configured OpenID Connect provider, if any.
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/time/unix"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ import (
|
|||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
)
|
||||
|
||||
func TestOIDCRedirect(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -206,7 +206,7 @@ func GetPhotoYaml(router *gin.RouterGroup) {
|
|||
}
|
||||
|
||||
if c.Query("download") != "" {
|
||||
AddDownloadHeader(c, clean.UID(c.Param("uid"))+fs.ExtYAML)
|
||||
AddDownloadHeader(c, clean.UID(c.Param("uid"))+fs.ExtYaml)
|
||||
}
|
||||
|
||||
c.Data(http.StatusOK, "text/x-yaml; charset=utf-8", data)
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/internal/photoprism/get"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import (
|
|||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/tidwall/gjson"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
)
|
||||
|
||||
func TestUploadToService(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/server/limiter"
|
||||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
// CreateSession creates a new client session and returns it as JSON if authentication was successful.
|
||||
|
|
|
|||
|
|
@ -3,6 +3,8 @@ package api
|
|||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/auth/acl"
|
||||
|
|
@ -13,7 +15,6 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/auth/acl"
|
||||
"github.com/photoprism/photoprism/internal/photoprism/get"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -49,7 +49,7 @@ func SharePreview(router *gin.RouterGroup) {
|
|||
return
|
||||
}
|
||||
|
||||
previewFilename := filepath.Join(thumbPath, shared+fs.ExtJPEG)
|
||||
previewFilename := filepath.Join(thumbPath, shared+fs.ExtJpeg)
|
||||
|
||||
expires := entity.Now().Add(-1 * time.Hour)
|
||||
|
||||
|
|
|
|||
|
|
@ -148,7 +148,7 @@ func GetThumb(router *gin.RouterGroup) {
|
|||
}
|
||||
|
||||
// Find supported preview image if media file is not a JPEG or PNG.
|
||||
if f.NoJPEG() && f.NoPNG() {
|
||||
if f.NoJpeg() && f.NoPng() {
|
||||
if f, err = query.FileByPhotoUID(f.PhotoUID); err != nil {
|
||||
c.Data(http.StatusOK, "image/svg+xml", fileIconSvg)
|
||||
return
|
||||
|
|
|
|||
|
|
@ -99,9 +99,9 @@ func UploadUserAvatar(router *gin.RouterGroup) {
|
|||
return
|
||||
} else {
|
||||
switch {
|
||||
case mimeType.Is(fs.MimeTypePNG):
|
||||
case mimeType.Is(fs.MimeTypePng):
|
||||
fileName = "avatar.png"
|
||||
case mimeType.Is(fs.MimeTypeJPEG):
|
||||
case mimeType.Is(fs.MimeTypeJpeg):
|
||||
fileName = "avatar.jpg"
|
||||
default:
|
||||
event.AuditWarn([]string{ClientIP(c), "session %s", "upload avatar", " %s not supported"}, s.RefID, mimeType)
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ import (
|
|||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
)
|
||||
|
||||
func TestFindUserSessions(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -6,10 +6,11 @@ import (
|
|||
"net/http"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestUpdateUser(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -13,8 +13,8 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/photoprism/get"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/video"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
|
|
@ -153,7 +153,7 @@ func GetVideo(router *gin.RouterGroup) {
|
|||
|
||||
if avcFile, avcErr := conv.ToAvc(mediaFile, get.Config().FFmpegEncoder(), false, false); avcFile != nil && avcErr == nil {
|
||||
videoFileName = avcFile.FileName()
|
||||
AddContentTypeHeader(c, header.ContentTypeAVC)
|
||||
AddContentTypeHeader(c, header.ContentTypeMp4Avc)
|
||||
} else {
|
||||
// Log error and default to 404.mp4
|
||||
log.Errorf("video: failed to transcode %s", clean.Log(f.FileName))
|
||||
|
|
|
|||
|
|
@ -9,15 +9,15 @@ import (
|
|||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/video"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
)
|
||||
|
||||
func TestGetVideo(t *testing.T) {
|
||||
t.Run("ContentTypeAVC", func(t *testing.T) {
|
||||
assert.Equal(t, header.ContentTypeAVC, clean.ContentType("video/mp4; codecs=\"avc1\""))
|
||||
assert.Equal(t, header.ContentTypeMp4Avc, clean.ContentType("video/mp4; codecs=\"avc1\""))
|
||||
mimeType := fmt.Sprintf("video/mp4; codecs=\"%s\"", clean.Codec("avc1"))
|
||||
assert.Equal(t, header.ContentTypeAVC, video.ContentType(mimeType, "mp4", "avc1"))
|
||||
assert.Equal(t, header.ContentTypeMp4Avc, video.ContentType(mimeType, "mp4", "avc1"))
|
||||
})
|
||||
|
||||
t.Run("NoHash", func(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package oidc
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config"
|
||||
)
|
||||
|
||||
func TestClientConfig(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ import (
|
|||
"strings"
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config/pwa"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/config/pwa"
|
||||
)
|
||||
|
||||
func TestConfig_AppName(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ import (
|
|||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
)
|
||||
|
||||
func TestConfig_CdnUrl(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -65,7 +65,7 @@ func (c *Config) WallpaperUri() string {
|
|||
|
||||
wallpaperUri = "welcome.jpg"
|
||||
} else if !strings.Contains(wallpaperUri, ".") {
|
||||
wallpaperUri += fs.ExtJPEG
|
||||
wallpaperUri += fs.ExtJpeg
|
||||
}
|
||||
|
||||
// Complete URI as needed if file path is valid.
|
||||
|
|
|
|||
|
|
@ -9,8 +9,8 @@ import (
|
|||
"github.com/photoprism/photoprism/internal/config/ttl"
|
||||
"github.com/photoprism/photoprism/internal/server/limiter"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/net/scheme"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/scheme"
|
||||
)
|
||||
|
||||
const (
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ import (
|
|||
|
||||
"github.com/photoprism/photoprism/internal/config/ttl"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/pkg/net/scheme"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/scheme"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package config
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/thumb"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/thumb"
|
||||
)
|
||||
|
||||
func TestConfig_ConvertSize(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -15,8 +15,8 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/media"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/net/scheme"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/scheme"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package config
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
func TestNewOptions(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import (
|
|||
"testing"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/stretchr/testify/assert"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
)
|
||||
|
||||
func TestConfig_TestdataPath2(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -5,10 +5,10 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity/sortby"
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -68,7 +68,7 @@ func (m *Album) YamlFileName(backupPath string) (absolute, relative string, err
|
|||
return "", "", fmt.Errorf("album uid is empty")
|
||||
}
|
||||
|
||||
relative = filepath.Join(m.AlbumType, m.AlbumUID+fs.ExtYAML)
|
||||
relative = filepath.Join(m.AlbumType, m.AlbumUID+fs.ExtYaml)
|
||||
|
||||
if backupPath == "" {
|
||||
return "", relative, fmt.Errorf("backup path is empty")
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package entity
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func Test_AddClient(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -18,7 +18,7 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/list"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/time/unix"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/i18n"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ import (
|
|||
|
||||
"github.com/photoprism/photoprism/internal/auth/acl"
|
||||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
"github.com/photoprism/photoprism/pkg/time/unix"
|
||||
"github.com/photoprism/photoprism/pkg/txt/report"
|
||||
|
|
|
|||
|
|
@ -1,10 +1,10 @@
|
|||
package entity
|
||||
|
||||
import (
|
||||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/urfave/cli/v2"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package entity
|
|||
import (
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
"github.com/sirupsen/logrus"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
)
|
||||
|
||||
// Error represents an error message log.
|
||||
|
|
|
|||
|
|
@ -360,7 +360,7 @@ func (m *File) ReplaceHash(newHash string) error {
|
|||
m.FileHash = newHash
|
||||
|
||||
// Ok to skip updating related tables?
|
||||
if m.NoJPEG() || m.FileHash == "" {
|
||||
if m.NoJpeg() || m.FileHash == "" {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
|
@ -590,13 +590,13 @@ func (m *File) RelatedPhoto() *Photo {
|
|||
}
|
||||
|
||||
// NoJPEG returns true if the file is not a JPEG image.
|
||||
func (m *File) NoJPEG() bool {
|
||||
return fs.ImageJPEG.NotEqual(m.FileType)
|
||||
func (m *File) NoJpeg() bool {
|
||||
return fs.ImageJpeg.NotEqual(m.FileType)
|
||||
}
|
||||
|
||||
// NoPNG returns true if the file is not a PNG image.
|
||||
func (m *File) NoPNG() bool {
|
||||
return fs.ImagePNG.NotEqual(m.FileType)
|
||||
func (m *File) NoPng() bool {
|
||||
return fs.ImagePng.NotEqual(m.FileType)
|
||||
}
|
||||
|
||||
// Type returns the file type.
|
||||
|
|
|
|||
|
|
@ -2602,7 +2602,7 @@ var FileFixtures = FileMap{
|
|||
FileHash: "pcad9168fa6acc5c5c2965adf6ec465ca42fd3451",
|
||||
FileSize: 921858,
|
||||
FileCodec: "jpeg",
|
||||
FileType: string(fs.ImageJPEG),
|
||||
FileType: string(fs.ImageJpeg),
|
||||
MediaType: media.Image.String(),
|
||||
FileMime: "image/jpg",
|
||||
FilePrimary: true,
|
||||
|
|
|
|||
|
|
@ -11,8 +11,8 @@ import (
|
|||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/fs"
|
||||
"github.com/photoprism/photoprism/pkg/media/colors"
|
||||
"github.com/photoprism/photoprism/pkg/media/http/header"
|
||||
"github.com/photoprism/photoprism/pkg/media/projection"
|
||||
"github.com/photoprism/photoprism/pkg/net/header"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
|
|
@ -63,7 +63,7 @@ func TestFile_ShareFileName(t *testing.T) {
|
|||
|
||||
assert.Contains(t, filename, "20190115-000000-Berlin-Morning-Mood")
|
||||
assert.Equal(t, "20190115-000000-Berlin-Morning-Mood.jpg", filename)
|
||||
assert.Contains(t, filename, fs.ExtJPEG)
|
||||
assert.Contains(t, filename, fs.ExtJpeg)
|
||||
})
|
||||
t.Run("WithPhotoTitleSequence", func(t *testing.T) {
|
||||
photo := &Photo{TakenAtLocal: time.Date(2019, 01, 15, 0, 0, 0, 0, time.UTC), PhotoTitle: "Berlin / Morning Mood"}
|
||||
|
|
@ -73,7 +73,7 @@ func TestFile_ShareFileName(t *testing.T) {
|
|||
|
||||
assert.Contains(t, filename, "20190115-000000-Berlin-Morning-Mood")
|
||||
assert.Equal(t, "20190115-000000-Berlin-Morning-Mood (2).jpg", filename)
|
||||
assert.Contains(t, filename, fs.ExtJPEG)
|
||||
assert.Contains(t, filename, fs.ExtJpeg)
|
||||
})
|
||||
t.Run("EmptyPhotoTitle", func(t *testing.T) {
|
||||
photo := &Photo{TakenAtLocal: time.Date(2019, 01, 15, 0, 0, 0, 0, time.UTC), PhotoTitle: ""}
|
||||
|
|
@ -303,14 +303,14 @@ func TestFile_Links(t *testing.T) {
|
|||
})
|
||||
}
|
||||
|
||||
func TestFile_NoJPEG(t *testing.T) {
|
||||
func TestFile_NoJpeg(t *testing.T) {
|
||||
t.Run("true", func(t *testing.T) {
|
||||
file := &File{Photo: nil, FileType: "xmp", FileSize: 500}
|
||||
assert.True(t, file.NoJPEG())
|
||||
assert.True(t, file.NoJpeg())
|
||||
})
|
||||
t.Run("false", func(t *testing.T) {
|
||||
file := &File{Photo: nil, FileType: "jpg", FileSize: 500}
|
||||
assert.False(t, file.NoJPEG())
|
||||
assert.False(t, file.NoJpeg())
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -432,12 +432,12 @@ func TestFile_OriginalBase(t *testing.T) {
|
|||
filename := file.OriginalBase(0)
|
||||
|
||||
assert.Contains(t, filename, "20190115-000000-Berlin-Morning-Mood")
|
||||
assert.Contains(t, filename, fs.ExtJPEG)
|
||||
assert.Contains(t, filename, fs.ExtJpeg)
|
||||
|
||||
filename2 := file.OriginalBase(1)
|
||||
assert.Contains(t, filename2, "20190115-000000-Berlin-Morning-Mood")
|
||||
assert.Contains(t, filename2, "(1)")
|
||||
assert.Contains(t, filename2, fs.ExtJPEG)
|
||||
assert.Contains(t, filename2, fs.ExtJpeg)
|
||||
})
|
||||
t.Run("original name empty", func(t *testing.T) {
|
||||
photo := &Photo{TakenAtLocal: time.Date(2019, 01, 15, 0, 0, 0, 0, time.UTC), PhotoTitle: "Berlin / Morning Mood"}
|
||||
|
|
@ -446,12 +446,12 @@ func TestFile_OriginalBase(t *testing.T) {
|
|||
filename := file.OriginalBase(0)
|
||||
|
||||
assert.Contains(t, filename, "sonnenaufgang")
|
||||
assert.Contains(t, filename, fs.ExtJPEG)
|
||||
assert.Contains(t, filename, fs.ExtJpeg)
|
||||
|
||||
filename2 := file.OriginalBase(1)
|
||||
assert.Contains(t, filename2, "sonnenaufgang")
|
||||
assert.Contains(t, filename2, "(1)")
|
||||
assert.Contains(t, filename2, fs.ExtJPEG)
|
||||
assert.Contains(t, filename2, fs.ExtJpeg)
|
||||
})
|
||||
t.Run("original name not empty", func(t *testing.T) {
|
||||
photo := &Photo{TakenAtLocal: time.Date(2019, 01, 15, 0, 0, 0, 0, time.UTC), PhotoTitle: "Berlin / Morning Mood"}
|
||||
|
|
@ -460,12 +460,12 @@ func TestFile_OriginalBase(t *testing.T) {
|
|||
filename := file.OriginalBase(0)
|
||||
|
||||
assert.Contains(t, filename, "Sonnenaufgang")
|
||||
assert.Contains(t, filename, fs.ExtJPEG)
|
||||
assert.Contains(t, filename, fs.ExtJpeg)
|
||||
|
||||
filename2 := file.OriginalBase(1)
|
||||
assert.Contains(t, filename2, "Sonnenaufgang")
|
||||
assert.Contains(t, filename2, "(1)")
|
||||
assert.Contains(t, filename2, fs.ExtJPEG)
|
||||
assert.Contains(t, filename2, fs.ExtJpeg)
|
||||
})
|
||||
}
|
||||
|
||||
|
|
@ -476,12 +476,12 @@ func TestFile_DownloadName(t *testing.T) {
|
|||
|
||||
filename := file.DownloadName(customize.DownloadNameFile, 0)
|
||||
assert.Contains(t, filename, "filename")
|
||||
assert.Contains(t, filename, fs.ExtJPEG)
|
||||
assert.Contains(t, filename, fs.ExtJpeg)
|
||||
|
||||
filename2 := file.DownloadName(customize.DownloadNameOriginal, 1)
|
||||
assert.Contains(t, filename2, "originalName")
|
||||
assert.Contains(t, filename2, "(1)")
|
||||
assert.Contains(t, filename2, fs.ExtJPEG)
|
||||
assert.Contains(t, filename2, fs.ExtJpeg)
|
||||
|
||||
filename3 := file.DownloadName("xxx", 0)
|
||||
assert.Contains(t, filename3, "20190115-000000-Berlin-Morning-Mood")
|
||||
|
|
@ -881,14 +881,14 @@ func TestFile_ContentType(t *testing.T) {
|
|||
t.Run("Image", func(t *testing.T) {
|
||||
m := FileFixtures.Get("exampleFileName.jpg")
|
||||
assert.Equal(t, false, m.FileVideo)
|
||||
assert.Equal(t, header.ContentTypeJPEG, m.ContentType())
|
||||
assert.Equal(t, header.ContentTypeJpeg, m.ContentType())
|
||||
})
|
||||
t.Run("Video", func(t *testing.T) {
|
||||
avc := FileFixtures.Get("Video.mp4")
|
||||
assert.Equal(t, true, avc.FileVideo)
|
||||
assert.Equal(t, header.ContentTypeAVC, avc.ContentType())
|
||||
assert.Equal(t, header.ContentTypeMp4Avc, avc.ContentType())
|
||||
hevc := FileFixtures.Get("Photo21.mp4")
|
||||
assert.Equal(t, true, hevc.FileVideo)
|
||||
assert.Equal(t, header.ContentTypeHEVC, hevc.ContentType())
|
||||
assert.Equal(t, header.ContentTypeMp4Hevc, hevc.ContentType())
|
||||
})
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package entity
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
func TestNewLink(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -4,9 +4,10 @@ import (
|
|||
"fmt"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/photoprism/photoprism/internal/thumb/crop"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
var testArea = crop.Area{
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/dustin/go-humanize/english"
|
||||
"github.com/jinzhu/gorm"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/list"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -8,12 +8,12 @@ import (
|
|||
"image/png"
|
||||
"time"
|
||||
|
||||
"github.com/pquerna/otp"
|
||||
"github.com/pquerna/otp/totp"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/authn"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
"github.com/pquerna/otp"
|
||||
)
|
||||
|
||||
// Passcode represents a two-factor authentication key.
|
||||
|
|
@ -326,7 +326,7 @@ func (m *Passcode) Image(size int) (image.Image, error) {
|
|||
}
|
||||
|
||||
// PNG returns a PNG image buffer with a QR Code that can be used to initialize compatible authenticator apps.
|
||||
func (m *Passcode) PNG(size int) *bytes.Buffer {
|
||||
func (m *Passcode) Png(size int) *bytes.Buffer {
|
||||
if m == nil {
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,7 @@ func (m *Passcode) MarshalJSON() ([]byte, error) {
|
|||
UID: m.UID,
|
||||
Type: m.KeyType,
|
||||
Secret: m.Secret(),
|
||||
QRCode: media.Base64(m.PNG(350)),
|
||||
QRCode: media.Base64(m.Png(350)),
|
||||
RecoveryCode: m.RecoveryCode,
|
||||
CreatedAt: m.CreatedAt,
|
||||
UpdatedAt: m.UpdatedAt,
|
||||
|
|
|
|||
|
|
@ -7,12 +7,13 @@ import (
|
|||
|
||||
"github.com/dustin/go-humanize/english"
|
||||
|
||||
"gopkg.in/photoprism/go-tz.v2/tz"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/ai/classify"
|
||||
"github.com/photoprism/photoprism/internal/service/maps"
|
||||
"github.com/photoprism/photoprism/pkg/clean"
|
||||
"github.com/photoprism/photoprism/pkg/geo"
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
"gopkg.in/photoprism/go-tz.v2/tz"
|
||||
)
|
||||
|
||||
// SetCoordinates changes the photo lat, lng and altitude if not empty and from an acceptable source.
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import (
|
|||
"sync"
|
||||
|
||||
"github.com/jinzhu/gorm"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/rnd"
|
||||
)
|
||||
|
||||
|
|
|
|||
|
|
@ -67,8 +67,8 @@ func (m *Photo) SaveAsYaml(fileName string) error {
|
|||
|
||||
// YamlFileName returns both the absolute file path and the relative name for the YAML sidecar file, e.g. for logging.
|
||||
func (m *Photo) YamlFileName(originalsPath, sidecarPath string) (absolute, relative string, err error) {
|
||||
absolute, err = fs.FileName(filepath.Join(originalsPath, m.PhotoPath, m.PhotoName), sidecarPath, originalsPath, fs.ExtYAML)
|
||||
relative = filepath.Join(m.PhotoPath, m.PhotoName) + fs.ExtYAML
|
||||
absolute, err = fs.FileName(filepath.Join(originalsPath, m.PhotoPath, m.PhotoName), sidecarPath, originalsPath, fs.ExtYaml)
|
||||
relative = filepath.Join(m.PhotoPath, m.PhotoName) + fs.ExtYaml
|
||||
|
||||
return absolute, relative, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package query
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
)
|
||||
|
||||
func TestAccountUploads(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -61,13 +61,13 @@ func ShareSelection(originals bool) FileSelection {
|
|||
}
|
||||
|
||||
omitTypes = []string{
|
||||
fs.ImagePNG.String(),
|
||||
fs.ImageWebP.String(),
|
||||
fs.ImageTIFF.String(),
|
||||
fs.ImageAVIF.String(),
|
||||
fs.ImageHEIC.String(),
|
||||
fs.ImageBMP.String(),
|
||||
fs.ImageGIF.String(),
|
||||
fs.ImagePng.String(),
|
||||
fs.ImageWebp.String(),
|
||||
fs.ImageTiff.String(),
|
||||
fs.ImageAvif.String(),
|
||||
fs.ImageHeic.String(),
|
||||
fs.ImageBmp.String(),
|
||||
fs.ImageGif.String(),
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
)
|
||||
|
||||
func TestFileShares(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package query
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
)
|
||||
|
||||
func TestFileSyncs(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -85,7 +85,7 @@ func VideoByPhotoUID(photoUID string) (*entity.File, error) {
|
|||
}
|
||||
|
||||
err := Db().Where("photo_uid = ? AND file_missing = 0", photoUID).
|
||||
Where("file_video = 1 OR file_duration > 0 OR file_frames > 0 OR file_type = ?", fs.ImageGIF).
|
||||
Where("file_video = 1 OR file_duration > 0 OR file_frames > 0 OR file_type = ?", fs.ImageGif).
|
||||
Order("file_error ASC, file_video DESC, file_duration DESC, file_frames DESC").
|
||||
Preload("Photo").First(&f).Error
|
||||
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
)
|
||||
|
||||
func TestFilesByPath(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package query
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
)
|
||||
|
||||
func TestFolderCoverByUID(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@ import (
|
|||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
)
|
||||
|
||||
func TestPurgeOrphans(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -26,6 +26,7 @@ package query
|
|||
|
||||
import (
|
||||
"github.com/jinzhu/gorm"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/event"
|
||||
)
|
||||
|
|
|
|||
|
|
@ -3,9 +3,10 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/entity"
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
func TestAccounts(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterAlbum(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterAlt(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosQueryAnimated(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosQueryArchived(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosQueryError(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterFNumber(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterFaces(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosQueryFavorite(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterFilename(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterFocalLength(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterFolder(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosQueryGeo(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosQueryHidden(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterIso(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterKeywords(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterLabel(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosQueryLandscape(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosQueryLive(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosQueryMono(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterName(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosQueryPanorama(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosFilterPath(t *testing.T) {
|
||||
|
|
|
|||
|
|
@ -3,8 +3,9 @@ package search
|
|||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
"github.com/stretchr/testify/assert"
|
||||
|
||||
"github.com/photoprism/photoprism/internal/form"
|
||||
)
|
||||
|
||||
func TestPhotosQueryPhoto(t *testing.T) {
|
||||
|
|
|
|||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue