mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 00:34:13 +01:00
Log4j: Sanitize user input in logs like filenames and album titles #1814
This commit is contained in:
@@ -35,7 +35,7 @@ func SaveAlbumAsYaml(a entity.Album) {
|
||||
if err := a.SaveAsYaml(fileName); err != nil {
|
||||
log.Errorf("album: %s (update yaml)", err)
|
||||
} else {
|
||||
log.Debugf("album: updated yaml file %s", txt.Quote(filepath.Base(fileName)))
|
||||
log.Debugf("album: updated yaml file %s", txt.LogParam(filepath.Base(fileName)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -85,10 +85,8 @@ func CreateAlbum(router *gin.RouterGroup) {
|
||||
a := entity.NewAlbum(f.AlbumTitle, entity.AlbumDefault)
|
||||
a.AlbumFavorite = f.AlbumFavorite
|
||||
|
||||
log.Debugf("album: creating %+v %+v", f, a)
|
||||
|
||||
if res := entity.Db().Create(a); res.Error != nil {
|
||||
AbortAlreadyExists(c, txt.Quote(a.AlbumTitle))
|
||||
AbortAlreadyExists(c, txt.LogParam(a.AlbumTitle))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -198,7 +196,7 @@ func DeleteAlbum(router *gin.RouterGroup) {
|
||||
|
||||
SaveAlbumAsYaml(a)
|
||||
|
||||
event.SuccessMsg(i18n.MsgAlbumDeleted, txt.Quote(a.AlbumTitle))
|
||||
event.SuccessMsg(i18n.MsgAlbumDeleted, txt.LogParam(a.AlbumTitle))
|
||||
|
||||
c.JSON(http.StatusOK, a)
|
||||
})
|
||||
@@ -327,7 +325,7 @@ func CloneAlbums(router *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
if len(added) > 0 {
|
||||
event.SuccessMsg(i18n.MsgSelectionAddedTo, txt.Quote(a.Title()))
|
||||
event.SuccessMsg(i18n.MsgSelectionAddedTo, txt.LogParam(a.Title()))
|
||||
|
||||
PublishAlbumEvent(EntityUpdated, a.AlbumUID, c)
|
||||
|
||||
@@ -377,9 +375,9 @@ func AddPhotosToAlbum(router *gin.RouterGroup) {
|
||||
|
||||
if len(added) > 0 {
|
||||
if len(added) == 1 {
|
||||
event.SuccessMsg(i18n.MsgEntryAddedTo, txt.Quote(a.Title()))
|
||||
event.SuccessMsg(i18n.MsgEntryAddedTo, txt.LogParam(a.Title()))
|
||||
} else {
|
||||
event.SuccessMsg(i18n.MsgEntriesAddedTo, len(added), txt.Quote(a.Title()))
|
||||
event.SuccessMsg(i18n.MsgEntriesAddedTo, len(added), txt.LogParam(a.Title()))
|
||||
}
|
||||
|
||||
RemoveFromAlbumCoverCache(a.AlbumUID)
|
||||
@@ -428,9 +426,9 @@ func RemovePhotosFromAlbum(router *gin.RouterGroup) {
|
||||
|
||||
if len(removed) > 0 {
|
||||
if len(removed) == 1 {
|
||||
event.SuccessMsg(i18n.MsgEntryRemovedFrom, txt.Quote(a.Title()))
|
||||
event.SuccessMsg(i18n.MsgEntryRemovedFrom, txt.LogParam(a.Title()))
|
||||
} else {
|
||||
event.SuccessMsg(i18n.MsgEntriesRemovedFrom, len(removed), txt.Quote(txt.Quote(a.Title())))
|
||||
event.SuccessMsg(i18n.MsgEntriesRemovedFrom, len(removed), txt.LogParam(txt.LogParam(a.Title())))
|
||||
}
|
||||
|
||||
RemoveFromAlbumCoverCache(a.AlbumUID)
|
||||
@@ -480,12 +478,12 @@ func DownloadAlbum(router *gin.RouterGroup) {
|
||||
|
||||
for _, file := range files {
|
||||
if file.FileHash == "" {
|
||||
log.Warnf("download: empty file hash, skipped %s", txt.Quote(file.FileName))
|
||||
log.Warnf("download: empty file hash, skipped %s", txt.LogParam(file.FileName))
|
||||
continue
|
||||
}
|
||||
|
||||
if file.FileSidecar {
|
||||
log.Debugf("download: skipped sidecar %s", txt.Quote(file.FileName))
|
||||
log.Debugf("download: skipped sidecar %s", txt.LogParam(file.FileName))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -505,12 +503,12 @@ func DownloadAlbum(router *gin.RouterGroup) {
|
||||
Abort(c, http.StatusInternalServerError, i18n.ErrZipFailed)
|
||||
return
|
||||
}
|
||||
log.Infof("download: added %s as %s", txt.Quote(file.FileName), txt.Quote(alias))
|
||||
log.Infof("download: added %s as %s", txt.LogParam(file.FileName), txt.LogParam(alias))
|
||||
} else {
|
||||
log.Errorf("download: failed finding %s", txt.Quote(file.FileName))
|
||||
log.Errorf("download: failed finding %s", txt.LogParam(file.FileName))
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("download: created %s [%s]", txt.Quote(zipFileName), time.Since(start))
|
||||
log.Infof("download: created %s [%s]", txt.LogParam(zipFileName), time.Since(start))
|
||||
})
|
||||
}
|
||||
|
||||
@@ -74,7 +74,7 @@ func Error(c *gin.Context, code int, err error, id i18n.Message, params ...inter
|
||||
|
||||
if err != nil {
|
||||
resp.Details = err.Error()
|
||||
log.Errorf("api: error %s with code %d in %s (%s)", txt.Quote(err.Error()), code, c.FullPath(), resp.String())
|
||||
log.Errorf("api: error %s with code %d in %s (%s)", txt.LogParam(err.Error()), code, c.FullPath(), resp.String())
|
||||
}
|
||||
|
||||
c.AbortWithStatusJSON(code, resp)
|
||||
|
||||
@@ -88,7 +88,7 @@ func AlbumCover(router *gin.RouterGroup) {
|
||||
c.Data(http.StatusOK, "image/svg+xml", albumIconSvg)
|
||||
|
||||
// Set missing flag so that the file doesn't show up in search results anymore.
|
||||
log.Warnf("%s: %s is missing", albumCover, txt.Quote(f.FileName))
|
||||
log.Warnf("%s: %s is missing", albumCover, txt.LogParam(f.FileName))
|
||||
logError(albumCover, f.Update("FileMissing", true))
|
||||
return
|
||||
}
|
||||
@@ -196,7 +196,7 @@ func LabelCover(router *gin.RouterGroup) {
|
||||
fileName := photoprism.FileName(f.FileRoot, f.FileName)
|
||||
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("%s: file %s is missing", labelCover, txt.Quote(f.FileName))
|
||||
log.Errorf("%s: file %s is missing", labelCover, txt.LogParam(f.FileName))
|
||||
c.Data(http.StatusOK, "image/svg+xml", labelIconSvg)
|
||||
|
||||
// Set missing flag so that the file doesn't show up in search results anymore.
|
||||
|
||||
@@ -56,7 +56,7 @@ func GetDownload(router *gin.RouterGroup) {
|
||||
fileName := photoprism.FileName(f.FileRoot, f.FileName)
|
||||
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("download: file %s is missing", txt.Quote(f.FileName))
|
||||
log.Errorf("download: file %s is missing", txt.LogParam(f.FileName))
|
||||
c.Data(404, "image/svg+xml", brokenIconSvg)
|
||||
|
||||
// Set missing flag so that the file doesn't show up in search results anymore.
|
||||
|
||||
@@ -58,17 +58,17 @@ func DeleteFile(router *gin.RouterGroup) {
|
||||
mediaFile, err := photoprism.NewMediaFile(fileName)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("photo: %s (delete %s)", err, txt.Quote(baseName))
|
||||
log.Errorf("photo: %s (delete %s)", err, txt.LogParam(baseName))
|
||||
AbortEntityNotFound(c)
|
||||
return
|
||||
}
|
||||
|
||||
if err := mediaFile.Remove(); err != nil {
|
||||
log.Errorf("photo: %s (delete %s from folder)", err, txt.Quote(baseName))
|
||||
log.Errorf("photo: %s (delete %s from folder)", err, txt.LogParam(baseName))
|
||||
}
|
||||
|
||||
if err := file.Delete(true); err != nil {
|
||||
log.Errorf("photo: %s (delete %s from index)", err, txt.Quote(baseName))
|
||||
log.Errorf("photo: %s (delete %s from index)", err, txt.LogParam(baseName))
|
||||
AbortDeleteFailed(c)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ func FolderCover(router *gin.RouterGroup) {
|
||||
c.Data(http.StatusOK, "image/svg+xml", folderIconSvg)
|
||||
|
||||
// Set missing flag so that the file doesn't show up in search results anymore.
|
||||
log.Warnf("%s: %s is missing", folderCover, txt.Quote(f.FileName))
|
||||
log.Warnf("%s: %s is missing", folderCover, txt.LogParam(f.FileName))
|
||||
logError(folderCover, f.Update("FileMissing", true))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -69,10 +69,10 @@ func StartImport(router *gin.RouterGroup) {
|
||||
var opt photoprism.ImportOptions
|
||||
|
||||
if f.Move {
|
||||
event.InfoMsg(i18n.MsgMovingFilesFrom, txt.Quote(filepath.Base(path)))
|
||||
event.InfoMsg(i18n.MsgMovingFilesFrom, txt.LogParam(filepath.Base(path)))
|
||||
opt = photoprism.ImportOptionsMove(path)
|
||||
} else {
|
||||
event.InfoMsg(i18n.MsgCopyingFilesFrom, txt.Quote(filepath.Base(path)))
|
||||
event.InfoMsg(i18n.MsgCopyingFilesFrom, txt.LogParam(filepath.Base(path)))
|
||||
opt = photoprism.ImportOptionsCopy(path)
|
||||
}
|
||||
|
||||
@@ -85,9 +85,9 @@ func StartImport(router *gin.RouterGroup) {
|
||||
|
||||
if subPath != "" && path != conf.ImportPath() && fs.IsEmpty(path) {
|
||||
if err := os.Remove(path); err != nil {
|
||||
log.Errorf("import: failed deleting empty folder %s: %s", txt.Quote(path), err)
|
||||
log.Errorf("import: failed deleting empty folder %s: %s", txt.LogParam(path), err)
|
||||
} else {
|
||||
log.Infof("import: deleted empty folder %s", txt.Quote(path))
|
||||
log.Infof("import: deleted empty folder %s", txt.LogParam(path))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ func StartIndexing(router *gin.RouterGroup) {
|
||||
}
|
||||
|
||||
if len(indOpt.Path) > 1 {
|
||||
event.InfoMsg(i18n.MsgIndexingFiles, txt.Quote(indOpt.Path))
|
||||
event.InfoMsg(i18n.MsgIndexingFiles, txt.LogParam(indOpt.Path))
|
||||
} else {
|
||||
event.InfoMsg(i18n.MsgIndexingOriginals)
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ func SavePhotoAsYaml(p entity.Photo) {
|
||||
if err := p.SaveAsYaml(fileName); err != nil {
|
||||
log.Errorf("photo: %s (update yaml)", err)
|
||||
} else {
|
||||
log.Debugf("photo: updated yaml file %s", txt.Quote(filepath.Base(fileName)))
|
||||
log.Debugf("photo: updated yaml file %s", txt.LogParam(filepath.Base(fileName)))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -145,7 +145,7 @@ func GetPhotoDownload(router *gin.RouterGroup) {
|
||||
fileName := photoprism.FileName(f.FileRoot, f.FileName)
|
||||
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("photo: file %s is missing", txt.Quote(f.FileName))
|
||||
log.Errorf("photo: file %s is missing", txt.LogParam(f.FileName))
|
||||
c.Data(http.StatusNotFound, "image/svg+xml", photoIconSvg)
|
||||
|
||||
// Set missing flag so that the file doesn't show up in search results anymore.
|
||||
|
||||
@@ -154,17 +154,17 @@ func GetThumb(router *gin.RouterGroup) {
|
||||
fileName := photoprism.FileName(f.FileRoot, f.FileName)
|
||||
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("%s: file %s is missing", logPrefix, txt.Quote(f.FileName))
|
||||
log.Errorf("%s: file %s is missing", logPrefix, txt.LogParam(f.FileName))
|
||||
c.Data(http.StatusOK, "image/svg+xml", brokenIconSvg)
|
||||
|
||||
// Set missing flag so that the file doesn't show up in search results anymore.
|
||||
logError(logPrefix, f.Update("FileMissing", true))
|
||||
|
||||
if f.AllFilesMissing() {
|
||||
log.Infof("%s: deleting photo, all files missing for %s", logPrefix, txt.Quote(f.FileName))
|
||||
log.Infof("%s: deleting photo, all files missing for %s", logPrefix, txt.LogParam(f.FileName))
|
||||
|
||||
if _, err := f.RelatedPhoto().Delete(false); err != nil {
|
||||
log.Errorf("%s: %s while deleting %s", logPrefix, err, txt.Quote(f.FileName))
|
||||
log.Errorf("%s: %s while deleting %s", logPrefix, err, txt.LogParam(f.FileName))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -60,7 +60,7 @@ func PhotoUnstack(router *gin.RouterGroup) {
|
||||
unstackFile, err := photoprism.NewMediaFile(fileName)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("photo: %s (unstack %s)", err, txt.Quote(baseName))
|
||||
log.Errorf("photo: %s (unstack %s)", err, txt.LogParam(baseName))
|
||||
AbortEntityNotFound(c)
|
||||
return
|
||||
}
|
||||
@@ -69,7 +69,7 @@ func PhotoUnstack(router *gin.RouterGroup) {
|
||||
stackPrimary, err := stackPhoto.PrimaryFile()
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("photo: can't find primary file for %s (unstack)", txt.Quote(baseName))
|
||||
log.Errorf("photo: can't find primary file for %s (unstack)", txt.LogParam(baseName))
|
||||
AbortUnexpected(c)
|
||||
return
|
||||
}
|
||||
@@ -77,15 +77,15 @@ func PhotoUnstack(router *gin.RouterGroup) {
|
||||
related, err := unstackFile.RelatedFiles(false)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("photo: %s (unstack %s)", err, txt.Quote(baseName))
|
||||
log.Errorf("photo: %s (unstack %s)", err, txt.LogParam(baseName))
|
||||
AbortEntityNotFound(c)
|
||||
return
|
||||
} else if related.Len() == 0 {
|
||||
log.Errorf("photo: found no files for %s (unstack)", txt.Quote(baseName))
|
||||
log.Errorf("photo: found no files for %s (unstack)", txt.LogParam(baseName))
|
||||
AbortEntityNotFound(c)
|
||||
return
|
||||
} else if related.Main == nil {
|
||||
log.Errorf("photo: found no main file for %s (unstack)", txt.Quote(baseName))
|
||||
log.Errorf("photo: found no main file for %s (unstack)", txt.LogParam(baseName))
|
||||
AbortEntityNotFound(c)
|
||||
return
|
||||
}
|
||||
@@ -95,7 +95,7 @@ func PhotoUnstack(router *gin.RouterGroup) {
|
||||
|
||||
if unstackFile.BasePrefix(false) == stackPhoto.PhotoName {
|
||||
if conf.ReadOnly() {
|
||||
log.Errorf("photo: can't rename files in read only mode (unstack %s)", txt.Quote(baseName))
|
||||
log.Errorf("photo: can't rename files in read only mode (unstack %s)", txt.LogParam(baseName))
|
||||
AbortFeatureDisabled(c)
|
||||
return
|
||||
}
|
||||
@@ -103,7 +103,7 @@ func PhotoUnstack(router *gin.RouterGroup) {
|
||||
destName := fmt.Sprintf("%s.%s%s", unstackFile.AbsPrefix(false), unstackFile.Checksum(), unstackFile.Extension())
|
||||
|
||||
if err := unstackFile.Move(destName); err != nil {
|
||||
log.Errorf("photo: can't rename %s to %s (unstack)", txt.Quote(unstackFile.BaseName()), txt.Quote(filepath.Base(destName)))
|
||||
log.Errorf("photo: can't rename %s to %s (unstack)", txt.LogParam(unstackFile.BaseName()), txt.LogParam(filepath.Base(destName)))
|
||||
AbortUnexpected(c)
|
||||
return
|
||||
}
|
||||
@@ -119,7 +119,7 @@ func PhotoUnstack(router *gin.RouterGroup) {
|
||||
newPhoto.PhotoName = unstackFile.BasePrefix(false)
|
||||
|
||||
if err := newPhoto.Create(); err != nil {
|
||||
log.Errorf("photo: %s (unstack %s)", err.Error(), txt.Quote(baseName))
|
||||
log.Errorf("photo: %s (unstack %s)", err.Error(), txt.LogParam(baseName))
|
||||
AbortSaveFailed(c)
|
||||
return
|
||||
}
|
||||
@@ -139,17 +139,17 @@ func PhotoUnstack(router *gin.RouterGroup) {
|
||||
newPhoto.ID, newPhoto.PhotoUID, r.RootRelName(),
|
||||
relName, relRoot).Error; err != nil {
|
||||
// Handle error...
|
||||
log.Errorf("photo: %s (unstack %s)", err.Error(), txt.Quote(r.BaseName()))
|
||||
log.Errorf("photo: %s (unstack %s)", err.Error(), txt.LogParam(r.BaseName()))
|
||||
|
||||
// Remove new photo from index.
|
||||
if _, err := newPhoto.Delete(true); err != nil {
|
||||
log.Errorf("photo: %s (unstack %s)", err.Error(), txt.Quote(r.BaseName()))
|
||||
log.Errorf("photo: %s (unstack %s)", err.Error(), txt.LogParam(r.BaseName()))
|
||||
}
|
||||
|
||||
// Revert file rename.
|
||||
if unstackSingle {
|
||||
if err := r.Move(photoprism.FileName(relRoot, relName)); err != nil {
|
||||
log.Errorf("photo: %s (unstack %s)", err.Error(), txt.Quote(r.BaseName()))
|
||||
log.Errorf("photo: %s (unstack %s)", err.Error(), txt.LogParam(r.BaseName()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -162,21 +162,21 @@ func PhotoUnstack(router *gin.RouterGroup) {
|
||||
|
||||
// Index unstacked files.
|
||||
if res := ind.FileName(unstackFile.FileName(), photoprism.IndexOptionsSingle()); res.Failed() {
|
||||
log.Errorf("photo: %s (unstack %s)", res.Err, txt.Quote(baseName))
|
||||
log.Errorf("photo: %s (unstack %s)", res.Err, txt.LogParam(baseName))
|
||||
AbortSaveFailed(c)
|
||||
return
|
||||
}
|
||||
|
||||
// Reset type for existing photo stack to image.
|
||||
if err := stackPhoto.Update("PhotoType", entity.TypeImage); err != nil {
|
||||
log.Errorf("photo: %s (unstack %s)", err, txt.Quote(baseName))
|
||||
log.Errorf("photo: %s (unstack %s)", err, txt.LogParam(baseName))
|
||||
AbortUnexpected(c)
|
||||
return
|
||||
}
|
||||
|
||||
// Re-index existing photo stack.
|
||||
if res := ind.FileName(photoprism.FileName(stackPrimary.FileRoot, stackPrimary.FileName), photoprism.IndexOptionsSingle()); res.Failed() {
|
||||
log.Errorf("photo: %s (unstack %s)", res.Err, txt.Quote(baseName))
|
||||
log.Errorf("photo: %s (unstack %s)", res.Err, txt.LogParam(baseName))
|
||||
AbortSaveFailed(c)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -95,7 +95,7 @@ func SharePreview(router *gin.RouterGroup) {
|
||||
fileName := photoprism.FileName(f.FileRoot, f.FileName)
|
||||
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("share: file %s is missing (preview)", txt.Quote(f.FileName))
|
||||
log.Errorf("share: file %s is missing (preview)", txt.LogParam(f.FileName))
|
||||
c.Redirect(http.StatusTemporaryRedirect, conf.SitePreview())
|
||||
return
|
||||
}
|
||||
@@ -125,7 +125,7 @@ func SharePreview(router *gin.RouterGroup) {
|
||||
fileName := photoprism.FileName(f.FileRoot, f.FileName)
|
||||
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Errorf("share: file %s is missing (preview)", txt.Quote(f.FileName))
|
||||
log.Errorf("share: file %s is missing (preview)", txt.LogParam(f.FileName))
|
||||
c.Redirect(http.StatusTemporaryRedirect, conf.SitePreview())
|
||||
return
|
||||
}
|
||||
|
||||
@@ -52,7 +52,7 @@ func Upload(router *gin.RouterGroup) {
|
||||
p := path.Join(conf.ImportPath(), "upload", subPath)
|
||||
|
||||
if err := os.MkdirAll(p, os.ModePerm); err != nil {
|
||||
log.Errorf("upload: failed creating folder %s", txt.Quote(subPath))
|
||||
log.Errorf("upload: failed creating folder %s", txt.LogParam(subPath))
|
||||
AbortBadRequest(c)
|
||||
return
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func Upload(router *gin.RouterGroup) {
|
||||
for _, file := range files {
|
||||
filename := path.Join(p, filepath.Base(file.Filename))
|
||||
|
||||
log.Debugf("upload: saving file %s", txt.Quote(file.Filename))
|
||||
log.Debugf("upload: saving file %s", txt.LogParam(file.Filename))
|
||||
|
||||
if err := c.SaveUploadedFile(file, filename); err != nil {
|
||||
log.Errorf("upload: failed saving file %s", filepath.Base(file.Filename))
|
||||
@@ -88,7 +88,7 @@ func Upload(router *gin.RouterGroup) {
|
||||
continue
|
||||
}
|
||||
|
||||
log.Infof("nsfw: %s might be offensive", txt.Quote(filename))
|
||||
log.Infof("nsfw: %s might be offensive", txt.LogParam(filename))
|
||||
|
||||
containsNSFW = true
|
||||
}
|
||||
@@ -96,7 +96,7 @@ func Upload(router *gin.RouterGroup) {
|
||||
if containsNSFW {
|
||||
for _, filename := range uploads {
|
||||
if err := os.Remove(filename); err != nil {
|
||||
log.Errorf("nsfw: could not delete %s", txt.Quote(filename))
|
||||
log.Errorf("nsfw: could not delete %s", txt.LogParam(filename))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ func GetVideo(router *gin.RouterGroup) {
|
||||
videoType, ok := video.Types[typeName]
|
||||
|
||||
if !ok {
|
||||
log.Errorf("video: invalid type %s", txt.Quote(typeName))
|
||||
log.Errorf("video: invalid type %s", txt.LogParam(typeName))
|
||||
c.Data(http.StatusOK, "image/svg+xml", videoIconSvg)
|
||||
return
|
||||
}
|
||||
@@ -62,7 +62,7 @@ func GetVideo(router *gin.RouterGroup) {
|
||||
fileName := photoprism.FileName(f.FileRoot, f.FileName)
|
||||
|
||||
if mf, err := photoprism.NewMediaFile(fileName); err != nil {
|
||||
log.Errorf("video: file %s is missing", txt.Quote(f.FileName))
|
||||
log.Errorf("video: file %s is missing", txt.LogParam(f.FileName))
|
||||
c.Data(http.StatusOK, "image/svg+xml", videoIconSvg)
|
||||
|
||||
// Set missing flag so that the file doesn't show up in search results anymore.
|
||||
@@ -73,7 +73,7 @@ func GetVideo(router *gin.RouterGroup) {
|
||||
conv := service.Convert()
|
||||
|
||||
if avcFile, err := conv.ToAvc(mf, service.Config().FFmpegEncoder()); err != nil {
|
||||
log.Errorf("video: transcoding %s failed", txt.Quote(f.FileName))
|
||||
log.Errorf("video: transcoding %s failed", txt.LogParam(f.FileName))
|
||||
c.Data(http.StatusOK, "image/svg+xml", videoIconSvg)
|
||||
return
|
||||
} else {
|
||||
|
||||
@@ -93,12 +93,12 @@ func CreateZip(router *gin.RouterGroup) {
|
||||
|
||||
for _, file := range files {
|
||||
if file.FileHash == "" {
|
||||
log.Warnf("download: empty file hash, skipped %s", txt.Quote(file.FileName))
|
||||
log.Warnf("download: empty file hash, skipped %s", txt.LogParam(file.FileName))
|
||||
continue
|
||||
}
|
||||
|
||||
if file.FileSidecar {
|
||||
log.Debugf("download: skipped sidecar %s", txt.Quote(file.FileName))
|
||||
log.Debugf("download: skipped sidecar %s", txt.LogParam(file.FileName))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -117,16 +117,16 @@ func CreateZip(router *gin.RouterGroup) {
|
||||
Error(c, http.StatusInternalServerError, err, i18n.ErrZipFailed)
|
||||
return
|
||||
}
|
||||
log.Infof("download: added %s as %s", txt.Quote(file.FileName), txt.Quote(alias))
|
||||
log.Infof("download: added %s as %s", txt.LogParam(file.FileName), txt.LogParam(alias))
|
||||
} else {
|
||||
log.Warnf("download: file %s is missing", txt.Quote(file.FileName))
|
||||
log.Warnf("download: file %s is missing", txt.LogParam(file.FileName))
|
||||
logError("download", file.Update("FileMissing", true))
|
||||
}
|
||||
}
|
||||
|
||||
elapsed := int(time.Since(start).Seconds())
|
||||
|
||||
log.Infof("download: created %s [%s]", txt.Quote(zipBaseName), time.Since(start))
|
||||
log.Infof("download: created %s [%s]", txt.LogParam(zipBaseName), time.Since(start))
|
||||
|
||||
c.JSON(http.StatusOK, gin.H{"code": http.StatusOK, "message": i18n.Msg(i18n.MsgZipCreatedIn, elapsed), "filename": zipBaseName})
|
||||
})
|
||||
@@ -154,7 +154,7 @@ func DownloadZip(router *gin.RouterGroup) {
|
||||
c.FileAttachment(zipFileName, zipBaseName)
|
||||
|
||||
if err := os.Remove(zipFileName); err != nil {
|
||||
log.Errorf("download: failed removing %s (%s)", txt.Quote(zipFileName), err.Error())
|
||||
log.Errorf("download: failed removing %s (%s)", txt.LogParam(zipFileName), err.Error())
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
@@ -66,7 +66,7 @@ func Import() error {
|
||||
|
||||
api.RemoveFromFolderCache(entity.RootImport)
|
||||
|
||||
event.InfoMsg(i18n.MsgCopyingFilesFrom, txt.Quote(filepath.Base(path)))
|
||||
event.InfoMsg(i18n.MsgCopyingFilesFrom, txt.LogParam(filepath.Base(path)))
|
||||
|
||||
var opt photoprism.ImportOptions
|
||||
|
||||
|
||||
@@ -34,7 +34,7 @@ func main() {
|
||||
fileName := "rules.yml"
|
||||
|
||||
if !fs.FileExists(fileName) {
|
||||
log.Panicf("classify: found no label rules in %s", txt.Quote(filepath.Base(fileName)))
|
||||
log.Panicf("classify: found no label rules in %s", txt.LogParam(filepath.Base(fileName)))
|
||||
}
|
||||
|
||||
yamlConfig, err := os.ReadFile(fileName)
|
||||
|
||||
@@ -148,7 +148,7 @@ func (t *TensorFlow) loadModel() error {
|
||||
|
||||
modelPath := path.Join(t.modelsPath, t.modelName)
|
||||
|
||||
log.Infof("classify: loading %s", txt.Quote(filepath.Base(modelPath)))
|
||||
log.Infof("classify: loading %s", txt.LogParam(filepath.Base(modelPath)))
|
||||
|
||||
// Load model
|
||||
model, err := tf.LoadSavedModel(modelPath, t.modelTags, nil)
|
||||
|
||||
@@ -113,7 +113,7 @@ func backupAction(ctx *cli.Context) error {
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("backing up database to %s", txt.Quote(indexFileName))
|
||||
log.Infof("backing up database to %s", txt.LogParam(indexFileName))
|
||||
}
|
||||
|
||||
var cmd *exec.Cmd
|
||||
@@ -175,7 +175,7 @@ func backupAction(ctx *cli.Context) error {
|
||||
albumsPath = conf.AlbumsPath()
|
||||
}
|
||||
|
||||
log.Infof("backing up albums to %s", txt.Quote(albumsPath))
|
||||
log.Infof("backing up albums to %s", txt.LogParam(albumsPath))
|
||||
|
||||
if count, err := photoprism.BackupAlbums(albumsPath, true); err != nil {
|
||||
return err
|
||||
|
||||
@@ -48,7 +48,7 @@ func convertAction(ctx *cli.Context) error {
|
||||
convertPath = filepath.Join(convertPath, subPath)
|
||||
}
|
||||
|
||||
log.Infof("converting originals in %s", txt.Quote(convertPath))
|
||||
log.Infof("converting originals in %s", txt.LogParam(convertPath))
|
||||
|
||||
w := service.Convert()
|
||||
|
||||
|
||||
@@ -239,9 +239,9 @@ func facesIndexAction(ctx *cli.Context) error {
|
||||
subPath := strings.TrimSpace(ctx.Args().First())
|
||||
|
||||
if subPath == "" {
|
||||
log.Infof("finding faces in %s", txt.Quote(conf.OriginalsPath()))
|
||||
log.Infof("finding faces in %s", txt.LogParam(conf.OriginalsPath()))
|
||||
} else {
|
||||
log.Infof("finding faces in %s", txt.Quote(filepath.Join(conf.OriginalsPath(), subPath)))
|
||||
log.Infof("finding faces in %s", txt.LogParam(filepath.Join(conf.OriginalsPath(), subPath)))
|
||||
}
|
||||
|
||||
if conf.ReadOnly() {
|
||||
|
||||
@@ -57,9 +57,9 @@ func indexAction(ctx *cli.Context) error {
|
||||
subPath := strings.TrimSpace(ctx.Args().First())
|
||||
|
||||
if subPath == "" {
|
||||
log.Infof("indexing originals in %s", txt.Quote(conf.OriginalsPath()))
|
||||
log.Infof("indexing originals in %s", txt.LogParam(conf.OriginalsPath()))
|
||||
} else {
|
||||
log.Infof("indexing originals in %s", txt.Quote(filepath.Join(conf.OriginalsPath(), subPath)))
|
||||
log.Infof("indexing originals in %s", txt.LogParam(filepath.Join(conf.OriginalsPath(), subPath)))
|
||||
}
|
||||
|
||||
if conf.ReadOnly() {
|
||||
|
||||
@@ -39,7 +39,7 @@ func passwdAction(ctx *cli.Context) error {
|
||||
|
||||
user := entity.Admin
|
||||
|
||||
log.Infof("please enter a new password for %s (at least 6 characters)\n", txt.Quote(user.Username()))
|
||||
log.Infof("please enter a new password for %s (at least 6 characters)\n", txt.LogParam(user.Username()))
|
||||
|
||||
newPassword := getPassword("New Password: ")
|
||||
|
||||
@@ -57,7 +57,7 @@ func passwdAction(ctx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("changed password for %s\n", txt.Quote(user.Username()))
|
||||
log.Infof("changed password for %s\n", txt.LogParam(user.Username()))
|
||||
|
||||
conf.Shutdown()
|
||||
|
||||
|
||||
@@ -56,9 +56,9 @@ func purgeAction(ctx *cli.Context) error {
|
||||
subPath := strings.TrimSpace(ctx.Args().First())
|
||||
|
||||
if subPath == "" {
|
||||
log.Infof("purge: removing missing files in %s", txt.Quote(filepath.Base(conf.OriginalsPath())))
|
||||
log.Infof("purge: removing missing files in %s", txt.LogParam(filepath.Base(conf.OriginalsPath())))
|
||||
} else {
|
||||
log.Infof("purge: removing missing files in %s", txt.Quote(fs.RelName(filepath.Join(conf.OriginalsPath(), subPath), filepath.Dir(conf.OriginalsPath()))))
|
||||
log.Infof("purge: removing missing files in %s", txt.LogParam(fs.RelName(filepath.Join(conf.OriginalsPath(), subPath), filepath.Dir(conf.OriginalsPath()))))
|
||||
}
|
||||
|
||||
if conf.ReadOnly() {
|
||||
|
||||
@@ -123,7 +123,7 @@ func restoreAction(ctx *cli.Context) error {
|
||||
log.Warnf("replacing existing index with %d photos", counts.Photos)
|
||||
}
|
||||
|
||||
log.Infof("restoring index from %s", txt.Quote(indexFileName))
|
||||
log.Infof("restoring index from %s", txt.LogParam(indexFileName))
|
||||
|
||||
sqlBackup, err := os.ReadFile(indexFileName)
|
||||
|
||||
@@ -199,9 +199,9 @@ func restoreAction(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
if !fs.PathExists(albumsPath) {
|
||||
log.Warnf("albums backup path %s not found", txt.Quote(albumsPath))
|
||||
log.Warnf("albums backup path %s not found", txt.LogParam(albumsPath))
|
||||
} else {
|
||||
log.Infof("restoring albums from %s", txt.Quote(albumsPath))
|
||||
log.Infof("restoring albums from %s", txt.LogParam(albumsPath))
|
||||
|
||||
if count, err := photoprism.RestoreAlbums(albumsPath, true); err != nil {
|
||||
return err
|
||||
|
||||
@@ -95,7 +95,7 @@ func startAction(ctx *cli.Context) error {
|
||||
|
||||
if child != nil {
|
||||
if !fs.Overwrite(conf.PIDFilename(), []byte(strconv.Itoa(child.Pid))) {
|
||||
log.Fatalf("failed writing process id to %s", txt.Quote(conf.PIDFilename()))
|
||||
log.Fatalf("failed writing process id to %s", txt.LogParam(conf.PIDFilename()))
|
||||
}
|
||||
|
||||
log.Infof("daemon started with process id %v\n", child.Pid)
|
||||
|
||||
@@ -22,7 +22,7 @@ var StopCommand = cli.Command{
|
||||
func stopAction(ctx *cli.Context) error {
|
||||
conf := config.NewConfig(ctx)
|
||||
|
||||
log.Infof("looking for pid in %s", txt.Quote(conf.PIDFilename()))
|
||||
log.Infof("looking for pid in %s", txt.LogParam(conf.PIDFilename()))
|
||||
|
||||
dcxt := new(daemon.Context)
|
||||
dcxt.PidFileName = conf.PIDFilename()
|
||||
|
||||
@@ -34,7 +34,7 @@ func thumbsAction(ctx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Infof("creating thumbnails in %s", txt.Quote(conf.ThumbPath()))
|
||||
log.Infof("creating thumbnails in %s", txt.LogParam(conf.ThumbPath()))
|
||||
|
||||
rs := service.Resample()
|
||||
|
||||
|
||||
@@ -183,7 +183,7 @@ func usersDeleteAction(ctx *cli.Context) error {
|
||||
}
|
||||
|
||||
actionPrompt := promptui.Prompt{
|
||||
Label: fmt.Sprintf("Delete %s?", txt.Quote(userName)),
|
||||
Label: fmt.Sprintf("Delete %s?", txt.LogParam(userName)),
|
||||
IsConfirm: true,
|
||||
}
|
||||
|
||||
@@ -193,7 +193,7 @@ func usersDeleteAction(ctx *cli.Context) error {
|
||||
} else if err := m.Delete(); err != nil {
|
||||
return err
|
||||
} else {
|
||||
log.Infof("%s deleted", txt.Quote(userName))
|
||||
log.Infof("%s deleted", txt.LogParam(userName))
|
||||
}
|
||||
} else {
|
||||
log.Infof("keeping user")
|
||||
@@ -242,7 +242,7 @@ func usersUpdateAction(ctx *cli.Context) error {
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
fmt.Printf("password successfully changed: %v\n", u.Username())
|
||||
fmt.Printf("password successfully changed: %s\n", txt.LogParam(u.Username()))
|
||||
}
|
||||
|
||||
if ctx.IsSet("fullname") {
|
||||
@@ -261,7 +261,7 @@ func usersUpdateAction(ctx *cli.Context) error {
|
||||
return err
|
||||
}
|
||||
|
||||
fmt.Printf("user successfully updated: %v\n", u.Username())
|
||||
fmt.Printf("user successfully updated: %s\n", txt.LogParam(u.Username()))
|
||||
|
||||
return nil
|
||||
})
|
||||
|
||||
@@ -124,7 +124,7 @@ func NewConfig(ctx *cli.Context) *Config {
|
||||
if err := c.options.Load(configFile); err != nil {
|
||||
log.Warnf("config: %s", err)
|
||||
} else {
|
||||
log.Debugf("config: options loaded from %s", txt.Quote(configFile))
|
||||
log.Debugf("config: options loaded from %s", txt.LogParam(configFile))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -192,7 +192,7 @@ func (c *Config) Init() error {
|
||||
}
|
||||
|
||||
if cpuName := cpuid.CPU.BrandName; cpuName != "" {
|
||||
log.Debugf("config: running on %s, %s memory detected", txt.Quote(cpuid.CPU.BrandName), humanize.Bytes(TotalMem))
|
||||
log.Debugf("config: running on %s, %s memory detected", txt.LogParam(cpuid.CPU.BrandName), humanize.Bytes(TotalMem))
|
||||
}
|
||||
|
||||
// Check memory requirements.
|
||||
|
||||
@@ -33,9 +33,9 @@ func findExecutable(configBin, defaultBin string) (result string) {
|
||||
func (c *Config) CreateDirectories() error {
|
||||
createError := func(path string, err error) (result error) {
|
||||
if fs.FileExists(path) {
|
||||
result = fmt.Errorf("%s is a file, not a folder: please check your configuration", txt.Quote(path))
|
||||
result = fmt.Errorf("%s is a file, not a folder: please check your configuration", txt.LogParam(path))
|
||||
} else {
|
||||
result = fmt.Errorf("can't create %s: please check configuration and permissions", txt.Quote(path))
|
||||
result = fmt.Errorf("can't create %s: please check configuration and permissions", txt.LogParam(path))
|
||||
}
|
||||
|
||||
log.Debug(err)
|
||||
|
||||
@@ -181,7 +181,7 @@ func (s Settings) StackMeta() bool {
|
||||
// Load user settings from file.
|
||||
func (s *Settings) Load(fileName string) error {
|
||||
if !fs.FileExists(fileName) {
|
||||
return fmt.Errorf("settings file not found: %s", txt.Quote(fileName))
|
||||
return fmt.Errorf("settings file not found: %s", txt.LogParam(fileName))
|
||||
}
|
||||
|
||||
yamlConfig, err := os.ReadFile(fileName)
|
||||
|
||||
@@ -28,7 +28,7 @@ func FromCache(hash, area string, size Size, thumbPath string) (fileName string,
|
||||
// FileName returns the crop file name based on cache path, size, and area.
|
||||
func FileName(hash, area string, width, height int, thumbPath string) (fileName string, err error) {
|
||||
if len(hash) < 4 {
|
||||
return "", fmt.Errorf("crop: invalid file hash %s", txt.Quote(hash))
|
||||
return "", fmt.Errorf("crop: invalid file hash %s", txt.LogParam(hash))
|
||||
}
|
||||
|
||||
if len(thumbPath) < 1 {
|
||||
|
||||
@@ -92,7 +92,7 @@ func ImageFromThumb(thumbName string, area Area, size Size, cache bool) (img ima
|
||||
// ThumbFileName returns the ideal thumb file name.
|
||||
func ThumbFileName(hash string, area Area, size Size, thumbPath string) (string, error) {
|
||||
if len(hash) < 4 {
|
||||
return "", fmt.Errorf("invalid file hash %s", txt.Quote(hash))
|
||||
return "", fmt.Errorf("invalid file hash %s", txt.LogParam(hash))
|
||||
}
|
||||
|
||||
if len(thumbPath) < 1 {
|
||||
|
||||
@@ -3,6 +3,8 @@ package entity
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
)
|
||||
|
||||
type Addresses []Address
|
||||
@@ -62,7 +64,7 @@ func FirstOrCreateAddress(m *Address) *Address {
|
||||
|
||||
// String returns an identifier that can be used in logs.
|
||||
func (m *Address) String() string {
|
||||
return fmt.Sprintf("%s, %s %s, %s", m.AddressLine1, m.AddressZip, m.AddressCity, m.AddressCountry)
|
||||
return txt.LogParam(fmt.Sprintf("%s, %s %s, %s", m.AddressLine1, m.AddressZip, m.AddressCity, m.AddressCountry))
|
||||
}
|
||||
|
||||
// Unknown returns true if the address is unknown.
|
||||
|
||||
@@ -38,7 +38,7 @@ func TestAddress_String(t *testing.T) {
|
||||
t.Run("success", func(t *testing.T) {
|
||||
address := Address{ID: 1234567, AddressLine1: "Line 1", AddressLine2: "Line 2", AddressCity: "Berlin", AddressCountry: "DE"}
|
||||
addressString := address.String()
|
||||
assert.Equal(t, "Line 1, Berlin, DE", addressString)
|
||||
assert.Equal(t, "'Line 1, Berlin, DE'", addressString)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -336,15 +336,15 @@ func (m *Album) BeforeCreate(scope *gorm.Scope) error {
|
||||
// String returns the id or name as string.
|
||||
func (m *Album) String() string {
|
||||
if m.AlbumSlug != "" {
|
||||
return m.AlbumSlug
|
||||
return txt.LogParam(m.AlbumSlug)
|
||||
}
|
||||
|
||||
if m.AlbumTitle != "" {
|
||||
return txt.Quote(m.AlbumTitle)
|
||||
return txt.LogParam(m.AlbumTitle)
|
||||
}
|
||||
|
||||
if m.AlbumUID != "" {
|
||||
return m.AlbumUID
|
||||
return txt.LogParam(m.AlbumUID)
|
||||
}
|
||||
|
||||
return "[unknown album]"
|
||||
|
||||
@@ -123,7 +123,7 @@ func FirstOrCreateCamera(m *Camera) *Camera {
|
||||
cameraCache.SetDefault(m.CameraSlug, &result)
|
||||
return &result
|
||||
} else {
|
||||
log.Errorf("camera: %s (create %s)", err.Error(), txt.Quote(m.String()))
|
||||
log.Errorf("camera: %s (create %s)", err.Error(), txt.LogParam(m.String()))
|
||||
}
|
||||
|
||||
return &UnknownCamera
|
||||
@@ -131,7 +131,7 @@ func FirstOrCreateCamera(m *Camera) *Camera {
|
||||
|
||||
// String returns an identifier that can be used in logs.
|
||||
func (m *Camera) String() string {
|
||||
return m.CameraName
|
||||
return txt.LogParam(m.CameraName)
|
||||
}
|
||||
|
||||
// Unknown returns true if the camera is not a known make or model.
|
||||
|
||||
@@ -119,7 +119,7 @@ func TestCamera_String(t *testing.T) {
|
||||
t.Run("model XXX make Nikon", func(t *testing.T) {
|
||||
camera := NewCamera("XXX", "Nikon")
|
||||
cameraString := camera.String()
|
||||
assert.Equal(t, "Nikon XXX", cameraString)
|
||||
assert.Equal(t, "'Nikon XXX'", cameraString)
|
||||
})
|
||||
t.Run("model XXX make Unknown", func(t *testing.T) {
|
||||
camera := NewCamera("XXX", "")
|
||||
|
||||
@@ -56,10 +56,10 @@ func (list Tables) WaitForMigration(db *gorm.DB) {
|
||||
for i := 0; i <= attempts; i++ {
|
||||
count := RowCount{}
|
||||
if err := db.Raw(fmt.Sprintf("SELECT COUNT(*) AS count FROM %s", name)).Scan(&count).Error; err == nil {
|
||||
log.Tracef("entity: %s migrated", txt.Quote(name))
|
||||
log.Tracef("entity: %s migrated", txt.LogParam(name))
|
||||
break
|
||||
} else {
|
||||
log.Debugf("entity: waiting for %s migration (%s)", txt.Quote(name), err.Error())
|
||||
log.Debugf("entity: waiting for %s migration (%s)", txt.LogParam(name), err.Error())
|
||||
}
|
||||
|
||||
if i == attempts {
|
||||
@@ -78,7 +78,7 @@ func (list Tables) Truncate(db *gorm.DB) {
|
||||
// log.Debugf("entity: removed all data from %s", name)
|
||||
break
|
||||
} else if err.Error() != "record not found" {
|
||||
log.Debugf("entity: %s in %s", err, txt.Quote(name))
|
||||
log.Debugf("entity: %s in %s", err, txt.LogParam(name))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -92,7 +92,7 @@ func (list Tables) Migrate(db *gorm.DB, runFailed bool) {
|
||||
time.Sleep(time.Second)
|
||||
|
||||
if err := db.AutoMigrate(entity).Error; err != nil {
|
||||
log.Errorf("entity: failed migrating %s", txt.Quote(name))
|
||||
log.Errorf("entity: failed migrating %s", txt.LogParam(name))
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -138,8 +138,8 @@ func TestNewDetails(t *testing.T) {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
t.Logf("PHOTO: %#v", p)
|
||||
t.Logf("DETAILS: %#v", d)
|
||||
// t.Logf("PHOTO: %#v", p)
|
||||
// t.Logf("DETAILS: %#v", d)
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ func PurgeDuplicate(fileName, fileRoot string) error {
|
||||
}
|
||||
|
||||
if err := UnscopedDb().Delete(Duplicate{}, "file_name = ? AND file_root = ?", fileName, fileRoot).Error; err != nil {
|
||||
log.Errorf("duplicate: %s in %s (purge)", err, txt.Quote(fileName))
|
||||
log.Errorf("duplicate: %s in %s (purge)", err, txt.LogParam(fileName))
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -101,7 +101,7 @@ func (m *Duplicate) Save() error {
|
||||
}
|
||||
|
||||
if err := UnscopedDb().Save(m).Error; err != nil {
|
||||
log.Errorf("duplicate: %s in %s (save)", err, txt.Quote(m.FileName))
|
||||
log.Errorf("duplicate: %s in %s (save)", err, txt.LogParam(m.FileName))
|
||||
return err
|
||||
}
|
||||
|
||||
|
||||
@@ -206,23 +206,23 @@ func (m File) Missing() bool {
|
||||
// DeletePermanently permanently removes a file from the index.
|
||||
func (m *File) DeletePermanently() error {
|
||||
if m.ID < 1 || m.FileUID == "" {
|
||||
return fmt.Errorf("invalid file id %d / uid %s", m.ID, txt.Quote(m.FileUID))
|
||||
return fmt.Errorf("invalid file id %d / uid %s", m.ID, txt.LogParam(m.FileUID))
|
||||
}
|
||||
|
||||
if err := UnscopedDb().Delete(Marker{}, "file_uid = ?", m.FileUID).Error; err != nil {
|
||||
log.Errorf("file %s: %s while removing markers", txt.Quote(m.FileUID), err)
|
||||
log.Errorf("file %s: %s while removing markers", txt.LogParam(m.FileUID), err)
|
||||
}
|
||||
|
||||
if err := UnscopedDb().Delete(FileShare{}, "file_id = ?", m.ID).Error; err != nil {
|
||||
log.Errorf("file %s: %s while removing share info", txt.Quote(m.FileUID), err)
|
||||
log.Errorf("file %s: %s while removing share info", txt.LogParam(m.FileUID), err)
|
||||
}
|
||||
|
||||
if err := UnscopedDb().Delete(FileSync{}, "file_id = ?", m.ID).Error; err != nil {
|
||||
log.Errorf("file %s: %s while removing remote sync info", txt.Quote(m.FileUID), err)
|
||||
log.Errorf("file %s: %s while removing remote sync info", txt.LogParam(m.FileUID), err)
|
||||
}
|
||||
|
||||
if err := m.ReplaceHash(""); err != nil {
|
||||
log.Errorf("file %s: %s while removing covers", txt.Quote(m.FileUID), err)
|
||||
log.Errorf("file %s: %s while removing covers", txt.LogParam(m.FileUID), err)
|
||||
}
|
||||
|
||||
return UnscopedDb().Delete(m).Error
|
||||
@@ -237,9 +237,9 @@ func (m *File) ReplaceHash(newHash string) error {
|
||||
|
||||
// Log values.
|
||||
if m.FileHash != "" && newHash == "" {
|
||||
log.Tracef("file %s: removing hash %s", txt.Quote(m.FileUID), txt.Quote(m.FileHash))
|
||||
log.Tracef("file %s: removing hash %s", txt.LogParam(m.FileUID), txt.LogParam(m.FileHash))
|
||||
} else if m.FileHash != "" && newHash != "" {
|
||||
log.Tracef("file %s: hash %s changed to %s", txt.Quote(m.FileUID), txt.Quote(m.FileHash), txt.Quote(newHash))
|
||||
log.Tracef("file %s: hash %s changed to %s", txt.LogParam(m.FileUID), txt.LogParam(m.FileHash), txt.LogParam(newHash))
|
||||
// Reset error when hash changes.
|
||||
m.FileError = ""
|
||||
}
|
||||
@@ -275,7 +275,7 @@ func (m *File) ReplaceHash(newHash string) error {
|
||||
// Delete deletes the entity from the database.
|
||||
func (m *File) Delete(permanently bool) error {
|
||||
if m.ID < 1 || m.FileUID == "" {
|
||||
return fmt.Errorf("invalid file id %d / uid %s", m.ID, txt.Quote(m.FileUID))
|
||||
return fmt.Errorf("invalid file id %d / uid %s", m.ID, txt.LogParam(m.FileUID))
|
||||
}
|
||||
|
||||
if permanently {
|
||||
@@ -326,7 +326,7 @@ func (m *File) Create() error {
|
||||
}
|
||||
|
||||
if _, err := m.SaveMarkers(); err != nil {
|
||||
log.Errorf("file %s: %s while saving markers", txt.Quote(m.FileUID), err)
|
||||
log.Errorf("file %s: %s while saving markers", txt.LogParam(m.FileUID), err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -349,12 +349,12 @@ func (m *File) Save() error {
|
||||
}
|
||||
|
||||
if err := UnscopedDb().Save(m).Error; err != nil {
|
||||
log.Errorf("file %s: %s while saving", txt.Quote(m.FileUID), err)
|
||||
log.Errorf("file %s: %s while saving", txt.LogParam(m.FileUID), err)
|
||||
return err
|
||||
}
|
||||
|
||||
if _, err := m.SaveMarkers(); err != nil {
|
||||
log.Errorf("file %s: %s while saving markers", txt.Quote(m.FileUID), err)
|
||||
log.Errorf("file %s: %s while saving markers", txt.LogParam(m.FileUID), err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -384,7 +384,7 @@ func (m *File) Updates(values interface{}) error {
|
||||
|
||||
// Rename updates the name and path of this file.
|
||||
func (m *File) Rename(fileName, rootName, filePath, fileBase string) error {
|
||||
log.Debugf("file %s: renaming %s to %s", txt.Quote(m.FileUID), txt.Quote(m.FileName), txt.Quote(fileName))
|
||||
log.Debugf("file %s: renaming %s to %s", txt.LogParam(m.FileUID), txt.LogParam(m.FileName), txt.LogParam(fileName))
|
||||
|
||||
// Update database row.
|
||||
if err := m.Updates(map[string]interface{}{
|
||||
@@ -428,7 +428,7 @@ func (m *File) Undelete() error {
|
||||
return err
|
||||
}
|
||||
|
||||
log.Debugf("file %s: removed missing flag from %s", txt.Quote(m.FileUID), txt.Quote(m.FileName))
|
||||
log.Debugf("file %s: removed missing flag from %s", txt.LogParam(m.FileUID), txt.LogParam(m.FileName))
|
||||
|
||||
m.FileMissing = false
|
||||
m.DeletedAt = nil
|
||||
@@ -562,7 +562,7 @@ func (m *File) Markers() *Markers {
|
||||
} else if m.FileUID == "" {
|
||||
m.markers = &Markers{}
|
||||
} else if res, err := FindMarkers(m.FileUID); err != nil {
|
||||
log.Warnf("file %s: %s while loading markers", txt.Quote(m.FileUID), err)
|
||||
log.Warnf("file %s: %s while loading markers", txt.LogParam(m.FileUID), err)
|
||||
m.markers = &Markers{}
|
||||
} else {
|
||||
m.markers = &res
|
||||
|
||||
@@ -179,7 +179,7 @@ func (m *Folder) Create() error {
|
||||
if err := a.Create(); err != nil {
|
||||
log.Errorf("folder: %s (add album)", err)
|
||||
} else {
|
||||
log.Infof("folder: added album %s (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Infof("folder: added album %s (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -124,7 +124,7 @@ func FirstOrCreateLens(m *Lens) *Lens {
|
||||
lensCache.SetDefault(m.LensSlug, &result)
|
||||
return &result
|
||||
} else {
|
||||
log.Errorf("lens: %s (create %s)", err.Error(), txt.Quote(m.String()))
|
||||
log.Errorf("lens: %s (create %s)", err.Error(), txt.LogParam(m.String()))
|
||||
}
|
||||
|
||||
return &UnknownLens
|
||||
@@ -132,7 +132,7 @@ func FirstOrCreateLens(m *Lens) *Lens {
|
||||
|
||||
// String returns an identifier that can be used in logs.
|
||||
func (m *Lens) String() string {
|
||||
return m.LensName
|
||||
return txt.LogParam(m.LensName)
|
||||
}
|
||||
|
||||
// Unknown returns true if the lens is not a known make or model.
|
||||
|
||||
@@ -33,7 +33,7 @@ func TestLens_TableName(t *testing.T) {
|
||||
|
||||
func TestLens_String(t *testing.T) {
|
||||
lens := NewLens("F500-99", "samsung")
|
||||
assert.Equal(t, "Samsung F500-99", lens.String())
|
||||
assert.Equal(t, "'Samsung F500-99'", lens.String())
|
||||
}
|
||||
|
||||
func TestFirstOrCreateLens(t *testing.T) {
|
||||
|
||||
@@ -192,5 +192,5 @@ func FindValidLinks(token, share string) (result Links) {
|
||||
|
||||
// String returns an human readable identifier for logging.
|
||||
func (m *Link) String() string {
|
||||
return m.LinkUID
|
||||
return txt.LogParam(m.LinkUID)
|
||||
}
|
||||
|
||||
@@ -232,7 +232,7 @@ func (m *Marker) SetFace(f *Face, dist float64) (updated bool, err error) {
|
||||
} else if reported, err := f.ResolveCollision(m.Embeddings()); err != nil {
|
||||
return false, err
|
||||
} else if reported {
|
||||
log.Warnf("marker %s: face %s has ambiguous subjects %s <> %s, subject source %s", txt.Quote(m.MarkerUID), txt.Quote(f.ID), txt.Quote(m.SubjUID), txt.Quote(f.SubjUID), SrcString(m.SubjSrc))
|
||||
log.Warnf("marker %s: face %s has ambiguous subjects %s <> %s, subject source %s", txt.LogParam(m.MarkerUID), txt.LogParam(f.ID), txt.LogParam(m.SubjUID), txt.LogParam(f.SubjUID), SrcString(m.SubjSrc))
|
||||
return false, nil
|
||||
} else {
|
||||
return false, nil
|
||||
@@ -428,10 +428,10 @@ func (m *Marker) Subject() (subj *Subject) {
|
||||
// Create subject?
|
||||
if m.SubjSrc != SrcAuto && m.MarkerName != "" && m.SubjUID == "" {
|
||||
if subj = NewSubject(m.MarkerName, SubjPerson, m.SubjSrc); subj == nil {
|
||||
log.Errorf("marker %s: invalid subject %s", txt.Quote(m.MarkerUID), txt.Quote(m.MarkerName))
|
||||
log.Errorf("marker %s: invalid subject %s", txt.LogParam(m.MarkerUID), txt.LogParam(m.MarkerName))
|
||||
return nil
|
||||
} else if subj = FirstOrCreateSubject(subj); subj == nil {
|
||||
log.Debugf("marker %s: invalid subject %s", txt.Quote(m.MarkerUID), txt.Quote(m.MarkerName))
|
||||
log.Debugf("marker %s: invalid subject %s", txt.LogParam(m.MarkerUID), txt.LogParam(m.MarkerName))
|
||||
return nil
|
||||
} else {
|
||||
m.subject = subj
|
||||
@@ -457,9 +457,9 @@ func (m *Marker) ClearSubject(src string) error {
|
||||
// Find and (soft) delete unused subjects.
|
||||
start := time.Now()
|
||||
if count, err := DeleteOrphanPeople(); err != nil {
|
||||
log.Errorf("marker %s: %s while removing unused subjects [%s]", txt.Quote(m.MarkerUID), err, time.Since(start))
|
||||
log.Errorf("marker %s: %s while removing unused subjects [%s]", txt.LogParam(m.MarkerUID), err, time.Since(start))
|
||||
} else if count > 0 {
|
||||
log.Debugf("marker %s: removed %s [%s]", txt.Quote(m.MarkerUID), english.Plural(count, "person", "people"), time.Since(start))
|
||||
log.Debugf("marker %s: removed %s [%s]", txt.LogParam(m.MarkerUID), english.Plural(count, "person", "people"), time.Since(start))
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -472,7 +472,7 @@ func (m *Marker) ClearSubject(src string) error {
|
||||
} else if resolved, err := m.face.ResolveCollision(m.Embeddings()); err != nil {
|
||||
return err
|
||||
} else if resolved {
|
||||
log.Debugf("marker %s: resolved ambiguous subjects for face %s", txt.Quote(m.MarkerUID), txt.Quote(m.face.ID))
|
||||
log.Debugf("marker %s: resolved ambiguous subjects for face %s", txt.LogParam(m.MarkerUID), txt.LogParam(m.face.ID))
|
||||
}
|
||||
|
||||
// Clear references.
|
||||
@@ -498,21 +498,21 @@ func (m *Marker) Face() (f *Face) {
|
||||
// Add face if size
|
||||
if m.SubjSrc != SrcAuto && m.FaceID == "" {
|
||||
if m.Size < face.ClusterSizeThreshold || m.Score < face.ClusterScoreThreshold {
|
||||
log.Debugf("marker %s: skipped adding face due to low-quality (size %d, score %d)", txt.Quote(m.MarkerUID), m.Size, m.Score)
|
||||
log.Debugf("marker %s: skipped adding face due to low-quality (size %d, score %d)", txt.LogParam(m.MarkerUID), m.Size, m.Score)
|
||||
return nil
|
||||
} else if emb := m.Embeddings(); emb.Empty() {
|
||||
log.Warnf("marker %s: found no face embeddings", txt.Quote(m.MarkerUID))
|
||||
log.Warnf("marker %s: found no face embeddings", txt.LogParam(m.MarkerUID))
|
||||
return nil
|
||||
} else if f = NewFace(m.SubjUID, m.SubjSrc, emb); f == nil {
|
||||
log.Warnf("marker %s: failed assigning face", txt.Quote(m.MarkerUID))
|
||||
log.Warnf("marker %s: failed assigning face", txt.LogParam(m.MarkerUID))
|
||||
return nil
|
||||
} else if f.Unsuitable() {
|
||||
log.Infof("marker %s: face %s is unsuitable for clustering and matching", txt.Quote(m.MarkerUID), f.ID)
|
||||
log.Infof("marker %s: face %s is unsuitable for clustering and matching", txt.LogParam(m.MarkerUID), f.ID)
|
||||
} else if f = FirstOrCreateFace(f); f == nil {
|
||||
log.Warnf("marker %s: failed assigning face", txt.Quote(m.MarkerUID))
|
||||
log.Warnf("marker %s: failed assigning face", txt.LogParam(m.MarkerUID))
|
||||
return nil
|
||||
} else if err := f.MatchMarkers(Faceless); err != nil {
|
||||
log.Errorf("marker %s: %s while matching with faces", txt.Quote(m.MarkerUID), err)
|
||||
log.Errorf("marker %s: %s while matching with faces", txt.LogParam(m.MarkerUID), err)
|
||||
}
|
||||
|
||||
m.face = f
|
||||
@@ -695,7 +695,7 @@ func FindFaceMarker(faceId string) *Marker {
|
||||
if err := Db().Where("face_id = ?", faceId).
|
||||
Where("thumb <> '' AND marker_invalid = 0").
|
||||
Order("face_dist ASC, q DESC").First(&result).Error; err != nil {
|
||||
log.Warnf("markers: found no marker for face %s", txt.Quote(faceId))
|
||||
log.Warnf("markers: found no marker for face %s", txt.LogParam(faceId))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -714,7 +714,7 @@ func CreateMarkerIfNotExists(m *Marker) (*Marker, error) {
|
||||
} else if err := m.Create(); err != nil {
|
||||
return m, err
|
||||
} else {
|
||||
log.Debugf("markers: added %s marker %s for %s", TypeString(m.MarkerType), txt.Quote(m.MarkerUID), txt.Quote(m.FileUID))
|
||||
log.Debugf("markers: added %s marker %s for %s", TypeString(m.MarkerType), txt.LogParam(m.MarkerUID), txt.LogParam(m.FileUID))
|
||||
}
|
||||
|
||||
return m, nil
|
||||
|
||||
@@ -210,15 +210,15 @@ func SavePhotoForm(model Photo, form form.Photo) error {
|
||||
func (m *Photo) String() string {
|
||||
if m.PhotoUID == "" {
|
||||
if m.PhotoName != "" {
|
||||
return txt.Quote(m.PhotoName)
|
||||
return txt.LogParam(m.PhotoName)
|
||||
} else if m.OriginalName != "" {
|
||||
return txt.Quote(m.OriginalName)
|
||||
return txt.LogParam(m.OriginalName)
|
||||
}
|
||||
|
||||
return "(unknown)"
|
||||
}
|
||||
|
||||
return "uid " + txt.Quote(m.PhotoUID)
|
||||
return "uid " + txt.LogParam(m.PhotoUID)
|
||||
}
|
||||
|
||||
// FirstOrCreate fetches an existing row from the database or inserts a new one.
|
||||
@@ -561,12 +561,12 @@ func (m *Photo) AddLabels(labels classify.Labels) {
|
||||
labelEntity := FirstOrCreateLabel(NewLabel(classifyLabel.Title(), classifyLabel.Priority))
|
||||
|
||||
if labelEntity == nil {
|
||||
log.Errorf("index: label %s should not be nil - bug? (%s)", txt.Quote(classifyLabel.Title()), m)
|
||||
log.Errorf("index: label %s should not be nil - bug? (%s)", txt.LogParam(classifyLabel.Title()), m)
|
||||
continue
|
||||
}
|
||||
|
||||
if labelEntity.Deleted() {
|
||||
log.Debugf("index: skipping deleted label %s (%s)", txt.Quote(classifyLabel.Title()), m)
|
||||
log.Debugf("index: skipping deleted label %s (%s)", txt.LogParam(classifyLabel.Title()), m)
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -721,7 +721,7 @@ func (m *Photo) Restore() error {
|
||||
// Delete deletes the photo from the index.
|
||||
func (m *Photo) Delete(permanently bool) (files Files, err error) {
|
||||
if m.ID < 1 || m.PhotoUID == "" {
|
||||
return files, fmt.Errorf("invalid photo id %d / uid %s", m.ID, txt.Quote(m.PhotoUID))
|
||||
return files, fmt.Errorf("invalid photo id %d / uid %s", m.ID, txt.LogParam(m.PhotoUID))
|
||||
}
|
||||
|
||||
if permanently {
|
||||
@@ -742,7 +742,7 @@ func (m *Photo) Delete(permanently bool) (files Files, err error) {
|
||||
// DeletePermanently permanently removes a photo from the index.
|
||||
func (m *Photo) DeletePermanently() (files Files, err error) {
|
||||
if m.ID < 1 || m.PhotoUID == "" {
|
||||
return files, fmt.Errorf("invalid photo id %d / uid %s", m.ID, txt.Quote(m.PhotoUID))
|
||||
return files, fmt.Errorf("invalid photo id %d / uid %s", m.ID, txt.LogParam(m.PhotoUID))
|
||||
}
|
||||
|
||||
files = m.AllFiles()
|
||||
|
||||
@@ -52,7 +52,7 @@ func (m *Photo) EstimateCountry() {
|
||||
m.PhotoCountry = countryCode
|
||||
m.PlaceSrc = SrcEstimate
|
||||
m.EstimatedAt = TimePointer()
|
||||
log.Debugf("photo: estimated country for %s is %s", m, txt.Quote(m.CountryName()))
|
||||
log.Debugf("photo: estimated country for %s is %s", m, txt.LogParam(m.CountryName()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -109,7 +109,7 @@ func (m *Photo) EstimateLocation(force bool) {
|
||||
Order(gorm.Expr("ABS(JulianDay(taken_at) - JulianDay(?))", m.TakenAt)).Limit(2).
|
||||
Preload("Place").Find(&mostRecent).Error
|
||||
default:
|
||||
log.Warnf("photo: unsupported sql dialect %s", txt.Quote(DbDialect()))
|
||||
log.Warnf("photo: unsupported sql dialect %s", txt.LogParam(DbDialect()))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -146,7 +146,7 @@ func (m *Photo) EstimateLocation(force bool) {
|
||||
}
|
||||
}
|
||||
} else if recentPhoto.HasCountry() {
|
||||
log.Debugf("photo: estimated country for %s is %s", m, txt.Quote(m.CountryName()))
|
||||
log.Debugf("photo: estimated country for %s is %s", m, txt.LogParam(m.CountryName()))
|
||||
m.RemoveLocation(SrcEstimate, false)
|
||||
m.RemoveLocationLabels()
|
||||
m.PhotoCountry = recentPhoto.PhotoCountry
|
||||
|
||||
@@ -77,7 +77,7 @@ func (m *Photo) SetPosition(pos geo.Position, source string, force bool) {
|
||||
if m.Place == nil {
|
||||
log.Warnf("photo: failed updating position of %s", m)
|
||||
} else {
|
||||
log.Debugf("photo: approximate place of %s is %s (id %s)", m, txt.Quote(m.Place.Label()), m.PlaceID)
|
||||
log.Debugf("photo: approximate place of %s is %s (id %s)", m, txt.LogParam(m.Place.Label()), m.PlaceID)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -106,7 +106,7 @@ func (m *Photo) AdoptPlace(other Photo, source string, force bool) {
|
||||
|
||||
m.UpdateTimeZone(other.TimeZone)
|
||||
|
||||
log.Debugf("photo: %s now located at %s (id %s)", m.String(), txt.Quote(m.Place.Label()), m.PlaceID)
|
||||
log.Debugf("photo: %s now located at %s (id %s)", m.String(), txt.LogParam(m.Place.Label()), m.PlaceID)
|
||||
}
|
||||
|
||||
// RemoveLocation removes the current location.
|
||||
|
||||
@@ -66,7 +66,7 @@ func (m *Photo) UpdateTitle(labels classify.Labels) error {
|
||||
|
||||
// TODO: User defined title format
|
||||
if names != "" {
|
||||
log.Debugf("photo: %s title based on %s (%s)", m.String(), english.Plural(len(people), "person", "people"), txt.Quote(names))
|
||||
log.Debugf("photo: %s title based on %s (%s)", m.String(), english.Plural(len(people), "person", "people"), txt.LogParam(names))
|
||||
|
||||
if l := len([]rune(names)); l > 35 {
|
||||
m.SetTitle(names, SrcAuto)
|
||||
@@ -80,7 +80,7 @@ func (m *Photo) UpdateTitle(labels classify.Labels) error {
|
||||
m.SetTitle(fmt.Sprintf("%s / %s / %s", names, loc.City(), m.TakenAt.Format("2006")), SrcAuto)
|
||||
}
|
||||
} else if title := labels.Title(loc.Name()); title != "" {
|
||||
log.Debugf("photo: %s title based on label %s", m.String(), txt.Quote(title))
|
||||
log.Debugf("photo: %s title based on label %s", m.String(), txt.LogParam(title))
|
||||
if loc.NoCity() || loc.LongCity() || loc.CityContains(title) {
|
||||
m.SetTitle(fmt.Sprintf("%s / %s / %s", txt.Title(title), loc.CountryName(), m.TakenAt.Format("2006")), SrcAuto)
|
||||
} else {
|
||||
@@ -105,7 +105,7 @@ func (m *Photo) UpdateTitle(labels classify.Labels) error {
|
||||
knownLocation = true
|
||||
|
||||
if names != "" {
|
||||
log.Debugf("photo: %s title based on %s (%s)", m.String(), english.Plural(len(people), "person", "people"), txt.Quote(names))
|
||||
log.Debugf("photo: %s title based on %s (%s)", m.String(), english.Plural(len(people), "person", "people"), txt.LogParam(names))
|
||||
|
||||
if l := len([]rune(names)); l > 35 {
|
||||
m.SetTitle(names, SrcAuto)
|
||||
@@ -119,7 +119,7 @@ func (m *Photo) UpdateTitle(labels classify.Labels) error {
|
||||
m.SetTitle(fmt.Sprintf("%s / %s / %s", names, m.Place.City(), m.TakenAt.Format("2006")), SrcAuto)
|
||||
}
|
||||
} else if title := labels.Title(fileTitle); title != "" {
|
||||
log.Debugf("photo: %s title based on label %s", m.String(), txt.Quote(title))
|
||||
log.Debugf("photo: %s title based on label %s", m.String(), txt.LogParam(title))
|
||||
if m.Place.NoCity() || m.Place.LongCity() || m.Place.CityContains(title) {
|
||||
m.SetTitle(fmt.Sprintf("%s / %s / %s", txt.Title(title), m.Place.CountryName(), m.TakenAt.Format("2006")), SrcAuto)
|
||||
} else {
|
||||
@@ -161,7 +161,7 @@ func (m *Photo) UpdateTitle(labels classify.Labels) error {
|
||||
}
|
||||
|
||||
if m.PhotoTitle != oldTitle {
|
||||
log.Debugf("photo: %s has new title %s [%s]", m.String(), txt.Quote(m.PhotoTitle), time.Since(start))
|
||||
log.Debugf("photo: %s has new title %s [%s]", m.String(), txt.LogParam(m.PhotoTitle), time.Since(start))
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -54,7 +54,7 @@ func FindPlace(id string) *Place {
|
||||
place := Place{}
|
||||
|
||||
if err := Db().Where("id = ?", id).First(&place).Error; err != nil {
|
||||
log.Debugf("place: %s no found", txt.Quote(id))
|
||||
log.Debugf("place: %s no found", txt.LogParam(id))
|
||||
return nil
|
||||
} else {
|
||||
return &place
|
||||
|
||||
@@ -104,7 +104,7 @@ func (m *Subject) Delete() error {
|
||||
subjectMutex.Lock()
|
||||
defer subjectMutex.Unlock()
|
||||
|
||||
log.Infof("subject: deleting %s %s", TypeString(m.SubjType), txt.Quote(m.SubjName))
|
||||
log.Infof("subject: deleting %s %s", TypeString(m.SubjType), txt.LogParam(m.SubjName))
|
||||
|
||||
event.EntitiesDeleted("subjects", []string{m.SubjUID})
|
||||
|
||||
@@ -141,7 +141,7 @@ func (m *Subject) Restore() error {
|
||||
if m.Deleted() {
|
||||
m.DeletedAt = nil
|
||||
|
||||
log.Infof("subject: restoring %s %s", TypeString(m.SubjType), txt.Quote(m.SubjName))
|
||||
log.Infof("subject: restoring %s %s", TypeString(m.SubjType), txt.LogParam(m.SubjName))
|
||||
|
||||
event.EntitiesCreated("subjects", []*Subject{m})
|
||||
|
||||
@@ -179,7 +179,7 @@ func FirstOrCreateSubject(m *Subject) *Subject {
|
||||
if found := FindSubjectByName(m.SubjName); found != nil {
|
||||
return found
|
||||
} else if createErr := m.Create(); createErr == nil {
|
||||
log.Infof("subject: added %s %s", TypeString(m.SubjType), txt.Quote(m.SubjName))
|
||||
log.Infof("subject: added %s %s", TypeString(m.SubjType), txt.LogParam(m.SubjName))
|
||||
|
||||
event.EntitiesCreated("subjects", []*Subject{m})
|
||||
|
||||
@@ -194,7 +194,7 @@ func FirstOrCreateSubject(m *Subject) *Subject {
|
||||
} else if found = FindSubjectByName(m.SubjName); found != nil {
|
||||
return found
|
||||
} else {
|
||||
log.Errorf("subject: %s while creating %s", createErr, txt.Quote(m.SubjName))
|
||||
log.Errorf("subject: %s while creating %s", createErr, txt.LogParam(m.SubjName))
|
||||
}
|
||||
|
||||
return nil
|
||||
@@ -327,8 +327,6 @@ func (m *Subject) SaveForm(f form.Subject) (changed bool, err error) {
|
||||
}
|
||||
|
||||
if err := m.Updates(values); err == nil {
|
||||
log.Debugf("subject: updated values %v", values)
|
||||
|
||||
event.EntitiesUpdated("subjects", []*Subject{m})
|
||||
|
||||
if m.IsPerson() {
|
||||
@@ -349,7 +347,7 @@ func (m *Subject) UpdateName(name string) (*Subject, error) {
|
||||
if err := m.SetName(name); err != nil {
|
||||
return m, err
|
||||
} else if err := m.Updates(Values{"SubjName": m.SubjName, "SubjSlug": m.SubjSlug}); err == nil {
|
||||
log.Infof("subject: renamed %s %s", TypeString(m.SubjType), txt.Quote(m.SubjName))
|
||||
log.Infof("subject: renamed %s %s", TypeString(m.SubjType), txt.LogParam(m.SubjName))
|
||||
|
||||
event.EntitiesUpdated("subjects", []*Subject{m})
|
||||
|
||||
|
||||
@@ -176,7 +176,7 @@ func FindUserByName(userName string) *User {
|
||||
if err := Db().Preload("Address").Where("user_name = ?", userName).First(&result).Error; err == nil {
|
||||
return &result
|
||||
} else {
|
||||
log.Debugf("user %s not found", txt.Quote(userName))
|
||||
log.Debugf("user %s not found", txt.LogParam(userName))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -192,7 +192,7 @@ func FindUserByUID(uid string) *User {
|
||||
if err := Db().Preload("Address").Where("user_uid = ?", uid).First(&result).Error; err == nil {
|
||||
return &result
|
||||
} else {
|
||||
log.Debugf("user %s not found", txt.Quote(uid))
|
||||
log.Debugf("user %s not found", txt.LogParam(uid))
|
||||
return nil
|
||||
}
|
||||
}
|
||||
@@ -214,14 +214,14 @@ func (m *User) Deleted() bool {
|
||||
// String returns an identifier that can be used in logs.
|
||||
func (m *User) String() string {
|
||||
if n := m.Username(); n != "" {
|
||||
return n
|
||||
return txt.LogParam(n)
|
||||
}
|
||||
|
||||
if m.FullName != "" {
|
||||
return m.FullName
|
||||
return txt.LogParam(m.FullName)
|
||||
}
|
||||
|
||||
return m.UserUID
|
||||
return txt.LogParam(m.UserUID)
|
||||
}
|
||||
|
||||
// Username returns the normalized username.
|
||||
@@ -256,7 +256,7 @@ func (m *User) SetPassword(password string) error {
|
||||
}
|
||||
|
||||
if len(password) < 4 {
|
||||
return fmt.Errorf("new password for %s must be at least 4 characters", txt.Quote(m.Username()))
|
||||
return fmt.Errorf("new password for %s must be at least 4 characters", txt.LogParam(m.Username()))
|
||||
}
|
||||
|
||||
pw := NewPassword(m.UserUID, password)
|
||||
@@ -398,7 +398,7 @@ func CreateWithPassword(uc form.UserCreate) error {
|
||||
RoleAdmin: true,
|
||||
}
|
||||
if len(uc.Password) < 4 {
|
||||
return fmt.Errorf("new password for %s must be at least 4 characters", txt.Quote(u.Username()))
|
||||
return fmt.Errorf("new password for %s must be at least 4 characters", txt.LogParam(u.Username()))
|
||||
}
|
||||
err := u.Validate()
|
||||
if err != nil {
|
||||
@@ -412,7 +412,7 @@ func CreateWithPassword(uc form.UserCreate) error {
|
||||
if err := tx.Create(&pw).Error; err != nil {
|
||||
return err
|
||||
}
|
||||
log.Infof("created user %v with uid %v", txt.Quote(u.Username()), txt.Quote(u.UserUID))
|
||||
log.Infof("created user %s with uid %s", txt.LogParam(u.Username()), txt.LogParam(u.UserUID))
|
||||
return nil
|
||||
})
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ func TestPublishSubscribe(t *testing.T) {
|
||||
|
||||
msg := <-s.Receiver
|
||||
|
||||
t.Logf("receive msg with topic %s: %v\n", msg.Name, msg.Fields)
|
||||
// t.Logf("receive msg with topic %s: %v\n", msg.Name, msg.Fields)
|
||||
|
||||
assert.Equal(t, "foo.bar", msg.Name)
|
||||
assert.Equal(t, Data{"id": 13}, msg.Fields)
|
||||
|
||||
@@ -92,13 +92,13 @@ func Detect(fileName string, findLandmarks bool, minSize int) (faces Faces, err
|
||||
}
|
||||
|
||||
if !fs.FileExists(fileName) {
|
||||
return faces, fmt.Errorf("faces: file '%s' not found", txt.Quote(filepath.Base(fileName)))
|
||||
return faces, fmt.Errorf("faces: file '%s' not found", txt.LogParam(filepath.Base(fileName)))
|
||||
}
|
||||
|
||||
det, params, err := d.Detect(fileName)
|
||||
|
||||
if err != nil {
|
||||
return faces, fmt.Errorf("faces: %v (detect faces)", err)
|
||||
return faces, fmt.Errorf("faces: %s (detect faces)", err)
|
||||
}
|
||||
|
||||
if det == nil {
|
||||
|
||||
@@ -57,7 +57,7 @@ func (t *Net) Detect(fileName string, minSize int, cacheCrop bool, expected int)
|
||||
}
|
||||
|
||||
if img, err := crop.ImageFromThumb(fileName, f.CropArea(), CropSize, cacheCrop); err != nil {
|
||||
log.Errorf("faces: failed to decode image: %v", err)
|
||||
log.Errorf("faces: failed to decode image: %s", err)
|
||||
} else if embeddings := t.getEmbeddings(img); !embeddings.Empty() {
|
||||
faces[i].Embeddings = embeddings
|
||||
}
|
||||
@@ -82,7 +82,7 @@ func (t *Net) loadModel() error {
|
||||
|
||||
modelPath := path.Join(t.modelPath)
|
||||
|
||||
log.Infof("faces: loading %s", txt.Quote(filepath.Base(modelPath)))
|
||||
log.Infof("faces: loading %s", txt.LogParam(filepath.Base(modelPath)))
|
||||
|
||||
// Load model
|
||||
model, err := tf.LoadSavedModel(modelPath, t.modelTags, nil)
|
||||
@@ -101,7 +101,7 @@ func (t *Net) getEmbeddings(img image.Image) Embeddings {
|
||||
tensor, err := imageToTensor(img, CropSize.Width, CropSize.Height)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("faces: failed to convert image to tensor: %v", err)
|
||||
log.Errorf("faces: failed to convert image to tensor: %s", err)
|
||||
}
|
||||
|
||||
// TODO: pre-whiten image as in facenet
|
||||
|
||||
@@ -182,7 +182,7 @@ func (c *Config) Refresh() (err error) {
|
||||
// Load backend api credentials from a YAML file.
|
||||
func (c *Config) Load() error {
|
||||
if !fs.FileExists(c.FileName) {
|
||||
return fmt.Errorf("settings file not found: %s", txt.Quote(c.FileName))
|
||||
return fmt.Errorf("settings file not found: %s", txt.LogParam(c.FileName))
|
||||
}
|
||||
|
||||
mutex.Lock()
|
||||
|
||||
@@ -46,7 +46,7 @@ func FindLocation(id string) (result Location, err error) {
|
||||
if len(id) == 0 {
|
||||
return result, fmt.Errorf("empty cell id")
|
||||
} else if n := len(id); n < 4 || n > 16 {
|
||||
return result, fmt.Errorf("invalid cell id %s", txt.Quote(id))
|
||||
return result, fmt.Errorf("invalid cell id %s", txt.LogParam(id))
|
||||
}
|
||||
|
||||
// Remember start time.
|
||||
@@ -133,7 +133,7 @@ func FindLocation(id string) (result Location, err error) {
|
||||
}
|
||||
|
||||
cache.SetDefault(id, result)
|
||||
log.Tracef("places: cached cell %s [%s]", txt.Quote(id), time.Since(start))
|
||||
log.Tracef("places: cached cell %s [%s]", txt.LogParam(id), time.Since(start))
|
||||
|
||||
result.Cached = false
|
||||
|
||||
|
||||
@@ -51,7 +51,7 @@ func (data *Data) Exif(fileName string, fileType fs.FileFormat) (err error) {
|
||||
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("metadata: %s in %s (exif panic)\nstack: %s", e, txt.Quote(filepath.Base(fileName)), debug.Stack())
|
||||
err = fmt.Errorf("metadata: %s in %s (exif panic)\nstack: %s", e, txt.LogParam(filepath.Base(fileName)), debug.Stack())
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -62,7 +62,7 @@ func (data *Data) Exif(fileName string, fileType fs.FileFormat) (err error) {
|
||||
return err
|
||||
}
|
||||
|
||||
logName := txt.Quote(filepath.Base(fileName))
|
||||
logName := txt.LogParam(filepath.Base(fileName))
|
||||
|
||||
if data.All == nil {
|
||||
data.All = make(map[string]string)
|
||||
|
||||
@@ -18,14 +18,14 @@ import (
|
||||
func RawExif(fileName string, fileType fs.FileFormat) (rawExif []byte, err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("metadata: %s in %s (raw exif panic)\nstack: %s", e, txt.Quote(filepath.Base(fileName)), debug.Stack())
|
||||
err = fmt.Errorf("metadata: %s in %s (raw exif panic)\nstack: %s", e, txt.LogParam(filepath.Base(fileName)), debug.Stack())
|
||||
}
|
||||
}()
|
||||
|
||||
// Extract raw EXIF block.
|
||||
var parsed bool
|
||||
|
||||
logName := txt.Quote(filepath.Base(fileName))
|
||||
logName := txt.LogParam(filepath.Base(fileName))
|
||||
|
||||
if fileType == fs.FormatJpeg {
|
||||
jpegMp := jpegstructure.NewJpegMediaParser()
|
||||
|
||||
@@ -23,7 +23,7 @@ func JSON(jsonName, originalName string) (data Data, err error) {
|
||||
func (data *Data) JSON(jsonName, originalName string) (err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("metadata: %s in %s (json panic)\nstack: %s", e, txt.Quote(filepath.Base(jsonName)), debug.Stack())
|
||||
err = fmt.Errorf("metadata: %s in %s (json panic)\nstack: %s", e, txt.LogParam(filepath.Base(jsonName)), debug.Stack())
|
||||
}
|
||||
}()
|
||||
|
||||
@@ -31,7 +31,7 @@ func (data *Data) JSON(jsonName, originalName string) (err error) {
|
||||
data.All = make(map[string]string)
|
||||
}
|
||||
|
||||
quotedName := txt.Quote(filepath.Base(jsonName))
|
||||
quotedName := txt.LogParam(filepath.Base(jsonName))
|
||||
|
||||
if !fs.FileExists(jsonName) {
|
||||
return fmt.Errorf("metadata: %s not found", quotedName)
|
||||
|
||||
@@ -29,7 +29,7 @@ func (data *Data) Exiftool(jsonData []byte, originalName string) (err error) {
|
||||
j := gjson.GetBytes(jsonData, "@flatten|@join")
|
||||
|
||||
if !j.IsObject() {
|
||||
return fmt.Errorf("metadata: data is not an object in %s (exiftool)", txt.Quote(filepath.Base(originalName)))
|
||||
return fmt.Errorf("metadata: data is not an object in %s (exiftool)", txt.LogParam(filepath.Base(originalName)))
|
||||
}
|
||||
|
||||
jsonStrings := make(map[string]string)
|
||||
@@ -40,7 +40,7 @@ func (data *Data) Exiftool(jsonData []byte, originalName string) (err error) {
|
||||
}
|
||||
|
||||
if fileName, ok := jsonStrings["FileName"]; ok && fileName != "" && originalName != "" && fileName != originalName {
|
||||
return fmt.Errorf("metadata: original name %s does not match %s (exiftool)", txt.Quote(originalName), txt.Quote(fileName))
|
||||
return fmt.Errorf("metadata: original name %s does not match %s (exiftool)", txt.LogParam(originalName), txt.LogParam(fileName))
|
||||
}
|
||||
|
||||
v := reflect.ValueOf(data).Elem()
|
||||
|
||||
@@ -19,14 +19,14 @@ func XMP(fileName string) (data Data, err error) {
|
||||
func (data *Data) XMP(fileName string) (err error) {
|
||||
defer func() {
|
||||
if e := recover(); e != nil {
|
||||
err = fmt.Errorf("metadata: %s in %s (xmp panic)\nstack: %s", e, txt.Quote(filepath.Base(fileName)), debug.Stack())
|
||||
err = fmt.Errorf("metadata: %s in %s (xmp panic)\nstack: %s", e, txt.LogParam(filepath.Base(fileName)), debug.Stack())
|
||||
}
|
||||
}()
|
||||
|
||||
doc := XmpDocument{}
|
||||
|
||||
if err := doc.Load(fileName); err != nil {
|
||||
return fmt.Errorf("metadata: can't read %s (xmp)", txt.Quote(filepath.Base(fileName)))
|
||||
return fmt.Errorf("metadata: can't read %s (xmp)", txt.LogParam(filepath.Base(fileName)))
|
||||
}
|
||||
|
||||
if doc.Title() != "" {
|
||||
|
||||
@@ -30,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) != "image/jpeg" {
|
||||
return result, fmt.Errorf("nsfw: %s is not a jpeg file", txt.Quote(filepath.Base(filename)))
|
||||
return result, fmt.Errorf("nsfw: %s is not a jpeg file", txt.LogParam(filepath.Base(filename)))
|
||||
}
|
||||
|
||||
imageBuffer, err := os.ReadFile(filename)
|
||||
@@ -76,7 +76,7 @@ func (t *Detector) Labels(img []byte) (result Labels, err error) {
|
||||
// Return best labels
|
||||
result = t.getLabels(output[0].Value().([][]float32)[0])
|
||||
|
||||
log.Debugf("nsfw: image classified as %+v", result)
|
||||
log.Tracef("nsfw: image classified as %+v", result)
|
||||
|
||||
return result, nil
|
||||
}
|
||||
@@ -118,7 +118,7 @@ func (t *Detector) loadModel() error {
|
||||
return nil
|
||||
}
|
||||
|
||||
log.Infof("nsfw: loading %s", txt.Quote(filepath.Base(t.modelPath)))
|
||||
log.Infof("nsfw: loading %s", txt.LogParam(filepath.Base(t.modelPath)))
|
||||
|
||||
// Load model
|
||||
model, err := tf.LoadSavedModel(t.modelPath, t.modelTags, nil)
|
||||
|
||||
@@ -36,7 +36,7 @@ func BackupAlbums(backupPath string, force bool) (count int, result error) {
|
||||
log.Errorf("album: %s (update yaml)", err)
|
||||
result = err
|
||||
} else {
|
||||
log.Tracef("backup: saved album yaml file %s", txt.Quote(filepath.Base(fileName)))
|
||||
log.Tracef("backup: saved album yaml file %s", txt.LogParam(filepath.Base(fileName)))
|
||||
count++
|
||||
}
|
||||
}
|
||||
@@ -87,14 +87,14 @@ func RestoreAlbums(backupPath string, force bool) (count int, result error) {
|
||||
a := entity.Album{}
|
||||
|
||||
if err := a.LoadFromYaml(fileName); err != nil {
|
||||
log.Errorf("restore: %s in %s", err, txt.Quote(filepath.Base(fileName)))
|
||||
log.Errorf("restore: %s in %s", err, txt.LogParam(filepath.Base(fileName)))
|
||||
result = err
|
||||
} else if a.AlbumType == "" || len(a.Photos) == 0 && a.AlbumFilter == "" {
|
||||
log.Debugf("restore: skipping %s", txt.Quote(filepath.Base(fileName)))
|
||||
log.Debugf("restore: skipping %s", txt.LogParam(filepath.Base(fileName)))
|
||||
} else if err := a.Find(); err == nil {
|
||||
log.Infof("%s: %s already exists", a.AlbumType, txt.Quote(a.AlbumTitle))
|
||||
log.Infof("%s: %s already exists", a.AlbumType, txt.LogParam(a.AlbumTitle))
|
||||
} else if err := a.Create(); err != nil {
|
||||
log.Errorf("%s: %s in %s", a.AlbumType, err, txt.Quote(filepath.Base(fileName)))
|
||||
log.Errorf("%s: %s in %s", a.AlbumType, err, txt.LogParam(filepath.Base(fileName)))
|
||||
} else {
|
||||
count++
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ func (w *CleanUp) Start(opt CleanUpOptions) (thumbs int, orphans int, err error)
|
||||
}
|
||||
|
||||
hash := base[:i]
|
||||
logName := txt.Quote(fs.RelName(fileName, thumbPath))
|
||||
logName := txt.LogParam(fs.RelName(fileName, thumbPath))
|
||||
|
||||
if ok := fileHashes[hash]; ok {
|
||||
// Do nothing.
|
||||
@@ -119,7 +119,7 @@ func (w *CleanUp) Start(opt CleanUpOptions) (thumbs int, orphans int, err error)
|
||||
|
||||
if opt.Dry {
|
||||
orphans++
|
||||
log.Infof("cleanup: orphan photo %s would be removed", txt.Quote(p.PhotoUID))
|
||||
log.Infof("cleanup: orphan photo %s would be removed", txt.LogParam(p.PhotoUID))
|
||||
continue
|
||||
}
|
||||
|
||||
|
||||
@@ -15,13 +15,13 @@ import (
|
||||
// Colors returns the ColorPerception of an image (only JPEG supported).
|
||||
func (m *MediaFile) Colors(thumbPath string) (perception colors.ColorPerception, err error) {
|
||||
if !m.IsJpeg() {
|
||||
return perception, fmt.Errorf("%s is not a jpeg", txt.Quote(m.BaseName()))
|
||||
return perception, fmt.Errorf("%s is not a jpeg", txt.LogParam(m.BaseName()))
|
||||
}
|
||||
|
||||
img, err := m.Resample(thumbPath, thumb.Colors)
|
||||
|
||||
if err != nil {
|
||||
log.Debugf("colors: %s in %s (resample)", err, txt.Quote(m.BaseName()))
|
||||
log.Debugf("colors: %s in %s (resample)", err, txt.LogParam(m.BaseName()))
|
||||
return perception, err
|
||||
}
|
||||
|
||||
|
||||
@@ -82,7 +82,7 @@ func (c *Convert) Start(path string) (err error) {
|
||||
}
|
||||
|
||||
ignore.Log = func(fileName string) {
|
||||
log.Infof("convert: ignoring %s", txt.Quote(filepath.Base(fileName)))
|
||||
log.Infof("convert: ignoring %s", txt.LogParam(filepath.Base(fileName)))
|
||||
}
|
||||
|
||||
err = godirwalk.Walk(path, &godirwalk.Options{
|
||||
@@ -403,7 +403,7 @@ func (c *Convert) AvcConvertCommand(f *MediaFile, avcName, codecName string) (re
|
||||
)
|
||||
}
|
||||
} else {
|
||||
return nil, useMutex, fmt.Errorf("convert: file type %s not supported in %s", f.FileType(), txt.Quote(f.BaseName()))
|
||||
return nil, useMutex, fmt.Errorf("convert: file type %s not supported in %s", f.FileType(), txt.LogParam(f.BaseName()))
|
||||
}
|
||||
|
||||
return result, useMutex, nil
|
||||
|
||||
@@ -14,7 +14,7 @@ type ConvertJob struct {
|
||||
func ConvertWorker(jobs <-chan ConvertJob) {
|
||||
logError := func(err error, job ConvertJob) {
|
||||
fileName := job.file.RelName(job.convert.conf.OriginalsPath())
|
||||
log.Errorf("convert: %s for %s", strings.TrimSpace(err.Error()), txt.Quote(fileName))
|
||||
log.Errorf("convert: %s for %s", strings.TrimSpace(err.Error()), txt.LogParam(fileName))
|
||||
}
|
||||
|
||||
for job := range jobs {
|
||||
|
||||
@@ -24,16 +24,16 @@ func Delete(p entity.Photo) error {
|
||||
for _, file := range files {
|
||||
fileName := FileName(file.FileRoot, file.FileName)
|
||||
|
||||
log.Debugf("delete: removing file %s", txt.Quote(file.FileName))
|
||||
log.Debugf("delete: removing file %s", txt.LogParam(file.FileName))
|
||||
|
||||
if f, err := NewMediaFile(fileName); err == nil {
|
||||
if sidecarJson := f.SidecarJsonName(); fs.FileExists(sidecarJson) {
|
||||
log.Debugf("delete: removing json sidecar %s", txt.Quote(filepath.Base(sidecarJson)))
|
||||
log.Debugf("delete: removing json sidecar %s", txt.LogParam(filepath.Base(sidecarJson)))
|
||||
logWarn("delete", os.Remove(sidecarJson))
|
||||
}
|
||||
|
||||
if exifJson, err := f.ExifToolJsonName(); err == nil && fs.FileExists(exifJson) {
|
||||
log.Debugf("delete: removing exiftool sidecar %s", txt.Quote(filepath.Base(exifJson)))
|
||||
log.Debugf("delete: removing exiftool sidecar %s", txt.LogParam(filepath.Base(exifJson)))
|
||||
logWarn("delete", os.Remove(exifJson))
|
||||
}
|
||||
|
||||
@@ -47,7 +47,7 @@ func Delete(p entity.Photo) error {
|
||||
|
||||
// Remove sidecar backup.
|
||||
if fs.FileExists(yamlFileName) {
|
||||
log.Debugf("delete: removing yaml sidecar %s", txt.Quote(filepath.Base(yamlFileName)))
|
||||
log.Debugf("delete: removing yaml sidecar %s", txt.LogParam(filepath.Base(yamlFileName)))
|
||||
logWarn("delete", os.Remove(yamlFileName))
|
||||
}
|
||||
|
||||
|
||||
@@ -78,13 +78,13 @@ func (w *Faces) Audit(fix bool) (err error) {
|
||||
log.Infof("face %s: ambiguous subject at dist %f, Ø %f from %d samples, collision Ø %f", f1.ID, dist, r, f1.Samples, f1.CollisionRadius)
|
||||
|
||||
if f1.SubjUID != "" {
|
||||
log.Infof("face %s: subject %s (%s %s)", f1.ID, txt.Quote(subj[f1.SubjUID].SubjName), f1.SubjUID, entity.SrcString(f1.FaceSrc))
|
||||
log.Infof("face %s: subject %s (%s %s)", f1.ID, txt.LogParam(subj[f1.SubjUID].SubjName), f1.SubjUID, entity.SrcString(f1.FaceSrc))
|
||||
} else {
|
||||
log.Infof("face %s: has no subject (%s)", f1.ID, entity.SrcString(f1.FaceSrc))
|
||||
}
|
||||
|
||||
if f2.SubjUID != "" {
|
||||
log.Infof("face %s: subject %s (%s %s)", f2.ID, txt.Quote(subj[f2.SubjUID].SubjName), f2.SubjUID, entity.SrcString(f2.FaceSrc))
|
||||
log.Infof("face %s: subject %s (%s %s)", f2.ID, txt.LogParam(subj[f2.SubjUID].SubjName), f2.SubjUID, entity.SrcString(f2.FaceSrc))
|
||||
} else {
|
||||
log.Infof("face %s: has no subject (%s)", f2.ID, entity.SrcString(f2.FaceSrc))
|
||||
}
|
||||
@@ -115,7 +115,7 @@ func (w *Faces) Audit(fix bool) (err error) {
|
||||
log.Error(err)
|
||||
} else {
|
||||
for _, m := range markers {
|
||||
log.Infof("marker %s: %s subject %s conflicts with face %s subject %s", m.MarkerUID, entity.SrcString(m.SubjSrc), txt.Quote(subj[m.SubjUID].SubjName), m.FaceID, txt.Quote(subj[faceMap[m.FaceID].SubjUID].SubjName))
|
||||
log.Infof("marker %s: %s subject %s conflicts with face %s subject %s", m.MarkerUID, entity.SrcString(m.SubjSrc), txt.LogParam(subj[m.SubjUID].SubjName), m.FaceID, txt.LogParam(subj[faceMap[m.FaceID].SubjUID].SubjName))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -165,7 +165,7 @@ func (imp *Import) Start(opt ImportOptions) fs.Done {
|
||||
}
|
||||
|
||||
if mf.FileSize() == 0 {
|
||||
log.Infof("import: skipped empty file %s", txt.Quote(mf.BaseName()))
|
||||
log.Infof("import: skipped empty file %s", txt.LogParam(mf.BaseName()))
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -219,9 +219,9 @@ func (imp *Import) Start(opt ImportOptions) fs.Done {
|
||||
for _, directory := range directories {
|
||||
if fs.IsEmpty(directory) {
|
||||
if err := os.Remove(directory); err != nil {
|
||||
log.Errorf("import: failed deleting empty folder %s (%s)", txt.Quote(fs.RelName(directory, importPath)), err)
|
||||
log.Errorf("import: failed deleting empty folder %s (%s)", txt.LogParam(fs.RelName(directory, importPath)), err)
|
||||
} else {
|
||||
log.Infof("import: deleted empty folder %s", txt.Quote(fs.RelName(directory, importPath)))
|
||||
log.Infof("import: deleted empty folder %s", txt.LogParam(fs.RelName(directory, importPath)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -235,7 +235,7 @@ func (imp *Import) Start(opt ImportOptions) fs.Done {
|
||||
}
|
||||
|
||||
if err := os.Remove(file); err != nil {
|
||||
log.Errorf("import: failed removing %s (%s)", txt.Quote(fs.RelName(file, importPath)), err.Error())
|
||||
log.Errorf("import: failed removing %s (%s)", txt.LogParam(fs.RelName(file, importPath)), err.Error())
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -278,7 +278,7 @@ func (imp *Import) DestinationFilename(mainFile *MediaFile, mediaFile *MediaFile
|
||||
if f, err := entity.FirstFileByHash(mediaFile.Hash()); err == nil {
|
||||
existingFilename := FileName(f.FileRoot, f.FileName)
|
||||
if fs.FileExists(existingFilename) {
|
||||
return existingFilename, fmt.Errorf("%s is identical to %s (sha1 %s)", txt.Quote(filepath.Base(mediaFile.FileName())), txt.Quote(f.FileName), mediaFile.Hash())
|
||||
return existingFilename, fmt.Errorf("%s is identical to %s (sha1 %s)", txt.LogParam(filepath.Base(mediaFile.FileName())), txt.LogParam(f.FileName), mediaFile.Hash())
|
||||
} else {
|
||||
return existingFilename, nil
|
||||
}
|
||||
@@ -294,7 +294,7 @@ func (imp *Import) DestinationFilename(mainFile *MediaFile, mediaFile *MediaFile
|
||||
|
||||
for fs.FileExists(result) {
|
||||
if mediaFile.Hash() == fs.Hash(result) {
|
||||
return result, fmt.Errorf("%s already exists", txt.Quote(fs.RelName(result, imp.originalsPath())))
|
||||
return result, fmt.Errorf("%s already exists", txt.LogParam(fs.RelName(result, imp.originalsPath())))
|
||||
}
|
||||
|
||||
iteration++
|
||||
|
||||
@@ -30,15 +30,15 @@ func ImportWorker(jobs <-chan ImportJob) {
|
||||
importPath := job.ImportOpt.Path
|
||||
|
||||
if related.Main == nil {
|
||||
log.Warnf("import: %s belongs to no supported media file", txt.Quote(fs.RelName(job.FileName, importPath)))
|
||||
log.Warnf("import: %s belongs to no supported media file", txt.LogParam(fs.RelName(job.FileName, importPath)))
|
||||
continue
|
||||
}
|
||||
|
||||
if related.Main.NeedsExifToolJson() {
|
||||
if jsonName, err := imp.convert.ToJson(related.Main); err != nil {
|
||||
log.Debugf("import: %s in %s (extract metadata)", txt.Quote(err.Error()), txt.Quote(related.Main.BaseName()))
|
||||
log.Debugf("import: %s in %s (extract metadata)", txt.LogParam(err.Error()), txt.LogParam(related.Main.BaseName()))
|
||||
} else if err := related.Main.ReadExifToolJson(); err != nil {
|
||||
log.Errorf("import: %s in %s (read metadata)", txt.Quote(err.Error()), txt.Quote(related.Main.BaseName()))
|
||||
log.Errorf("import: %s in %s (read metadata)", txt.LogParam(err.Error()), txt.LogParam(related.Main.BaseName()))
|
||||
} else {
|
||||
log.Debugf("import: created %s", filepath.Base(jsonName))
|
||||
}
|
||||
@@ -60,7 +60,7 @@ func ImportWorker(jobs <-chan ImportJob) {
|
||||
if fs.PathExists(destDir) {
|
||||
// Do nothing.
|
||||
} else if err := os.MkdirAll(destDir, os.ModePerm); err != nil {
|
||||
log.Errorf("import: failed creating folder for %s (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
log.Errorf("import: failed creating folder for %s (%s)", txt.LogParam(f.BaseName()), err.Error())
|
||||
} else {
|
||||
destDirRel := fs.RelName(destDir, imp.originalsPath())
|
||||
|
||||
@@ -73,20 +73,20 @@ func ImportWorker(jobs <-chan ImportJob) {
|
||||
|
||||
if related.Main.HasSameName(f) {
|
||||
destMainFileName = destFileName
|
||||
log.Infof("import: moving main %s file %s to %s", f.FileType(), txt.Quote(relFileName), txt.Quote(fs.RelName(destFileName, imp.originalsPath())))
|
||||
log.Infof("import: moving main %s file %s to %s", f.FileType(), txt.LogParam(relFileName), txt.LogParam(fs.RelName(destFileName, imp.originalsPath())))
|
||||
} else {
|
||||
log.Infof("import: moving related %s file %s to %s", f.FileType(), txt.Quote(relFileName), txt.Quote(fs.RelName(destFileName, imp.originalsPath())))
|
||||
log.Infof("import: moving related %s file %s to %s", f.FileType(), txt.LogParam(relFileName), txt.LogParam(fs.RelName(destFileName, imp.originalsPath())))
|
||||
}
|
||||
|
||||
if opt.Move {
|
||||
if err := f.Move(destFileName); err != nil {
|
||||
logRelName := txt.Quote(fs.RelName(destMainFileName, imp.originalsPath()))
|
||||
logRelName := txt.LogParam(fs.RelName(destMainFileName, imp.originalsPath()))
|
||||
log.Debugf("import: %s", err.Error())
|
||||
log.Warnf("import: failed moving file to %s, is another import running at the same time?", logRelName)
|
||||
}
|
||||
} else {
|
||||
if err := f.Copy(destFileName); err != nil {
|
||||
logRelName := txt.Quote(fs.RelName(destMainFileName, imp.originalsPath()))
|
||||
logRelName := txt.LogParam(fs.RelName(destMainFileName, imp.originalsPath()))
|
||||
log.Debugf("import: %s", err.Error())
|
||||
log.Warnf("import: failed copying file to %s, is another import running at the same time?", logRelName)
|
||||
}
|
||||
@@ -106,9 +106,9 @@ func ImportWorker(jobs <-chan ImportJob) {
|
||||
// Remove duplicates to save storage.
|
||||
if opt.RemoveExistingFiles {
|
||||
if err := f.Remove(); err != nil {
|
||||
log.Errorf("import: failed deleting %s (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
log.Errorf("import: failed deleting %s (%s)", txt.LogParam(f.BaseName()), err.Error())
|
||||
} else {
|
||||
log.Infof("import: deleted %s (already exists)", txt.Quote(relFileName))
|
||||
log.Infof("import: deleted %s (already exists)", txt.LogParam(relFileName))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -118,13 +118,13 @@ func ImportWorker(jobs <-chan ImportJob) {
|
||||
f, err := NewMediaFile(destMainFileName)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("import: %s in %s", err.Error(), txt.Quote(fs.RelName(destMainFileName, imp.originalsPath())))
|
||||
log.Errorf("import: %s in %s", err.Error(), txt.LogParam(fs.RelName(destMainFileName, imp.originalsPath())))
|
||||
continue
|
||||
}
|
||||
|
||||
if f.NeedsExifToolJson() {
|
||||
if jsonName, err := imp.convert.ToJson(f); err != nil {
|
||||
log.Debugf("import: %s in %s (extract metadata)", txt.Quote(err.Error()), txt.Quote(f.BaseName()))
|
||||
log.Debugf("import: %s in %s (extract metadata)", txt.LogParam(err.Error()), txt.LogParam(f.BaseName()))
|
||||
} else {
|
||||
log.Debugf("import: created %s", filepath.Base(jsonName))
|
||||
}
|
||||
@@ -132,10 +132,10 @@ func ImportWorker(jobs <-chan ImportJob) {
|
||||
|
||||
if indexOpt.Convert && f.IsMedia() && !f.HasJpeg() {
|
||||
if jpegFile, err := imp.convert.ToJpeg(f); err != nil {
|
||||
log.Errorf("import: %s in %s (convert to jpeg)", err.Error(), txt.Quote(fs.RelName(destMainFileName, imp.originalsPath())))
|
||||
log.Errorf("import: %s in %s (convert to jpeg)", err.Error(), txt.LogParam(fs.RelName(destMainFileName, imp.originalsPath())))
|
||||
continue
|
||||
} else {
|
||||
log.Debugf("import: created %s", txt.Quote(jpegFile.BaseName()))
|
||||
log.Debugf("import: created %s", txt.LogParam(jpegFile.BaseName()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -143,7 +143,7 @@ func ImportWorker(jobs <-chan ImportJob) {
|
||||
log.Error(err)
|
||||
} else {
|
||||
if err := jpg.ResampleDefault(imp.thumbPath(), false); err != nil {
|
||||
log.Errorf("import: %s in %s (resample)", err.Error(), txt.Quote(jpg.BaseName()))
|
||||
log.Errorf("import: %s in %s (resample)", err.Error(), txt.LogParam(jpg.BaseName()))
|
||||
continue
|
||||
}
|
||||
}
|
||||
@@ -151,7 +151,7 @@ func ImportWorker(jobs <-chan ImportJob) {
|
||||
related, err := f.RelatedFiles(imp.conf.Settings().StackSequences())
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("import: %s in %s (find related files)", err.Error(), txt.Quote(fs.RelName(destMainFileName, imp.originalsPath())))
|
||||
log.Errorf("import: %s in %s (find related files)", err.Error(), txt.LogParam(fs.RelName(destMainFileName, imp.originalsPath())))
|
||||
|
||||
continue
|
||||
}
|
||||
@@ -165,13 +165,13 @@ func ImportWorker(jobs <-chan ImportJob) {
|
||||
|
||||
// Enforce file size limit for originals.
|
||||
if sizeLimit > 0 && f.FileSize() > sizeLimit {
|
||||
log.Warnf("import: %s exceeds file size limit (%d / %d MB)", txt.Quote(f.BaseName()), f.FileSize()/(1024*1024), sizeLimit/(1024*1024))
|
||||
log.Warnf("import: %s exceeds file size limit (%d / %d MB)", txt.LogParam(f.BaseName()), f.FileSize()/(1024*1024), sizeLimit/(1024*1024))
|
||||
continue
|
||||
}
|
||||
|
||||
res := ind.MediaFile(f, indexOpt, originalName)
|
||||
|
||||
log.Infof("import: %s main %s file %s", res, f.FileType(), txt.Quote(f.RelName(ind.originalsPath())))
|
||||
log.Infof("import: %s main %s file %s", res, f.FileType(), txt.LogParam(f.RelName(ind.originalsPath())))
|
||||
done[f.FileName()] = true
|
||||
|
||||
if res.Success() {
|
||||
@@ -198,13 +198,13 @@ func ImportWorker(jobs <-chan ImportJob) {
|
||||
|
||||
// Enforce file size limit for originals.
|
||||
if sizeLimit > 0 && f.FileSize() > sizeLimit {
|
||||
log.Warnf("import: %s exceeds file size limit (%d / %d MB)", txt.Quote(f.BaseName()), f.FileSize()/(1024*1024), sizeLimit/(1024*1024))
|
||||
log.Warnf("import: %s exceeds file size limit (%d / %d MB)", txt.LogParam(f.BaseName()), f.FileSize()/(1024*1024), sizeLimit/(1024*1024))
|
||||
continue
|
||||
}
|
||||
|
||||
if f.NeedsExifToolJson() {
|
||||
if jsonName, err := imp.convert.ToJson(f); err != nil {
|
||||
log.Debugf("import: %s in %s (extract metadata)", txt.Quote(err.Error()), txt.Quote(f.BaseName()))
|
||||
log.Debugf("import: %s in %s (extract metadata)", txt.LogParam(err.Error()), txt.LogParam(f.BaseName()))
|
||||
} else {
|
||||
log.Debugf("import: created %s", filepath.Base(jsonName))
|
||||
}
|
||||
@@ -214,12 +214,12 @@ func ImportWorker(jobs <-chan ImportJob) {
|
||||
|
||||
if res.Indexed() && f.IsJpeg() {
|
||||
if err := f.ResampleDefault(ind.thumbPath(), false); err != nil {
|
||||
log.Errorf("import: failed creating thumbnails for %s (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
log.Errorf("import: failed creating thumbnails for %s (%s)", txt.LogParam(f.BaseName()), err.Error())
|
||||
query.SetFileError(res.FileUID, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("import: %s related %s file %s", res, f.FileType(), txt.Quote(f.RelName(ind.originalsPath())))
|
||||
log.Infof("import: %s related %s file %s", res, f.FileType(), txt.LogParam(f.RelName(ind.originalsPath())))
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -89,7 +89,7 @@ func (ind *Index) Start(opt IndexOptions) fs.Done {
|
||||
optionsPath := filepath.Join(originalsPath, opt.Path)
|
||||
|
||||
if !fs.PathExists(optionsPath) {
|
||||
event.Error(fmt.Sprintf("index: %s does not exist", txt.Quote(optionsPath)))
|
||||
event.Error(fmt.Sprintf("index: %s does not exist", txt.LogParam(optionsPath)))
|
||||
return done
|
||||
}
|
||||
|
||||
@@ -182,7 +182,7 @@ func (ind *Index) Start(opt IndexOptions) fs.Done {
|
||||
}
|
||||
|
||||
if mf.FileSize() == 0 {
|
||||
log.Infof("index: skipped empty file %s", txt.Quote(mf.BaseName()))
|
||||
log.Infof("index: skipped empty file %s", txt.LogParam(mf.BaseName()))
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -29,12 +29,12 @@ func (ind *Index) Faces(jpeg *MediaFile, expected int) face.Faces {
|
||||
thumbName, err := jpeg.Thumbnail(Config().ThumbPath(), thumbSize)
|
||||
|
||||
if err != nil {
|
||||
log.Debugf("index: %s in %s (faces)", err, txt.Quote(jpeg.BaseName()))
|
||||
log.Debugf("index: %s in %s (faces)", err, txt.LogParam(jpeg.BaseName()))
|
||||
return face.Faces{}
|
||||
}
|
||||
|
||||
if thumbName == "" {
|
||||
log.Debugf("index: thumb %s not found in %s (faces)", thumbSize, txt.Quote(jpeg.BaseName()))
|
||||
log.Debugf("index: thumb %s not found in %s (faces)", thumbSize, txt.LogParam(jpeg.BaseName()))
|
||||
return face.Faces{}
|
||||
}
|
||||
|
||||
@@ -43,11 +43,11 @@ func (ind *Index) Faces(jpeg *MediaFile, expected int) face.Faces {
|
||||
faces, err := ind.faceNet.Detect(thumbName, Config().FaceSize(), true, expected)
|
||||
|
||||
if err != nil {
|
||||
log.Debugf("%s in %s", err, txt.Quote(jpeg.BaseName()))
|
||||
log.Debugf("%s in %s", err, txt.LogParam(jpeg.BaseName()))
|
||||
}
|
||||
|
||||
if l := len(faces); l > 0 {
|
||||
log.Infof("index: found %s in %s [%s]", english.Plural(l, "face", "faces"), txt.Quote(jpeg.BaseName()), time.Since(start))
|
||||
log.Infof("index: found %s in %s [%s]", english.Plural(l, "face", "faces"), txt.LogParam(jpeg.BaseName()), time.Since(start))
|
||||
}
|
||||
|
||||
return faces
|
||||
|
||||
@@ -28,14 +28,14 @@ func (ind *Index) Labels(jpeg *MediaFile) (results classify.Labels) {
|
||||
filename, err := jpeg.Thumbnail(Config().ThumbPath(), size)
|
||||
|
||||
if err != nil {
|
||||
log.Debugf("%s in %s", err, txt.Quote(jpeg.BaseName()))
|
||||
log.Debugf("%s in %s", err, txt.LogParam(jpeg.BaseName()))
|
||||
continue
|
||||
}
|
||||
|
||||
imageLabels, err := ind.tensorFlow.File(filename)
|
||||
|
||||
if err != nil {
|
||||
log.Debugf("%s in %s", err, txt.Quote(jpeg.BaseName()))
|
||||
log.Debugf("%s in %s", err, txt.LogParam(jpeg.BaseName()))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -58,9 +58,9 @@ func (ind *Index) Labels(jpeg *MediaFile) (results classify.Labels) {
|
||||
}
|
||||
|
||||
if l := len(labels); l == 1 {
|
||||
log.Infof("index: matched %d label with %s [%s]", l, txt.Quote(jpeg.BaseName()), time.Since(start))
|
||||
log.Infof("index: matched %d label with %s [%s]", l, txt.LogParam(jpeg.BaseName()), time.Since(start))
|
||||
} else if l > 1 {
|
||||
log.Infof("index: matched %d labels with %s [%s]", l, txt.Quote(jpeg.BaseName()), time.Since(start))
|
||||
log.Infof("index: matched %d labels with %s [%s]", l, txt.LogParam(jpeg.BaseName()), time.Since(start))
|
||||
}
|
||||
|
||||
return results
|
||||
|
||||
@@ -54,7 +54,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
||||
|
||||
fileRoot, fileBase, filePath, fileName := m.PathNameInfo(stripSequence)
|
||||
fullBase := m.BasePrefix(false)
|
||||
logName := txt.Quote(fileName)
|
||||
logName := txt.LogParam(fileName)
|
||||
fileSize, modTime, err := m.Stat()
|
||||
|
||||
if err != nil {
|
||||
@@ -160,13 +160,13 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
||||
|
||||
if fileRenamed {
|
||||
fileChanged = true
|
||||
log.Debugf("index: %s was renamed", txt.Quote(m.BaseName()))
|
||||
log.Debugf("index: %s was renamed", txt.LogParam(m.BaseName()))
|
||||
} else if file.Changed(fileSize, modTime) {
|
||||
fileChanged = true
|
||||
log.Debugf("index: %s was modified (new size %d, old size %d, new timestamp %d, old timestamp %d)", txt.Quote(m.BaseName()), fileSize, file.FileSize, modTime.Unix(), file.ModTime)
|
||||
log.Debugf("index: %s was modified (new size %d, old size %d, new timestamp %d, old timestamp %d)", txt.LogParam(m.BaseName()), fileSize, file.FileSize, modTime.Unix(), file.ModTime)
|
||||
} else if file.Missing() {
|
||||
fileChanged = true
|
||||
log.Debugf("index: %s was missing", txt.Quote(m.BaseName()))
|
||||
log.Debugf("index: %s was missing", txt.LogParam(m.BaseName()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -196,10 +196,10 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
||||
if err := photo.LoadFromYaml(yamlName); err != nil {
|
||||
log.Errorf("index: %s in %s (restore from yaml)", err.Error(), logName)
|
||||
} else if err := photo.Find(); err != nil {
|
||||
log.Infof("index: %s restored from %s", txt.Quote(m.BaseName()), txt.Quote(filepath.Base(yamlName)))
|
||||
log.Infof("index: %s restored from %s", txt.LogParam(m.BaseName()), txt.LogParam(filepath.Base(yamlName)))
|
||||
} else {
|
||||
photoExists = true
|
||||
log.Infof("index: uid %s restored from %s", photo.PhotoUID, txt.Quote(filepath.Base(yamlName)))
|
||||
log.Infof("index: uid %s restored from %s", photo.PhotoUID, txt.LogParam(filepath.Base(yamlName)))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -332,7 +332,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
||||
file.SetColorProfile(metaData.ColorProfile)
|
||||
|
||||
if metaData.HasInstanceID() {
|
||||
log.Infof("index: %s has instance_id %s", logName, txt.Quote(metaData.InstanceID))
|
||||
log.Infof("index: %s has instance_id %s", logName, txt.LogParam(metaData.InstanceID))
|
||||
|
||||
file.InstanceID = metaData.InstanceID
|
||||
}
|
||||
@@ -371,13 +371,13 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
||||
details.SetCopyright(metaData.Copyright, entity.SrcMeta)
|
||||
|
||||
if metaData.HasDocumentID() && photo.UUID == "" {
|
||||
log.Infof("index: %s has document_id %s", logName, txt.Quote(metaData.DocumentID))
|
||||
log.Infof("index: %s has document_id %s", logName, txt.LogParam(metaData.DocumentID))
|
||||
|
||||
photo.UUID = metaData.DocumentID
|
||||
}
|
||||
|
||||
if metaData.HasInstanceID() {
|
||||
log.Infof("index: %s has instance_id %s", logName, txt.Quote(metaData.InstanceID))
|
||||
log.Infof("index: %s has instance_id %s", logName, txt.LogParam(metaData.InstanceID))
|
||||
|
||||
file.InstanceID = metaData.InstanceID
|
||||
}
|
||||
@@ -421,13 +421,13 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
||||
details.SetCopyright(metaData.Copyright, entity.SrcMeta)
|
||||
|
||||
if metaData.HasDocumentID() && photo.UUID == "" {
|
||||
log.Infof("index: %s has document_id %s", logName, txt.Quote(metaData.DocumentID))
|
||||
log.Infof("index: %s has document_id %s", logName, txt.LogParam(metaData.DocumentID))
|
||||
|
||||
photo.UUID = metaData.DocumentID
|
||||
}
|
||||
|
||||
if metaData.HasInstanceID() {
|
||||
log.Infof("index: %s has instance_id %s", logName, txt.Quote(metaData.InstanceID))
|
||||
log.Infof("index: %s has instance_id %s", logName, txt.LogParam(metaData.InstanceID))
|
||||
|
||||
file.InstanceID = metaData.InstanceID
|
||||
}
|
||||
@@ -526,7 +526,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
||||
details.SetCopyright(metaData.Copyright, entity.SrcMeta)
|
||||
|
||||
if metaData.HasDocumentID() && photo.UUID == "" {
|
||||
log.Debugf("index: %s has document_id %s", logName, txt.Quote(metaData.DocumentID))
|
||||
log.Debugf("index: %s has document_id %s", logName, txt.LogParam(metaData.DocumentID))
|
||||
|
||||
photo.UUID = metaData.DocumentID
|
||||
}
|
||||
@@ -745,7 +745,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
||||
if err := photo.SaveAsYaml(yamlFile); err != nil {
|
||||
log.Errorf("index: %s in %s (update yaml)", err.Error(), logName)
|
||||
} else {
|
||||
log.Debugf("index: updated yaml file %s", txt.Quote(filepath.Base(yamlFile)))
|
||||
log.Debugf("index: updated yaml file %s", txt.LogParam(filepath.Base(yamlFile)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -20,7 +20,7 @@ func (ind *Index) NSFW(jpeg *MediaFile) bool {
|
||||
return false
|
||||
} else {
|
||||
if nsfwLabels.NSFW(nsfw.ThresholdHigh) {
|
||||
log.Warnf("index: %s might contain offensive content", txt.Quote(jpeg.RelName(Config().OriginalsPath())))
|
||||
log.Warnf("index: %s might contain offensive content", txt.LogParam(jpeg.RelName(Config().OriginalsPath())))
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import (
|
||||
func IndexMain(related *RelatedFiles, ind *Index, opt IndexOptions) (result IndexResult) {
|
||||
// Skip sidecar files without related media file.
|
||||
if related.Main == nil {
|
||||
result.Err = fmt.Errorf("index: found no main file for %s", txt.Quote(related.String()))
|
||||
result.Err = fmt.Errorf("index: found no main file for %s", txt.LogParam(related.String()))
|
||||
result.Status = IndexFailed
|
||||
return result
|
||||
}
|
||||
@@ -22,14 +22,14 @@ func IndexMain(related *RelatedFiles, ind *Index, opt IndexOptions) (result Inde
|
||||
|
||||
// Enforce file size limit for originals.
|
||||
if sizeLimit > 0 && f.FileSize() > sizeLimit {
|
||||
result.Err = fmt.Errorf("index: %s exceeds file size limit (%d / %d MB)", txt.Quote(f.BaseName()), f.FileSize()/(1024*1024), sizeLimit/(1024*1024))
|
||||
result.Err = fmt.Errorf("index: %s exceeds file size limit (%d / %d MB)", txt.LogParam(f.BaseName()), f.FileSize()/(1024*1024), sizeLimit/(1024*1024))
|
||||
result.Status = IndexFailed
|
||||
return result
|
||||
}
|
||||
|
||||
if f.NeedsExifToolJson() {
|
||||
if jsonName, err := ind.convert.ToJson(f); err != nil {
|
||||
log.Debugf("index: %s in %s (extract metadata)", txt.Quote(err.Error()), txt.Quote(f.BaseName()))
|
||||
log.Debugf("index: %s in %s (extract metadata)", txt.LogParam(err.Error()), txt.LogParam(f.BaseName()))
|
||||
} else {
|
||||
log.Debugf("index: created %s", filepath.Base(jsonName))
|
||||
}
|
||||
@@ -37,15 +37,15 @@ func IndexMain(related *RelatedFiles, ind *Index, opt IndexOptions) (result Inde
|
||||
|
||||
if opt.Convert && f.IsMedia() && !f.HasJpeg() {
|
||||
if jpegFile, err := ind.convert.ToJpeg(f); err != nil {
|
||||
result.Err = fmt.Errorf("index: failed converting %s to jpeg (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
result.Err = fmt.Errorf("index: failed converting %s to jpeg (%s)", txt.LogParam(f.BaseName()), err.Error())
|
||||
result.Status = IndexFailed
|
||||
|
||||
return result
|
||||
} else {
|
||||
log.Debugf("index: created %s", txt.Quote(jpegFile.BaseName()))
|
||||
log.Debugf("index: created %s", txt.LogParam(jpegFile.BaseName()))
|
||||
|
||||
if err := jpegFile.ResampleDefault(ind.thumbPath(), false); err != nil {
|
||||
result.Err = fmt.Errorf("index: failed creating thumbnails for %s (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
result.Err = fmt.Errorf("index: failed creating thumbnails for %s (%s)", txt.LogParam(f.BaseName()), err.Error())
|
||||
result.Status = IndexFailed
|
||||
|
||||
return result
|
||||
@@ -59,12 +59,12 @@ func IndexMain(related *RelatedFiles, ind *Index, opt IndexOptions) (result Inde
|
||||
|
||||
if result.Indexed() && f.IsJpeg() {
|
||||
if err := f.ResampleDefault(ind.thumbPath(), false); err != nil {
|
||||
log.Errorf("index: failed creating thumbnails for %s (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
log.Errorf("index: failed creating thumbnails for %s (%s)", txt.LogParam(f.BaseName()), err.Error())
|
||||
query.SetFileError(result.FileUID, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("index: %s main %s file %s", result, f.FileType(), txt.Quote(f.RelName(ind.originalsPath())))
|
||||
log.Infof("index: %s main %s file %s", result, f.FileType(), txt.LogParam(f.RelName(ind.originalsPath())))
|
||||
|
||||
return result
|
||||
}
|
||||
@@ -104,13 +104,13 @@ func IndexRelated(related RelatedFiles, ind *Index, opt IndexOptions) (result In
|
||||
|
||||
// Enforce file size limit for originals.
|
||||
if sizeLimit > 0 && f.FileSize() > sizeLimit {
|
||||
log.Warnf("index: %s exceeds file size limit (%d / %d MB)", txt.Quote(f.BaseName()), f.FileSize()/(1024*1024), sizeLimit/(1024*1024))
|
||||
log.Warnf("index: %s exceeds file size limit (%d / %d MB)", txt.LogParam(f.BaseName()), f.FileSize()/(1024*1024), sizeLimit/(1024*1024))
|
||||
continue
|
||||
}
|
||||
|
||||
if f.NeedsExifToolJson() {
|
||||
if jsonName, err := ind.convert.ToJson(f); err != nil {
|
||||
log.Debugf("index: %s in %s (extract metadata)", txt.Quote(err.Error()), txt.Quote(f.BaseName()))
|
||||
log.Debugf("index: %s in %s (extract metadata)", txt.LogParam(err.Error()), txt.LogParam(f.BaseName()))
|
||||
} else {
|
||||
log.Debugf("index: created %s", filepath.Base(jsonName))
|
||||
}
|
||||
@@ -118,15 +118,15 @@ func IndexRelated(related RelatedFiles, ind *Index, opt IndexOptions) (result In
|
||||
|
||||
if opt.Convert && f.IsMedia() && !f.HasJpeg() {
|
||||
if jpegFile, err := ind.convert.ToJpeg(f); err != nil {
|
||||
result.Err = fmt.Errorf("index: failed converting %s to jpeg (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
result.Err = fmt.Errorf("index: failed converting %s to jpeg (%s)", txt.LogParam(f.BaseName()), err.Error())
|
||||
result.Status = IndexFailed
|
||||
|
||||
return result
|
||||
} else {
|
||||
log.Debugf("index: created %s", txt.Quote(jpegFile.BaseName()))
|
||||
log.Debugf("index: created %s", txt.LogParam(jpegFile.BaseName()))
|
||||
|
||||
if err := jpegFile.ResampleDefault(ind.thumbPath(), false); err != nil {
|
||||
result.Err = fmt.Errorf("index: failed creating thumbnails for %s (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
result.Err = fmt.Errorf("index: failed creating thumbnails for %s (%s)", txt.LogParam(f.BaseName()), err.Error())
|
||||
result.Status = IndexFailed
|
||||
|
||||
return result
|
||||
@@ -140,12 +140,12 @@ func IndexRelated(related RelatedFiles, ind *Index, opt IndexOptions) (result In
|
||||
|
||||
if res.Indexed() && f.IsJpeg() {
|
||||
if err := f.ResampleDefault(ind.thumbPath(), false); err != nil {
|
||||
log.Errorf("index: failed creating thumbnails for %s (%s)", txt.Quote(f.BaseName()), err.Error())
|
||||
log.Errorf("index: failed creating thumbnails for %s (%s)", txt.LogParam(f.BaseName()), err.Error())
|
||||
query.SetFileError(res.FileUID, err.Error())
|
||||
}
|
||||
}
|
||||
|
||||
log.Infof("index: %s related %s file %s", res, f.FileType(), txt.Quote(f.BaseName()))
|
||||
log.Infof("index: %s related %s file %s", res, f.FileType(), txt.LogParam(f.BaseName()))
|
||||
}
|
||||
|
||||
return result
|
||||
|
||||
@@ -60,7 +60,7 @@ func NewMediaFile(fileName string) (*MediaFile, error) {
|
||||
}
|
||||
|
||||
if _, _, err := m.Stat(); err != nil {
|
||||
return m, fmt.Errorf("media: %s not found", txt.Quote(m.BaseName()))
|
||||
return m, fmt.Errorf("media: %s not found", txt.LogParam(m.BaseName()))
|
||||
}
|
||||
|
||||
return m, nil
|
||||
@@ -300,12 +300,12 @@ func (m *MediaFile) RelatedFiles(stripSequence bool) (result RelatedFiles, err e
|
||||
f, err := NewMediaFile(fileName)
|
||||
|
||||
if err != nil {
|
||||
log.Warnf("media: %s in %s", err, txt.Quote(filepath.Base(fileName)))
|
||||
log.Warnf("media: %s in %s", err, txt.LogParam(filepath.Base(fileName)))
|
||||
continue
|
||||
}
|
||||
|
||||
if f.FileSize() == 0 {
|
||||
log.Warnf("media: %s is empty", txt.Quote(filepath.Base(fileName)))
|
||||
log.Warnf("media: %s is empty", txt.LogParam(filepath.Base(fileName)))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -335,7 +335,7 @@ func (m *MediaFile) RelatedFiles(stripSequence bool) (result RelatedFiles, err e
|
||||
t = "unknown type"
|
||||
}
|
||||
|
||||
return result, fmt.Errorf("no supported files found for %s (%s)", txt.Quote(m.BaseName()), t)
|
||||
return result, fmt.Errorf("no supported files found for %s (%s)", txt.LogParam(m.BaseName()), t)
|
||||
}
|
||||
|
||||
// Add hidden JPEG if exists.
|
||||
@@ -789,7 +789,7 @@ func (m *MediaFile) HasJpeg() bool {
|
||||
|
||||
func (m *MediaFile) decodeDimensions() error {
|
||||
if !m.IsMedia() {
|
||||
return fmt.Errorf("failed decoding dimensions for %s", txt.Quote(m.BaseName()))
|
||||
return fmt.Errorf("failed decoding dimensions for %s", txt.LogParam(m.BaseName()))
|
||||
}
|
||||
|
||||
if m.IsJpeg() || m.IsPng() || m.IsGif() {
|
||||
@@ -901,7 +901,7 @@ func (m *MediaFile) Thumbnail(path string, sizeName thumb.Name) (filename string
|
||||
thumbnail, err := thumb.FromFile(m.FileName(), m.Hash(), path, size.Width, size.Height, m.Orientation(), size.Options...)
|
||||
|
||||
if err != nil {
|
||||
err = fmt.Errorf("media: failed creating thumbnail for %s (%s)", txt.Quote(m.BaseName()), err)
|
||||
err = fmt.Errorf("media: failed creating thumbnail for %s (%s)", txt.LogParam(m.BaseName()), err)
|
||||
log.Debug(err)
|
||||
return "", err
|
||||
}
|
||||
@@ -949,7 +949,7 @@ func (m *MediaFile) ResampleDefault(thumbPath string, force bool) (err error) {
|
||||
}
|
||||
|
||||
if fileName, err := thumb.FileName(hash, thumbPath, size.Width, size.Height, size.Options...); err != nil {
|
||||
log.Errorf("media: failed creating %s (%s)", txt.Quote(string(name)), err)
|
||||
log.Errorf("media: failed creating %s (%s)", txt.LogParam(string(name)), err)
|
||||
|
||||
return err
|
||||
} else {
|
||||
@@ -961,7 +961,7 @@ func (m *MediaFile) ResampleDefault(thumbPath string, force bool) (err error) {
|
||||
img, err := thumb.Open(m.FileName(), m.Orientation())
|
||||
|
||||
if err != nil {
|
||||
log.Debugf("media: %s in %s", err.Error(), txt.Quote(m.BaseName()))
|
||||
log.Debugf("media: %s in %s", err.Error(), txt.LogParam(m.BaseName()))
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -980,7 +980,7 @@ func (m *MediaFile) ResampleDefault(thumbPath string, force bool) (err error) {
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("media: failed creating %s (%s)", txt.Quote(string(name)), err)
|
||||
log.Errorf("media: failed creating %s (%s)", txt.LogParam(string(name)), err)
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -1015,9 +1015,9 @@ func (m *MediaFile) RenameSidecars(oldFileName string) (renamed map[string]strin
|
||||
renamed[fs.RelName(srcName, sidecarPath)] = fs.RelName(destName, sidecarPath)
|
||||
|
||||
if err := os.Remove(srcName); err != nil {
|
||||
log.Errorf("media: failed removing sidecar %s", txt.Quote(fs.RelName(srcName, sidecarPath)))
|
||||
log.Errorf("media: failed removing sidecar %s", txt.LogParam(fs.RelName(srcName, sidecarPath)))
|
||||
} else {
|
||||
log.Infof("media: removed sidecar %s", txt.Quote(fs.RelName(srcName, sidecarPath)))
|
||||
log.Infof("media: removed sidecar %s", txt.LogParam(fs.RelName(srcName, sidecarPath)))
|
||||
}
|
||||
|
||||
continue
|
||||
@@ -1026,7 +1026,7 @@ func (m *MediaFile) RenameSidecars(oldFileName string) (renamed map[string]strin
|
||||
if err := fs.Move(srcName, destName); err != nil {
|
||||
return renamed, err
|
||||
} else {
|
||||
log.Infof("media: moved existing sidecar to %s", txt.Quote(newName+filepath.Ext(srcName)))
|
||||
log.Infof("media: moved existing sidecar to %s", txt.LogParam(newName+filepath.Ext(srcName)))
|
||||
renamed[fs.RelName(srcName, sidecarPath)] = fs.RelName(destName, sidecarPath)
|
||||
}
|
||||
}
|
||||
@@ -1051,9 +1051,9 @@ func (m *MediaFile) RemoveSidecars() (err error) {
|
||||
|
||||
for _, sidecarName := range matches {
|
||||
if err = os.Remove(sidecarName); err != nil {
|
||||
log.Errorf("media: failed removing sidecar %s", txt.Quote(fs.RelName(sidecarName, sidecarPath)))
|
||||
log.Errorf("media: failed removing sidecar %s", txt.LogParam(fs.RelName(sidecarName, sidecarPath)))
|
||||
} else {
|
||||
log.Infof("media: removed sidecar %s", txt.Quote(fs.RelName(sidecarName, sidecarPath)))
|
||||
log.Infof("media: removed sidecar %s", txt.LogParam(fs.RelName(sidecarName, sidecarPath)))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -80,7 +80,7 @@ func (m *MediaFile) MetaData() (result meta.Data) {
|
||||
// Parse regular JSON sidecar files ("img_1234.json")
|
||||
if !m.IsSidecar() {
|
||||
if jsonFiles := fs.FormatJson.FindAll(m.FileName(), []string{Config().SidecarPath(), fs.HiddenPath}, Config().OriginalsPath(), false); len(jsonFiles) == 0 {
|
||||
log.Tracef("metadata: found no additional sidecar file for %s", txt.Quote(filepath.Base(m.FileName())))
|
||||
log.Tracef("metadata: found no additional sidecar file for %s", txt.LogParam(filepath.Base(m.FileName())))
|
||||
} else {
|
||||
for _, jsonFile := range jsonFiles {
|
||||
jsonErr := m.metaData.JSON(jsonFile, m.BaseName())
|
||||
@@ -102,7 +102,7 @@ func (m *MediaFile) MetaData() (result meta.Data) {
|
||||
|
||||
if err != nil {
|
||||
m.metaData.Error = err
|
||||
log.Debugf("metadata: %s in %s", err, txt.Quote(m.BaseName()))
|
||||
log.Debugf("metadata: %s in %s", err, txt.LogParam(m.BaseName()))
|
||||
}
|
||||
})
|
||||
|
||||
|
||||
@@ -95,11 +95,11 @@ func (w *Moments) Start() (err error) {
|
||||
if a := entity.FindFolderAlbum(mom.Path); a != nil {
|
||||
if a.DeletedAt != nil {
|
||||
// Nothing to do.
|
||||
log.Tracef("moments: %s was deleted (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Tracef("moments: %s was deleted (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
} else if err := a.UpdateFolder(mom.Path, f.Serialize()); err != nil {
|
||||
log.Errorf("moments: %s (update folder)", err.Error())
|
||||
} else {
|
||||
log.Tracef("moments: %s already exists (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Tracef("moments: %s already exists (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
}
|
||||
} else if a := entity.NewFolderAlbum(mom.Title(), mom.Path, f.Serialize()); a != nil {
|
||||
a.AlbumYear = mom.FolderYear
|
||||
@@ -110,7 +110,7 @@ func (w *Moments) Start() (err error) {
|
||||
if err := a.Create(); err != nil {
|
||||
log.Errorf("moments: %s (create folder)", err)
|
||||
} else {
|
||||
log.Infof("moments: added %s (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Infof("moments: added %s (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -127,17 +127,17 @@ func (w *Moments) Start() (err error) {
|
||||
}
|
||||
|
||||
if !a.Deleted() {
|
||||
log.Tracef("moments: %s already exists (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Tracef("moments: %s already exists (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
} else if err := a.Restore(); err != nil {
|
||||
log.Errorf("moments: %s (restore month)", err.Error())
|
||||
} else {
|
||||
log.Infof("moments: %s restored", txt.Quote(a.AlbumTitle))
|
||||
log.Infof("moments: %s restored", txt.LogParam(a.AlbumTitle))
|
||||
}
|
||||
} else if a := entity.NewMonthAlbum(mom.Title(), mom.Slug(), mom.Year, mom.Month); a != nil {
|
||||
if err := a.Create(); err != nil {
|
||||
log.Errorf("moments: %s", err)
|
||||
} else {
|
||||
log.Infof("moments: added %s (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Infof("moments: added %s (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -161,9 +161,9 @@ func (w *Moments) Start() (err error) {
|
||||
|
||||
if a.DeletedAt != nil {
|
||||
// Nothing to do.
|
||||
log.Tracef("moments: %s was deleted (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Tracef("moments: %s was deleted (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
} else {
|
||||
log.Tracef("moments: %s already exists (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Tracef("moments: %s already exists (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
}
|
||||
} else if a := entity.NewMomentsAlbum(mom.Title(), mom.Slug(), f.Serialize()); a != nil {
|
||||
a.AlbumYear = mom.Year
|
||||
@@ -172,7 +172,7 @@ func (w *Moments) Start() (err error) {
|
||||
if err := a.Create(); err != nil {
|
||||
log.Errorf("moments: %s", err)
|
||||
} else {
|
||||
log.Infof("moments: added %s (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Infof("moments: added %s (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -195,11 +195,11 @@ func (w *Moments) Start() (err error) {
|
||||
}
|
||||
|
||||
if !a.Deleted() {
|
||||
log.Tracef("moments: %s already exists (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Tracef("moments: %s already exists (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
} else if err := a.Restore(); err != nil {
|
||||
log.Errorf("moments: %s (restore state)", err.Error())
|
||||
} else {
|
||||
log.Infof("moments: %s restored", txt.Quote(a.AlbumTitle))
|
||||
log.Infof("moments: %s restored", txt.LogParam(a.AlbumTitle))
|
||||
}
|
||||
} else if a := entity.NewStateAlbum(mom.Title(), mom.Slug(), f.Serialize()); a != nil {
|
||||
a.AlbumLocation = mom.CountryName()
|
||||
@@ -209,7 +209,7 @@ func (w *Moments) Start() (err error) {
|
||||
if err := a.Create(); err != nil {
|
||||
log.Errorf("moments: %s", err)
|
||||
} else {
|
||||
log.Infof("moments: added %s (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Infof("moments: added %s (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -233,20 +233,20 @@ func (w *Moments) Start() (err error) {
|
||||
}
|
||||
|
||||
if a.DeletedAt != nil || f.Serialize() == a.AlbumFilter {
|
||||
log.Tracef("moments: %s already exists (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Tracef("moments: %s already exists (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
continue
|
||||
}
|
||||
|
||||
if err := a.Update("AlbumFilter", f.Serialize()); err != nil {
|
||||
log.Errorf("moments: %s", err.Error())
|
||||
} else {
|
||||
log.Debugf("moments: updated %s (%s)", txt.Quote(a.AlbumTitle), f.Serialize())
|
||||
log.Debugf("moments: updated %s (%s)", txt.LogParam(a.AlbumTitle), f.Serialize())
|
||||
}
|
||||
} else if a := entity.NewMomentsAlbum(mom.Title(), mom.Slug(), f.Serialize()); a != nil {
|
||||
if err := a.Create(); err != nil {
|
||||
log.Errorf("moments: %s", err.Error())
|
||||
} else {
|
||||
log.Infof("moments: added %s (%s)", txt.Quote(a.AlbumTitle), a.AlbumFilter)
|
||||
log.Infof("moments: added %s (%s)", txt.LogParam(a.AlbumTitle), a.AlbumFilter)
|
||||
}
|
||||
} else {
|
||||
log.Errorf("moments: failed to create new moment %s (%s)", mom.Title(), f.Serialize())
|
||||
|
||||
@@ -87,20 +87,20 @@ func (w *Purge) Start(opt PurgeOptions) (purgedFiles map[string]bool, purgedPhot
|
||||
if file.FileMissing {
|
||||
if fs.FileExists(fileName) {
|
||||
if opt.Dry {
|
||||
log.Infof("purge: found %s", txt.Quote(file.FileName))
|
||||
log.Infof("purge: found %s", txt.LogParam(file.FileName))
|
||||
continue
|
||||
}
|
||||
|
||||
if err := file.Found(); err != nil {
|
||||
log.Errorf("purge: %s", err)
|
||||
} else {
|
||||
log.Infof("purge: found %s", txt.Quote(file.FileName))
|
||||
log.Infof("purge: found %s", txt.LogParam(file.FileName))
|
||||
}
|
||||
}
|
||||
} else if !fs.FileExists(fileName) {
|
||||
if opt.Dry {
|
||||
purgedFiles[fileName] = true
|
||||
log.Infof("purge: file %s would be flagged as missing", txt.Quote(file.FileName))
|
||||
log.Infof("purge: file %s would be flagged as missing", txt.LogParam(file.FileName))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -113,7 +113,7 @@ func (w *Purge) Start(opt PurgeOptions) (purgedFiles map[string]bool, purgedPhot
|
||||
|
||||
w.files.Remove(file.FileName, file.FileRoot)
|
||||
purgedFiles[fileName] = true
|
||||
log.Infof("purge: flagged file %s as missing", txt.Quote(file.FileName))
|
||||
log.Infof("purge: flagged file %s as missing", txt.LogParam(file.FileName))
|
||||
|
||||
if !wasPrimary {
|
||||
continue
|
||||
@@ -162,7 +162,7 @@ func (w *Purge) Start(opt PurgeOptions) (purgedFiles map[string]bool, purgedPhot
|
||||
if !fs.FileExists(fileName) {
|
||||
if opt.Dry {
|
||||
purgedFiles[fileName] = true
|
||||
log.Infof("purge: duplicate %s would be removed", txt.Quote(file.FileName))
|
||||
log.Infof("purge: duplicate %s would be removed", txt.LogParam(file.FileName))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -171,7 +171,7 @@ func (w *Purge) Start(opt PurgeOptions) (purgedFiles map[string]bool, purgedPhot
|
||||
} else {
|
||||
w.files.Remove(file.FileName, file.FileRoot)
|
||||
purgedFiles[fileName] = true
|
||||
log.Infof("purge: removed duplicate %s", txt.Quote(file.FileName))
|
||||
log.Infof("purge: removed duplicate %s", txt.LogParam(file.FileName))
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -210,7 +210,7 @@ func (w *Purge) Start(opt PurgeOptions) (purgedFiles map[string]bool, purgedPhot
|
||||
|
||||
if opt.Dry {
|
||||
purgedPhotos[photo.PhotoUID] = true
|
||||
log.Infof("purge: %s would be removed", txt.Quote(photo.PhotoName))
|
||||
log.Infof("purge: %s would be removed", txt.LogParam(photo.PhotoName))
|
||||
continue
|
||||
}
|
||||
|
||||
@@ -220,9 +220,9 @@ func (w *Purge) Start(opt PurgeOptions) (purgedFiles map[string]bool, purgedPhot
|
||||
purgedPhotos[photo.PhotoUID] = true
|
||||
|
||||
if opt.Hard {
|
||||
log.Infof("purge: permanently removed %s", txt.Quote(photo.PhotoName))
|
||||
log.Infof("purge: permanently removed %s", txt.LogParam(photo.PhotoName))
|
||||
} else {
|
||||
log.Infof("purge: flagged photo %s as deleted", txt.Quote(photo.PhotoName))
|
||||
log.Infof("purge: flagged photo %s as deleted", txt.LogParam(photo.PhotoName))
|
||||
}
|
||||
|
||||
// Remove files from lookup table.
|
||||
|
||||
@@ -52,7 +52,7 @@ func AlbumCoverByUID(uid string) (file entity.File, err error) {
|
||||
if err := a.Delete(); err != nil {
|
||||
log.Errorf("%s: %s (hide)", a.AlbumType, err)
|
||||
} else {
|
||||
log.Infof("%s: %s hidden", a.AlbumType, txt.Quote(a.AlbumTitle))
|
||||
log.Infof("%s: %s hidden", a.AlbumType, txt.LogParam(a.AlbumTitle))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -138,15 +138,15 @@ func MergeFaces(merge entity.Faces) (merged *entity.Face, err error) {
|
||||
for i := 1; i < len(merge); i++ {
|
||||
if merge[i].SubjUID != subjUID {
|
||||
return merged, fmt.Errorf("faces: can't merge clusters with conflicting subjects %s <> %s",
|
||||
txt.Quote(subjUID), txt.Quote(merge[i].SubjUID))
|
||||
txt.LogParam(subjUID), txt.LogParam(merge[i].SubjUID))
|
||||
}
|
||||
}
|
||||
|
||||
// Find or create merged face cluster.
|
||||
if merged = entity.NewFace(merge[0].SubjUID, merge[0].FaceSrc, merge.Embeddings()); merged == nil {
|
||||
return merged, fmt.Errorf("faces: new cluster is nil for subject %s", txt.Quote(subjUID))
|
||||
return merged, fmt.Errorf("faces: new cluster is nil for subject %s", txt.LogParam(subjUID))
|
||||
} else if merged = entity.FirstOrCreateFace(merged); merged == nil {
|
||||
return merged, fmt.Errorf("faces: failed creating new cluster for subject %s", txt.Quote(subjUID))
|
||||
return merged, fmt.Errorf("faces: failed creating new cluster for subject %s", txt.LogParam(subjUID))
|
||||
} else if err := merged.MatchMarkers(append(merge.IDs(), "")); err != nil {
|
||||
return merged, err
|
||||
}
|
||||
@@ -155,9 +155,9 @@ func MergeFaces(merge entity.Faces) (merged *entity.Face, err error) {
|
||||
if removed, err := PurgeOrphanFaces(merge.IDs()); err != nil {
|
||||
return merged, err
|
||||
} else if removed > 0 {
|
||||
log.Debugf("faces: removed %d orphans for subject %s", removed, txt.Quote(subjUID))
|
||||
log.Debugf("faces: removed %d orphans for subject %s", removed, txt.LogParam(subjUID))
|
||||
} else {
|
||||
log.Warnf("faces: failed removing merged clusters for subject %s", txt.Quote(subjUID))
|
||||
log.Warnf("faces: failed removing merged clusters for subject %s", txt.LogParam(subjUID))
|
||||
}
|
||||
|
||||
return merged, err
|
||||
@@ -185,13 +185,13 @@ func ResolveFaceCollisions() (conflicts, resolved int, err error) {
|
||||
log.Infof("face %s: ambiguous subject at dist %f, Ø %f from %d samples, collision Ø %f", f1.ID, dist, r, f1.Samples, f1.CollisionRadius)
|
||||
|
||||
if f1.SubjUID != "" {
|
||||
log.Debugf("face %s: subject %s (%s %s)", f1.ID, txt.Quote(f1.SubjUID), f1.SubjUID, entity.SrcString(f1.FaceSrc))
|
||||
log.Debugf("face %s: subject %s (%s %s)", f1.ID, txt.LogParam(f1.SubjUID), f1.SubjUID, entity.SrcString(f1.FaceSrc))
|
||||
} else {
|
||||
log.Debugf("face %s: has no subject (%s)", f1.ID, entity.SrcString(f1.FaceSrc))
|
||||
}
|
||||
|
||||
if f2.SubjUID != "" {
|
||||
log.Debugf("face %s: subject %s (%s %s)", f2.ID, txt.Quote(f2.SubjUID), f2.SubjUID, entity.SrcString(f2.FaceSrc))
|
||||
log.Debugf("face %s: subject %s (%s %s)", f2.ID, txt.LogParam(f2.SubjUID), f2.SubjUID, entity.SrcString(f2.FaceSrc))
|
||||
} else {
|
||||
log.Debugf("face %s: has no subject (%s)", f2.ID, entity.SrcString(f2.FaceSrc))
|
||||
}
|
||||
|
||||
@@ -94,10 +94,10 @@ func CreateMarkerSubjects() (affected int64, err error) {
|
||||
if name == m.MarkerName && subj != nil {
|
||||
// Do nothing.
|
||||
} else if subj = entity.NewSubject(m.MarkerName, entity.SubjPerson, entity.SrcMarker); subj == nil {
|
||||
log.Errorf("faces: invalid subject %s", txt.Quote(m.MarkerName))
|
||||
log.Errorf("faces: invalid subject %s", txt.LogParam(m.MarkerName))
|
||||
continue
|
||||
} else if subj = entity.FirstOrCreateSubject(subj); subj == nil {
|
||||
log.Errorf("faces: failed adding subject %s", txt.Quote(m.MarkerName))
|
||||
log.Errorf("faces: failed adding subject %s", txt.LogParam(m.MarkerName))
|
||||
continue
|
||||
} else {
|
||||
affected++
|
||||
|
||||
@@ -104,7 +104,7 @@ func Geo(f form.SearchGeo) (results GeoResults, err error) {
|
||||
var labelIds []uint
|
||||
|
||||
if err := Db().Where(AnySlug("custom_slug", f.Query, " ")).Find(&labels).Error; len(labels) == 0 || err != nil {
|
||||
log.Debugf("search: label %s not found, using fuzzy search", txt.QuoteLower(f.Query))
|
||||
log.Debugf("search: label %s not found, using fuzzy search", txt.LogParamLower(f.Query))
|
||||
|
||||
for _, where := range LikeAnyKeyword("k.keyword", f.Query) {
|
||||
s = s.Where("photos.id IN (SELECT pk.photo_id FROM keywords k JOIN photos_keywords pk ON k.id = pk.keyword_id WHERE (?))", gorm.Expr(where))
|
||||
@@ -115,7 +115,7 @@ func Geo(f form.SearchGeo) (results GeoResults, err error) {
|
||||
|
||||
Db().Where("category_id = ?", l.ID).Find(&categories)
|
||||
|
||||
log.Debugf("search: label %s includes %d categories", txt.QuoteLower(l.LabelName), len(categories))
|
||||
log.Debugf("search: label %s includes %d categories", txt.LogParamLower(l.LabelName), len(categories))
|
||||
|
||||
for _, category := range categories {
|
||||
labelIds = append(labelIds, category.LabelID)
|
||||
|
||||
@@ -59,7 +59,7 @@ func Labels(f form.SearchLabels) (results []Label, err error) {
|
||||
likeString := "%" + f.Query + "%"
|
||||
|
||||
if result := Db().First(&label, "label_slug = ? OR custom_slug = ?", slugString, slugString); result.Error != nil {
|
||||
log.Infof("search: label %s not found", txt.Quote(f.Query))
|
||||
log.Infof("search: label %s not found", txt.LogParam(f.Query))
|
||||
|
||||
s = s.Where("labels.label_name LIKE ?", likeString)
|
||||
} else {
|
||||
@@ -71,7 +71,7 @@ func Labels(f form.SearchLabels) (results []Label, err error) {
|
||||
labelIds = append(labelIds, category.LabelID)
|
||||
}
|
||||
|
||||
log.Infof("search: label %s includes %d categories", txt.Quote(label.LabelName), len(labelIds))
|
||||
log.Infof("search: label %s includes %d categories", txt.LogParam(label.LabelName), len(labelIds))
|
||||
|
||||
s = s.Where("labels.id IN (?)", labelIds)
|
||||
}
|
||||
|
||||
@@ -116,7 +116,7 @@ func Photos(f form.SearchPhotos) (results PhotoResults, count int, err error) {
|
||||
|
||||
if f.Label != "" {
|
||||
if err := Db().Where(AnySlug("label_slug", f.Label, txt.Or)).Or(AnySlug("custom_slug", f.Label, txt.Or)).Find(&labels).Error; len(labels) == 0 || err != nil {
|
||||
log.Debugf("search: label %s not found", txt.QuoteLower(f.Label))
|
||||
log.Debugf("search: label %s not found", txt.LogParamLower(f.Label))
|
||||
return PhotoResults{}, 0, nil
|
||||
} else {
|
||||
for _, l := range labels {
|
||||
@@ -124,7 +124,7 @@ func Photos(f form.SearchPhotos) (results PhotoResults, count int, err error) {
|
||||
|
||||
Db().Where("category_id = ?", l.ID).Find(&categories)
|
||||
|
||||
log.Infof("search: label %s includes %d categories", txt.QuoteLower(l.LabelName), len(categories))
|
||||
log.Infof("search: label %s includes %d categories", txt.LogParamLower(l.LabelName), len(categories))
|
||||
|
||||
for _, category := range categories {
|
||||
labelIds = append(labelIds, category.LabelID)
|
||||
@@ -195,7 +195,7 @@ func Photos(f form.SearchPhotos) (results PhotoResults, count int, err error) {
|
||||
}
|
||||
} else if f.Query != "" {
|
||||
if err := Db().Where(AnySlug("custom_slug", f.Query, " ")).Find(&labels).Error; len(labels) == 0 || err != nil {
|
||||
log.Debugf("search: label %s not found, using fuzzy search", txt.QuoteLower(f.Query))
|
||||
log.Debugf("search: label %s not found, using fuzzy search", txt.LogParamLower(f.Query))
|
||||
|
||||
for _, where := range LikeAnyKeyword("k.keyword", f.Query) {
|
||||
s = s.Where("photos.id IN (SELECT pk.photo_id FROM keywords k JOIN photos_keywords pk ON k.id = pk.keyword_id WHERE (?))", gorm.Expr(where))
|
||||
@@ -206,7 +206,7 @@ func Photos(f form.SearchPhotos) (results PhotoResults, count int, err error) {
|
||||
|
||||
Db().Where("category_id = ?", l.ID).Find(&categories)
|
||||
|
||||
log.Debugf("search: label %s includes %d categories", txt.QuoteLower(l.LabelName), len(categories))
|
||||
log.Debugf("search: label %s includes %d categories", txt.LogParamLower(l.LabelName), len(categories))
|
||||
|
||||
for _, category := range categories {
|
||||
labelIds = append(labelIds, category.LabelID)
|
||||
|
||||
@@ -3,6 +3,8 @@ package server
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/photoprism/photoprism/pkg/txt"
|
||||
|
||||
"github.com/gin-gonic/gin"
|
||||
)
|
||||
|
||||
@@ -32,7 +34,7 @@ func Logger() gin.HandlerFunc {
|
||||
// Use debug level to keep production logs clean.
|
||||
log.Debugf("http: %s %s (%3d) [%v]",
|
||||
method,
|
||||
path,
|
||||
txt.LogParam(path),
|
||||
statusCode,
|
||||
latency,
|
||||
)
|
||||
|
||||
@@ -83,7 +83,7 @@ func (s *security) process(w http.ResponseWriter, r *http.Request) error {
|
||||
|
||||
if !isGoodHost {
|
||||
s.opt.BadHostHandler.ServeHTTP(w, r)
|
||||
return fmt.Errorf("http: bad host %s", txt.Quote(r.Host))
|
||||
return fmt.Errorf("http: bad host %s", txt.LogParam(r.Host))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ func MarkUploadAsFavorite(fileName string) {
|
||||
|
||||
// Abort if YAML file already exists to avoid overwriting metadata.
|
||||
if fs.FileExists(yamlName) {
|
||||
log.Warnf("webdav: %s already exists", txt.Quote(filepath.Base(yamlName)))
|
||||
log.Warnf("webdav: %s already exists", txt.LogParam(filepath.Base(yamlName)))
|
||||
return
|
||||
}
|
||||
|
||||
@@ -42,7 +42,7 @@ func MarkUploadAsFavorite(fileName string) {
|
||||
}
|
||||
|
||||
// Log success.
|
||||
log.Infof("webdav: marked %s as favorite", txt.Quote(filepath.Base(fileName)))
|
||||
log.Infof("webdav: marked %s as favorite", txt.LogParam(filepath.Base(fileName)))
|
||||
}
|
||||
|
||||
// WebDAV handles any requests to /originals|import/*
|
||||
@@ -67,11 +67,11 @@ func WebDAV(path string, router *gin.RouterGroup, conf *config.Config) {
|
||||
if err != nil {
|
||||
switch r.Method {
|
||||
case MethodPut, MethodPost, MethodPatch, MethodDelete, MethodCopy, MethodMove:
|
||||
log.Errorf("webdav: %s in %s %s", txt.Quote(err.Error()), r.Method, r.URL)
|
||||
log.Errorf("webdav: %s in %s %s", txt.LogParam(err.Error()), txt.LogParam(r.Method), txt.LogParam(r.URL.String()))
|
||||
case MethodPropfind:
|
||||
log.Tracef("webdav: %s in %s %s", txt.Quote(err.Error()), r.Method, r.URL)
|
||||
log.Tracef("webdav: %s in %s %s", txt.LogParam(err.Error()), txt.LogParam(r.Method), txt.LogParam(r.URL.String()))
|
||||
default:
|
||||
log.Debugf("webdav: %s in %s %s", txt.Quote(err.Error()), r.Method, r.URL)
|
||||
log.Debugf("webdav: %s in %s %s", txt.LogParam(err.Error()), txt.LogParam(r.Method), txt.LogParam(r.URL.String()))
|
||||
}
|
||||
|
||||
} else {
|
||||
@@ -86,7 +86,7 @@ func WebDAV(path string, router *gin.RouterGroup, conf *config.Config) {
|
||||
|
||||
switch r.Method {
|
||||
case MethodPut, MethodPost, MethodPatch, MethodDelete, MethodCopy, MethodMove:
|
||||
log.Infof("webdav: %s %s", r.Method, r.URL)
|
||||
log.Infof("webdav: %s %s", txt.LogParam(r.Method), txt.LogParam(r.URL.String()))
|
||||
|
||||
if router.BasePath() == WebDAVOriginals {
|
||||
auto.ShouldIndex()
|
||||
@@ -94,7 +94,7 @@ func WebDAV(path string, router *gin.RouterGroup, conf *config.Config) {
|
||||
auto.ShouldImport()
|
||||
}
|
||||
default:
|
||||
log.Tracef("webdav: %s %s", r.Method, r.URL)
|
||||
log.Tracef("webdav: %s %s", txt.LogParam(r.Method), txt.LogParam(r.URL.String()))
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
@@ -35,7 +35,7 @@ func FileName(hash string, thumbPath string, width, height int, opts ...Resample
|
||||
}
|
||||
|
||||
if len(hash) < 4 {
|
||||
return "", fmt.Errorf("resample: file hash is empty or too short (%s)", txt.Quote(hash))
|
||||
return "", fmt.Errorf("resample: file hash is empty or too short (%s)", txt.LogParam(hash))
|
||||
}
|
||||
|
||||
if len(thumbPath) == 0 {
|
||||
@@ -57,11 +57,11 @@ func FileName(hash string, thumbPath string, width, height int, opts ...Resample
|
||||
// FromCache returns the thumb cache file name for an image.
|
||||
func FromCache(imageFilename, hash, thumbPath string, width, height int, opts ...ResampleOption) (fileName string, err error) {
|
||||
if len(hash) < 4 {
|
||||
return "", fmt.Errorf("resample: invalid file hash %s", txt.Quote(hash))
|
||||
return "", fmt.Errorf("resample: invalid file hash %s", txt.LogParam(hash))
|
||||
}
|
||||
|
||||
if len(imageFilename) < 4 {
|
||||
return "", fmt.Errorf("resample: invalid file name %s", txt.Quote(imageFilename))
|
||||
return "", fmt.Errorf("resample: invalid file name %s", txt.LogParam(imageFilename))
|
||||
}
|
||||
|
||||
fileName, err = FileName(hash, thumbPath, width, height, opts...)
|
||||
@@ -135,7 +135,7 @@ func Create(img image.Image, fileName string, width, height int, opts ...Resampl
|
||||
err = imaging.Save(result, fileName, saveOption)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("resample: failed to save %s", txt.Quote(filepath.Base(fileName)))
|
||||
log.Errorf("resample: failed to save %s", txt.LogParam(filepath.Base(fileName)))
|
||||
return result, err
|
||||
}
|
||||
|
||||
|
||||
@@ -272,7 +272,7 @@ func TestFromFile(t *testing.T) {
|
||||
t.Fatal("error expected")
|
||||
}
|
||||
assert.Equal(t, "", fileName)
|
||||
assert.Equal(t, "resample: invalid file name “”", err.Error())
|
||||
assert.Equal(t, "resample: invalid file name ''", err.Error())
|
||||
})
|
||||
}
|
||||
|
||||
@@ -325,7 +325,7 @@ func TestFromCache(t *testing.T) {
|
||||
if err == nil {
|
||||
t.Fatal("error expected")
|
||||
}
|
||||
assert.Equal(t, "resample: invalid file name “”", err.Error())
|
||||
assert.Equal(t, "resample: invalid file name ''", err.Error())
|
||||
assert.Empty(t, fileName)
|
||||
})
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ func Jpeg(srcFilename, jpgFilename string, orientation int) (img image.Image, er
|
||||
img, err = imaging.Open(srcFilename)
|
||||
|
||||
if err != nil {
|
||||
log.Errorf("resample: can't open %s", txt.Quote(filepath.Base(srcFilename)))
|
||||
log.Errorf("resample: can't open %s", txt.LogParam(filepath.Base(srcFilename)))
|
||||
return img, err
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ func Jpeg(srcFilename, jpgFilename string, orientation int) (img image.Image, er
|
||||
saveOption := imaging.JPEGQuality(JpegQuality)
|
||||
|
||||
if err = imaging.Save(img, jpgFilename, saveOption); err != nil {
|
||||
log.Errorf("resample: failed to save %s", txt.Quote(filepath.Base(jpgFilename)))
|
||||
log.Errorf("resample: failed to save %s", txt.LogParam(filepath.Base(jpgFilename)))
|
||||
return img, err
|
||||
}
|
||||
|
||||
|
||||
@@ -49,7 +49,7 @@ func OpenJpeg(fileName string, orientation int) (result image.Image, err error)
|
||||
return result, fmt.Errorf("filename missing")
|
||||
}
|
||||
|
||||
logName := txt.Quote(filepath.Base(fileName))
|
||||
logName := txt.LogParam(filepath.Base(fileName))
|
||||
|
||||
// Open file.
|
||||
fileReader, err := os.Open(fileName)
|
||||
@@ -81,7 +81,7 @@ func OpenJpeg(fileName string, orientation int) (result image.Image, err error)
|
||||
// Do nothing.
|
||||
log.Tracef("resample: detected no color profile in %s", logName)
|
||||
} else if profile, err := iccProfile.Description(); err == nil && profile != "" {
|
||||
log.Debugf("resample: detected color profile %s in %s", txt.Quote(profile), logName)
|
||||
log.Debugf("resample: detected color profile %s in %s", txt.LogParam(profile), logName)
|
||||
switch {
|
||||
case colors.ProfileDisplayP3.Equal(profile):
|
||||
img = colors.ToSRGB(img, colors.ProfileDisplayP3)
|
||||
|
||||
@@ -56,7 +56,7 @@ func (worker *Sync) upload(a entity.Account) (complete bool, err error) {
|
||||
continue // try again next time
|
||||
}
|
||||
|
||||
log.Infof("sync: uploaded %s to %s (%s)", txt.Quote(file.FileName), txt.Quote(remoteName), a.AccName)
|
||||
log.Infof("sync: uploaded %s to %s (%s)", txt.LogParam(file.FileName), txt.LogParam(remoteName), a.AccName)
|
||||
|
||||
fileSync := entity.NewFileSync(a.ID, remoteName)
|
||||
fileSync.Status = entity.FileSyncUploaded
|
||||
|
||||
45
pkg/txt/log.go
Normal file
45
pkg/txt/log.go
Normal file
@@ -0,0 +1,45 @@
|
||||
package txt
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"strings"
|
||||
"unicode"
|
||||
)
|
||||
|
||||
// LogParam sanitizes strings created from user input in response to the log4j debacle.
|
||||
func LogParam(s string) string {
|
||||
if len(s) > ClipTitle || strings.Contains(s, "ldap:/") {
|
||||
return "?"
|
||||
}
|
||||
|
||||
// Trim quotes, tabs, and newline characters.
|
||||
s = strings.Trim(s, "'\"“`\t\n\r")
|
||||
|
||||
// Remove non-printable and other potentially problematic characters.
|
||||
s = strings.Map(func(r rune) rune {
|
||||
if !unicode.IsPrint(r) {
|
||||
return -1
|
||||
}
|
||||
|
||||
switch r {
|
||||
case '`', '"':
|
||||
return '\''
|
||||
case '~', '\\', '|', '$', '<', '>', '{', '}', '∅':
|
||||
return '?'
|
||||
default:
|
||||
return r
|
||||
}
|
||||
}, s)
|
||||
|
||||
// Empty?
|
||||
if s == "" || strings.ContainsAny(s, " ") {
|
||||
return fmt.Sprintf("'%s'", s)
|
||||
}
|
||||
|
||||
return s
|
||||
}
|
||||
|
||||
// LogParamLower sanitizes strings created from user input and converts them to lowercase.
|
||||
func LogParamLower(s string) string {
|
||||
return LogParam(strings.ToLower(s))
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user