mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
API: Add action and user context to indexing events #98
Signed-off-by: Michael Mayer <michael@photoprism.app>
This commit is contained in:
@@ -105,7 +105,7 @@ func StartImport(router *gin.RouterGroup) {
|
|||||||
|
|
||||||
// Set user UID if known.
|
// Set user UID if known.
|
||||||
if s.UserUID != "" {
|
if s.UserUID != "" {
|
||||||
opt.UserUID = s.UserUID
|
opt.UID = s.UserUID
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start import.
|
// Start import.
|
||||||
@@ -138,8 +138,16 @@ func StartImport(router *gin.RouterGroup) {
|
|||||||
msg := i18n.Msg(i18n.MsgImportCompletedIn, elapsed)
|
msg := i18n.Msg(i18n.MsgImportCompletedIn, elapsed)
|
||||||
|
|
||||||
event.Success(msg)
|
event.Success(msg)
|
||||||
event.Publish("import.completed", event.Data{"path": importPath, "seconds": elapsed})
|
|
||||||
event.Publish("index.completed", event.Data{"path": importPath, "seconds": elapsed})
|
eventData := event.Data{
|
||||||
|
"uid": opt.UID,
|
||||||
|
"action": opt.Action,
|
||||||
|
"path": importPath,
|
||||||
|
"seconds": elapsed,
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Publish("import.completed", eventData)
|
||||||
|
event.Publish("index.completed", eventData)
|
||||||
|
|
||||||
for _, uid := range f.Albums {
|
for _, uid := range f.Albums {
|
||||||
PublishAlbumEvent(EntityUpdated, uid, c)
|
PublishAlbumEvent(EntityUpdated, uid, c)
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ func StartIndexing(router *gin.RouterGroup) {
|
|||||||
skipArchived := settings.Index.SkipArchived
|
skipArchived := settings.Index.SkipArchived
|
||||||
|
|
||||||
indOpt := photoprism.NewIndexOptions(filepath.Clean(f.Path), f.Rescan, convert, true, false, skipArchived)
|
indOpt := photoprism.NewIndexOptions(filepath.Clean(f.Path), f.Rescan, convert, true, false, skipArchived)
|
||||||
|
indOpt.SetUser(s.User())
|
||||||
|
|
||||||
if len(indOpt.Path) > 1 {
|
if len(indOpt.Path) > 1 {
|
||||||
event.InfoMsg(i18n.MsgIndexingFiles, clean.Log(indOpt.Path))
|
event.InfoMsg(i18n.MsgIndexingFiles, clean.Log(indOpt.Path))
|
||||||
@@ -76,13 +77,17 @@ func StartIndexing(router *gin.RouterGroup) {
|
|||||||
// Update index?
|
// Update index?
|
||||||
if updateIndex {
|
if updateIndex {
|
||||||
event.Publish("index.updating", event.Data{
|
event.Publish("index.updating", event.Data{
|
||||||
"step": "folders",
|
"uid": indOpt.UID,
|
||||||
|
"action": indOpt.Action,
|
||||||
|
"step": "folders",
|
||||||
})
|
})
|
||||||
|
|
||||||
RemoveFromFolderCache(entity.RootOriginals)
|
RemoveFromFolderCache(entity.RootOriginals)
|
||||||
|
|
||||||
event.Publish("index.updating", event.Data{
|
event.Publish("index.updating", event.Data{
|
||||||
"step": "purge",
|
"uid": indOpt.UID,
|
||||||
|
"action": indOpt.Action,
|
||||||
|
"step": "purge",
|
||||||
})
|
})
|
||||||
|
|
||||||
// Configure purge options.
|
// Configure purge options.
|
||||||
@@ -107,7 +112,9 @@ func StartIndexing(router *gin.RouterGroup) {
|
|||||||
// Update moments?
|
// Update moments?
|
||||||
if forceUpdate {
|
if forceUpdate {
|
||||||
event.Publish("index.updating", event.Data{
|
event.Publish("index.updating", event.Data{
|
||||||
"step": "moments",
|
"uid": indOpt.UID,
|
||||||
|
"action": indOpt.Action,
|
||||||
|
"step": "moments",
|
||||||
})
|
})
|
||||||
|
|
||||||
moments := get.Moments()
|
moments := get.Moments()
|
||||||
@@ -122,7 +129,12 @@ func StartIndexing(router *gin.RouterGroup) {
|
|||||||
msg := i18n.Msg(i18n.MsgIndexingCompletedIn, elapsed)
|
msg := i18n.Msg(i18n.MsgIndexingCompletedIn, elapsed)
|
||||||
|
|
||||||
event.Success(msg)
|
event.Success(msg)
|
||||||
event.Publish("index.completed", event.Data{"path": path, "seconds": elapsed})
|
event.Publish("index.completed", event.Data{
|
||||||
|
"uid": indOpt.UID,
|
||||||
|
"action": indOpt.Action,
|
||||||
|
"path": path,
|
||||||
|
"seconds": elapsed,
|
||||||
|
})
|
||||||
|
|
||||||
UpdateClientConfig()
|
UpdateClientConfig()
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import (
|
|||||||
|
|
||||||
"github.com/photoprism/photoprism/internal/acl"
|
"github.com/photoprism/photoprism/internal/acl"
|
||||||
"github.com/photoprism/photoprism/internal/entity"
|
"github.com/photoprism/photoprism/internal/entity"
|
||||||
"github.com/photoprism/photoprism/internal/event"
|
|
||||||
"github.com/photoprism/photoprism/internal/form"
|
"github.com/photoprism/photoprism/internal/form"
|
||||||
"github.com/photoprism/photoprism/internal/get"
|
"github.com/photoprism/photoprism/internal/get"
|
||||||
"github.com/photoprism/photoprism/internal/i18n"
|
"github.com/photoprism/photoprism/internal/i18n"
|
||||||
@@ -145,8 +144,6 @@ func AddService(router *gin.RouterGroup) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
event.SuccessMsg(i18n.MsgAccountCreated)
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, m)
|
c.JSON(http.StatusOK, m)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -201,8 +198,6 @@ func UpdateService(router *gin.RouterGroup) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
event.SuccessMsg(i18n.MsgAccountSaved)
|
|
||||||
|
|
||||||
m, err = query.AccountByID(id)
|
m, err = query.AccountByID(id)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -250,8 +245,6 @@ func DeleteService(router *gin.RouterGroup) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
event.SuccessMsg(i18n.MsgAccountDeleted)
|
|
||||||
|
|
||||||
c.JSON(http.StatusOK, m)
|
c.JSON(http.StatusOK, m)
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ func UploadUserAvatar(router *gin.RouterGroup) {
|
|||||||
|
|
||||||
// Users may only change their own avatar.
|
// Users may only change their own avatar.
|
||||||
if !isPrivileged && s.User().UserUID != uid {
|
if !isPrivileged && s.User().UserUID != uid {
|
||||||
event.AuditErr([]string{ClientIP(c), "session %s", "upload avatar", "user uid does not match"}, s.RefID)
|
event.AuditErr([]string{ClientIP(c), "session %s", "upload avatar", "user does not match"}, s.RefID)
|
||||||
AbortForbidden(c)
|
AbortForbidden(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,6 @@ import (
|
|||||||
|
|
||||||
"github.com/photoprism/photoprism/internal/acl"
|
"github.com/photoprism/photoprism/internal/acl"
|
||||||
"github.com/photoprism/photoprism/internal/entity"
|
"github.com/photoprism/photoprism/internal/entity"
|
||||||
"github.com/photoprism/photoprism/internal/event"
|
|
||||||
"github.com/photoprism/photoprism/internal/get"
|
"github.com/photoprism/photoprism/internal/get"
|
||||||
"github.com/photoprism/photoprism/internal/i18n"
|
"github.com/photoprism/photoprism/internal/i18n"
|
||||||
"github.com/photoprism/photoprism/pkg/clean"
|
"github.com/photoprism/photoprism/pkg/clean"
|
||||||
@@ -75,8 +74,6 @@ func UpdateUser(router *gin.RouterGroup) {
|
|||||||
// Clear the session cache, as it contains user information.
|
// Clear the session cache, as it contains user information.
|
||||||
s.ClearCache()
|
s.ClearCache()
|
||||||
|
|
||||||
event.SuccessMsg(i18n.MsgChangesSaved)
|
|
||||||
|
|
||||||
m = entity.FindUserByUID(uid)
|
m = entity.FindUserByUID(uid)
|
||||||
|
|
||||||
if m == nil {
|
if m == nil {
|
||||||
|
|||||||
@@ -29,11 +29,13 @@ func UploadUserFiles(router *gin.RouterGroup) {
|
|||||||
router.POST("/users/:uid/upload/:token", func(c *gin.Context) {
|
router.POST("/users/:uid/upload/:token", func(c *gin.Context) {
|
||||||
conf := get.Config()
|
conf := get.Config()
|
||||||
|
|
||||||
|
// Abort in public mode or when the upload feature is disabled.
|
||||||
if conf.ReadOnly() || !conf.Settings().Features.Upload {
|
if conf.ReadOnly() || !conf.Settings().Features.Upload {
|
||||||
Abort(c, http.StatusForbidden, i18n.ErrReadOnly)
|
Abort(c, http.StatusForbidden, i18n.ErrReadOnly)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check permission.
|
||||||
s := AuthAny(c, acl.ResourceFiles, acl.Permissions{acl.ActionManage, acl.ActionUpload})
|
s := AuthAny(c, acl.ResourceFiles, acl.Permissions{acl.ActionManage, acl.ActionUpload})
|
||||||
|
|
||||||
if s.Abort(c) {
|
if s.Abort(c) {
|
||||||
@@ -44,7 +46,7 @@ func UploadUserFiles(router *gin.RouterGroup) {
|
|||||||
|
|
||||||
// Users may only upload their own files.
|
// Users may only upload their own files.
|
||||||
if s.User().UserUID != uid {
|
if s.User().UserUID != uid {
|
||||||
event.AuditErr([]string{ClientIP(c), "session %s", "upload files", "user uid does not match"}, s.RefID)
|
event.AuditErr([]string{ClientIP(c), "session %s", "upload files", "user does not match"}, s.RefID)
|
||||||
AbortForbidden(c)
|
AbortForbidden(c)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@@ -60,13 +62,15 @@ func UploadUserFiles(router *gin.RouterGroup) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
event.Publish("upload.start", event.Data{"time": start})
|
// Publish upload start event.
|
||||||
|
event.Publish("upload.start", event.Data{"uid": s.UserUID, "time": start})
|
||||||
|
|
||||||
files := f.File["files"]
|
files := f.File["files"]
|
||||||
uploaded := len(files)
|
uploaded := len(files)
|
||||||
|
|
||||||
var uploads []string
|
var uploads []string
|
||||||
|
|
||||||
|
// Compose upload path.
|
||||||
uploadDir, err := conf.UserUploadPath(s.UserUID, s.RefID+token)
|
uploadDir, err := conf.UserUploadPath(s.UserUID, s.RefID+token)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@@ -75,20 +79,24 @@ func UploadUserFiles(router *gin.RouterGroup) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Save uploaded files.
|
||||||
for _, file := range files {
|
for _, file := range files {
|
||||||
filename := path.Join(uploadDir, filepath.Base(file.Filename))
|
fileName := filepath.Base(file.Filename)
|
||||||
|
filePath := path.Join(uploadDir, fileName)
|
||||||
|
|
||||||
log.Debugf("upload: saving file %s", clean.Log(file.Filename))
|
if err = c.SaveUploadedFile(file, filePath); err != nil {
|
||||||
|
log.Errorf("upload: failed saving file %s", clean.Log(fileName))
|
||||||
if err := c.SaveUploadedFile(file, filename); err != nil {
|
|
||||||
log.Errorf("upload: failed saving file %s", clean.Log(filepath.Base(file.Filename)))
|
|
||||||
Abort(c, http.StatusBadRequest, i18n.ErrUploadFailed)
|
Abort(c, http.StatusBadRequest, i18n.ErrUploadFailed)
|
||||||
return
|
return
|
||||||
|
} else {
|
||||||
|
log.Debugf("upload: saved file %s", clean.Log(fileName))
|
||||||
|
event.Publish("upload.saved", event.Data{"uid": s.UserUID, "file": fileName})
|
||||||
}
|
}
|
||||||
|
|
||||||
uploads = append(uploads, filename)
|
uploads = append(uploads, filePath)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Check if uploaded file is safe.
|
||||||
if !conf.UploadNSFW() {
|
if !conf.UploadNSFW() {
|
||||||
nd := get.NsfwDetector()
|
nd := get.NsfwDetector()
|
||||||
|
|
||||||
@@ -195,7 +203,7 @@ func ProcessUserUpload(router *gin.RouterGroup) {
|
|||||||
|
|
||||||
// Set user UID if known.
|
// Set user UID if known.
|
||||||
if s.UserUID != "" {
|
if s.UserUID != "" {
|
||||||
opt.UserUID = s.UserUID
|
opt.UID = s.UserUID
|
||||||
}
|
}
|
||||||
|
|
||||||
// Start import.
|
// Start import.
|
||||||
@@ -228,8 +236,9 @@ func ProcessUserUpload(router *gin.RouterGroup) {
|
|||||||
msg := i18n.Msg(i18n.MsgUploadProcessed)
|
msg := i18n.Msg(i18n.MsgUploadProcessed)
|
||||||
|
|
||||||
event.Success(msg)
|
event.Success(msg)
|
||||||
event.Publish("import.completed", event.Data{"path": uploadPath, "seconds": elapsed})
|
event.Publish("import.completed", event.Data{"uid": opt.UID, "path": uploadPath, "seconds": elapsed})
|
||||||
event.Publish("index.completed", event.Data{"path": uploadPath, "seconds": elapsed})
|
event.Publish("index.completed", event.Data{"uid": opt.UID, "path": uploadPath, "seconds": elapsed})
|
||||||
|
event.Publish("upload.completed", event.Data{"uid": opt.UID, "path": uploadPath, "seconds": elapsed})
|
||||||
|
|
||||||
for _, uid := range f.Albums {
|
for _, uid := range f.Albums {
|
||||||
PublishAlbumEvent(EntityUpdated, uid, c)
|
PublishAlbumEvent(EntityUpdated, uid, c)
|
||||||
|
|||||||
@@ -69,6 +69,7 @@ func Import() error {
|
|||||||
event.InfoMsg(i18n.MsgCopyingFilesFrom, clean.Log(filepath.Base(path)))
|
event.InfoMsg(i18n.MsgCopyingFilesFrom, clean.Log(filepath.Base(path)))
|
||||||
|
|
||||||
var opt photoprism.ImportOptions
|
var opt photoprism.ImportOptions
|
||||||
|
opt.Action = photoprism.ActionAutoImport
|
||||||
|
|
||||||
if conf.Settings().Import.Move {
|
if conf.Settings().Import.Move {
|
||||||
opt = photoprism.ImportOptionsMove(path, conf.ImportDest())
|
opt = photoprism.ImportOptionsMove(path, conf.ImportDest())
|
||||||
@@ -93,8 +94,16 @@ func Import() error {
|
|||||||
msg := i18n.Msg(i18n.MsgImportCompletedIn, elapsed)
|
msg := i18n.Msg(i18n.MsgImportCompletedIn, elapsed)
|
||||||
|
|
||||||
event.Success(msg)
|
event.Success(msg)
|
||||||
event.Publish("import.completed", event.Data{"path": path, "seconds": elapsed})
|
|
||||||
event.Publish("index.completed", event.Data{"path": path, "seconds": elapsed})
|
eventData := event.Data{
|
||||||
|
"uid": opt.UID,
|
||||||
|
"action": opt.Action,
|
||||||
|
"path": path,
|
||||||
|
"seconds": elapsed,
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Publish("import.completed", eventData)
|
||||||
|
event.Publish("index.completed", eventData)
|
||||||
|
|
||||||
api.UpdateClientConfig()
|
api.UpdateClientConfig()
|
||||||
|
|
||||||
|
|||||||
@@ -62,6 +62,7 @@ func Index() error {
|
|||||||
|
|
||||||
convert := settings.Index.Convert && conf.SidecarWritable()
|
convert := settings.Index.Convert && conf.SidecarWritable()
|
||||||
indOpt := photoprism.NewIndexOptions(entity.RootPath, false, convert, true, false, true)
|
indOpt := photoprism.NewIndexOptions(entity.RootPath, false, convert, true, false, true)
|
||||||
|
indOpt.Action = photoprism.ActionAutoIndex
|
||||||
|
|
||||||
lastRun, lastFound := ind.LastRun()
|
lastRun, lastFound := ind.LastRun()
|
||||||
found, indexed := ind.Start(indOpt)
|
found, indexed := ind.Start(indOpt)
|
||||||
@@ -87,7 +88,9 @@ func Index() error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
event.Publish("index.updating", event.Data{
|
event.Publish("index.updating", event.Data{
|
||||||
"step": "moments",
|
"uid": indOpt.UID,
|
||||||
|
"action": indOpt.Action,
|
||||||
|
"step": "moments",
|
||||||
})
|
})
|
||||||
|
|
||||||
moments := get.Moments()
|
moments := get.Moments()
|
||||||
@@ -101,7 +104,15 @@ func Index() error {
|
|||||||
msg := i18n.Msg(i18n.MsgIndexingCompletedIn, elapsed)
|
msg := i18n.Msg(i18n.MsgIndexingCompletedIn, elapsed)
|
||||||
|
|
||||||
event.Success(msg)
|
event.Success(msg)
|
||||||
event.Publish("index.completed", event.Data{"path": path, "seconds": elapsed})
|
|
||||||
|
eventData := event.Data{
|
||||||
|
"uid": indOpt.UID,
|
||||||
|
"action": indOpt.Action,
|
||||||
|
"path": path,
|
||||||
|
"seconds": elapsed,
|
||||||
|
}
|
||||||
|
|
||||||
|
event.Publish("index.completed", eventData)
|
||||||
|
|
||||||
api.UpdateClientConfig()
|
api.UpdateClientConfig()
|
||||||
|
|
||||||
|
|||||||
10
internal/photoprism/actions.go
Normal file
10
internal/photoprism/actions.go
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
package photoprism
|
||||||
|
|
||||||
|
const (
|
||||||
|
ActionIndex = "index"
|
||||||
|
ActionAutoIndex = "autoindex"
|
||||||
|
ActionImport = "import"
|
||||||
|
ActionAutoImport = "autoimport"
|
||||||
|
ActionUpload = "upload"
|
||||||
|
ActionUnknown = ""
|
||||||
|
)
|
||||||
@@ -107,6 +107,8 @@ func (imp *Import) Start(opt ImportOptions) fs.Done {
|
|||||||
settings := imp.conf.Settings()
|
settings := imp.conf.Settings()
|
||||||
convert := settings.Index.Convert && imp.conf.SidecarWritable()
|
convert := settings.Index.Convert && imp.conf.SidecarWritable()
|
||||||
indexOpt := NewIndexOptions("/", true, convert, true, false, false)
|
indexOpt := NewIndexOptions("/", true, convert, true, false, false)
|
||||||
|
indexOpt.UID = opt.UID
|
||||||
|
indexOpt.Action = opt.Action
|
||||||
skipRaw := imp.conf.DisableRaw()
|
skipRaw := imp.conf.DisableRaw()
|
||||||
ignore := fs.NewIgnoreList(fs.IgnoreFile, true, false)
|
ignore := fs.NewIgnoreList(fs.IgnoreFile, true, false)
|
||||||
|
|
||||||
|
|||||||
@@ -1,21 +1,35 @@
|
|||||||
package photoprism
|
package photoprism
|
||||||
|
|
||||||
|
import "github.com/photoprism/photoprism/internal/entity"
|
||||||
|
|
||||||
// ImportOptions represents file import options.
|
// ImportOptions represents file import options.
|
||||||
type ImportOptions struct {
|
type ImportOptions struct {
|
||||||
|
UID string
|
||||||
|
Action string
|
||||||
Albums []string
|
Albums []string
|
||||||
Path string
|
Path string
|
||||||
Move bool
|
Move bool
|
||||||
NonBlocking bool
|
NonBlocking bool
|
||||||
UserUID string
|
|
||||||
DestFolder string
|
DestFolder string
|
||||||
RemoveDotFiles bool
|
RemoveDotFiles bool
|
||||||
RemoveExistingFiles bool
|
RemoveExistingFiles bool
|
||||||
RemoveEmptyDirectories bool
|
RemoveEmptyDirectories bool
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetUser sets the user who performs the import operation.
|
||||||
|
func (o *ImportOptions) SetUser(user *entity.User) *ImportOptions {
|
||||||
|
if o != nil && user != nil {
|
||||||
|
o.UID = user.UID()
|
||||||
|
}
|
||||||
|
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
// ImportOptionsCopy returns import options for copying files to originals (read-only).
|
// ImportOptionsCopy returns import options for copying files to originals (read-only).
|
||||||
func ImportOptionsCopy(importPath, destFolder string) ImportOptions {
|
func ImportOptionsCopy(importPath, destFolder string) ImportOptions {
|
||||||
result := ImportOptions{
|
result := ImportOptions{
|
||||||
|
UID: entity.Admin.UID(),
|
||||||
|
Action: ActionImport,
|
||||||
Path: importPath,
|
Path: importPath,
|
||||||
Move: false,
|
Move: false,
|
||||||
NonBlocking: false,
|
NonBlocking: false,
|
||||||
@@ -31,6 +45,8 @@ func ImportOptionsCopy(importPath, destFolder string) ImportOptions {
|
|||||||
// ImportOptionsMove returns import options for moving files to originals (modifies import directory).
|
// ImportOptionsMove returns import options for moving files to originals (modifies import directory).
|
||||||
func ImportOptionsMove(importPath, destFolder string) ImportOptions {
|
func ImportOptionsMove(importPath, destFolder string) ImportOptions {
|
||||||
result := ImportOptions{
|
result := ImportOptions{
|
||||||
|
UID: entity.Admin.UID(),
|
||||||
|
Action: ActionImport,
|
||||||
Path: importPath,
|
Path: importPath,
|
||||||
Move: true,
|
Move: true,
|
||||||
NonBlocking: false,
|
NonBlocking: false,
|
||||||
@@ -46,6 +62,8 @@ func ImportOptionsMove(importPath, destFolder string) ImportOptions {
|
|||||||
// ImportOptionsUpload returns options for importing user uploads.
|
// ImportOptionsUpload returns options for importing user uploads.
|
||||||
func ImportOptionsUpload(uploadPath, destFolder string) ImportOptions {
|
func ImportOptionsUpload(uploadPath, destFolder string) ImportOptions {
|
||||||
result := ImportOptions{
|
result := ImportOptions{
|
||||||
|
UID: entity.Admin.UID(),
|
||||||
|
Action: ActionUpload,
|
||||||
Path: uploadPath,
|
Path: uploadPath,
|
||||||
Move: true,
|
Move: true,
|
||||||
NonBlocking: true,
|
NonBlocking: true,
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ func ImportWorker(jobs <-chan ImportJob) {
|
|||||||
// Do nothing.
|
// Do nothing.
|
||||||
} else if file, err := entity.FirstFileByHash(fileHash); err != nil {
|
} else if file, err := entity.FirstFileByHash(fileHash); err != nil {
|
||||||
// Do nothing.
|
// Do nothing.
|
||||||
} else if err := entity.AddPhotoToUserAlbums(file.PhotoUID, opt.Albums, opt.UserUID); err != nil {
|
} else if err := entity.AddPhotoToUserAlbums(file.PhotoUID, opt.Albums, opt.UID); err != nil {
|
||||||
log.Warn(err)
|
log.Warn(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -190,7 +190,7 @@ func ImportWorker(jobs <-chan ImportJob) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Index main MediaFile.
|
// Index main MediaFile.
|
||||||
res := ind.UserMediaFile(f, o, originalName, "", opt.UserUID)
|
res := ind.UserMediaFile(f, o, originalName, "", opt.UID)
|
||||||
|
|
||||||
// Log result.
|
// Log result.
|
||||||
log.Infof("import: %s main %s file %s", res, f.FileType(), clean.Log(f.RootRelName()))
|
log.Infof("import: %s main %s file %s", res, f.FileType(), clean.Log(f.RootRelName()))
|
||||||
@@ -203,7 +203,7 @@ func ImportWorker(jobs <-chan ImportJob) {
|
|||||||
photoUID = res.PhotoUID
|
photoUID = res.PhotoUID
|
||||||
|
|
||||||
// Add photo to album if a list of albums was provided when importing.
|
// Add photo to album if a list of albums was provided when importing.
|
||||||
if err := entity.AddPhotoToUserAlbums(photoUID, opt.Albums, opt.UserUID); err != nil {
|
if err := entity.AddPhotoToUserAlbums(photoUID, opt.Albums, opt.UID); err != nil {
|
||||||
log.Warn(err)
|
log.Warn(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,7 +240,7 @@ func ImportWorker(jobs <-chan ImportJob) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Index related media file including its original filename.
|
// Index related media file including its original filename.
|
||||||
res := ind.UserMediaFile(f, o, relatedOriginalNames[f.FileName()], photoUID, opt.UserUID)
|
res := ind.UserMediaFile(f, o, relatedOriginalNames[f.FileName()], photoUID, opt.UID)
|
||||||
|
|
||||||
// Save file error.
|
// Save file error.
|
||||||
if fileUid, err := res.FileError(); err != nil {
|
if fileUid, err := res.FileError(); err != nil {
|
||||||
|
|||||||
@@ -177,6 +177,7 @@ func (ind *Index) Start(o IndexOptions) (found fs.Done, updated int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
event.Publish("index.folder", event.Data{
|
event.Publish("index.folder", event.Data{
|
||||||
|
"uid": o.UID,
|
||||||
"filePath": relName,
|
"filePath": relName,
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -291,6 +292,7 @@ func (ind *Index) Start(o IndexOptions) (found fs.Done, updated int) {
|
|||||||
|
|
||||||
if updated > 0 {
|
if updated > 0 {
|
||||||
event.Publish("index.updating", event.Data{
|
event.Publish("index.updating", event.Data{
|
||||||
|
"uid": o.UID,
|
||||||
"step": "faces",
|
"step": "faces",
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -302,6 +304,7 @@ func (ind *Index) Start(o IndexOptions) (found fs.Done, updated int) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
event.Publish("index.updating", event.Data{
|
event.Publish("index.updating", event.Data{
|
||||||
|
"uid": o.UID,
|
||||||
"step": "counts",
|
"step": "counts",
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -76,6 +76,8 @@ func (ind *Index) UserMediaFile(m *MediaFile, o IndexOptions, originalName, phot
|
|||||||
photoExists := false
|
photoExists := false
|
||||||
|
|
||||||
event.Publish("index.indexing", event.Data{
|
event.Publish("index.indexing", event.Data{
|
||||||
|
"uid": o.UID,
|
||||||
|
"action": o.Action,
|
||||||
"fileHash": fileHash,
|
"fileHash": fileHash,
|
||||||
"fileSize": fileSize,
|
"fileSize": fileSize,
|
||||||
"fileName": fileName,
|
"fileName": fileName,
|
||||||
|
|||||||
@@ -1,7 +1,11 @@
|
|||||||
package photoprism
|
package photoprism
|
||||||
|
|
||||||
|
import "github.com/photoprism/photoprism/internal/entity"
|
||||||
|
|
||||||
// IndexOptions represents file indexing options.
|
// IndexOptions represents file indexing options.
|
||||||
type IndexOptions struct {
|
type IndexOptions struct {
|
||||||
|
UID string
|
||||||
|
Action string
|
||||||
Path string
|
Path string
|
||||||
Rescan bool
|
Rescan bool
|
||||||
Convert bool
|
Convert bool
|
||||||
@@ -15,6 +19,8 @@ type IndexOptions struct {
|
|||||||
// NewIndexOptions returns new index options instance.
|
// NewIndexOptions returns new index options instance.
|
||||||
func NewIndexOptions(path string, rescan, convert, stack, facesOnly, skipArchived bool) IndexOptions {
|
func NewIndexOptions(path string, rescan, convert, stack, facesOnly, skipArchived bool) IndexOptions {
|
||||||
result := IndexOptions{
|
result := IndexOptions{
|
||||||
|
UID: entity.Admin.UID(),
|
||||||
|
Action: ActionIndex,
|
||||||
Path: path,
|
Path: path,
|
||||||
Rescan: rescan,
|
Rescan: rescan,
|
||||||
Convert: convert,
|
Convert: convert,
|
||||||
@@ -33,6 +39,15 @@ func (o *IndexOptions) SkipUnchanged() bool {
|
|||||||
return !o.Rescan
|
return !o.Rescan
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SetUser sets the user who performs the index operation.
|
||||||
|
func (o *IndexOptions) SetUser(user *entity.User) *IndexOptions {
|
||||||
|
if o != nil && user != nil {
|
||||||
|
o.UID = user.UID()
|
||||||
|
}
|
||||||
|
|
||||||
|
return o
|
||||||
|
}
|
||||||
|
|
||||||
// IndexOptionsAll returns new index options with all options set to true.
|
// IndexOptionsAll returns new index options with all options set to true.
|
||||||
func IndexOptionsAll() IndexOptions {
|
func IndexOptionsAll() IndexOptions {
|
||||||
return NewIndexOptions("/", true, true, true, false, true)
|
return NewIndexOptions("/", true, true, true, false, true)
|
||||||
|
|||||||
Reference in New Issue
Block a user