Indexer: Improve stacking settings and merging

This commit is contained in:
Michael Mayer
2020-12-11 17:21:13 +01:00
parent 8f80026b3e
commit 04c17fb77b
24 changed files with 397 additions and 316 deletions

View File

@@ -111,6 +111,19 @@
></v-switch> ></v-switch>
</td> </td>
</tr> </tr>
<tr>
<td>
<translate>Single</translate>
</td>
<td>
<v-switch
@change="save"
hide-details
v-model="model.Single"
:label="model.Single ? $gettext('Yes') : $gettext('No')"
></v-switch>
</td>
</tr>
<tr> <tr>
<td> <td>
<translate>Scan</translate> <translate>Scan</translate>

Binary file not shown.

View File

@@ -10,7 +10,7 @@ msgstr ""
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
"Content-Transfer-Encoding: 8bit\n" "Content-Transfer-Encoding: 8bit\n"
"Generated-By: easygettext\n" "Generated-By: easygettext\n"
"X-Generator: Poedit 2.4.2\n" "X-Generator: Poedit 2.3\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n" "Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/pages/albums.vue:273 src/share/albums.vue:248 #: src/pages/albums.vue:273 src/share/albums.vue:248
@@ -37,15 +37,15 @@ msgstr "%{n} Kategorien gefunden"
msgid "%{n} results" msgid "%{n} results"
msgstr "%{n} Ergebnisse" msgstr "%{n} Ergebnisse"
#: src/options/options.js:206 #: src/options/options.js:210
msgid "1 hour" msgid "1 hour"
msgstr "1 Stunde" msgstr "1 Stunde"
#: src/options/options.js:208 #: src/options/options.js:212
msgid "12 hours" msgid "12 hours"
msgstr "12 Stunden" msgstr "12 Stunden"
#: src/options/options.js:207 #: src/options/options.js:211
msgid "4 hours" msgid "4 hours"
msgstr "4 Stunden" msgstr "4 Stunden"
@@ -62,7 +62,7 @@ msgstr "Info"
msgid "Account" msgid "Account"
msgstr "Zugang" msgstr "Zugang"
#: src/dialog/photo/info.vue:141 #: src/dialog/photo/info.vue:149
msgid "Accuracy" msgid "Accuracy"
msgstr "Genauigkeit" msgstr "Genauigkeit"
@@ -78,7 +78,7 @@ msgstr "Aktionen"
msgid "Add Album" msgid "Add Album"
msgstr "Neues Album erstellen" msgstr "Neues Album erstellen"
#: src/pages/settings/general.vue:377 #: src/pages/settings/general.vue:348
msgid "Add files to your library via Web Upload." msgid "Add files to your library via Web Upload."
msgstr "Dateien über den Browser hochladen und indexieren." msgstr "Dateien über den Browser hochladen und indexieren."
@@ -104,23 +104,23 @@ msgstr "Hinzufügen"
msgid "Added" msgid "Added"
msgstr "Hinzugefügt" msgstr "Hinzugefügt"
#: src/options/options.js:216 #: src/options/options.js:220
msgid "After 1 day" msgid "After 1 day"
msgstr "Nach einem Tag" msgstr "Nach einem Tag"
#: src/options/options.js:217 #: src/options/options.js:221
msgid "After 3 days" msgid "After 3 days"
msgstr "Nach 3 Tagen" msgstr "Nach 3 Tagen"
#: src/options/options.js:218 #: src/options/options.js:222
msgid "After 7 days" msgid "After 7 days"
msgstr "Nach 7 Tagen" msgstr "Nach 7 Tagen"
#: src/options/options.js:220 #: src/options/options.js:224
msgid "After one month" msgid "After one month"
msgstr "Nach einem Monat" msgstr "Nach einem Monat"
#: src/options/options.js:222 #: src/options/options.js:226
msgid "After one year" msgid "After one year"
msgstr "Nach einem Jahr" msgstr "Nach einem Jahr"
@@ -132,11 +132,11 @@ msgstr ""
"Fotos und Videos können über das Kontextmenü zu bestehenden oder neuen Alben " "Fotos und Videos können über das Kontextmenü zu bestehenden oder neuen Alben "
"hinzugefügt werden." "hinzugefügt werden."
#: src/options/options.js:221 #: src/options/options.js:225
msgid "After two months" msgid "After two months"
msgstr "Nach zwei Monaten" msgstr "Nach zwei Monaten"
#: src/options/options.js:219 #: src/options/options.js:223
msgid "After two weeks" msgid "After two weeks"
msgstr "Nach zwei Wochen" msgstr "Nach zwei Wochen"
@@ -218,7 +218,7 @@ msgstr ""
"Alternativ können Dateien auch direkt auf kompatible WebDAV-Server " "Alternativ können Dateien auch direkt auf kompatible WebDAV-Server "
"hochgeladen z.B. Nextcloud." "hochgeladen z.B. Nextcloud."
#: src/dialog/photo/info.vue:133 #: src/dialog/photo/info.vue:141
msgid "Altitude" msgid "Altitude"
msgstr "Höhe" msgstr "Höhe"
@@ -230,7 +230,7 @@ msgstr "Höhe (m)"
msgid "An error occurred - are you offline?" msgid "An error occurred - are you offline?"
msgstr "Server nicht erreichbar - offline?" msgstr "Server nicht erreichbar - offline?"
#: src/pages/settings/general.vue:698 #: src/pages/settings/general.vue:669
msgid "Animation" msgid "Animation"
msgstr "Animation" msgstr "Animation"
@@ -254,12 +254,12 @@ msgid "Approve"
msgstr "Übernehmen" msgstr "Übernehmen"
#: src/component/navigation.vue:114 src/component/photo/cards.vue:20 #: src/component/navigation.vue:114 src/component/photo/cards.vue:20
#: src/component/photo/clipboard.vue:211 src/pages/settings/general.vue:442 #: src/component/photo/clipboard.vue:211 src/pages/settings/general.vue:413
#: src/routes.js:185 #: src/routes.js:185
msgid "Archive" msgid "Archive"
msgstr "Archiv" msgstr "Archiv"
#: src/dialog/photo/info.vue:181 #: src/dialog/photo/info.vue:189
msgid "Archived" msgid "Archived"
msgstr "Archiviert" msgstr "Archiviert"
@@ -295,7 +295,7 @@ msgstr "Seitenverhältnis"
msgid "At least 6 characters." msgid "At least 6 characters."
msgstr "Mindestens 6 Zeichen." msgstr "Mindestens 6 Zeichen."
#: src/pages/settings/general.vue:123 #: src/pages/settings/general.vue:120
msgid "" msgid ""
"Automatically create JPEGs for other file types so that they can be " "Automatically create JPEGs for other file types so that they can be "
"displayed in a browser." "displayed in a browser."
@@ -307,27 +307,27 @@ msgstr ""
msgid "Backup" msgid "Backup"
msgstr "Backup" msgstr "Backup"
#: src/options/options.js:241 #: src/options/options.js:245
msgid "Black" msgid "Black"
msgstr "Schwarz" msgstr "Schwarz"
#: src/options/options.js:237 #: src/options/options.js:241
msgid "Blue" msgid "Blue"
msgstr "Blau" msgstr "Blau"
#: src/options/options.js:238 #: src/options/options.js:242
msgid "Brown" msgid "Brown"
msgstr "Braun" msgstr "Braun"
#: src/pages/settings/general.vue:531 #: src/pages/settings/general.vue:502
msgid "Browse and edit image classification labels." msgid "Browse and edit image classification labels."
msgstr "Automatische Bild-Kategorisierung sehen und bearbeiten." msgstr "Automatische Bild-Kategorisierung sehen und bearbeiten."
#: src/pages/settings/general.vue:487 #: src/pages/settings/general.vue:458
msgid "Browse indexed files and folders in Library." msgid "Browse indexed files and folders in Library."
msgstr "Durchsuche Ordner hierarchisch nach indexierten Original-Dateien." msgstr "Durchsuche Ordner hierarchisch nach indexierten Original-Dateien."
#: src/options/options.js:248 #: src/options/options.js:252
msgid "Bug Report" msgid "Bug Report"
msgstr "Fehlerbericht" msgstr "Fehlerbericht"
@@ -384,7 +384,7 @@ msgstr "Kategorie"
msgid "Change" msgid "Change"
msgstr "Ändern" msgstr "Ändern"
#: src/pages/settings/general.vue:465 #: src/pages/settings/general.vue:436
msgid "Change photo titles, locations and other metadata." msgid "Change photo titles, locations and other metadata."
msgstr "Titel, Datum, Ort und andere Metadaten können geändert werden." msgstr "Titel, Datum, Ort und andere Metadaten können geändert werden."
@@ -392,7 +392,7 @@ msgstr "Titel, Datum, Ort und andere Metadaten können geändert werden."
msgid "Change private flag" msgid "Change private flag"
msgstr "Als privat markieren" msgstr "Als privat markieren"
#: src/dialog/photo/info.vue:173 #: src/dialog/photo/info.vue:181
msgid "Checked" msgid "Checked"
msgstr "Geprüft" msgstr "Geprüft"
@@ -453,7 +453,7 @@ msgstr "Enthält einen Eintrag."
msgid "Contributors" msgid "Contributors"
msgstr "Contributors" msgstr "Contributors"
#: src/pages/settings/general.vue:122 #: src/pages/settings/general.vue:119
msgid "Convert to JPEG" msgid "Convert to JPEG"
msgstr "Automatisch konvertieren" msgstr "Automatisch konvertieren"
@@ -500,7 +500,7 @@ msgstr "Land"
msgid "Create album" msgid "Create album"
msgstr "Erstellen" msgstr "Erstellen"
#: src/dialog/photo/info.vue:149 #: src/dialog/photo/info.vue:157
msgid "Created" msgid "Created"
msgstr "Hinzugefügt" msgstr "Hinzugefügt"
@@ -512,19 +512,19 @@ msgstr "Erstelle Thumbnails für"
msgid "Current Password" msgid "Current Password"
msgstr "Aktuelles Passwort" msgstr "Aktuelles Passwort"
#: src/options/options.js:245 #: src/options/options.js:249
msgid "Customer Support" msgid "Customer Support"
msgstr "Support-Anfrage" msgstr "Support-Anfrage"
#: src/options/options.js:236 #: src/options/options.js:240
msgid "Cyan" msgid "Cyan"
msgstr "Cyan" msgstr "Cyan"
#: src/options/options.js:119 #: src/options/options.js:123
msgid "Cyano" msgid "Cyano"
msgstr "Cyano" msgstr "Cyano"
#: src/options/options.js:209 #: src/options/options.js:213
msgid "Daily" msgid "Daily"
msgstr "Täglich" msgstr "Täglich"
@@ -532,7 +532,7 @@ msgstr "Täglich"
msgid "Day" msgid "Day"
msgstr "Tag" msgstr "Tag"
#: src/options/options.js:115 #: src/options/options.js:119
msgid "Default" msgid "Default"
msgstr "Standard" msgstr "Standard"
@@ -571,7 +571,7 @@ msgstr "Deaktiviert"
msgid "Discover" msgid "Discover"
msgstr "Entdecken" msgstr "Entdecken"
#: src/options/options.js:249 #: src/options/options.js:253
msgid "Donations" msgid "Donations"
msgstr "Spenden" msgstr "Spenden"
@@ -587,7 +587,7 @@ msgstr "Fertig."
#: src/component/album/clipboard.vue:111 src/component/album/toolbar.vue:106 #: src/component/album/clipboard.vue:111 src/component/album/toolbar.vue:106
#: src/component/file/clipboard.vue:64 src/component/photo/clipboard.vue:165 #: src/component/file/clipboard.vue:64 src/component/photo/clipboard.vue:165
#: src/component/photo/viewer.vue:72 src/dialog/photo/files.vue:33 #: src/component/photo/viewer.vue:72 src/dialog/photo/files.vue:33
#: src/pages/settings/general.vue:398 src/share/album/clipboard.vue:60 #: src/pages/settings/general.vue:369 src/share/album/clipboard.vue:60
#: src/share/photo/clipboard.vue:62 src/share/photos.vue:75 #: src/share/photo/clipboard.vue:62 src/share/photos.vue:75
msgid "Download" msgid "Download"
msgstr "Download" msgstr "Download"
@@ -596,7 +596,7 @@ msgstr "Download"
msgid "Download remote files" msgid "Download remote files"
msgstr "Dateien herunterladen" msgstr "Dateien herunterladen"
#: src/pages/settings/general.vue:399 #: src/pages/settings/general.vue:370
msgid "Download single files and zip archives." msgid "Download single files and zip archives."
msgstr "" msgstr ""
"Einzelne Fotos, Videos sowie Zip-Archive können heruntergeladen werden." "Einzelne Fotos, Videos sowie Zip-Archive können heruntergeladen werden."
@@ -623,7 +623,7 @@ msgstr "E-Mail"
#: src/component/album/clipboard.vue:89 src/component/album/toolbar.vue:69 #: src/component/album/clipboard.vue:89 src/component/album/toolbar.vue:69
#: src/component/photo/clipboard.vue:119 src/component/photo/viewer.vue:89 #: src/component/photo/clipboard.vue:119 src/component/photo/viewer.vue:89
#: src/pages/settings/general.vue:464 #: src/pages/settings/general.vue:435
msgid "Edit" msgid "Edit"
msgstr "Bearbeiten" msgstr "Bearbeiten"
@@ -639,7 +639,7 @@ msgstr "Account bearbeiten"
msgid "Edit Photo" msgid "Edit Photo"
msgstr "Foto bearbeiten" msgstr "Foto bearbeiten"
#: src/dialog/photo/info.vue:165 #: src/dialog/photo/info.vue:173
msgid "Edited" msgid "Edited"
msgstr "Bearbeitet" msgstr "Bearbeitet"
@@ -659,11 +659,11 @@ msgstr "Fehler"
msgid "Errors" msgid "Errors"
msgstr "Fehler" msgstr "Fehler"
#: src/options/options.js:210 #: src/options/options.js:214
msgid "Every two days" msgid "Every two days"
msgstr "Jeden zweiten Tag" msgstr "Jeden zweiten Tag"
#: src/pages/settings/general.vue:79 #: src/pages/settings/general.vue:78
msgid "" msgid ""
"Exclude content marked as private from search results, shared albums, labels " "Exclude content marked as private from search results, shared albums, labels "
"and places." "and places."
@@ -703,7 +703,7 @@ msgstr "Der Link konnte nicht gespeichert werden"
msgid "Failure while importing uploaded files" msgid "Failure while importing uploaded files"
msgstr "Fehler beim Importieren der hochgeladenen Dateien" msgstr "Fehler beim Importieren der hochgeladenen Dateien"
#: src/options/options.js:149 #: src/options/options.js:153
msgid "Fast" msgid "Fast"
msgstr "Schnell" msgstr "Schnell"
@@ -715,7 +715,7 @@ msgstr "Favorit"
msgid "Favorites" msgid "Favorites"
msgstr "Favoriten" msgstr "Favoriten"
#: src/options/options.js:247 #: src/options/options.js:251
msgid "Feature Request" msgid "Feature Request"
msgstr "Feature Request" msgstr "Feature Request"
@@ -735,7 +735,7 @@ msgstr "Datei Browser"
msgid "Files" msgid "Files"
msgstr "Dateien" msgstr "Dateien"
#: src/pages/settings/general.vue:249 #: src/pages/settings/general.vue:222
msgid "" msgid ""
"Files with sequential names like 'IMG_1234 (2)' and 'IMG_1234 (3)' belong to " "Files with sequential names like 'IMG_1234 (2)' and 'IMG_1234 (3)' belong to "
"the same picture." "the same picture."
@@ -781,15 +781,15 @@ msgstr "Allgemein"
msgid "German" msgid "German"
msgstr "Deutsch" msgstr "Deutsch"
#: src/options/options.js:231 #: src/options/options.js:235
msgid "Gold" msgid "Gold"
msgstr "Gold" msgstr "Gold"
#: src/options/options.js:234 #: src/options/options.js:238
msgid "Green" msgid "Green"
msgstr "Grün" msgstr "Grün"
#: src/options/options.js:240 #: src/options/options.js:244
msgid "Grey" msgid "Grey"
msgstr "Grau" msgstr "Grau"
@@ -814,11 +814,11 @@ msgstr "Versteckt"
msgid "Hidden Files" msgid "Hidden Files"
msgstr "Unsichtbare Dateien" msgstr "Unsichtbare Dateien"
#: src/pages/settings/general.vue:443 #: src/pages/settings/general.vue:414
msgid "Hide photos that have been moved to archive." msgid "Hide photos that have been moved to archive."
msgstr "Archivierte Inhalte werden nicht in den Suchergebnissen angezeigt." msgstr "Archivierte Inhalte werden nicht in den Suchergebnissen angezeigt."
#: src/pages/settings/general.vue:78 #: src/pages/settings/general.vue:77
msgid "Hide Private" msgid "Hide Private"
msgstr "Privates ausblenden" msgstr "Privates ausblenden"
@@ -830,7 +830,7 @@ msgstr "Hindi"
msgid "How can we help?" msgid "How can we help?"
msgstr "Wie können wir helfen?" msgstr "Wie können wir helfen?"
#: src/options/options.js:172 #: src/options/options.js:176
msgid "Hybrid" msgid "Hybrid"
msgstr "Hybrid" msgstr "Hybrid"
@@ -848,11 +848,11 @@ msgstr ""
msgid "image" msgid "image"
msgstr "Bild" msgstr "Bild"
#: src/options/options.js:187 #: src/options/options.js:191
msgid "Image" msgid "Image"
msgstr "Bild" msgstr "Bild"
#: src/pages/library/import.vue:43 src/pages/settings/general.vue:574 #: src/pages/library/import.vue:43 src/pages/settings/general.vue:545
msgid "Import" msgid "Import"
msgstr "Import" msgstr "Import"
@@ -868,7 +868,7 @@ msgstr ""
"Import kopiert neue Dateien und sortiert sie nach Datum, um Duplikate zu " "Import kopiert neue Dateien und sortiert sie nach Datum, um Duplikate zu "
"vermeiden." "vermeiden."
#: src/pages/settings/general.vue:575 #: src/pages/settings/general.vue:546
msgid "Imported files will be sorted by date and given a unique name." msgid "Imported files will be sorted by date and given a unique name."
msgstr "" msgstr ""
"Import kopiert neue Dateien und sortiert sie nach Datum, um Duplikate zu " "Import kopiert neue Dateien und sortiert sie nach Datum, um Duplikate zu "
@@ -935,7 +935,7 @@ msgid "Label Name"
msgstr "Name" msgstr "Name"
#: src/component/navigation.vue:268 src/dialog/photo/edit.vue:27 #: src/component/navigation.vue:268 src/dialog/photo/edit.vue:27
#: src/pages/settings/general.vue:530 src/routes.js:236 #: src/pages/settings/general.vue:501 src/routes.js:236
msgid "Labels" msgid "Labels"
msgstr "Kategorien" msgstr "Kategorien"
@@ -943,7 +943,7 @@ msgstr "Kategorien"
msgid "Labels deleted" msgid "Labels deleted"
msgstr "Kategorien gelöscht" msgstr "Kategorien gelöscht"
#: src/pages/settings/general.vue:328 #: src/pages/settings/general.vue:299
msgid "Language" msgid "Language"
msgstr "Sprache" msgstr "Sprache"
@@ -951,11 +951,11 @@ msgstr "Sprache"
msgid "Last Backup" msgid "Last Backup"
msgstr "Letztes Backup" msgstr "Letztes Backup"
#: src/dialog/photo/details.vue:327 src/dialog/photo/info.vue:117 #: src/dialog/photo/details.vue:327 src/dialog/photo/info.vue:125
msgid "Latitude" msgid "Latitude"
msgstr "Breitengrad" msgstr "Breitengrad"
#: src/options/options.js:123 #: src/options/options.js:127
msgid "Lavender" msgid "Lavender"
msgstr "Lavendel" msgstr "Lavendel"
@@ -963,14 +963,14 @@ msgstr "Lavendel"
msgid "Lens" msgid "Lens"
msgstr "Objektiv" msgstr "Objektiv"
#: src/pages/settings/general.vue:509 #: src/pages/settings/general.vue:480
msgid "Let PhotoPrism create albums from past events." msgid "Let PhotoPrism create albums from past events."
msgstr "" msgstr ""
"PhotoPrism erstellt automatisch Alben mit besonderen Momenten, Reisen und " "PhotoPrism erstellt automatisch Alben mit besonderen Momenten, Reisen und "
"Orten." "Orten."
#: src/component/navigation.vue:281 src/component/navigation.vue:290 #: src/component/navigation.vue:281 src/component/navigation.vue:290
#: src/pages/settings/general.vue:6 src/pages/settings/general.vue:552 #: src/pages/settings/general.vue:6 src/pages/settings/general.vue:523
#: src/routes.js:255 src/routes.js:262 src/routes.js:269 #: src/routes.js:255 src/routes.js:262 src/routes.js:269
msgid "Library" msgid "Library"
msgstr "Dateien" msgstr "Dateien"
@@ -984,7 +984,7 @@ msgstr "Lizenz"
msgid "Like" msgid "Like"
msgstr "Favorit" msgstr "Favorit"
#: src/options/options.js:233 #: src/options/options.js:237
msgid "Lime" msgid "Lime"
msgstr "Hellgrün" msgstr "Hellgrün"
@@ -1000,7 +1000,7 @@ msgstr "Link"
msgid "List" msgid "List"
msgstr "Liste" msgstr "Liste"
#: src/options/options.js:195 #: src/options/options.js:199
msgid "Live" msgid "Live"
msgstr "Live" msgstr "Live"
@@ -1033,15 +1033,15 @@ msgstr "Anmelden"
msgid "Logout" msgid "Logout"
msgstr "Abmelden" msgstr "Abmelden"
#: src/pages/library.vue:17 src/pages/settings/general.vue:596 #: src/pages/library.vue:17 src/pages/settings/general.vue:567
msgid "Logs" msgid "Logs"
msgstr "Logs" msgstr "Logs"
#: src/dialog/photo/details.vue:348 src/dialog/photo/info.vue:125 #: src/dialog/photo/details.vue:348 src/dialog/photo/info.vue:133
msgid "Longitude" msgid "Longitude"
msgstr "Längengrad" msgstr "Längengrad"
#: src/options/options.js:227 #: src/options/options.js:231
msgid "Magenta" msgid "Magenta"
msgstr "Magenta" msgstr "Magenta"
@@ -1057,7 +1057,7 @@ msgstr "Manuell"
msgid "Manual Upload" msgid "Manual Upload"
msgstr "Manueller Upload" msgstr "Manueller Upload"
#: src/options/options.js:153 #: src/options/options.js:157
msgid "Medium" msgid "Medium"
msgstr "Mittel" msgstr "Mittel"
@@ -1069,7 +1069,7 @@ msgstr "Nachricht versendet"
msgid "Missing" msgid "Missing"
msgstr "Fehlend" msgstr "Fehlend"
#: src/component/navigation.vue:223 src/pages/settings/general.vue:508 #: src/component/navigation.vue:223 src/pages/settings/general.vue:479
#: src/routes.js:98 src/routes.js:105 #: src/routes.js:98 src/routes.js:105
msgid "Moments" msgid "Moments"
msgstr "Erlebnisse" msgstr "Erlebnisse"
@@ -1082,7 +1082,7 @@ msgstr "Monochrom"
msgid "Month" msgid "Month"
msgstr "Monat" msgstr "Monat"
#: src/options/options.js:127 #: src/options/options.js:131
msgid "Moonlight" msgid "Moonlight"
msgstr "Moonlight" msgstr "Moonlight"
@@ -1119,13 +1119,6 @@ msgstr "Verschieben"
msgid "Move Files" msgid "Move Files"
msgstr "Dateien verschieben" msgstr "Dateien verschieben"
#: src/common/vm.js:8 src/common/vm.js:9 src/common/vm.js:12
#: src/common/vm.js:13
msgid "msgid"
msgid_plural "plural"
msgstr[0] "msgid"
msgstr[1] ""
#: src/component/photo/list.vue:33 src/dialog/account/edit.vue:359 #: src/component/photo/list.vue:33 src/dialog/account/edit.vue:359
#: src/dialog/album/edit.vue:105 src/dialog/photo/files.vue:72 #: src/dialog/album/edit.vue:105 src/dialog/photo/files.vue:72
#: src/dialog/photo/files.vue:29 src/dialog/photo/info.vue:30 #: src/dialog/photo/files.vue:29 src/dialog/photo/info.vue:30
@@ -1140,7 +1133,7 @@ msgstr "Name"
msgid "Name too long" msgid "Name too long"
msgstr "Name zu lang" msgstr "Name zu lang"
#: src/options/options.js:205 src/options/options.js:215 #: src/options/options.js:209 src/options/options.js:219
#: src/pages/settings/sync.vue:43 #: src/pages/settings/sync.vue:43
msgid "Never" msgid "Never"
msgstr "Nie" msgstr "Nie"
@@ -1154,9 +1147,9 @@ msgstr "Neues Passwort"
msgid "Newest first" msgid "Newest first"
msgstr "Neueste zuerst" msgstr "Neueste zuerst"
#: src/dialog/photo/archive.vue:15 src/dialog/photo/info.vue:267 #: src/dialog/photo/archive.vue:15 src/dialog/photo/info.vue:268
#: src/dialog/photo/info.vue:286 src/dialog/photo/info.vue:305 #: src/dialog/photo/info.vue:287 src/dialog/photo/info.vue:306
#: src/dialog/photo/info.vue:324 #: src/dialog/photo/info.vue:325 src/dialog/photo/info.vue:344
msgid "No" msgid "No"
msgstr "Nein" msgstr "Nein"
@@ -1196,7 +1189,7 @@ msgstr ""
#: src/component/photo/list.vue:15 src/component/photo/list.vue:1 #: src/component/photo/list.vue:15 src/component/photo/list.vue:1
#: src/component/photo/list.vue:19 src/component/photo/mosaic.vue:15 #: src/component/photo/list.vue:19 src/component/photo/mosaic.vue:15
#: src/component/photo/mosaic.vue:1 src/dialog/upload.vue:50 #: src/component/photo/mosaic.vue:1 src/dialog/upload.vue:50
#: src/pages/settings/general.vue:101 #: src/pages/settings/general.vue:99
msgid "" msgid ""
"Non-photographic and low-quality images require a review before they appear " "Non-photographic and low-quality images require a review before they appear "
"in search results." "in search results."
@@ -1204,7 +1197,7 @@ msgstr ""
"Nicht-fotografische Inhalte oder Fotos mit geringer Qualität werden erst " "Nicht-fotografische Inhalte oder Fotos mit geringer Qualität werden erst "
"nach einer Bestätigung in der Suche angezeigt." "nach einer Bestätigung in der Suche angezeigt."
#: src/options/options.js:145 #: src/options/options.js:149
msgid "None" msgid "None"
msgstr "Keine" msgstr "Keine"
@@ -1251,7 +1244,7 @@ msgstr "Notizen"
msgid "Nothing to see here yet. Be patient." msgid "Nothing to see here yet. Be patient."
msgstr "Noch nichts zu sehen. Gedulde dich noch ein bisschen." msgstr "Noch nichts zu sehen. Gedulde dich noch ein bisschen."
#: src/component/navigation.vue:401 src/options/options.js:164 #: src/component/navigation.vue:401 src/options/options.js:168
msgid "Offline" msgid "Offline"
msgstr "Offline" msgstr "Offline"
@@ -1260,7 +1253,7 @@ msgstr "Offline"
msgid "Oldest first" msgid "Oldest first"
msgstr "Älteste zuerst" msgstr "Älteste zuerst"
#: src/options/options.js:211 #: src/options/options.js:215
msgid "Once a week" msgid "Once a week"
msgstr "Einmal die Woche" msgstr "Einmal die Woche"
@@ -1284,11 +1277,11 @@ msgstr "Ein Ordner gefunden"
msgid "One result" msgid "One result"
msgstr "Ein Ergebnis" msgstr "Ein Ergebnis"
#: src/options/options.js:131 #: src/options/options.js:135
msgid "Onyx" msgid "Onyx"
msgstr "Onyx" msgstr "Onyx"
#: src/options/options.js:230 #: src/options/options.js:234
msgid "Orange" msgid "Orange"
msgstr "Orange" msgstr "Orange"
@@ -1305,19 +1298,19 @@ msgid "Original Name"
msgstr "Originalname" msgstr "Originalname"
#: src/component/navigation.vue:298 src/pages/library/files.vue:6 #: src/component/navigation.vue:298 src/pages/library/files.vue:6
#: src/pages/settings/general.vue:486 #: src/pages/settings/general.vue:457
msgid "Originals" msgid "Originals"
msgstr "Originale" msgstr "Originale"
#: src/options/options.js:250 #: src/options/options.js:254
msgid "Other" msgid "Other"
msgstr "Sonstiges" msgstr "Sonstiges"
#: src/options/options.js:180 #: src/options/options.js:184
msgid "Outdoor" msgid "Outdoor"
msgstr "Outdoor" msgstr "Outdoor"
#: src/dialog/photo/info.vue:101 #: src/dialog/photo/info.vue:109
msgid "Panorama" msgid "Panorama"
msgstr "Panorama" msgstr "Panorama"
@@ -1366,20 +1359,20 @@ msgstr "PhotoPrism® ist ein eingetragenes Markenzeichen von Michael Mayer."
msgid "Photos" msgid "Photos"
msgstr "Fotos" msgstr "Fotos"
#: src/options/options.js:228 #: src/options/options.js:232
msgid "Pink" msgid "Pink"
msgstr "Pink" msgstr "Pink"
#: src/dialog/photo/info.vue:109 #: src/dialog/photo/info.vue:117
msgid "Place" msgid "Place"
msgstr "Ort" msgstr "Ort"
#: src/pages/settings/general.vue:204 #: src/pages/settings/general.vue:179
msgid "Place & Time" msgid "Place & Time"
msgstr "Gleicher Ort & Zeit" msgstr "Gleicher Ort & Zeit"
#: src/component/navigation.vue:236 src/component/navigation.vue:245 #: src/component/navigation.vue:236 src/component/navigation.vue:245
#: src/pages/settings/general.vue:152 src/pages/settings/general.vue:618 #: src/pages/settings/general.vue:147 src/pages/settings/general.vue:589
#: src/routes.js:192 src/routes.js:198 src/routes.js:204 src/routes.js:211 #: src/routes.js:192 src/routes.js:198 src/routes.js:204 src/routes.js:211
msgid "Places" msgid "Places"
msgstr "Karten" msgstr "Karten"
@@ -1434,7 +1427,7 @@ msgstr "Primärdatei"
msgid "Private" msgid "Private"
msgstr "Privat" msgstr "Privat"
#: src/options/options.js:246 #: src/options/options.js:250
msgid "Product Feedback" msgid "Product Feedback"
msgstr "Allgemeines Feedback" msgstr "Allgemeines Feedback"
@@ -1442,11 +1435,11 @@ msgstr "Allgemeines Feedback"
msgid "Projection" msgid "Projection"
msgstr "Projektion" msgstr "Projektion"
#: src/options/options.js:226 #: src/options/options.js:230
msgid "Purple" msgid "Purple"
msgstr "Purpur" msgstr "Purpur"
#: src/pages/settings/general.vue:100 #: src/pages/settings/general.vue:98
msgid "Quality Filter" msgid "Quality Filter"
msgstr "Qualitätsfilter" msgstr "Qualitätsfilter"
@@ -1458,11 +1451,11 @@ msgstr "Qualität"
msgid "Random" msgid "Random"
msgstr "Zufällig" msgstr "Zufällig"
#: src/options/options.js:135 #: src/options/options.js:139
msgid "Raspberry" msgid "Raspberry"
msgstr "Raspberry" msgstr "Raspberry"
#: src/options/options.js:191 #: src/options/options.js:195
msgid "Raw" msgid "Raw"
msgstr "Raw" msgstr "Raw"
@@ -1480,7 +1473,7 @@ msgstr "Zuletzt hinzugefügt"
msgid "Recently edited" msgid "Recently edited"
msgstr "Zuletzt bearbeitet" msgstr "Zuletzt bearbeitet"
#: src/options/options.js:229 #: src/options/options.js:233
msgid "Red" msgid "Red"
msgstr "Rot" msgstr "Rot"
@@ -1552,7 +1545,7 @@ msgstr "Russisch"
msgid "Save" msgid "Save"
msgstr "Speichern" msgstr "Speichern"
#: src/dialog/photo/info.vue:93 #: src/dialog/photo/info.vue:101
msgid "Scan" msgid "Scan"
msgstr "Scan" msgstr "Scan"
@@ -1566,7 +1559,7 @@ msgstr "Scans"
msgid "Search" msgid "Search"
msgstr "Suche" msgstr "Suche"
#: src/pages/settings/general.vue:619 #: src/pages/settings/general.vue:590
msgid "Search and display photos on a map." msgid "Search and display photos on a map."
msgstr "Fotos und Videos auf verschiedenen Weltkarten anzeigen und filtern." msgstr "Fotos und Videos auf verschiedenen Weltkarten anzeigen und filtern."
@@ -1581,7 +1574,7 @@ msgstr "Suchbegriff zu kurz"
msgid "Season" msgid "Season"
msgstr "Jahreszeit" msgstr "Jahreszeit"
#: src/options/options.js:139 #: src/options/options.js:143
msgid "Seaweed" msgid "Seaweed"
msgstr "Seegras" msgstr "Seegras"
@@ -1609,7 +1602,7 @@ msgstr "Auswahl wiederhergestellt"
msgid "Send" msgid "Send"
msgstr "Senden" msgstr "Senden"
#: src/pages/settings/general.vue:248 #: src/pages/settings/general.vue:221
msgid "Sequential Name" msgid "Sequential Name"
msgstr "Fortlaufender Name" msgstr "Fortlaufender Name"
@@ -1637,7 +1630,7 @@ msgid "Setup"
msgstr "Einrichtung" msgstr "Einrichtung"
#: src/component/album/clipboard.vue:68 src/component/album/toolbar.vue:87 #: src/component/album/clipboard.vue:68 src/component/album/toolbar.vue:87
#: src/component/photo/clipboard.vue:73 src/pages/settings/general.vue:420 #: src/component/photo/clipboard.vue:73 src/pages/settings/general.vue:391
msgid "Share" msgid "Share"
msgstr "Teilen" msgstr "Teilen"
@@ -1653,7 +1646,7 @@ msgstr "Mit dir geteilt."
msgid "Show less" msgid "Show less"
msgstr "Weniger zeigen" msgstr "Weniger zeigen"
#: src/pages/settings/general.vue:553 #: src/pages/settings/general.vue:524
msgid "Show Library in navigation menu." msgid "Show Library in navigation menu."
msgstr "Datei-Verwaltung in der Navigation anzeigen." msgstr "Datei-Verwaltung in der Navigation anzeigen."
@@ -1661,7 +1654,7 @@ msgstr "Datei-Verwaltung in der Navigation anzeigen."
msgid "Show more" msgid "Show more"
msgstr "Mehr zeigen" msgstr "Mehr zeigen"
#: src/pages/settings/general.vue:597 #: src/pages/settings/general.vue:568
msgid "Show server logs in Library." msgid "Show server logs in Library."
msgstr "Server-Ereignisprotokoll anzeigen, um Fehler zu finden." msgstr "Server-Ereignisprotokoll anzeigen, um Fehler zu finden."
@@ -1681,12 +1674,20 @@ msgstr "Anmelden"
msgid "Similar" msgid "Similar"
msgstr "Ähnlich" msgstr "Ähnlich"
#: src/dialog/photo/info.vue:93
msgid "Single"
msgstr "Einzelbild"
#: src/dialog/account/edit.vue:183 src/dialog/photo/files.vue:84 #: src/dialog/account/edit.vue:183 src/dialog/photo/files.vue:84
#: src/dialog/photo/files.vue:31 #: src/dialog/photo/files.vue:31
msgid "Size" msgid "Size"
msgstr "Größe" msgstr "Größe"
#: src/options/options.js:157 #: src/options/options.js:112
msgid "Slovak"
msgstr "Slowakisch"
#: src/options/options.js:161
msgid "Slow" msgid "Slow"
msgstr "Langsam" msgstr "Langsam"
@@ -1707,21 +1708,17 @@ msgstr "Quelle"
msgid "Spanish" msgid "Spanish"
msgstr "Spanisch" msgstr "Spanisch"
#: src/pages/settings/general.vue:227 #: src/pages/settings/general.vue:201
msgid "Stack files sharing the same unique image or instance identifier." msgid "Stack files sharing the same unique image or instance identifier."
msgstr "Bilder mit identischer ID als Stapel indexieren und anzeigen." msgstr "Bilder mit identischer ID als Stapel indexieren und anzeigen."
#: src/pages/settings/general.vue:38 #: src/pages/settings/general.vue:180
msgid "Stack files with matching..."
msgstr "Als Stapel zusammenfassen..."
#: src/pages/settings/general.vue:205
msgid "" msgid ""
"Stack pictures taken at the exact same time and location based on their " "Stack pictures taken at the exact same time and location based on their "
"metadata." "metadata."
msgstr "Aufnahmen mit übereinstimmenden Metadaten gruppieren." msgstr "Aufnahmen mit übereinstimmenden Metadaten gruppieren."
#: src/component/navigation.vue:89 src/pages/settings/general.vue:144 #: src/component/navigation.vue:89 src/pages/settings/general.vue:33
msgid "Stacks" msgid "Stacks"
msgstr "Bildstapel" msgstr "Bildstapel"
@@ -1753,11 +1750,11 @@ msgstr "Status"
msgid "Storage Folder" msgid "Storage Folder"
msgstr "Ablageverzeichnis" msgstr "Ablageverzeichnis"
#: src/options/options.js:168 #: src/options/options.js:172
msgid "Streets" msgid "Streets"
msgstr "Straßen" msgstr "Straßen"
#: src/pages/settings/general.vue:676 #: src/pages/settings/general.vue:647
msgid "Style" msgid "Style"
msgstr "Style" msgstr "Style"
@@ -1783,7 +1780,7 @@ msgstr "RAWs und Videos kopieren"
msgid "Taken" msgid "Taken"
msgstr "Aufgenommen" msgstr "Aufgenommen"
#: src/options/options.js:235 #: src/options/options.js:239
msgid "Teal" msgid "Teal"
msgstr "Blaugrün" msgstr "Blaugrün"
@@ -1803,7 +1800,7 @@ msgstr ""
"Ihr Format wird möglicherweise nicht unterstützt, es handelt sich um " "Ihr Format wird möglicherweise nicht unterstützt, es handelt sich um "
"Duplikate oder sie wurden noch nicht nach JPEG konvertiert." "Duplikate oder sie wurden noch nicht nach JPEG konvertiert."
#: src/pages/settings/general.vue:306 #: src/pages/settings/general.vue:277
msgid "Theme" msgid "Theme"
msgstr "Theme" msgstr "Theme"
@@ -1848,7 +1845,7 @@ msgstr "View wechseln"
msgid "Token" msgid "Token"
msgstr "Code" msgstr "Code"
#: src/options/options.js:176 #: src/options/options.js:180
msgid "Topographic" msgid "Topographic"
msgstr "Topographisch" msgstr "Topographisch"
@@ -1870,7 +1867,7 @@ msgstr "Versuche es mit anderen Filtern oder Suchbegriffen."
msgid "Type" msgid "Type"
msgstr "Typ" msgstr "Typ"
#: src/pages/settings/general.vue:226 #: src/pages/settings/general.vue:200
msgid "Unique ID" msgid "Unique ID"
msgstr "Eindeutige Bild-ID" msgstr "Eindeutige Bild-ID"
@@ -1892,7 +1889,7 @@ msgstr "Unsortiert"
msgid "Unstack" msgid "Unstack"
msgstr "Entfernen" msgstr "Entfernen"
#: src/dialog/photo/files.vue:165 src/dialog/photo/info.vue:157 #: src/dialog/photo/files.vue:165 src/dialog/photo/info.vue:165
msgid "Updated" msgid "Updated"
msgstr "Geändert" msgstr "Geändert"
@@ -1911,7 +1908,7 @@ msgstr "Aktualisiere Bildstapel"
#: src/component/album/toolbar.vue:175 src/component/navigation.vue:131 #: src/component/album/toolbar.vue:175 src/component/navigation.vue:131
#: src/component/photo/toolbar.vue:123 src/dialog/share/upload.vue:35 #: src/component/photo/toolbar.vue:123 src/dialog/share/upload.vue:35
#: src/dialog/upload.vue:8 src/dialog/upload.vue:54 src/pages/albums.vue:138 #: src/dialog/upload.vue:8 src/dialog/upload.vue:54 src/pages/albums.vue:138
#: src/pages/library/import.vue:38 src/pages/settings/general.vue:376 #: src/pages/library/import.vue:38 src/pages/settings/general.vue:347
#: src/pages/settings/sync.vue:24 #: src/pages/settings/sync.vue:24
msgid "Upload" msgid "Upload"
msgstr "Upload" msgstr "Upload"
@@ -1932,7 +1929,7 @@ msgstr "Upload fehlgeschlagen"
msgid "Upload local files" msgid "Upload local files"
msgstr "Dateien hochladen" msgstr "Dateien hochladen"
#: src/pages/settings/general.vue:421 #: src/pages/settings/general.vue:392
msgid "Upload to WebDAV and share links with friends." msgid "Upload to WebDAV and share links with friends."
msgstr "Teile Fotos, Videos und Alben mit Freunden." msgstr "Teile Fotos, Videos und Alben mit Freunden."
@@ -1956,7 +1953,7 @@ msgstr "URL"
msgid "User" msgid "User"
msgstr "Benutzer" msgstr "Benutzer"
#: src/pages/settings/general.vue:66 #: src/pages/settings/general.vue:61
msgid "User Interface" msgid "User Interface"
msgstr "Benutzeroberfläche" msgstr "Benutzeroberfläche"
@@ -1966,7 +1963,7 @@ msgid "Username"
msgstr "Nutzername" msgstr "Nutzername"
#: src/model/file.js:172 src/model/photo.js:489 src/model/photo.js:503 #: src/model/file.js:172 src/model/photo.js:489 src/model/photo.js:503
#: src/options/options.js:199 #: src/options/options.js:203
msgid "Video" msgid "Video"
msgstr "Video" msgstr "Video"
@@ -1995,7 +1992,7 @@ msgstr ""
msgid "WebDAV Upload" msgid "WebDAV Upload"
msgstr "WebDAV Upload" msgstr "WebDAV Upload"
#: src/options/options.js:239 #: src/options/options.js:243
msgid "White" msgid "White"
msgstr "Weiß" msgstr "Weiß"
@@ -2003,14 +2000,15 @@ msgstr "Weiß"
msgid "Year" msgid "Year"
msgstr "Jahr" msgstr "Jahr"
#: src/options/options.js:232 #: src/options/options.js:236
msgid "Yellow" msgid "Yellow"
msgstr "Gelb" msgstr "Gelb"
#: src/dialog/photo/archive.vue:18 src/dialog/photo/files.vue:105 #: src/dialog/photo/archive.vue:18 src/dialog/photo/files.vue:105
#: src/dialog/photo/files.vue:113 src/dialog/photo/files.vue:151 #: src/dialog/photo/files.vue:113 src/dialog/photo/files.vue:151
#: src/dialog/photo/info.vue:267 src/dialog/photo/info.vue:286 #: src/dialog/photo/info.vue:268 src/dialog/photo/info.vue:287
#: src/dialog/photo/info.vue:305 src/dialog/photo/info.vue:324 #: src/dialog/photo/info.vue:306 src/dialog/photo/info.vue:325
#: src/dialog/photo/info.vue:344
msgid "Yes" msgid "Yes"
msgstr "Ja" msgstr "Ja"
@@ -2045,6 +2043,14 @@ msgstr "Ihre Nachricht wurde gesendet"
msgid "Zoom in/out" msgid "Zoom in/out"
msgstr "Zoom in/out" msgstr "Zoom in/out"
#~ msgid "msgid"
#~ msgid_plural "plural"
#~ msgstr[0] "msgid"
#~ msgstr[1] ""
#~ msgid "Stack files with matching..."
#~ msgstr "Als Stapel zusammenfassen..."
#~ msgid "File Name Prefix" #~ msgid "File Name Prefix"
#~ msgstr "Fortlaufender Name" #~ msgstr "Fortlaufender Name"

