Videos: Refactor codec, content and file type specifications #4770

Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
Michael Mayer 2025-02-05 00:30:45 +01:00
parent 30a6ff248b
commit 6a89519e63
254 changed files with 1193 additions and 1032 deletions

View file

@ -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:

View file

@ -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

View file

@ -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"
)

View file

@ -11,6 +11,7 @@ import (
"sort"
pigo "github.com/esimov/pigo/core"
"github.com/photoprism/photoprism/pkg/clean"
"github.com/photoprism/photoprism/pkg/fs"
)

View file

@ -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) {

View file

@ -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)))
}

View file

@ -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)
}
}

View file

@ -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

View file

@ -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) {

View file

@ -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.

View file

@ -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.

View file

@ -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 {

View file

@ -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)
}

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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"
)

View file

@ -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"
)

View file

@ -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.

View file

@ -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) {

View file

@ -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,

View file

@ -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.

View file

@ -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"

View file

@ -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) {

View file

@ -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)

View file

@ -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"
)

View file

@ -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) {

View file

@ -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.

View file

@ -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"
)

View file

@ -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"
)

View file

@ -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)

View file

@ -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

View file

@ -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)

View file

@ -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"
)

View file

@ -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) {

View file

@ -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) {

View file

@ -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))

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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.

View file

@ -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 (

View file

@ -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"
)

View file

@ -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) {

View file

@ -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"
)

View file

@ -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) {

View file

@ -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) {

View file

@ -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"
)

View file

@ -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")

View file

@ -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) {

View file

@ -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"

View file

@ -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"
)

View file

@ -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"

View file

@ -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"
)

View file

@ -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.

View file

@ -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.

View file

@ -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,

View file

@ -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())
})
}

View file

@ -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) {

View file

@ -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{

View file

@ -5,6 +5,7 @@ import (
"github.com/dustin/go-humanize/english"
"github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/pkg/list"
)

View file

@ -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
}

View file

@ -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,

View file

@ -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.

View file

@ -4,6 +4,7 @@ import (
"sync"
"github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/pkg/rnd"
)

View file

@ -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
}

View file

@ -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) {

View file

@ -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(),
}
}

View file

@ -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) {

View file

@ -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) {

View file

@ -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

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -26,6 +26,7 @@ package query
import (
"github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/internal/entity"
"github.com/photoprism/photoprism/internal/event"
)

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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) {

View file

@ -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