-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
/
lens.go
151 lines (119 loc) Β· 4.09 KB
/
lens.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
package entity
import (
"strings"
"sync"
"time"
"github.com/photoprism/photoprism/internal/event"
"github.com/photoprism/photoprism/pkg/clean"
"github.com/photoprism/photoprism/pkg/txt"
)
var lensMutex = sync.Mutex{}
// Lenses represents a list of lenses.
type Lenses []Lens
// Lens represents camera lens (as extracted from UpdateExif metadata)
type Lens struct {
ID uint `gorm:"primary_key" json:"ID" yaml:"ID"`
LensSlug string `gorm:"type:VARBINARY(160);unique_index;" json:"Slug" yaml:"Slug,omitempty"`
LensName string `gorm:"type:VARCHAR(160);" json:"Name" yaml:"Name"`
LensMake string `gorm:"type:VARCHAR(160);" json:"Make" yaml:"Make,omitempty"`
LensModel string `gorm:"type:VARCHAR(160);" json:"Model" yaml:"Model,omitempty"`
LensType string `gorm:"type:VARCHAR(100);" json:"Type" yaml:"Type,omitempty"`
LensDescription string `gorm:"type:VARCHAR(2048);" json:"Description,omitempty" yaml:"Description,omitempty"`
LensNotes string `gorm:"type:VARCHAR(1024);" json:"Notes,omitempty" yaml:"Notes,omitempty"`
CreatedAt time.Time `json:"-" yaml:"-"`
UpdatedAt time.Time `json:"-" yaml:"-"`
DeletedAt *time.Time `sql:"index" json:"-" yaml:"-"`
}
// TableName returns the entity table name.
func (Lens) TableName() string {
return "lenses"
}
var UnknownLens = Lens{
LensSlug: UnknownID,
LensName: "Unknown",
LensMake: "",
LensModel: "Unknown",
}
// CreateUnknownLens initializes the database with an unknown lens if not exists
func CreateUnknownLens() {
UnknownLens = *FirstOrCreateLens(&UnknownLens)
}
// NewLens creates a new camera lens entity from make and model names.
func NewLens(makeName string, modelName string) *Lens {
makeName = strings.TrimSpace(makeName)
modelName = strings.TrimSpace(modelName)
if modelName == "" && makeName == "" {
return &UnknownLens
} else if strings.HasPrefix(modelName, makeName) {
modelName = strings.TrimSpace(modelName[len(makeName):])
}
// Normalize make name.
if n, ok := CameraMakes[makeName]; ok {
makeName = n
}
// Remove duplicate make from model name.
if strings.HasPrefix(modelName, makeName) {
modelName = strings.TrimSpace(modelName[len(makeName):])
}
// Remove ignored substrings from model name.
modelName = LensModelIgnore.ReplaceAllString(modelName, " ")
var name []string
if makeName != "" {
name = append(name, makeName)
}
if modelName != "" {
name = append(name, modelName)
}
lensName := strings.Join(name, " ")
result := &Lens{
LensSlug: txt.Slug(lensName),
LensName: txt.Clip(lensName, txt.ClipName),
LensMake: txt.Clip(makeName, txt.ClipName),
LensModel: txt.Clip(modelName, txt.ClipName),
}
return result
}
// Create inserts a new row to the database.
func (m *Lens) Create() error {
lensMutex.Lock()
defer lensMutex.Unlock()
return Db().Create(m).Error
}
// FirstOrCreateLens returns the existing row, inserts a new row or nil in case of errors.
func FirstOrCreateLens(m *Lens) *Lens {
if m.LensSlug == "" {
return &UnknownLens
}
if cacheData, ok := lensCache.Get(m.LensSlug); ok {
log.Tracef("lens: cache hit for %s", m.LensSlug)
return cacheData.(*Lens)
}
result := Lens{}
if res := Db().Where("lens_slug = ?", m.LensSlug).First(&result); res.Error == nil {
lensCache.SetDefault(m.LensSlug, &result)
return &result
} else if err := m.Create(); err == nil {
if !m.Unknown() {
event.EntitiesCreated("lenses", []*Lens{m})
event.Publish("count.lenses", event.Data{
"count": 1,
})
}
lensCache.SetDefault(m.LensSlug, m)
return m
} else if res := Db().Where("lens_slug = ?", m.LensSlug).First(&result); res.Error == nil {
lensCache.SetDefault(m.LensSlug, &result)
return &result
} else {
log.Errorf("lens: %s (create %s)", err.Error(), clean.Log(m.String()))
}
return &UnknownLens
}
// String returns an identifier that can be used in logs.
func (m *Lens) String() string {
return clean.Log(m.LensName)
}
// Unknown returns true if the lens is not a known make or model.
func (m *Lens) Unknown() bool {
return m.LensSlug == "" || m.LensSlug == UnknownLens.LensSlug
}