File diff suppressed because one or more lines are too long

View File

@@ -62,7 +62,7 @@ msgstr ""
msgid "Account" msgid "Account"
msgstr "" msgstr ""
#: src/dialog/photo/info.vue:141 #: src/dialog/photo/info.vue:149
msgid "Accuracy" msgid "Accuracy"
msgstr "" msgstr ""
@@ -78,7 +78,7 @@ msgstr ""
msgid "Add Album" msgid "Add Album"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:377 #: src/pages/settings/general.vue:348
msgid "Add files to your library via Web Upload." msgid "Add files to your library via Web Upload."
msgstr "" msgstr ""
@@ -222,7 +222,7 @@ msgstr ""
msgid "Alternatively, you can upload files directly to WebDAV servers like Nextcloud." msgid "Alternatively, you can upload files directly to WebDAV servers like Nextcloud."
msgstr "" msgstr ""
#: src/dialog/photo/info.vue:133 #: src/dialog/photo/info.vue:141
msgid "Altitude" msgid "Altitude"
msgstr "" msgstr ""
@@ -234,7 +234,7 @@ msgstr ""
msgid "An error occurred - are you offline?" msgid "An error occurred - are you offline?"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:698 #: src/pages/settings/general.vue:669
msgid "Animation" msgid "Animation"
msgstr "" msgstr ""
@@ -259,12 +259,12 @@ msgstr ""
#: src/component/navigation.vue:114 #: src/component/navigation.vue:114
#: src/component/photo/cards.vue:20 #: src/component/photo/cards.vue:20
#: src/component/photo/clipboard.vue:211 #: src/component/photo/clipboard.vue:211
#: src/pages/settings/general.vue:442 #: src/pages/settings/general.vue:413
#: src/routes.js:185 #: src/routes.js:185
msgid "Archive" msgid "Archive"
msgstr "" msgstr ""
#: src/dialog/photo/info.vue:181 #: src/dialog/photo/info.vue:189
msgid "Archived" msgid "Archived"
msgstr "" msgstr ""
@@ -300,7 +300,7 @@ msgstr ""
msgid "At least 6 characters." msgid "At least 6 characters."
msgstr "" msgstr ""
#: src/pages/settings/general.vue:123 #: src/pages/settings/general.vue:120
msgid "Automatically create JPEGs for other file types so that they can be displayed in a browser." msgid "Automatically create JPEGs for other file types so that they can be displayed in a browser."
msgstr "" msgstr ""
@@ -320,11 +320,11 @@ msgstr ""
msgid "Brown" msgid "Brown"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:531 #: src/pages/settings/general.vue:502
msgid "Browse and edit image classification labels." msgid "Browse and edit image classification labels."
msgstr "" msgstr ""
#: src/pages/settings/general.vue:487 #: src/pages/settings/general.vue:458
msgid "Browse indexed files and folders in Library." msgid "Browse indexed files and folders in Library."
msgstr "" msgstr ""
@@ -404,7 +404,7 @@ msgstr ""
msgid "Change" msgid "Change"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:465 #: src/pages/settings/general.vue:436
msgid "Change photo titles, locations and other metadata." msgid "Change photo titles, locations and other metadata."
msgstr "" msgstr ""
@@ -412,7 +412,7 @@ msgstr ""
msgid "Change private flag" msgid "Change private flag"
msgstr "" msgstr ""
#: src/dialog/photo/info.vue:173 #: src/dialog/photo/info.vue:181
msgid "Checked" msgid "Checked"
msgstr "" msgstr ""
@@ -476,7 +476,7 @@ msgstr ""
msgid "Contributors" msgid "Contributors"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:122 #: src/pages/settings/general.vue:119
msgid "Convert to JPEG" msgid "Convert to JPEG"
msgstr "" msgstr ""
@@ -535,7 +535,7 @@ msgstr ""
msgid "Create album" msgid "Create album"
msgstr "" msgstr ""
#: src/dialog/photo/info.vue:149 #: src/dialog/photo/info.vue:157
msgid "Created" msgid "Created"
msgstr "" msgstr ""
@@ -636,7 +636,7 @@ msgstr ""
#: src/component/photo/clipboard.vue:165 #: src/component/photo/clipboard.vue:165
#: src/component/photo/viewer.vue:72 #: src/component/photo/viewer.vue:72
#: src/dialog/photo/files.vue:33 #: src/dialog/photo/files.vue:33
#: src/pages/settings/general.vue:398 #: src/pages/settings/general.vue:369
#: src/share/album/clipboard.vue:60 #: src/share/album/clipboard.vue:60
#: src/share/photo/clipboard.vue:62 #: src/share/photo/clipboard.vue:62
#: src/share/photos.vue:75 #: src/share/photos.vue:75
@@ -647,7 +647,7 @@ msgstr ""
msgid "Download remote files" msgid "Download remote files"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:399 #: src/pages/settings/general.vue:370
msgid "Download single files and zip archives." msgid "Download single files and zip archives."
msgstr "" msgstr ""
@@ -679,7 +679,7 @@ msgstr ""
#: src/component/album/toolbar.vue:69 #: src/component/album/toolbar.vue:69
#: src/component/photo/clipboard.vue:119 #: src/component/photo/clipboard.vue:119
#: src/component/photo/viewer.vue:89 #: src/component/photo/viewer.vue:89
#: src/pages/settings/general.vue:464 #: src/pages/settings/general.vue:435
msgid "Edit" msgid "Edit"
msgstr "" msgstr ""
@@ -695,7 +695,7 @@ msgstr ""
msgid "Edit Photo" msgid "Edit Photo"
msgstr "" msgstr ""
#: src/dialog/photo/info.vue:165 #: src/dialog/photo/info.vue:173
msgid "Edited" msgid "Edited"
msgstr "" msgstr ""
@@ -720,7 +720,7 @@ msgstr ""
msgid "Every two days" msgid "Every two days"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:79 #: src/pages/settings/general.vue:78
msgid "Exclude content marked as private from search results, shared albums, labels and places." msgid "Exclude content marked as private from search results, shared albums, labels and places."
msgstr "" msgstr ""
@@ -792,7 +792,7 @@ msgstr ""
msgid "Files" msgid "Files"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:249 #: src/pages/settings/general.vue:222
msgid "Files with sequential names like 'IMG_1234 (2)' and 'IMG_1234 (3)' belong to the same picture." msgid "Files with sequential names like 'IMG_1234 (2)' and 'IMG_1234 (3)' belong to the same picture."
msgstr "" msgstr ""
@@ -873,11 +873,11 @@ msgstr ""
msgid "Hidden Files" msgid "Hidden Files"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:443 #: src/pages/settings/general.vue:414
msgid "Hide photos that have been moved to archive." msgid "Hide photos that have been moved to archive."
msgstr "" msgstr ""
#: src/pages/settings/general.vue:78 #: src/pages/settings/general.vue:77
msgid "Hide Private" msgid "Hide Private"
msgstr "" msgstr ""
@@ -909,7 +909,7 @@ msgid "Image"
msgstr "" msgstr ""
#: src/pages/library/import.vue:43 #: src/pages/library/import.vue:43
#: src/pages/settings/general.vue:574 #: src/pages/settings/general.vue:545
msgid "Import" msgid "Import"
msgstr "" msgstr ""
@@ -921,7 +921,7 @@ msgstr ""
msgid "Imported files will be sorted by date and given a unique name to avoid duplicates." msgid "Imported files will be sorted by date and given a unique name to avoid duplicates."
msgstr "" msgstr ""
#: src/pages/settings/general.vue:575 #: src/pages/settings/general.vue:546
msgid "Imported files will be sorted by date and given a unique name." msgid "Imported files will be sorted by date and given a unique name."
msgstr "" msgstr ""
@@ -991,7 +991,7 @@ msgstr ""
#: src/component/navigation.vue:268 #: src/component/navigation.vue:268
#: src/dialog/photo/edit.vue:27 #: src/dialog/photo/edit.vue:27
#: src/pages/settings/general.vue:530 #: src/pages/settings/general.vue:501
#: src/routes.js:236 #: src/routes.js:236
msgid "Labels" msgid "Labels"
msgstr "" msgstr ""
@@ -1000,7 +1000,7 @@ msgstr ""
msgid "Labels deleted" msgid "Labels deleted"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:328 #: src/pages/settings/general.vue:299
msgid "Language" msgid "Language"
msgstr "" msgstr ""
@@ -1009,7 +1009,7 @@ msgid "Last Backup"
msgstr "" msgstr ""
#: src/dialog/photo/details.vue:327 #: src/dialog/photo/details.vue:327
#: src/dialog/photo/info.vue:117 #: src/dialog/photo/info.vue:125
msgid "Latitude" msgid "Latitude"
msgstr "" msgstr ""
@@ -1021,14 +1021,14 @@ msgstr ""
msgid "Lens" msgid "Lens"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:509 #: src/pages/settings/general.vue:480
msgid "Let PhotoPrism create albums from past events." msgid "Let PhotoPrism create albums from past events."
msgstr "" msgstr ""
#: src/component/navigation.vue:281 #: src/component/navigation.vue:281
#: src/component/navigation.vue:290 #: src/component/navigation.vue:290
#: src/pages/settings/general.vue:6 #: src/pages/settings/general.vue:6
#: src/pages/settings/general.vue:552 #: src/pages/settings/general.vue:523
#: src/routes.js:255 #: src/routes.js:255
#: src/routes.js:262 #: src/routes.js:262
#: src/routes.js:269 #: src/routes.js:269
@@ -1094,12 +1094,12 @@ msgid "Logout"
msgstr "" msgstr ""
#: src/pages/library.vue:17 #: src/pages/library.vue:17
#: src/pages/settings/general.vue:596 #: src/pages/settings/general.vue:567
msgid "Logs" msgid "Logs"
msgstr "" msgstr ""
#: src/dialog/photo/details.vue:348 #: src/dialog/photo/details.vue:348
#: src/dialog/photo/info.vue:125 #: src/dialog/photo/info.vue:133
msgid "Longitude" msgid "Longitude"
msgstr "" msgstr ""
@@ -1132,7 +1132,7 @@ msgid "Missing"
msgstr "" msgstr ""
#: src/component/navigation.vue:223 #: src/component/navigation.vue:223
#: src/pages/settings/general.vue:508 #: src/pages/settings/general.vue:479
#: src/routes.js:98 #: src/routes.js:98
#: src/routes.js:105 #: src/routes.js:105
msgid "Moments" msgid "Moments"
@@ -1226,10 +1226,11 @@ msgid "Newest first"
msgstr "" msgstr ""
#: src/dialog/photo/archive.vue:15 #: src/dialog/photo/archive.vue:15
#: src/dialog/photo/info.vue:267 #: src/dialog/photo/info.vue:268
#: src/dialog/photo/info.vue:286 #: src/dialog/photo/info.vue:287
#: src/dialog/photo/info.vue:305 #: src/dialog/photo/info.vue:306
#: src/dialog/photo/info.vue:324 #: src/dialog/photo/info.vue:325
#: src/dialog/photo/info.vue:344
msgid "No" msgid "No"
msgstr "" msgstr ""
@@ -1272,7 +1273,7 @@ msgstr ""
#: src/component/photo/mosaic.vue:15 #: src/component/photo/mosaic.vue:15
#: src/component/photo/mosaic.vue:1 #: src/component/photo/mosaic.vue:1
#: src/dialog/upload.vue:50 #: src/dialog/upload.vue:50
#: src/pages/settings/general.vue:101 #: src/pages/settings/general.vue:99
msgid "Non-photographic and low-quality images require a review before they appear in search results." msgid "Non-photographic and low-quality images require a review before they appear in search results."
msgstr "" msgstr ""
@@ -1372,7 +1373,7 @@ msgstr ""
#: src/component/navigation.vue:298 #: src/component/navigation.vue:298
#: src/pages/library/files.vue:6 #: src/pages/library/files.vue:6
#: src/pages/settings/general.vue:486 #: src/pages/settings/general.vue:457
msgid "Originals" msgid "Originals"
msgstr "" msgstr ""
@@ -1384,7 +1385,7 @@ msgstr ""
msgid "Outdoor" msgid "Outdoor"
msgstr "" msgstr ""
#: src/dialog/photo/info.vue:101 #: src/dialog/photo/info.vue:109
msgid "Panorama" msgid "Panorama"
msgstr "" msgstr ""
@@ -1436,18 +1437,18 @@ msgstr ""
msgid "Pink" msgid "Pink"
msgstr "" msgstr ""
#: src/dialog/photo/info.vue:109 #: src/dialog/photo/info.vue:117
msgid "Place" msgid "Place"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:204 #: src/pages/settings/general.vue:179
msgid "Place & Time" msgid "Place & Time"
msgstr "" msgstr ""
#: src/component/navigation.vue:236 #: src/component/navigation.vue:236
#: src/component/navigation.vue:245 #: src/component/navigation.vue:245
#: src/pages/settings/general.vue:152 #: src/pages/settings/general.vue:147
#: src/pages/settings/general.vue:618 #: src/pages/settings/general.vue:589
#: src/routes.js:192 #: src/routes.js:192
#: src/routes.js:198 #: src/routes.js:198
#: src/routes.js:204 #: src/routes.js:204
@@ -1520,7 +1521,7 @@ msgstr ""
msgid "Purple" msgid "Purple"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:100 #: src/pages/settings/general.vue:98
msgid "Quality Filter" msgid "Quality Filter"
msgstr "" msgstr ""
@@ -1632,7 +1633,7 @@ msgstr ""
msgid "Save" msgid "Save"
msgstr "" msgstr ""
#: src/dialog/photo/info.vue:93 #: src/dialog/photo/info.vue:101
msgid "Scan" msgid "Scan"
msgstr "" msgstr ""
@@ -1649,7 +1650,7 @@ msgstr ""
msgid "Search" msgid "Search"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:619 #: src/pages/settings/general.vue:590
msgid "Search and display photos on a map." msgid "Search and display photos on a map."
msgstr "" msgstr ""
@@ -1697,7 +1698,7 @@ msgstr ""
msgid "Send" msgid "Send"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:248 #: src/pages/settings/general.vue:221
msgid "Sequential Name" msgid "Sequential Name"
msgstr "" msgstr ""
@@ -1732,7 +1733,7 @@ msgstr ""
#: src/component/album/clipboard.vue:68 #: src/component/album/clipboard.vue:68
#: src/component/album/toolbar.vue:87 #: src/component/album/toolbar.vue:87
#: src/component/photo/clipboard.vue:73 #: src/component/photo/clipboard.vue:73
#: src/pages/settings/general.vue:420 #: src/pages/settings/general.vue:391
msgid "Share" msgid "Share"
msgstr "" msgstr ""
@@ -1748,7 +1749,7 @@ msgstr ""
msgid "Show less" msgid "Show less"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:553 #: src/pages/settings/general.vue:524
msgid "Show Library in navigation menu." msgid "Show Library in navigation menu."
msgstr "" msgstr ""
@@ -1756,7 +1757,7 @@ msgstr ""
msgid "Show more" msgid "Show more"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:597 #: src/pages/settings/general.vue:568
msgid "Show server logs in Library." msgid "Show server logs in Library."
msgstr "" msgstr ""
@@ -1776,6 +1777,10 @@ msgstr ""
msgid "Similar" msgid "Similar"
msgstr "" msgstr ""
#: src/dialog/photo/info.vue:93
msgid "Single"
msgstr ""
#: src/dialog/account/edit.vue:183 #: src/dialog/account/edit.vue:183
#: src/dialog/photo/files.vue:84 #: src/dialog/photo/files.vue:84
#: src/dialog/photo/files.vue:31 #: src/dialog/photo/files.vue:31
@@ -1809,20 +1814,16 @@ msgstr ""
msgid "Spanish" msgid "Spanish"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:227 #: src/pages/settings/general.vue:201
msgid "Stack files sharing the same unique image or instance identifier." msgid "Stack files sharing the same unique image or instance identifier."
msgstr "" msgstr ""
#: src/pages/settings/general.vue:38 #: src/pages/settings/general.vue:180
msgid "Stack files with matching..."
msgstr ""
#: src/pages/settings/general.vue:205
msgid "Stack pictures taken at the exact same time and location based on their metadata." msgid "Stack pictures taken at the exact same time and location based on their metadata."
msgstr "" msgstr ""
#: src/component/navigation.vue:89 #: src/component/navigation.vue:89
#: src/pages/settings/general.vue:144 #: src/pages/settings/general.vue:33
msgid "Stacks" msgid "Stacks"
msgstr "" msgstr ""
@@ -1854,7 +1855,7 @@ msgstr ""
msgid "Streets" msgid "Streets"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:676 #: src/pages/settings/general.vue:647
msgid "Style" msgid "Style"
msgstr "" msgstr ""
@@ -1896,7 +1897,7 @@ msgstr ""
msgid "Their format may not be supported, they haven't been converted to JPEG yet or there are duplicates." msgid "Their format may not be supported, they haven't been converted to JPEG yet or there are duplicates."
msgstr "" msgstr ""
#: src/pages/settings/general.vue:306 #: src/pages/settings/general.vue:277
msgid "Theme" msgid "Theme"
msgstr "" msgstr ""
@@ -1973,7 +1974,7 @@ msgstr ""
msgid "Type" msgid "Type"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:226 #: src/pages/settings/general.vue:200
msgid "Unique ID" msgid "Unique ID"
msgstr "" msgstr ""
@@ -2007,7 +2008,7 @@ msgid "Unstack"
msgstr "" msgstr ""
#: src/dialog/photo/files.vue:165 #: src/dialog/photo/files.vue:165
#: src/dialog/photo/info.vue:157 #: src/dialog/photo/info.vue:165
msgid "Updated" msgid "Updated"
msgstr "" msgstr ""
@@ -2031,7 +2032,7 @@ msgstr ""
#: src/dialog/upload.vue:54 #: src/dialog/upload.vue:54
#: src/pages/albums.vue:138 #: src/pages/albums.vue:138
#: src/pages/library/import.vue:38 #: src/pages/library/import.vue:38
#: src/pages/settings/general.vue:376 #: src/pages/settings/general.vue:347
#: src/pages/settings/sync.vue:24 #: src/pages/settings/sync.vue:24
msgid "Upload" msgid "Upload"
msgstr "" msgstr ""
@@ -2052,7 +2053,7 @@ msgstr ""
msgid "Upload local files" msgid "Upload local files"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:421 #: src/pages/settings/general.vue:392
msgid "Upload to WebDAV and share links with friends." msgid "Upload to WebDAV and share links with friends."
msgstr "" msgstr ""
@@ -2078,7 +2079,7 @@ msgstr ""
msgid "User" msgid "User"
msgstr "" msgstr ""
#: src/pages/settings/general.vue:66 #: src/pages/settings/general.vue:61
msgid "User Interface" msgid "User Interface"
msgstr "" msgstr ""
@@ -2134,10 +2135,11 @@ msgstr ""
#: src/dialog/photo/files.vue:105 #: src/dialog/photo/files.vue:105
#: src/dialog/photo/files.vue:113 #: src/dialog/photo/files.vue:113
#: src/dialog/photo/files.vue:151 #: src/dialog/photo/files.vue:151
#: src/dialog/photo/info.vue:267 #: src/dialog/photo/info.vue:268
#: src/dialog/photo/info.vue:286 #: src/dialog/photo/info.vue:287
#: src/dialog/photo/info.vue:305 #: src/dialog/photo/info.vue:306
#: src/dialog/photo/info.vue:324 #: src/dialog/photo/info.vue:325
#: src/dialog/photo/info.vue:344
msgid "Yes" msgid "Yes"
msgstr "" msgstr ""

