Panoramas: Increase projection type string limit to 32 characters #1508

This commit is contained in:
Michael Mayer 2021-09-03 19:02:26 +02:00
parent 34c8f9d7b1
commit 2bde7e5696
7 changed files with 178 additions and 49 deletions

View file

@ -1,7 +1,69 @@
package entity
// Panorama Projection Types
// TODO: Move to separate package.
const (
ProjDefault = ""
ProjEquirectangular = "equirectangular"
ProjCubestrip = "cubestrip"
ProjCylindrical = "cylindrical"
ProjTransverseCylindrical = "transverse-cylindrical"
ProjPseudocylindricalCompromise = "pseudocylindrical-compromise"
)
// Content Types
const (
TypeDefault = ""
TypeImage = "image"
TypeLive = "live"
TypeVideo = "video"
TypeRaw = "raw"
TypeText = "text"
)
// Root Directories Types
const (
RootUnknown = ""
RootOriginals = "/"
RootExamples = "examples"
RootSidecar = "sidecar"
RootImport = "import"
RootPath = "/"
)
// Unknown Values
const (
UnknownYear = -1
UnknownMonth = -1
UnknownDay = -1
UnknownName = "Unknown"
UnknownTitle = UnknownName
UnknownID = "zz"
)
// Event Types
const (
Updated = "updated"
Created = "created"
Deleted = "deleted"
)
// Photo Stacks
const (
IsStacked int8 = 1
IsStackable int8 = 0
IsUnstacked int8 = -1
)
// Sort Orders
const (
// Sort orders:
SortOrderAdded = "added"
SortOrderNewest = "newest"
SortOrderOldest = "oldest"
@ -9,44 +71,4 @@ const (
SortOrderSimilar = "similar"
SortOrderRelevance = "relevance"
SortOrderEdited = "edited"
// Unknown values:
UnknownYear = -1
UnknownMonth = -1
UnknownDay = -1
UnknownName = "Unknown"
UnknownTitle = UnknownName
UnknownID = "zz"
// Content types:
TypeDefault = ""
TypeImage = "image"
TypeLive = "live"
TypeVideo = "video"
TypeRaw = "raw"
TypeText = "text"
// Root directories:
RootUnknown = ""
RootOriginals = "/"
RootExamples = "examples"
RootSidecar = "sidecar"
RootImport = "import"
RootPath = "/"
// Panorama projections:
ProjectionDefault = ""
ProjectionEquirectangular = "equirectangular"
ProjectionCubestrip = "cubestrip"
ProjectionCylindrical = "cylindrical"
// Event names:
Updated = "updated"
Created = "created"
Deleted = "deleted"
// Photo stacks:
IsStacked int8 = 1
IsStackable int8 = 0
IsUnstacked int8 = -1
)

View file

@ -53,7 +53,7 @@ type File struct {
FileWidth int `json:"Width" yaml:"Width,omitempty"`
FileHeight int `json:"Height" yaml:"Height,omitempty"`
FileOrientation int `json:"Orientation" yaml:"Orientation,omitempty"`
FileProjection string `gorm:"type:VARBINARY(16);" json:"Projection,omitempty" yaml:"Projection,omitempty"`
FileProjection string `gorm:"type:VARBINARY(32);" json:"Projection,omitempty" yaml:"Projection,omitempty"`
FileAspectRatio float32 `gorm:"type:FLOAT;" json:"AspectRatio" yaml:"AspectRatio,omitempty"`
FileMainColor string `gorm:"type:VARBINARY(16);index;" json:"MainColor" yaml:"MainColor,omitempty"`
FileColors string `gorm:"type:VARBINARY(9);" json:"Colors" yaml:"Colors,omitempty"`
@ -394,7 +394,17 @@ func (m *File) Panorama() bool {
return false
}
return m.FileProjection != ProjectionDefault || (m.FileWidth/m.FileHeight) >= 2
return m.Projection() != ProjDefault || (m.FileWidth/m.FileHeight) >= 2
}
// Projection returns the panorama projection type string.
func (m *File) Projection() string {
return SanitizeTypeString(m.FileProjection)
}
// SetProjection sets the panorama projection type string.
func (m *File) SetProjection(projType string) {
m.FileProjection = SanitizeTypeString(projType)
}
// AddFaces adds face markers to the file.

View file

@ -289,7 +289,11 @@ func TestFile_Panorama(t *testing.T) {
assert.False(t, file.Panorama())
})
t.Run("equirectangular", func(t *testing.T) {
file := &File{Photo: nil, FileType: "jpg", FileSidecar: false, FileWidth: 1500, FileHeight: 1000, FileProjection: ProjectionEquirectangular}
file := &File{Photo: nil, FileType: "jpg", FileSidecar: false, FileWidth: 1500, FileHeight: 1000, FileProjection: ProjEquirectangular}
assert.True(t, file.Panorama())
})
t.Run("transverse-cylindrical", func(t *testing.T) {
file := &File{Photo: nil, FileType: "jpg", FileSidecar: false, FileWidth: 1500, FileHeight: 1000, FileProjection: ProjTransverseCylindrical}
assert.True(t, file.Panorama())
})
t.Run("sidecar", func(t *testing.T) {
@ -298,6 +302,39 @@ func TestFile_Panorama(t *testing.T) {
})
}
func TestFile_SetProjection(t *testing.T) {
t.Run(ProjDefault, func(t *testing.T) {
m := &File{}
m.SetProjection(ProjDefault)
assert.Equal(t, ProjDefault, m.FileProjection)
})
t.Run(ProjCubestrip, func(t *testing.T) {
m := &File{}
m.SetProjection(ProjCubestrip)
assert.Equal(t, ProjCubestrip, m.FileProjection)
})
t.Run(ProjCylindrical, func(t *testing.T) {
m := &File{}
m.SetProjection(ProjCylindrical)
assert.Equal(t, ProjCylindrical, m.FileProjection)
})
t.Run(ProjTransverseCylindrical, func(t *testing.T) {
m := &File{}
m.SetProjection(ProjTransverseCylindrical)
assert.Equal(t, ProjTransverseCylindrical, m.FileProjection)
})
t.Run(ProjPseudocylindricalCompromise, func(t *testing.T) {
m := &File{}
m.SetProjection(ProjPseudocylindricalCompromise)
assert.Equal(t, ProjPseudocylindricalCompromise, m.FileProjection)
})
t.Run("Sanitize", func(t *testing.T) {
m := &File{}
m.SetProjection(" 幸福 Hanzi are logograms developed for the writing of Chinese! ")
assert.Equal(t, "hanzi are logograms developed for the writing of chinese", m.FileProjection)
})
}
func TestFile_Delete(t *testing.T) {
t.Run("permanently", func(t *testing.T) {
file := &File{FileType: "jpg", FileSize: 500, FileName: "ToBePermanentlyDeleted", FileRoot: "", PhotoID: 5678}

View file

@ -1,6 +1,13 @@
package entity
import "reflect"
import (
"reflect"
"strings"
)
const (
TrimTypeString = 32
)
// Values is a shortcut for map[string]interface{}
type Values map[string]interface{}
@ -34,3 +41,33 @@ func GetValues(m interface{}, omit ...string) (result Values) {
return result
}
// ToASCII removes all non-ascii characters from a string and returns it.
func ToASCII(s string) string {
result := make([]rune, 0, len(s))
for _, r := range s {
if r <= 127 {
result = append(result, r)
}
}
return string(result)
}
// Trim shortens a string to the given number of characters, and removes all leading and trailing white space.
func Trim(s string, maxLen int) string {
s = strings.TrimSpace(s)
l := len(s)
if l <= maxLen {
return s
} else {
return s[:l-1]
}
}
// SanitizeTypeString converts a type string to lowercase, omits invalid runes, and shortens it if needed.
func SanitizeTypeString(s string) string {
return Trim(ToASCII(strings.ToLower(s)), TrimTypeString)
}

View file

@ -0,0 +1,22 @@
package entity
import (
"testing"
"github.com/stretchr/testify/assert"
)
func TestToASCII(t *testing.T) {
result := ToASCII("幸福 = Happiness.")
assert.Equal(t, " = Happiness.", result)
}
func TestTrim(t *testing.T) {
result := Trim(" 幸福 Hanzi are logograms developed for the writing of Chinese! ", 16)
assert.Equal(t, "幸福 Hanzi are logograms developed for the writing of Chinese", result)
}
func TestSanitizeTypeString(t *testing.T) {
result := SanitizeTypeString(" 幸福 Hanzi are logograms developed for the writing of Chinese! ")
assert.Equal(t, "hanzi are logograms developed for the writing of chinese", result)
}

View file

@ -321,7 +321,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
if metaData := m.MetaData(); metaData.Error == nil {
file.FileCodec = metaData.Codec
file.FileProjection = metaData.Projection
file.SetProjection(metaData.Projection)
if metaData.HasInstanceID() {
log.Infof("index: %s has instance_id %s", logName, txt.Quote(metaData.InstanceID))
@ -379,7 +379,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
file.FileHeight = m.Height()
file.FileAspectRatio = m.AspectRatio()
file.FilePortrait = m.Portrait()
file.FileProjection = metaData.Projection
file.SetProjection(metaData.Projection)
if res := m.Megapixels(); res > photo.PhotoResolution {
photo.PhotoResolution = res
@ -429,7 +429,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
file.FileAspectRatio = m.AspectRatio()
file.FilePortrait = m.Portrait()
file.FileDuration = metaData.Duration
file.FileProjection = metaData.Projection
file.SetProjection(metaData.Projection)
if res := m.Megapixels(); res > photo.PhotoResolution {
photo.PhotoResolution = res

View file

@ -4,13 +4,14 @@ import "strings"
const (
ClipDefault = 160
ClipSlug = 80
ClipKeyword = 40
ClipSlug = 80
ClipVarchar = 255
ClipQuery = 1000
ClipDescription = 16000
)
// Clip shortens a string to the given number of runes, and removes all leading and trailing white space.
func Clip(s string, size int) string {
s = strings.TrimSpace(s)