diff --git a/internal/entity/camera.go b/internal/entity/camera.go index ad2d234bc..00fb90dc8 100644 --- a/internal/entity/camera.go +++ b/internal/entity/camera.go @@ -14,10 +14,9 @@ import ( type Camera struct { ID uint `gorm:"primary_key"` CameraSlug string `gorm:"type:varbinary(128);unique_index;"` - CameraModel string - CameraMake string - CameraType string - CameraOwner string + CameraModel string `gorm:"type:varchar(128);"` + CameraMake string `gorm:"type:varchar(128);"` + CameraType string `gorm:"type:varchar(128);"` CameraDescription string `gorm:"type:text;"` CameraNotes string `gorm:"type:text;"` CreatedAt time.Time diff --git a/internal/entity/photo.go b/internal/entity/photo.go index 563aed7c4..29d71ea31 100644 --- a/internal/entity/photo.go +++ b/internal/entity/photo.go @@ -19,10 +19,13 @@ type Photo struct { PhotoPath string `gorm:"type:varbinary(512);index;"` PhotoName string `gorm:"type:varbinary(256);"` PhotoTitle string `json:"PhotoTitle"` + PhotoSubject string `json:"PhotoSubject"` + PhotoKeywords string `json:"PhotoKeywords"` PhotoDescription string `gorm:"type:text;" json:"PhotoDescription"` PhotoNotes string `gorm:"type:text;" json:"PhotoNotes"` PhotoArtist string `json:"PhotoArtist"` PhotoCopyright string `json:"PhotoCopyright"` + PhotoLicense string `json:"PhotoLicense"` PhotoFavorite bool `json:"PhotoFavorite"` PhotoPrivate bool `json:"PhotoPrivate"` PhotoNSFW bool `json:"PhotoNSFW"` @@ -35,6 +38,7 @@ type Photo struct { PhotoFNumber float64 `json:"PhotoFNumber"` PhotoExposure string `gorm:"type:varbinary(64);" json:"PhotoExposure"` CameraID uint `gorm:"index:idx_photos_camera_lens;" json:"CameraID"` + CameraSerial string `gorm:"type:varbinary(128);" json:"CameraSerial"` LensID uint `gorm:"index:idx_photos_camera_lens;" json:"LensID"` AccountID uint `json:"AccountID"` PlaceID string `gorm:"type:varbinary(16);index;" json:"PlaceID"` @@ -111,8 +115,11 @@ func (m *Photo) BeforeSave(scope *gorm.Scope) error { func (m *Photo) IndexKeywords(keywords []string, db *gorm.DB) { var keywordIds []uint - // Index title and description + // Add title, description and other keywords keywords = append(keywords, txt.Keywords(m.PhotoTitle)...) + keywords = append(keywords, txt.Keywords(m.PhotoKeywords)...) + keywords = append(keywords, txt.Keywords(m.PhotoSubject)...) + keywords = append(keywords, txt.Keywords(m.PhotoArtist)...) keywords = append(keywords, txt.Keywords(m.PhotoDescription)...) last := "" @@ -207,6 +214,34 @@ func (m *Photo) NoTitle() bool { return m.PhotoTitle == "" } +func (m *Photo) NoDescription() bool { + return m.PhotoDescription == "" +} + +func (m *Photo) NoNotes() bool { + return m.PhotoNotes == "" +} + +func (m *Photo) NoArtist() bool { + return m.PhotoArtist == "" +} + +func (m *Photo) NoCopyright() bool { + return m.PhotoCopyright == "" +} + +func (m *Photo) NoSubject() bool { + return m.PhotoSubject == "" +} + +func (m *Photo) NoKeywords() bool { + return m.PhotoKeywords == "" +} + +func (m *Photo) NoCameraSerial() bool { + return m.CameraSerial == "" +} + func (m *Photo) HasTitle() bool { return m.PhotoTitle != "" } diff --git a/internal/photoprism/index_mediafile.go b/internal/photoprism/index_mediafile.go index 127be3ab4..ec423bb26 100644 --- a/internal/photoprism/index_mediafile.go +++ b/internal/photoprism/index_mediafile.go @@ -87,10 +87,8 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) I fileHash = m.Hash() } - if !photoExists { - photo.PhotoPath = filePath - photo.PhotoName = fileBase - } + photo.PhotoPath = filePath + photo.PhotoName = fileBase if !file.FilePrimary { if photoExists { @@ -105,9 +103,6 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) I if file.FilePrimary { primaryFile = file - photo.PhotoPath = filePath - photo.PhotoName = fileBase - if !ind.conf.TensorFlowDisabled() && (fileChanged || o.UpdateKeywords || o.UpdateLabels || o.UpdateTitle) { // Image classification via TensorFlow labels = ind.classifyImage(m) @@ -117,13 +112,49 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) I if fileChanged || o.UpdateExif { // Read UpdateExif data if metaData, err := m.MetaData(); err == nil { - photo.PhotoLat = metaData.Lat - photo.PhotoLng = metaData.Lng - photo.TakenAt = metaData.TakenAt - photo.TakenAtLocal = metaData.TakenAtLocal - photo.TimeZone = metaData.TimeZone - photo.PhotoAltitude = metaData.Altitude - photo.PhotoArtist = metaData.Artist + if !photo.ModifiedLocation { + photo.PhotoLat = metaData.Lat + photo.PhotoLng = metaData.Lng + photo.PhotoAltitude = metaData.Altitude + } + + if !photo.ModifiedDate { + photo.TakenAt = metaData.TakenAt + photo.TakenAtLocal = metaData.TakenAtLocal + photo.TimeZone = metaData.TimeZone + } + + if photo.NoTitle() { + photo.PhotoTitle = metaData.Title + } + + if photo.NoDescription() { + photo.PhotoDescription = metaData.Description + } + + if photo.NoNotes() { + photo.PhotoNotes = metaData.Comment + } + + if photo.NoSubject() { + photo.PhotoSubject = metaData.Subject + } + + if photo.NoKeywords() { + photo.PhotoKeywords = metaData.Keywords + } + + if photo.NoArtist() && metaData.Artist != "" { + photo.PhotoArtist = metaData.Artist + } + + if photo.NoArtist() && metaData.CameraOwner != "" { + photo.PhotoArtist = metaData.CameraOwner + } + + if photo.NoCameraSerial() { + photo.CameraSerial = metaData.CameraSerial + } if len(metaData.UniqueID) > 15 { log.Debugf("index: file uuid \"%s\"", metaData.UniqueID) @@ -133,7 +164,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) I } } - if fileChanged || o.UpdateCamera { + if !photo.ModifiedDetails && (fileChanged || o.UpdateCamera) { // Set UpdateCamera, Lens, Focal Length and F Number photo.Camera = entity.NewCamera(m.CameraModel(), m.CameraMake()).FirstOrCreate(ind.db) photo.Lens = entity.NewLens(m.LensModel(), m.LensMake()).FirstOrCreate(ind.db) @@ -184,15 +215,15 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) I photo.PhotoTitle = data.Title } - if data.Copyright != "" { + if photo.NoCopyright() && data.Copyright != "" { photo.PhotoCopyright = data.Copyright } - if data.Artist != "" { + if photo.NoArtist() && data.Artist != "" { photo.PhotoArtist = data.Artist } - if data.Description != "" { + if photo.NoDescription() && data.Description != "" { photo.PhotoDescription = data.Description } } diff --git a/internal/query/camera_test.go b/internal/query/camera_test.go index cc13baa26..88da4322c 100644 --- a/internal/query/camera_test.go +++ b/internal/query/camera_test.go @@ -14,6 +14,6 @@ func TestCamera_FirstOrCreate(t *testing.T) { camera := entity.NewCamera("iPhone SE", "Apple") c := config.TestConfig() camera.FirstOrCreate(c.Db()) - assert.Equal(t, uint(2), camera.ID) + assert.GreaterOrEqual(t, camera.ID, uint(1)) }) }