View File

@@ -12,7 +12,7 @@
<v-card-actions> <v-card-actions>
<v-layout wrap align-top> <v-layout wrap align-top>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2"> <v-flex xs12 sm4 class="px-2 pb-2 pt-2">
<v-checkbox <v-checkbox
@change="onChange" @change="onChange"
:disabled="busy" :disabled="busy"
@@ -27,7 +27,7 @@
</v-checkbox> </v-checkbox>
</v-flex> </v-flex>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2"> <v-flex xs12 sm4 class="px-2 pb-2 pt-2">
<v-checkbox <v-checkbox
@change="onChange" @change="onChange"
:disabled="busy" :disabled="busy"
@@ -42,7 +42,7 @@
</v-checkbox> </v-checkbox>
</v-flex> </v-flex>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2"> <v-flex xs12 sm4 class="px-2 pb-2 pt-2">
<v-checkbox <v-checkbox
@change="onChange" @change="onChange"
:disabled="busy" :disabled="busy"
@@ -56,35 +56,20 @@
> >
</v-checkbox> </v-checkbox>
</v-flex> </v-flex>
<v-flex xs12 sm6 lg3 class="px-2 pb-2 pt-2">
<v-checkbox
@change="onChange"
:disabled="busy"
class="ma-0 pa-0 input-stacks"
v-model="settings.index.stacks"
color="secondary-dark"
:label="$gettext('Stacks')"
:hint="$gettext('Stacks group files with a similar frame of reference, but differences of quality, format, size or color.')"
prepend-icon="burst_mode"
persistent-hint
>
</v-checkbox>
</v-flex>
</v-layout> </v-layout>
</v-card-actions> </v-card-actions>
</v-card> </v-card>
<v-card flat tile class="mt-0 px-1 application" v-show="settings.index.stacks"> <v-card flat tile class="mt-0 px-1 application">
<v-card-title primary-title class="pb-0"> <v-card-title primary-title class="pb-0" :title="$gettext('Stacks group files with a similar frame of reference, but differences of quality, format, size or color.')">
<h3 class="body-2 mb-0"> <h3 class="body-2 mb-0">
<translate>Stack files with matching...</translate> <translate>Stacks</translate>
</h3> </h3>
</v-card-title> </v-card-title>
<v-card-actions> <v-card-actions>
<v-layout wrap align-top> <v-layout wrap align-top>
<v-flex xs12 sm6 lg4 class="px-2 pb-2 pt-2"> <v-flex xs12 sm4 class="px-2 pb-2 pt-2">
<v-checkbox <v-checkbox
@change="onChange" @change="onChange"
:disabled="busy" :disabled="busy"
@@ -99,7 +84,7 @@
</v-checkbox> </v-checkbox>
</v-flex> </v-flex>
<v-flex xs12 sm6 lg4 class="px-2 pb-2 pt-2"> <v-flex xs12 sm4 class="px-2 pb-2 pt-2">
<v-checkbox <v-checkbox
@change="onChange" @change="onChange"
:disabled="busy" :disabled="busy"
@@ -115,7 +100,7 @@
</v-flex> </v-flex>
<v-flex xs12 sm6 lg4 class="px-2 pb-2 pt-2"> <v-flex xs12 sm4 class="px-2 pb-2 pt-2">
<v-checkbox <v-checkbox
@change="onChange" @change="onChange"
:disabled="busy" :disabled="busy"

