diff --git a/assets/locales/messages.pot b/assets/locales/messages.pot index f33027f1b..db23e1355 100644 --- a/assets/locales/messages.pot +++ b/assets/locales/messages.pot @@ -8,7 +8,7 @@ msgid "" msgstr "" "Project-Id-Version: PACKAGE VERSION\n" "Report-Msgid-Bugs-To: \n" -"POT-Creation-Date: 2022-06-16 16:58+0000\n" +"POT-Creation-Date: 2022-08-01 15:07+0000\n" "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" "Last-Translator: FULL NAME \n" "Language-Team: LANGUAGE \n" @@ -17,323 +17,331 @@ msgstr "" "Content-Type: text/plain; charset=CHARSET\n" "Content-Transfer-Encoding: 8bit\n" -#: messages.go:85 +#: messages.go:87 msgid "Unexpected error, please try again" msgstr "" -#: messages.go:86 +#: messages.go:88 msgid "Invalid request" msgstr "" -#: messages.go:87 +#: messages.go:89 msgid "Changes could not be saved" msgstr "" -#: messages.go:88 +#: messages.go:90 msgid "Could not be deleted" msgstr "" -#: messages.go:89 +#: messages.go:91 #, c-format msgid "%s already exists" msgstr "" -#: messages.go:90 +#: messages.go:92 msgid "Not found" msgstr "" -#: messages.go:91 +#: messages.go:93 msgid "File not found" msgstr "" -#: messages.go:92 -msgid "Selection not found" -msgstr "" - -#: messages.go:93 -msgid "Entity not found" -msgstr "" - #: messages.go:94 -msgid "Account not found" +msgid "Originals folder is empty" msgstr "" #: messages.go:95 -msgid "User not found" +msgid "Selection not found" msgstr "" #: messages.go:96 -msgid "Label not found" +msgid "Entity not found" msgstr "" #: messages.go:97 -msgid "Album not found" +msgid "Account not found" msgstr "" #: messages.go:98 -msgid "Subject not found" +msgid "User not found" msgstr "" #: messages.go:99 -msgid "Person not found" +msgid "Label not found" msgstr "" #: messages.go:100 -msgid "Face not found" +msgid "Album not found" msgstr "" #: messages.go:101 -msgid "Not available in public mode" +msgid "Subject not found" msgstr "" #: messages.go:102 -msgid "not available in read-only mode" +msgid "Person not found" msgstr "" #: messages.go:103 -msgid "Please log in and try again" +msgid "Face not found" msgstr "" #: messages.go:104 -msgid "Upload might be offensive" +msgid "Not available in public mode" msgstr "" #: messages.go:105 -msgid "No items selected" +msgid "not available in read-only mode" msgstr "" #: messages.go:106 -msgid "Failed creating file, please check permissions" +msgid "Please log in and try again" msgstr "" #: messages.go:107 -msgid "Failed creating folder, please check permissions" +msgid "Upload might be offensive" msgstr "" #: messages.go:108 -msgid "Could not connect, please try again" +msgid "No items selected" msgstr "" #: messages.go:109 -msgid "Invalid password, please try again" +msgid "Failed creating file, please check permissions" msgstr "" #: messages.go:110 -msgid "Feature disabled" +msgid "Failed creating folder, please check permissions" msgstr "" #: messages.go:111 -msgid "No labels selected" +msgid "Could not connect, please try again" msgstr "" #: messages.go:112 -msgid "No albums selected" +msgid "Invalid password, please try again" msgstr "" #: messages.go:113 -msgid "No files available for download" +msgid "Feature disabled" msgstr "" #: messages.go:114 -msgid "Failed to create zip file" +msgid "No labels selected" msgstr "" #: messages.go:115 -msgid "Invalid credentials" +msgid "No albums selected" msgstr "" #: messages.go:116 -msgid "Invalid link" +msgid "No files available for download" msgstr "" #: messages.go:117 -msgid "Invalid name" +msgid "Failed to create zip file" msgstr "" #: messages.go:118 -msgid "Busy, please try again later" +msgid "Invalid credentials" msgstr "" #: messages.go:119 +msgid "Invalid link" +msgstr "" + +#: messages.go:120 +msgid "Invalid name" +msgstr "" + +#: messages.go:121 +msgid "Busy, please try again later" +msgstr "" + +#: messages.go:122 #, c-format msgid "The wakeup interval is %s, but must be 1h or less" msgstr "" -#: messages.go:122 -msgid "Changes successfully saved" -msgstr "" - #: messages.go:123 -msgid "Album created" -msgstr "" - -#: messages.go:124 -msgid "Album saved" -msgstr "" - -#: messages.go:125 -#, c-format -msgid "Album %s deleted" +msgid "Your account could not be connected" msgstr "" #: messages.go:126 -msgid "Album contents cloned" +msgid "Changes successfully saved" msgstr "" #: messages.go:127 -msgid "File removed from stack" +msgid "Album created" msgstr "" #: messages.go:128 -msgid "File deleted" +msgid "Album saved" msgstr "" #: messages.go:129 #, c-format -msgid "Selection added to %s" +msgid "Album %s deleted" msgstr "" #: messages.go:130 -#, c-format -msgid "One entry added to %s" +msgid "Album contents cloned" msgstr "" #: messages.go:131 -#, c-format -msgid "%d entries added to %s" +msgid "File removed from stack" msgstr "" #: messages.go:132 -#, c-format -msgid "One entry removed from %s" +msgid "File deleted" msgstr "" #: messages.go:133 #, c-format -msgid "%d entries removed from %s" +msgid "Selection added to %s" msgstr "" #: messages.go:134 -msgid "Account created" +#, c-format +msgid "One entry added to %s" msgstr "" #: messages.go:135 -msgid "Account saved" +#, c-format +msgid "%d entries added to %s" msgstr "" #: messages.go:136 -msgid "Account deleted" +#, c-format +msgid "One entry removed from %s" msgstr "" #: messages.go:137 -msgid "Settings saved" +#, c-format +msgid "%d entries removed from %s" msgstr "" #: messages.go:138 -msgid "Password changed" +msgid "Account created" msgstr "" #: messages.go:139 -#, c-format -msgid "Import completed in %d s" +msgid "Account saved" msgstr "" #: messages.go:140 -msgid "Import canceled" +msgid "Account deleted" msgstr "" #: messages.go:141 -#, c-format -msgid "Indexing completed in %d s" +msgid "Settings saved" msgstr "" #: messages.go:142 -msgid "Indexing originals..." +msgid "Password changed" msgstr "" #: messages.go:143 #, c-format -msgid "Indexing files in %s" +msgid "Import completed in %d s" msgstr "" #: messages.go:144 -msgid "Indexing canceled" +msgid "Import canceled" msgstr "" #: messages.go:145 #, c-format -msgid "Removed %d files and %d photos" +msgid "Indexing completed in %d s" msgstr "" #: messages.go:146 -#, c-format -msgid "Moving files from %s" +msgid "Indexing originals..." msgstr "" #: messages.go:147 #, c-format -msgid "Copying files from %s" +msgid "Indexing files in %s" msgstr "" #: messages.go:148 -msgid "Labels deleted" +msgid "Indexing canceled" msgstr "" #: messages.go:149 -msgid "Label saved" +#, c-format +msgid "Removed %d files and %d photos" msgstr "" #: messages.go:150 -msgid "Subject saved" +#, c-format +msgid "Moving files from %s" msgstr "" #: messages.go:151 -msgid "Subject deleted" +#, c-format +msgid "Copying files from %s" msgstr "" #: messages.go:152 -msgid "Person saved" +msgid "Labels deleted" msgstr "" #: messages.go:153 -msgid "Person deleted" +msgid "Label saved" msgstr "" #: messages.go:154 +msgid "Subject saved" +msgstr "" + +#: messages.go:155 +msgid "Subject deleted" +msgstr "" + +#: messages.go:156 +msgid "Person saved" +msgstr "" + +#: messages.go:157 +msgid "Person deleted" +msgstr "" + +#: messages.go:158 #, c-format msgid "%d files uploaded in %d s" msgstr "" -#: messages.go:155 +#: messages.go:159 msgid "Selection approved" msgstr "" -#: messages.go:156 +#: messages.go:160 msgid "Selection archived" msgstr "" -#: messages.go:157 +#: messages.go:161 msgid "Selection restored" msgstr "" -#: messages.go:158 +#: messages.go:162 msgid "Selection marked as private" msgstr "" -#: messages.go:159 +#: messages.go:163 msgid "Albums deleted" msgstr "" -#: messages.go:160 +#: messages.go:164 #, c-format msgid "Zip created in %d s" msgstr "" -#: messages.go:161 +#: messages.go:165 msgid "Permanently deleted" msgstr "" -#: messages.go:162 +#: messages.go:166 #, c-format msgid "%s has been restored" msgstr "" diff --git a/internal/api/import.go b/internal/api/import.go index cb1f6c8bf..c866b4f02 100644 --- a/internal/api/import.go +++ b/internal/api/import.go @@ -84,7 +84,7 @@ func StartImport(router *gin.RouterGroup) { imp.Start(opt) - if subPath != "" && path != conf.ImportPath() && fs.IsEmpty(path) { + if subPath != "" && path != conf.ImportPath() && fs.DirIsEmpty(path) { if err := os.Remove(path); err != nil { log.Errorf("import: failed deleting empty folder %s: %s", clean.Log(path), err) } else { diff --git a/internal/i18n/messages.go b/internal/i18n/messages.go index 125db0bba..d167b6300 100644 --- a/internal/i18n/messages.go +++ b/internal/i18n/messages.go @@ -8,6 +8,7 @@ const ( ErrAlreadyExists ErrNotFound ErrFileNotFound + ErrOriginalsEmpty ErrSelectionNotFound ErrEntityNotFound ErrAccountNotFound @@ -90,6 +91,7 @@ var Messages = MessageMap{ ErrAlreadyExists: gettext("%s already exists"), ErrNotFound: gettext("Not found"), ErrFileNotFound: gettext("File not found"), + ErrOriginalsEmpty: gettext("Originals folder is empty"), ErrSelectionNotFound: gettext("Selection not found"), ErrEntityNotFound: gettext("Entity not found"), ErrAccountNotFound: gettext("Account not found"), diff --git a/internal/photoprism/cleanup.go b/internal/photoprism/cleanup.go index b81bbac6d..e70bdcc05 100644 --- a/internal/photoprism/cleanup.go +++ b/internal/photoprism/cleanup.go @@ -44,6 +44,13 @@ func (w *CleanUp) Start(opt CleanUpOptions) (thumbs int, orphans int, sidecars i } }() + originalsPath := w.conf.OriginalsPath() + + // Check if originals folder is empty. + if fs.DirIsEmpty(originalsPath) { + return thumbs, orphans, sidecars, err + } + if err = mutex.MainWorker.Start(); err != nil { log.Warnf("cleanup: %s (start)", err) return thumbs, orphans, sidecars, err diff --git a/internal/photoprism/import.go b/internal/photoprism/import.go index d841926d5..69c0894c9 100644 --- a/internal/photoprism/import.go +++ b/internal/photoprism/import.go @@ -10,8 +10,6 @@ import ( "sort" "sync" - "github.com/photoprism/photoprism/pkg/media" - "github.com/karrick/godirwalk" "github.com/photoprism/photoprism/internal/config" @@ -20,6 +18,7 @@ import ( "github.com/photoprism/photoprism/internal/mutex" "github.com/photoprism/photoprism/pkg/clean" "github.com/photoprism/photoprism/pkg/fs" + "github.com/photoprism/photoprism/pkg/media" ) // Import represents an importer that can copy/move MediaFiles to the originals directory. @@ -69,6 +68,7 @@ func (imp *Import) Start(opt ImportOptions) fs.Done { ind := imp.index importPath := opt.Path + // Check if the import folder exists. if !fs.PathExists(importPath) { event.Error(fmt.Sprintf("import: %s does not exist", importPath)) return done @@ -221,7 +221,7 @@ func (imp *Import) Start(opt ImportOptions) fs.Done { if opt.RemoveEmptyDirectories { // Remove empty directories from import path. for _, directory := range directories { - if fs.IsEmpty(directory) { + if fs.DirIsEmpty(directory) { if err := os.Remove(directory); err != nil { log.Errorf("import: failed deleting empty folder %s (%s)", clean.Log(fs.RelName(directory, importPath)), err) } else { diff --git a/internal/photoprism/index.go b/internal/photoprism/index.go index 9e1b7fe4e..deb441cf9 100644 --- a/internal/photoprism/index.go +++ b/internal/photoprism/index.go @@ -15,6 +15,7 @@ import ( "github.com/photoprism/photoprism/internal/entity" "github.com/photoprism/photoprism/internal/event" "github.com/photoprism/photoprism/internal/face" + "github.com/photoprism/photoprism/internal/i18n" "github.com/photoprism/photoprism/internal/mutex" "github.com/photoprism/photoprism/internal/nsfw" "github.com/photoprism/photoprism/pkg/clean" @@ -89,7 +90,10 @@ func (ind *Index) Start(o IndexOptions) fs.Done { optionsPath := filepath.Join(originalsPath, o.Path) if !fs.PathExists(optionsPath) { - event.Error(fmt.Sprintf("index: %s does not exist", clean.Log(optionsPath))) + event.Error(fmt.Sprintf("%s does not exist", clean.Log(optionsPath))) + return done + } else if fs.DirIsEmpty(originalsPath) { + event.InfoMsg(i18n.ErrOriginalsEmpty) return done } diff --git a/internal/photoprism/purge.go b/internal/photoprism/purge.go index 4d4224cb8..fc592cc82 100644 --- a/internal/photoprism/purge.go +++ b/internal/photoprism/purge.go @@ -41,6 +41,13 @@ func (w *Purge) Start(opt PurgeOptions) (purgedFiles map[string]bool, purgedPhot } }() + originalsPath := w.conf.OriginalsPath() + + // Check if originals folder is empty. + if fs.DirIsEmpty(originalsPath) { + return purgedFiles, purgedPhotos, err + } + var ignore fs.Done if opt.Ignore != nil { diff --git a/pkg/fs/fs.go b/pkg/fs/fs.go index 7a9ba014f..c27691632 100644 --- a/pkg/fs/fs.go +++ b/pkg/fs/fs.go @@ -213,8 +213,8 @@ func Download(filepath string, url string) error { return nil } -// IsEmpty returns true if a directory is empty. -func IsEmpty(path string) bool { +// DirIsEmpty returns true if a directory is empty. +func DirIsEmpty(path string) bool { f, err := os.Open(path) if err != nil { diff --git a/pkg/fs/fs_test.go b/pkg/fs/fs_test.go index cdb28609a..5238f5e40 100644 --- a/pkg/fs/fs_test.go +++ b/pkg/fs/fs_test.go @@ -82,16 +82,21 @@ func TestExpandedFilename(t *testing.T) { }) } -func TestDirectoryIsEmpty(t *testing.T) { - t.Run("not empty path", func(t *testing.T) { - assert.Equal(t, false, IsEmpty("./testdata")) +func TestDirIsEmpty(t *testing.T) { + t.Run("CurrentDir", func(t *testing.T) { + assert.Equal(t, false, DirIsEmpty(".")) }) - t.Run("not existing path", func(t *testing.T) { - assert.Equal(t, false, IsEmpty("./xxx")) + t.Run("Testdata", func(t *testing.T) { + assert.Equal(t, false, DirIsEmpty("./testdata")) }) - t.Run("empty path", func(t *testing.T) { - os.Mkdir("./testdata/emptyDir", 0777) + t.Run("XXX", func(t *testing.T) { + assert.Equal(t, false, DirIsEmpty("./xxx")) + }) + t.Run("EmptyDir", func(t *testing.T) { + if err := os.Mkdir("./testdata/emptyDir", 0777); err != nil { + t.Fatal(err) + } defer os.RemoveAll("./testdata/emptyDir") - assert.Equal(t, true, IsEmpty("./testdata/emptyDir")) + assert.Equal(t, true, DirIsEmpty("./testdata/emptyDir")) }) }