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>
</td>
</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>
<td>
<translate>Scan</translate>

Binary file not shown.

View File

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

File diff suppressed because one or more lines are too long

View File

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

View File

@@ -12,7 +12,7 @@
<v-card-actions>
<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
@change="onChange"
:disabled="busy"
@@ -27,7 +27,7 @@
</v-checkbox>
</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
@change="onChange"
:disabled="busy"
@@ -42,7 +42,7 @@
</v-checkbox>
</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
@change="onChange"
:disabled="busy"
@@ -56,35 +56,20 @@
>
</v-checkbox>
</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-card-actions>
</v-card>
<v-card flat tile class="mt-0 px-1 application" v-show="settings.index.stacks">
<v-card-title primary-title class="pb-0">
<v-card flat tile class="mt-0 px-1 application">
<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">
<translate>Stack files with matching...</translate>
<translate>Stacks</translate>
</h3>
</v-card-title>
<v-card-actions>
<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
@change="onChange"
:disabled="busy"
@@ -99,7 +84,7 @@
</v-checkbox>
</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
@change="onChange"
:disabled="busy"
@@ -115,7 +100,7 @@
</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
@change="onChange"
:disabled="busy"

View File

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

View File

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

View File

@@ -231,12 +231,6 @@ func (c *Config) InitTestDb() {
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.
func (c *Config) connectDb() error {
mutex.Db.Lock()

View File

@@ -56,7 +56,6 @@ type IndexSettings struct {
Path string `json:"path" yaml:"path"`
Convert bool `json:"convert" yaml:"convert"`
Rescan bool `json:"rescan" yaml:"rescan"`
Stacks bool `json:"stacks" yaml:"stacks"`
}
// StackSettings represents settings for files that belong to the same photo.
@@ -114,7 +113,6 @@ func NewSettings() *Settings {
Path: "/",
Rescan: false,
Convert: true,
Stacks: true,
},
Stack: StackSettings{
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).
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.
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.
func (s Settings) StackMeta() bool {
return s.Index.Stacks && s.Stack.Meta
return s.Stack.Meta
}
// Load user settings from file.

View File

@@ -27,7 +27,6 @@ index:
path: /
convert: true
rescan: false
stacks: true
stack:
uuid: 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.
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.
@@ -190,6 +192,15 @@ func (m *File) Create() error {
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.
func (m *File) Save() error {
if m.PhotoID == 0 {
@@ -201,7 +212,7 @@ func (m *File) Save() error {
return err
}
return nil
return m.ResolvePrimary()
}
// UpdateVideoInfos updates related video infos based on this file.

View File

@@ -526,6 +526,43 @@ var FileFixtures = map[string]File{
UpdatedIn: 0,
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"]

View File

@@ -230,7 +230,7 @@ func (m *Photo) Save() error {
return err
}
return nil
return m.ResolvePrimary()
}
// Find returns a photo from the database.
@@ -890,7 +890,7 @@ func (m *Photo) AllFilesMissing() bool {
count := 0
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 {
log.Error(err)
}
@@ -1010,61 +1010,3 @@ func (m *Photo) PrimaryFile() (File, error) {
func (m *Photo) MapKey() string {
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: "",
PhotoPath: "1990/04",
PhotoName: "Photo03",
PhotoQuality: 1,
PhotoQuality: -1,
PhotoResolution: 2,
PhotoFavorite: false,
PhotoPrivate: false,

View File

@@ -6,6 +6,8 @@ import (
"strings"
"time"
"github.com/photoprism/photoprism/pkg/rnd"
"github.com/jinzhu/gorm"
"github.com/photoprism/photoprism/pkg/fs"
"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()
}
// 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) {
t.Run("update", func(t *testing.T) {
photo := PhotoFixtures.Get("Photo19")
if updated, merged, err := photo.Optimize(false, false); err != nil {
t.Fatal(err)
} else if !updated {
@@ -64,16 +65,16 @@ func TestPhoto_Optimize(t *testing.T) {
if updated, merged, err := photo.Optimize(false, false); err != nil {
t.Fatal(err)
} 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 {
t.Error("no photos should be merged")
t.Errorf("no photos should be merged")
}
})
t.Run("photo without id", func(t *testing.T) {
photo := Photo{}
bool, merged, err := photo.Optimize(false, false)
result, merged, err := photo.Optimize(false, false)
assert.Error(t, err)
assert.False(t, bool)
assert.False(t, result)
if len(merged) > 0 {
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)
})
t.Run("no location no labels no takenAt", func(t *testing.T) {
m := PhotoFixtures.Get("Photo19")
m := PhotoFixtures.Get("Photo20")
classifyLabels := &classify.Labels{}
assert.Equal(t, "", m.PhotoTitle)
err := m.UpdateTitle(*classifyLabels)
@@ -872,22 +872,28 @@ func TestPhoto_SetFavorite(t *testing.T) {
func TestPhoto_Approve(t *testing.T) {
t.Run("quality = 4", func(t *testing.T) {
photo := Photo{PhotoQuality: 4}
photo.Save()
err := photo.Approve()
if err != nil {
if err := photo.Save(); err != nil {
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) {
photo := Photo{PhotoQuality: 1}
photo.Save()
err := photo.Approve()
if err != nil {
if err := photo.Save(); err != nil {
t.Fatal(err)
}
if err := photo.Approve(); err != nil {
t.Fatal(err)
}
assert.Equal(t, 3, photo.PhotoQuality)
})
}

View File

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

View File

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

View File

@@ -19,7 +19,7 @@ func TestNewPhoto(t *testing.T) {
PhotoFavorite: false,
PhotoPrivate: false,
PhotoType: "image",
PhotoReview: false,
PhotoSingle: false,
PhotoLat: 9.9999,
PhotoLng: 8.8888,
PhotoAltitude: 2,
@@ -50,7 +50,7 @@ func TestNewPhoto(t *testing.T) {
assert.Equal(t, false, r.PhotoFavorite)
assert.Equal(t, false, r.PhotoPrivate)
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(8.8888), r.PhotoLng)
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...
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?
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.
if !photoExists {
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 err := photo.LoadFromYaml(yamlName); err != nil {

View File

@@ -4,7 +4,7 @@ type IndexOptions struct {
Path string
Rescan bool
Convert bool
Stack bool
Single bool
}
func (o *IndexOptions) SkipUnchanged() bool {
@@ -17,7 +17,7 @@ func IndexOptionsAll() IndexOptions {
Path: "/",
Rescan: true,
Convert: true,
Stack: true,
Single: false,
}
return result
@@ -29,7 +29,7 @@ func IndexOptionsSingle() IndexOptions {
Path: "/",
Rescan: true,
Convert: true,
Stack: false,
Single: true,
}
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")
}
if f.Single {
s = s.Where("photos.photo_single = 1")
}
if f.Country != "" {
s = s.Where("photos.photo_country IN (?)", strings.Split(strings.ToLower(f.Country), ","))
}