View File

@@ -49,8 +49,8 @@ func StartIndexing(router *gin.RouterGroup) {
indOpt := photoprism.IndexOptions{ indOpt := photoprism.IndexOptions{
Rescan: f.Rescan, Rescan: f.Rescan,
Convert: conf.Settings().Index.Convert && conf.SidecarWritable(), Convert: conf.Settings().Index.Convert && conf.SidecarWritable(),
Stack: conf.Settings().Index.Stacks,
Path: filepath.Clean(f.Path), Path: filepath.Clean(f.Path),
Single: false,
} }
if len(indOpt.Path) > 1 { if len(indOpt.Path) > 1 {

View File

@@ -63,7 +63,7 @@ func indexAction(ctx *cli.Context) error {
Path: subPath, Path: subPath,
Rescan: ctx.Bool("all"), Rescan: ctx.Bool("all"),
Convert: conf.Settings().Index.Convert && conf.SidecarWritable(), Convert: conf.Settings().Index.Convert && conf.SidecarWritable(),
Stack: conf.Settings().Index.Stacks, Single: false,
} }
indexed := ind.Start(indOpt) indexed := ind.Start(indOpt)

View File

@@ -231,12 +231,6 @@ func (c *Config) InitTestDb() {
go entity.SaveErrorMessages() go entity.SaveErrorMessages()
} }
// TruncateDb drops all contents so that they can be restored from a backup.
func (c *Config) TruncateDb() {
entity.SetDbProvider(c)
entity.Entities.Truncate()
}
// connectDb establishes a database connection. // connectDb establishes a database connection.
func (c *Config) connectDb() error { func (c *Config) connectDb() error {
mutex.Db.Lock() mutex.Db.Lock()

View File

@@ -56,7 +56,6 @@ type IndexSettings struct {
Path string `json:"path" yaml:"path"` Path string `json:"path" yaml:"path"`
Convert bool `json:"convert" yaml:"convert"` Convert bool `json:"convert" yaml:"convert"`
Rescan bool `json:"rescan" yaml:"rescan"` Rescan bool `json:"rescan" yaml:"rescan"`
Stacks bool `json:"stacks" yaml:"stacks"`
} }
// StackSettings represents settings for files that belong to the same photo. // StackSettings represents settings for files that belong to the same photo.
@@ -114,7 +113,6 @@ func NewSettings() *Settings {
Path: "/", Path: "/",
Rescan: false, Rescan: false,
Convert: true, Convert: true,
Stacks: true,
}, },
Stack: StackSettings{ Stack: StackSettings{
UUID: true, UUID: true,
@@ -131,17 +129,17 @@ func (s *Settings) Propagate() {
// StackSequences tests if files should be stacked based on their file name prefix (sequential names). // StackSequences tests if files should be stacked based on their file name prefix (sequential names).
func (s Settings) StackSequences() bool { func (s Settings) StackSequences() bool {
return s.Index.Stacks && s.Stack.Name return s.Stack.Name
} }
// StackUUID tests if files should be stacked based on unique image or instance id. // StackUUID tests if files should be stacked based on unique image or instance id.
func (s Settings) StackUUID() bool { func (s Settings) StackUUID() bool {
return s.Index.Stacks && s.Stack.UUID return s.Stack.UUID
} }
// StackMeta tests if files should be stacked based on their place and time metadata. // StackMeta tests if files should be stacked based on their place and time metadata.
func (s Settings) StackMeta() bool { func (s Settings) StackMeta() bool {
return s.Index.Stacks && s.Stack.Meta return s.Stack.Meta
} }
// Load user settings from file. // Load user settings from file.

View File

@@ -27,7 +27,6 @@ index:
path: / path: /
convert: true convert: true
rescan: false rescan: false
stacks: true
stack: stack:
uuid: true uuid: true
meta: true meta: true

View File

@@ -160,7 +160,9 @@ func (m *File) Delete(permanently bool) error {
// Purge removes a file from the index by marking it as missing. // Purge removes a file from the index by marking it as missing.
func (m *File) Purge() error { func (m *File) Purge() error {
return Db().Unscoped().Model(m).Updates(map[string]interface{}{"file_missing": true, "file_primary": false}).Error m.FileMissing = true
m.FilePrimary = false
return Db().Unscoped().Exec("UPDATE files SET file_missing = 1, file_primary = 0 WHERE id = ?", m.ID).Error
} }
// AllFilesMissing returns true, if all files for the photo of this file are missing. // AllFilesMissing returns true, if all files for the photo of this file are missing.
@@ -190,6 +192,15 @@ func (m *File) Create() error {
return nil return nil
} }
// ResolvePrimary ensures there is only one primary file for a photo..
func (m *File) ResolvePrimary() error {
if m.FilePrimary {
return UnscopedDb().Exec("UPDATE `files` SET file_primary = (id = ?) WHERE photo_id = ?", m.ID, m.PhotoID).Error
}
return nil
}
// Saves the file in the database. // Saves the file in the database.
func (m *File) Save() error { func (m *File) Save() error {
if m.PhotoID == 0 { if m.PhotoID == 0 {
@@ -201,7 +212,7 @@ func (m *File) Save() error {
return err return err
} }
return nil return m.ResolvePrimary()
} }
// UpdateVideoInfos updates related video infos based on this file. // UpdateVideoInfos updates related video infos based on this file.

View File

@@ -526,6 +526,43 @@ var FileFixtures = map[string]File{
UpdatedIn: 0, UpdatedIn: 0,
DeletedAt: nil, DeletedAt: nil,
}, },
"Photo19.jpg": {
ID: 1000019,
Photo: PhotoFixtures.Pointer("Photo19"),
PhotoID: PhotoFixtures.Pointer("Photo19").ID,
PhotoUID: PhotoFixtures.Pointer("Photo19").PhotoUID,
FileUID: "ft2es49qhhinlqdn",
FileName: "Photo19.jpg",
FileRoot: RootOriginals,
OriginalName: "Photo19.jpg",
FileHash: "pcad9a68fa6acc5c5ba965adf6ec465ca42fd811",
ModTime: time.Date(2020, 2, 6, 2, 6, 51, 0, time.UTC).Unix(),
FileSize: 921831,
FileType: "jpg",
FileMime: "image/jpg",
FilePrimary: true,
FileSidecar: false,
FileVideo: false,
FileMissing: false,
FilePortrait: false,
FileWidth: 1200,
FileHeight: 1600,
FileOrientation: 6,
FileAspectRatio: 0.75,
FileMainColor: "magenta",
FileColors: "225221C1E",
FileLuminance: "DC42844C8",
FileDiff: 986,
FileChroma: 32,
FileError: "",
Share: []FileShare{},
Sync: []FileSync{},
CreatedAt: time.Date(2019, 1, 1, 2, 6, 51, 0, time.UTC),
CreatedIn: 2,
UpdatedAt: time.Date(2020, 3, 28, 14, 6, 0, 0, time.UTC),
UpdatedIn: 0,
DeletedAt: nil,
},
} }
var FileFixturesExampleJPG = FileFixtures["exampleFileName.jpg"] var FileFixturesExampleJPG = FileFixtures["exampleFileName.jpg"]

View File

@@ -230,7 +230,7 @@ func (m *Photo) Save() error {
return err return err
} }
return nil return m.ResolvePrimary()
} }
// Find returns a photo from the database. // Find returns a photo from the database.
@@ -890,7 +890,7 @@ func (m *Photo) AllFilesMissing() bool {
count := 0 count := 0
if err := Db().Model(&File{}). if err := Db().Model(&File{}).
Where("photo_id = ? AND b.file_missing = 0", m.ID). Where("photo_id = ? AND file_missing = 0", m.ID).
Count(&count).Error; err != nil { Count(&count).Error; err != nil {
log.Error(err) log.Error(err)
} }
@@ -1010,61 +1010,3 @@ func (m *Photo) PrimaryFile() (File, error) {
func (m *Photo) MapKey() string { func (m *Photo) MapKey() string {
return MapKey(m.TakenAt, m.CellID) return MapKey(m.TakenAt, m.CellID)
} }
// Stack merges a photo with identical ones.
func (m *Photo) Stack(stackMeta, stackUuid bool) (identical Photos, err error) {
if !stackMeta && !stackUuid || m.PhotoSingle || m.DeletedAt != nil {
return identical, nil
}
switch {
case stackMeta && stackUuid && m.HasLocation() && m.HasLatLng() && m.TakenSrc == SrcMeta && rnd.IsUUID(m.UUID):
if err := Db().Where("id > ? AND photo_single = 0", m.ID).
Where("(taken_at = ? AND taken_src = 'meta' AND cell_id = ? AND camera_serial = ? AND camera_id = ?) OR (uuid <> '' AND uuid = ?)",
m.TakenAt, m.CellID, m.CameraSerial, m.CameraID, m.UUID).Find(&identical).Error; err != nil {
return identical, err
}
case stackMeta && m.HasLocation() && m.HasLatLng() && m.TakenSrc == SrcMeta:
if err := Db().Where("id > ? AND photo_single = 0", m.ID).
Where("taken_at = ? AND taken_src = 'meta' AND cell_id = ? AND camera_serial = ? AND camera_id = ?",
m.TakenAt, m.CellID, m.CameraSerial, m.CameraID).Error; err != nil {
return identical, err
}
case stackUuid && rnd.IsUUID(m.UUID):
if err := Db().Where("id > ? AND photo_single = 0", m.ID).
Where("uuid <> '' AND uuid = ?", m.UUID).Error; err != nil {
return identical, err
}
default:
return identical, nil
}
if len(identical) == 0 {
return identical, nil
}
for _, photo := range identical {
if err := UnscopedDb().Model(File{}).Where("photo_id = ?", photo.ID).Updates(File{PhotoID: m.ID, PhotoUID: m.PhotoUID}).Error; err != nil {
return identical, err
}
switch DbDialect() {
case MySQL:
UnscopedDb().Exec("UPDATE IGNORE `photos_keywords` SET `photo_id` = ? WHERE (photo_id = ?)", m.ID, photo.ID)
UnscopedDb().Exec("UPDATE IGNORE `photos_labels` SET `photo_id` = ? WHERE (photo_id = ?)", m.ID, photo.ID)
UnscopedDb().Exec("UPDATE IGNORE `photos_albums` SET `photo_uid` = ? WHERE (photo_uid = ?)", m.PhotoUID, photo.PhotoUID)
case SQLite:
UnscopedDb().Exec("UPDATE OR IGNORE `photos_keywords` SET `photo_id` = ? WHERE (photo_id = ?)", m.ID, photo.ID)
UnscopedDb().Exec("UPDATE OR IGNORE `photos_labels` SET `photo_id` = ? WHERE (photo_id = ?)", m.ID, photo.ID)
UnscopedDb().Exec("UPDATE OR IGNORE `photos_albums` SET `photo_uid` = ? WHERE (photo_uid = ?)", m.PhotoUID, photo.PhotoUID)
default:
log.Warnf("photo: unknown SQL dialect (stack)")
}
if err := photo.Updates(map[string]interface{}{"DeletedAt": Timestamp(), "PhotoQuality": -1}); err != nil {
return identical, err
}
}
return identical, err
}

View File

@@ -970,7 +970,7 @@ var PhotoFixtures = PhotoMap{
TitleSrc: "", TitleSrc: "",
PhotoPath: "1990/04", PhotoPath: "1990/04",
PhotoName: "Photo03", PhotoName: "Photo03",
PhotoQuality: 1, PhotoQuality: -1,
PhotoResolution: 2, PhotoResolution: 2,
PhotoFavorite: false, PhotoFavorite: false,
PhotoPrivate: false, PhotoPrivate: false,

View File

@@ -6,6 +6,8 @@ import (
"strings" "strings"
"time" "time"
"github.com/photoprism/photoprism/pkg/rnd"
"github.com/jinzhu/gorm" "github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/pkg/fs" "github.com/photoprism/photoprism/pkg/fs"
"github.com/photoprism/photoprism/pkg/txt" "github.com/photoprism/photoprism/pkg/txt"
@@ -138,3 +140,77 @@ func (m *Photo) Optimize(stackMeta, stackUuid bool) (updated bool, merged Photos
return true, merged, m.Save() return true, merged, m.Save()
} }
// ResolvePrimary ensures there is only one primary file for a photo.
func (m *Photo) ResolvePrimary() error {
var file File
if err := Db().First(&file, "file_primary = 1 AND photo_id = ?", m.ID).Error; err == nil {
return file.ResolvePrimary()
}
if err := Db().First(&file, "file_type = 'jpg' AND photo_id = ?", m.ID).Error; err == nil {
file.FilePrimary = true
return file.ResolvePrimary()
}
return m.Update("PhotoQuality", -1)
}
// Stack merges a photo with identical ones.
func (m *Photo) Stack(stackMeta, stackUuid bool) (identical Photos, err error) {
if !stackMeta && !stackUuid || m.PhotoSingle || m.DeletedAt != nil {
return identical, nil
}
switch {
case stackMeta && stackUuid && m.HasLocation() && m.HasLatLng() && m.TakenSrc == SrcMeta && rnd.IsUUID(m.UUID):
if err := Db().Where("id > ? AND photo_single = 0", m.ID).
Where("(taken_at = ? AND taken_src = 'meta' AND cell_id = ? AND camera_serial = ? AND camera_id = ?) OR (uuid <> '' AND uuid = ?)",
m.TakenAt, m.CellID, m.CameraSerial, m.CameraID, m.UUID).Find(&identical).Error; err != nil {
return identical, err
}
case stackMeta && m.HasLocation() && m.HasLatLng() && m.TakenSrc == SrcMeta:
if err := Db().Where("id > ? AND photo_single = 0", m.ID).
Where("taken_at = ? AND taken_src = 'meta' AND cell_id = ? AND camera_serial = ? AND camera_id = ?",
m.TakenAt, m.CellID, m.CameraSerial, m.CameraID).Error; err != nil {
return identical, err
}
case stackUuid && rnd.IsUUID(m.UUID):
if err := Db().Where("id > ? AND photo_single = 0", m.ID).
Where("uuid <> '' AND uuid = ?", m.UUID).Error; err != nil {
return identical, err
}
default:
return identical, nil
}
if len(identical) == 0 {
return identical, nil
}
for _, photo := range identical {
if err := UnscopedDb().Exec("UPDATE `files` SET photo_id = ?, photo_uid = ?, file_primary = 0 WHERE photo_id = ?", m.ID, m.PhotoUID, photo.ID).Error; err != nil {
return identical, err
}
switch DbDialect() {
case MySQL:
UnscopedDb().Exec("UPDATE IGNORE `photos_keywords` SET `photo_id` = ? WHERE (photo_id = ?)", m.ID, photo.ID)
UnscopedDb().Exec("UPDATE IGNORE `photos_labels` SET `photo_id` = ? WHERE (photo_id = ?)", m.ID, photo.ID)
UnscopedDb().Exec("UPDATE IGNORE `photos_albums` SET `photo_uid` = ? WHERE (photo_uid = ?)", m.PhotoUID, photo.PhotoUID)
case SQLite:
UnscopedDb().Exec("UPDATE OR IGNORE `photos_keywords` SET `photo_id` = ? WHERE (photo_id = ?)", m.ID, photo.ID)
UnscopedDb().Exec("UPDATE OR IGNORE `photos_labels` SET `photo_id` = ? WHERE (photo_id = ?)", m.ID, photo.ID)
UnscopedDb().Exec("UPDATE OR IGNORE `photos_albums` SET `photo_uid` = ? WHERE (photo_uid = ?)", m.PhotoUID, photo.PhotoUID)
default:
log.Warnf("photo: unknown SQL dialect (stack)")
}
if err := photo.Updates(map[string]interface{}{"DeletedAt": Timestamp(), "PhotoQuality": -1}); err != nil {
return identical, err
}
}
return identical, err
}

View File

@@ -53,6 +53,7 @@ func TestPhoto_EstimateCountry(t *testing.T) {
func TestPhoto_Optimize(t *testing.T) { func TestPhoto_Optimize(t *testing.T) {
t.Run("update", func(t *testing.T) { t.Run("update", func(t *testing.T) {
photo := PhotoFixtures.Get("Photo19") photo := PhotoFixtures.Get("Photo19")
if updated, merged, err := photo.Optimize(false, false); err != nil { if updated, merged, err := photo.Optimize(false, false); err != nil {
t.Fatal(err) t.Fatal(err)
} else if !updated { } else if !updated {
@@ -64,16 +65,16 @@ func TestPhoto_Optimize(t *testing.T) {
if updated, merged, err := photo.Optimize(false, false); err != nil { if updated, merged, err := photo.Optimize(false, false); err != nil {
t.Fatal(err) t.Fatal(err)
} else if updated { } else if updated {
t.Error("photo should NOT be updated") t.Errorf("photo should NOT be updated, merged: %+v", merged)
} else if len(merged) > 0 { } else if len(merged) > 0 {
t.Error("no photos should be merged") t.Errorf("no photos should be merged")
} }
}) })
t.Run("photo without id", func(t *testing.T) { t.Run("photo without id", func(t *testing.T) {
photo := Photo{} photo := Photo{}
bool, merged, err := photo.Optimize(false, false) result, merged, err := photo.Optimize(false, false)
assert.Error(t, err) assert.Error(t, err)
assert.False(t, bool) assert.False(t, result)
if len(merged) > 0 { if len(merged) > 0 {
t.Error("no photos should be merged") t.Error("no photos should be merged")

View File

@@ -460,7 +460,7 @@ func TestPhoto_UpdateTitle(t *testing.T) {
assert.Equal(t, "Unknown / 2008", m.PhotoTitle) assert.Equal(t, "Unknown / 2008", m.PhotoTitle)
}) })
t.Run("no location no labels no takenAt", func(t *testing.T) { t.Run("no location no labels no takenAt", func(t *testing.T) {
m := PhotoFixtures.Get("Photo19") m := PhotoFixtures.Get("Photo20")
classifyLabels := &classify.Labels{} classifyLabels := &classify.Labels{}
assert.Equal(t, "", m.PhotoTitle) assert.Equal(t, "", m.PhotoTitle)
err := m.UpdateTitle(*classifyLabels) err := m.UpdateTitle(*classifyLabels)
@@ -872,22 +872,28 @@ func TestPhoto_SetFavorite(t *testing.T) {
func TestPhoto_Approve(t *testing.T) { func TestPhoto_Approve(t *testing.T) {
t.Run("quality = 4", func(t *testing.T) { t.Run("quality = 4", func(t *testing.T) {
photo := Photo{PhotoQuality: 4} photo := Photo{PhotoQuality: 4}
photo.Save()
err := photo.Approve() if err := photo.Save(); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
assert.Equal(t, 4, photo.PhotoQuality)
if err := photo.Approve(); err != nil {
t.Fatal(err)
}
assert.Equal(t, 3, photo.PhotoQuality)
}) })
t.Run("quality = 1", func(t *testing.T) { t.Run("quality = 1", func(t *testing.T) {
photo := Photo{PhotoQuality: 1} photo := Photo{PhotoQuality: 1}
photo.Save()
err := photo.Approve() if err := photo.Save(); err != nil {
if err != nil {
t.Fatal(err) t.Fatal(err)
} }
if err := photo.Approve(); err != nil {
t.Fatal(err)
}
assert.Equal(t, 3, photo.PhotoQuality) assert.Equal(t, 3, photo.PhotoQuality)
}) })
} }

View File

@@ -35,7 +35,7 @@ type Photo struct {
Details Details `json:"Details"` Details Details `json:"Details"`
PhotoFavorite bool `json:"Favorite"` PhotoFavorite bool `json:"Favorite"`
PhotoPrivate bool `json:"Private"` PhotoPrivate bool `json:"Private"`
PhotoReview bool `json:"Review"` PhotoSingle bool `json:"Single"`
PhotoScan bool `json:"Scan"` PhotoScan bool `json:"Scan"`
PhotoPanorama bool `json:"Panorama"` PhotoPanorama bool `json:"Panorama"`
PhotoAltitude int `json:"Altitude"` PhotoAltitude int `json:"Altitude"`

View File

@@ -18,6 +18,7 @@ type PhotoSearch struct {
Title string `form:"title"` Title string `form:"title"`
Hash string `form:"hash"` Hash string `form:"hash"`
Primary bool `form:"primary"` Primary bool `form:"primary"`
Single bool `form:"single"`
Video bool `form:"video"` Video bool `form:"video"`
Photo bool `form:"photo"` Photo bool `form:"photo"`
Scan bool `form:"scan"` Scan bool `form:"scan"`

View File

@@ -19,7 +19,7 @@ func TestNewPhoto(t *testing.T) {
PhotoFavorite: false, PhotoFavorite: false,
PhotoPrivate: false, PhotoPrivate: false,
PhotoType: "image", PhotoType: "image",
PhotoReview: false, PhotoSingle: false,
PhotoLat: 9.9999, PhotoLat: 9.9999,
PhotoLng: 8.8888, PhotoLng: 8.8888,
PhotoAltitude: 2, PhotoAltitude: 2,
@@ -50,7 +50,7 @@ func TestNewPhoto(t *testing.T) {
assert.Equal(t, false, r.PhotoFavorite) assert.Equal(t, false, r.PhotoFavorite)
assert.Equal(t, false, r.PhotoPrivate) assert.Equal(t, false, r.PhotoPrivate)
assert.Equal(t, "image", r.PhotoType) assert.Equal(t, "image", r.PhotoType)
assert.Equal(t, false, r.PhotoReview) assert.Equal(t, false, r.PhotoSingle)
assert.Equal(t, float32(9.9999), r.PhotoLat) assert.Equal(t, float32(9.9999), r.PhotoLat)
assert.Equal(t, float32(8.8888), r.PhotoLng) assert.Equal(t, float32(8.8888), r.PhotoLng)
assert.Equal(t, 2, r.PhotoAltitude) assert.Equal(t, 2, r.PhotoAltitude)

View File

@@ -158,7 +158,13 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
// Look for existing photo if file wasn't indexed yet... // Look for existing photo if file wasn't indexed yet...
if !fileExists { if !fileExists {
photoQuery = entity.UnscopedDb().First(&photo, "photo_path = ? AND photo_name = ?", filePath, fileBase) fullBase := m.BasePrefix(false)
photoQuery = entity.UnscopedDb().First(&photo, "photo_path = ? AND photo_name IN (?)", filePath, []string{fullBase, fileBase})
if photoQuery.Error == nil {
fileBase = photo.PhotoName
fileStacked = true
}
// Stack file based on matching location and time metadata? // Stack file based on matching location and time metadata?
if photoQuery.Error != nil && Config().Settings().StackMeta() && m.MetaData().HasTimeAndPlace() { if photoQuery.Error != nil && Config().Settings().StackMeta() && m.MetaData().HasTimeAndPlace() {
@@ -210,7 +216,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
// Try to recover photo metadata from backup if not exists. // Try to recover photo metadata from backup if not exists.
if !photoExists { if !photoExists {
photo.PhotoQuality = -1 photo.PhotoQuality = -1
photo.PhotoSingle = !o.Stack photo.PhotoSingle = o.Single
if yamlName := fs.TypeYaml.FindFirst(m.FileName(), []string{Config().SidecarPath(), fs.HiddenPath}, Config().OriginalsPath(), stripSequence); yamlName != "" { if yamlName := fs.TypeYaml.FindFirst(m.FileName(), []string{Config().SidecarPath(), fs.HiddenPath}, Config().OriginalsPath(), stripSequence); yamlName != "" {
if err := photo.LoadFromYaml(yamlName); err != nil { if err := photo.LoadFromYaml(yamlName); err != nil {

View File

@@ -4,7 +4,7 @@ type IndexOptions struct {
Path string Path string
Rescan bool Rescan bool
Convert bool Convert bool
Stack bool Single bool
} }
func (o *IndexOptions) SkipUnchanged() bool { func (o *IndexOptions) SkipUnchanged() bool {
@@ -17,7 +17,7 @@ func IndexOptionsAll() IndexOptions {
Path: "/", Path: "/",
Rescan: true, Rescan: true,
Convert: true, Convert: true,
Stack: true, Single: false,
} }
return result return result
@@ -29,7 +29,7 @@ func IndexOptionsSingle() IndexOptions {
Path: "/", Path: "/",
Rescan: true, Rescan: true,
Convert: true, Convert: true,
Stack: false, Single: true,
} }
return result return result

View File

@@ -198,6 +198,10 @@ func PhotoSearch(f form.PhotoSearch) (results PhotoResults, count int, err error
s = s.Where("photos.photo_panorama = 1") s = s.Where("photos.photo_panorama = 1")
} }
if f.Single {
s = s.Where("photos.photo_single = 1")
}
if f.Country != "" { if f.Country != "" {
s = s.Where("photos.photo_country IN (?)", strings.Split(strings.ToLower(f.Country), ",")) s = s.Where("photos.photo_country IN (?)", strings.Split(strings.ToLower(f.Country), ","))
} }