mirror of
https://github.com/photoprism/photoprism.git
synced 2025-12-12 08:44:04 +01:00
Binary file not shown.
@@ -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:269
|
#: src/pages/settings/general.vue:377
|
||||||
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 indizieren."
|
msgstr "Dateien über den Browser hochladen und indizieren."
|
||||||
|
|
||||||
@@ -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:590
|
#: src/pages/settings/general.vue:698
|
||||||
msgid "Animation"
|
msgid "Animation"
|
||||||
msgstr "Animation"
|
msgstr "Animation"
|
||||||
|
|
||||||
@@ -254,7 +254,7 @@ 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:334
|
#: src/component/photo/clipboard.vue:211 src/pages/settings/general.vue:442
|
||||||
#: src/routes.js:185
|
#: src/routes.js:185
|
||||||
msgid "Archive"
|
msgid "Archive"
|
||||||
msgstr "Archiv"
|
msgstr "Archiv"
|
||||||
@@ -295,13 +295,13 @@ 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:121
|
#: src/pages/settings/general.vue:123
|
||||||
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."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"RAW-Bilder und Videos müssen zu JPEGs konvertiert werden, damit sie in der "
|
"Videos und andere Bild-Formate nach JPEG konvertieren, damit sie indexiert "
|
||||||
"Suche angezeigt werden können."
|
"und angezeigt werden können."
|
||||||
|
|
||||||
#: src/pages/settings.vue:8
|
#: src/pages/settings.vue:8
|
||||||
msgid "Backup"
|
msgid "Backup"
|
||||||
@@ -319,11 +319,11 @@ msgstr "Blau"
|
|||||||
msgid "Brown"
|
msgid "Brown"
|
||||||
msgstr "Braun"
|
msgstr "Braun"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:423
|
#: src/pages/settings/general.vue:531
|
||||||
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:379
|
#: src/pages/settings/general.vue:487
|
||||||
msgid "Browse indexed files and folders in Library."
|
msgid "Browse indexed files and folders in Library."
|
||||||
msgstr "Durchsuche indizierte Dateien und Verzeichnisse."
|
msgstr "Durchsuche indizierte Dateien und Verzeichnisse."
|
||||||
|
|
||||||
@@ -384,7 +384,7 @@ msgstr "Kategorie"
|
|||||||
msgid "Change"
|
msgid "Change"
|
||||||
msgstr "Ändern"
|
msgstr "Ändern"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:357
|
#: src/pages/settings/general.vue:465
|
||||||
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."
|
||||||
|
|
||||||
@@ -453,7 +453,7 @@ msgstr "Enthält einen Eintrag."
|
|||||||
msgid "Contributors"
|
msgid "Contributors"
|
||||||
msgstr "Contributors"
|
msgstr "Contributors"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:120
|
#: src/pages/settings/general.vue:122
|
||||||
msgid "Convert to JPEG"
|
msgid "Convert to JPEG"
|
||||||
msgstr "Automatisch konvertieren"
|
msgstr "Automatisch konvertieren"
|
||||||
|
|
||||||
@@ -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:290 src/share/album/clipboard.vue:60
|
#: src/pages/settings/general.vue:398 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:291
|
#: src/pages/settings/general.vue:399
|
||||||
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:356
|
#: src/pages/settings/general.vue:464
|
||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr "Bearbeiten"
|
msgstr "Bearbeiten"
|
||||||
|
|
||||||
@@ -663,7 +663,7 @@ msgstr "Fehler"
|
|||||||
msgid "Every two days"
|
msgid "Every two days"
|
||||||
msgstr "Jeden zweiten Tag"
|
msgstr "Jeden zweiten Tag"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:77
|
#: src/pages/settings/general.vue:79
|
||||||
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."
|
||||||
@@ -731,17 +731,21 @@ msgstr "Datei"
|
|||||||
msgid "File Browser"
|
msgid "File Browser"
|
||||||
msgstr "Datei Browser"
|
msgstr "Datei Browser"
|
||||||
|
|
||||||
|
#: src/pages/settings/general.vue:248
|
||||||
|
msgid "File Name Prefix"
|
||||||
|
msgstr "Fortlaufender Name"
|
||||||
|
|
||||||
#: src/dialog/photo/edit.vue:31
|
#: src/dialog/photo/edit.vue:31
|
||||||
msgid "Files"
|
msgid "Files"
|
||||||
msgstr "Dateien"
|
msgstr "Dateien"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:143
|
#: src/pages/settings/general.vue:249
|
||||||
msgid ""
|
msgid ""
|
||||||
"Files with sequential names like 'IMG_1234 (2)' or 'IMG_1234 copy 2' belong "
|
"Files with sequential names like 'IMG_1234 (2)' and 'IMG_1234 (3)' belong to "
|
||||||
"to the same photo."
|
"the same picture."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
"Dateien mit Namen wie ‘IMG_1234 (2)’ oder ‘IMG_1234 copy 2’ werden als "
|
"Dateien mit fortlaufenden Namen wie ‘IMG_1234 (2)’ und ‘IMG_1234 (3)’ "
|
||||||
"Stapel zusammengefasst."
|
"gehören zum gleichen Bild."
|
||||||
|
|
||||||
#: src/dialog/photo/details.vue:476
|
#: src/dialog/photo/details.vue:476
|
||||||
msgid "Focal Length"
|
msgid "Focal Length"
|
||||||
@@ -814,11 +818,11 @@ msgstr "Unsichtbar"
|
|||||||
msgid "Hidden Files"
|
msgid "Hidden Files"
|
||||||
msgstr "Unsichtbare Dateien"
|
msgstr "Unsichtbare Dateien"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:335
|
#: src/pages/settings/general.vue:443
|
||||||
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:76
|
#: src/pages/settings/general.vue:78
|
||||||
msgid "Hide Private"
|
msgid "Hide Private"
|
||||||
msgstr "Privates ausblenden"
|
msgstr "Privates ausblenden"
|
||||||
|
|
||||||
@@ -852,7 +856,7 @@ msgstr "Bild"
|
|||||||
msgid "Image"
|
msgid "Image"
|
||||||
msgstr "Bild"
|
msgstr "Bild"
|
||||||
|
|
||||||
#: src/pages/library/import.vue:43 src/pages/settings/general.vue:466
|
#: src/pages/library/import.vue:43 src/pages/settings/general.vue:574
|
||||||
msgid "Import"
|
msgid "Import"
|
||||||
msgstr "Import"
|
msgstr "Import"
|
||||||
|
|
||||||
@@ -868,7 +872,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:467
|
#: src/pages/settings/general.vue:575
|
||||||
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 +939,7 @@ msgid "Label Name"
|
|||||||
msgstr "Name"
|
msgstr "Name"
|
||||||
|
|
||||||
#: src/component/navigation.vue:263 src/dialog/photo/edit.vue:27
|
#: src/component/navigation.vue:263 src/dialog/photo/edit.vue:27
|
||||||
#: src/pages/settings/general.vue:422 src/routes.js:236
|
#: src/pages/settings/general.vue:530 src/routes.js:236
|
||||||
msgid "Labels"
|
msgid "Labels"
|
||||||
msgstr "Kategorien"
|
msgstr "Kategorien"
|
||||||
|
|
||||||
@@ -943,7 +947,7 @@ msgstr "Kategorien"
|
|||||||
msgid "Labels deleted"
|
msgid "Labels deleted"
|
||||||
msgstr "Kategorien gelöscht"
|
msgstr "Kategorien gelöscht"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:220
|
#: src/pages/settings/general.vue:328
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr "Sprache"
|
msgstr "Sprache"
|
||||||
|
|
||||||
@@ -963,14 +967,14 @@ msgstr "Lavendel"
|
|||||||
msgid "Lens"
|
msgid "Lens"
|
||||||
msgstr "Objektiv"
|
msgstr "Objektiv"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:401
|
#: src/pages/settings/general.vue:509
|
||||||
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:276 src/component/navigation.vue:285
|
#: src/component/navigation.vue:276 src/component/navigation.vue:285
|
||||||
#: src/pages/settings/general.vue:6 src/pages/settings/general.vue:444
|
#: src/pages/settings/general.vue:6 src/pages/settings/general.vue:552
|
||||||
#: 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"
|
||||||
@@ -1033,7 +1037,7 @@ msgstr "Anmelden"
|
|||||||
msgid "Logout"
|
msgid "Logout"
|
||||||
msgstr "Abmelden"
|
msgstr "Abmelden"
|
||||||
|
|
||||||
#: src/pages/library.vue:17 src/pages/settings/general.vue:488
|
#: src/pages/library.vue:17 src/pages/settings/general.vue:596
|
||||||
msgid "Logs"
|
msgid "Logs"
|
||||||
msgstr "Logs"
|
msgstr "Logs"
|
||||||
|
|
||||||
@@ -1069,7 +1073,7 @@ msgstr "Nachricht versendet"
|
|||||||
msgid "Missing"
|
msgid "Missing"
|
||||||
msgstr "Fehlend"
|
msgstr "Fehlend"
|
||||||
|
|
||||||
#: src/component/navigation.vue:218 src/pages/settings/general.vue:400
|
#: src/component/navigation.vue:218 src/pages/settings/general.vue:508
|
||||||
#: src/routes.js:98 src/routes.js:105
|
#: src/routes.js:98 src/routes.js:105
|
||||||
msgid "Moments"
|
msgid "Moments"
|
||||||
msgstr "Erlebnisse"
|
msgstr "Erlebnisse"
|
||||||
@@ -1196,7 +1200,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:99
|
#: src/pages/settings/general.vue:101
|
||||||
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."
|
||||||
@@ -1305,7 +1309,7 @@ msgid "Original Name"
|
|||||||
msgstr "Originalname"
|
msgstr "Originalname"
|
||||||
|
|
||||||
#: src/component/navigation.vue:293 src/pages/library/files.vue:6
|
#: src/component/navigation.vue:293 src/pages/library/files.vue:6
|
||||||
#: src/pages/settings/general.vue:378
|
#: src/pages/settings/general.vue:486
|
||||||
msgid "Originals"
|
msgid "Originals"
|
||||||
msgstr "Originale"
|
msgstr "Originale"
|
||||||
|
|
||||||
@@ -1374,8 +1378,12 @@ msgstr "Pink"
|
|||||||
msgid "Place"
|
msgid "Place"
|
||||||
msgstr "Ort"
|
msgstr "Ort"
|
||||||
|
|
||||||
|
#: src/pages/settings/general.vue:204
|
||||||
|
msgid "Place & Time"
|
||||||
|
msgstr "Gleicher Ort & Zeit"
|
||||||
|
|
||||||
#: src/component/navigation.vue:231 src/component/navigation.vue:240
|
#: src/component/navigation.vue:231 src/component/navigation.vue:240
|
||||||
#: src/pages/settings/general.vue:124 src/pages/settings/general.vue:510
|
#: src/pages/settings/general.vue:152 src/pages/settings/general.vue:618
|
||||||
#: 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"
|
||||||
@@ -1442,7 +1450,7 @@ msgstr "Projektion"
|
|||||||
msgid "Purple"
|
msgid "Purple"
|
||||||
msgstr "Purpur"
|
msgstr "Purpur"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:98
|
#: src/pages/settings/general.vue:100
|
||||||
msgid "Quality Filter"
|
msgid "Quality Filter"
|
||||||
msgstr "Qualitätsfilter"
|
msgstr "Qualitätsfilter"
|
||||||
|
|
||||||
@@ -1562,7 +1570,7 @@ msgstr "Scans"
|
|||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr "Suche"
|
msgstr "Suche"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:511
|
#: src/pages/settings/general.vue:619
|
||||||
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."
|
||||||
|
|
||||||
@@ -1629,7 +1637,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:312
|
#: src/component/photo/clipboard.vue:73 src/pages/settings/general.vue:420
|
||||||
msgid "Share"
|
msgid "Share"
|
||||||
msgstr "Teilen"
|
msgstr "Teilen"
|
||||||
|
|
||||||
@@ -1645,7 +1653,7 @@ msgstr "Mit dir geteilt."
|
|||||||
msgid "Show less"
|
msgid "Show less"
|
||||||
msgstr "Weniger zeigen"
|
msgstr "Weniger zeigen"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:445
|
#: src/pages/settings/general.vue:553
|
||||||
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."
|
||||||
|
|
||||||
@@ -1653,7 +1661,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:489
|
#: src/pages/settings/general.vue:597
|
||||||
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."
|
||||||
|
|
||||||
@@ -1699,14 +1707,32 @@ msgstr "Quelle"
|
|||||||
msgid "Spanish"
|
msgid "Spanish"
|
||||||
msgstr "Spanisch"
|
msgstr "Spanisch"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:142
|
#: src/pages/settings/general.vue:227
|
||||||
msgid "Stack Sequences"
|
msgid "Stack files sharing the same unique image or instance identifier."
|
||||||
msgstr "Sequenzen gruppieren"
|
msgstr "Bilder mit identischer ID als Stapel indexieren und anzeigen."
|
||||||
|
|
||||||
#: src/component/navigation.vue:89
|
#: src/pages/settings/general.vue:38
|
||||||
|
msgid "Stack files with matching..."
|
||||||
|
msgstr "Als Stapel zusammenfassen..."
|
||||||
|
|
||||||
|
#: src/pages/settings/general.vue:205
|
||||||
|
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
|
||||||
msgid "Stacks"
|
msgid "Stacks"
|
||||||
msgstr "Bildstapel"
|
msgstr "Bildstapel"
|
||||||
|
|
||||||
|
#: src/pages/settings/general.vue:145
|
||||||
|
msgid ""
|
||||||
|
"Stacks group files with a similar frame of reference, but differences of "
|
||||||
|
"quality, format, size or color."
|
||||||
|
msgstr ""
|
||||||
|
"Bildstapel enthalten zusammengehörige Aufnahmen, die jedoch Unterschiede in "
|
||||||
|
"Qualität, Format, Größe oder Farben aufweisen können."
|
||||||
|
|
||||||
#: src/pages/library/index.vue:30
|
#: src/pages/library/index.vue:30
|
||||||
msgid "Start"
|
msgid "Start"
|
||||||
msgstr "Start"
|
msgstr "Start"
|
||||||
@@ -1731,7 +1757,7 @@ msgstr "Ablageverzeichnis"
|
|||||||
msgid "Streets"
|
msgid "Streets"
|
||||||
msgstr "Straßen"
|
msgstr "Straßen"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:568
|
#: src/pages/settings/general.vue:676
|
||||||
msgid "Style"
|
msgid "Style"
|
||||||
msgstr "Style"
|
msgstr "Style"
|
||||||
|
|
||||||
@@ -1777,7 +1803,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:198
|
#: src/pages/settings/general.vue:306
|
||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr "Theme"
|
msgstr "Theme"
|
||||||
|
|
||||||
@@ -1844,6 +1870,10 @@ msgstr "Versuche es mit anderen Filtern oder Suchbegriffen."
|
|||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr "Typ"
|
msgstr "Typ"
|
||||||
|
|
||||||
|
#: src/pages/settings/general.vue:226
|
||||||
|
msgid "Unique ID"
|
||||||
|
msgstr "Eindeutige Bild-ID"
|
||||||
|
|
||||||
#: src/dialog/photo/details.vue:16 src/dialog/photo/info.vue:21
|
#: src/dialog/photo/details.vue:16 src/dialog/photo/info.vue:21
|
||||||
#: src/model/album.js:122 src/model/photo.js:401 src/model/photo.js:415
|
#: src/model/album.js:122 src/model/photo.js:401 src/model/photo.js:415
|
||||||
#: src/model/photo.js:438 src/model/photo.js:452 src/model/photo.js:529
|
#: src/model/photo.js:438 src/model/photo.js:452 src/model/photo.js:529
|
||||||
@@ -1869,7 +1899,7 @@ msgstr "Geändert"
|
|||||||
#: src/component/album/toolbar.vue:175 src/component/navigation.vue:130
|
#: src/component/album/toolbar.vue:175 src/component/navigation.vue:130
|
||||||
#: 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:134
|
#: src/dialog/upload.vue:8 src/dialog/upload.vue:54 src/pages/albums.vue:134
|
||||||
#: src/pages/library/import.vue:38 src/pages/settings/general.vue:268
|
#: src/pages/library/import.vue:38 src/pages/settings/general.vue:376
|
||||||
#: src/pages/settings/sync.vue:24
|
#: src/pages/settings/sync.vue:24
|
||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr "Upload"
|
msgstr "Upload"
|
||||||
@@ -1890,7 +1920,7 @@ msgstr "Upload fehlgeschlagen"
|
|||||||
msgid "Upload local files"
|
msgid "Upload local files"
|
||||||
msgstr "Dateien hochladen"
|
msgstr "Dateien hochladen"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:313
|
#: src/pages/settings/general.vue:421
|
||||||
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."
|
||||||
|
|
||||||
@@ -1914,7 +1944,7 @@ msgstr "URL"
|
|||||||
msgid "User"
|
msgid "User"
|
||||||
msgstr "Benutzer"
|
msgstr "Benutzer"
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:38
|
#: src/pages/settings/general.vue:66
|
||||||
msgid "User Interface"
|
msgid "User Interface"
|
||||||
msgstr "Benutzeroberfläche"
|
msgstr "Benutzeroberfläche"
|
||||||
|
|
||||||
@@ -2003,6 +2033,9 @@ msgstr "Ihre Nachricht wurde gesendet"
|
|||||||
msgid "Zoom in/out"
|
msgid "Zoom in/out"
|
||||||
msgstr "Zoom in/out"
|
msgstr "Zoom in/out"
|
||||||
|
|
||||||
|
#~ msgid "Stack Sequences"
|
||||||
|
#~ msgstr "Sequenzen gruppieren"
|
||||||
|
|
||||||
#~ msgid "Brazilian Portuguese"
|
#~ msgid "Brazilian Portuguese"
|
||||||
#~ msgstr "Brasilianisches Portugiesisch"
|
#~ msgstr "Brasilianisches Portugiesisch"
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -78,7 +78,7 @@ msgstr ""
|
|||||||
msgid "Add Album"
|
msgid "Add Album"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:269
|
#: src/pages/settings/general.vue:377
|
||||||
msgid "Add files to your library via Web Upload."
|
msgid "Add files to your library via Web Upload."
|
||||||
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:590
|
#: src/pages/settings/general.vue:698
|
||||||
msgid "Animation"
|
msgid "Animation"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -259,7 +259,7 @@ 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:334
|
#: src/pages/settings/general.vue:442
|
||||||
#: src/routes.js:185
|
#: src/routes.js:185
|
||||||
msgid "Archive"
|
msgid "Archive"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -300,7 +300,7 @@ msgstr ""
|
|||||||
msgid "At least 6 characters."
|
msgid "At least 6 characters."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:121
|
#: src/pages/settings/general.vue:123
|
||||||
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:423
|
#: src/pages/settings/general.vue:531
|
||||||
msgid "Browse and edit image classification labels."
|
msgid "Browse and edit image classification labels."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:379
|
#: src/pages/settings/general.vue:487
|
||||||
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:357
|
#: src/pages/settings/general.vue:465
|
||||||
msgid "Change photo titles, locations and other metadata."
|
msgid "Change photo titles, locations and other metadata."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -476,7 +476,7 @@ msgstr ""
|
|||||||
msgid "Contributors"
|
msgid "Contributors"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:120
|
#: src/pages/settings/general.vue:122
|
||||||
msgid "Convert to JPEG"
|
msgid "Convert to JPEG"
|
||||||
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:290
|
#: src/pages/settings/general.vue:398
|
||||||
#: 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:291
|
#: src/pages/settings/general.vue:399
|
||||||
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:356
|
#: src/pages/settings/general.vue:464
|
||||||
msgid "Edit"
|
msgid "Edit"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -720,7 +720,7 @@ msgstr ""
|
|||||||
msgid "Every two days"
|
msgid "Every two days"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:77
|
#: src/pages/settings/general.vue:79
|
||||||
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 ""
|
||||||
|
|
||||||
@@ -788,12 +788,16 @@ msgstr ""
|
|||||||
msgid "File Browser"
|
msgid "File Browser"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/settings/general.vue:248
|
||||||
|
msgid "File Name Prefix"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/dialog/photo/edit.vue:31
|
#: src/dialog/photo/edit.vue:31
|
||||||
msgid "Files"
|
msgid "Files"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:143
|
#: src/pages/settings/general.vue:249
|
||||||
msgid "Files with sequential names like 'IMG_1234 (2)' or 'IMG_1234 copy 2' belong to the same photo."
|
msgid "Files with sequential names like 'IMG_1234 (2)' and 'IMG_1234 (3)' belong to the same picture."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/dialog/photo/details.vue:476
|
#: src/dialog/photo/details.vue:476
|
||||||
@@ -873,11 +877,11 @@ msgstr ""
|
|||||||
msgid "Hidden Files"
|
msgid "Hidden Files"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:335
|
#: src/pages/settings/general.vue:443
|
||||||
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:76
|
#: src/pages/settings/general.vue:78
|
||||||
msgid "Hide Private"
|
msgid "Hide Private"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -909,7 +913,7 @@ msgid "Image"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/library/import.vue:43
|
#: src/pages/library/import.vue:43
|
||||||
#: src/pages/settings/general.vue:466
|
#: src/pages/settings/general.vue:574
|
||||||
msgid "Import"
|
msgid "Import"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -921,7 +925,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:467
|
#: src/pages/settings/general.vue:575
|
||||||
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 ""
|
||||||
|
|
||||||
@@ -990,7 +994,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/component/navigation.vue:263
|
#: src/component/navigation.vue:263
|
||||||
#: src/dialog/photo/edit.vue:27
|
#: src/dialog/photo/edit.vue:27
|
||||||
#: src/pages/settings/general.vue:422
|
#: src/pages/settings/general.vue:530
|
||||||
#: src/routes.js:236
|
#: src/routes.js:236
|
||||||
msgid "Labels"
|
msgid "Labels"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -999,7 +1003,7 @@ msgstr ""
|
|||||||
msgid "Labels deleted"
|
msgid "Labels deleted"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:220
|
#: src/pages/settings/general.vue:328
|
||||||
msgid "Language"
|
msgid "Language"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1020,14 +1024,14 @@ msgstr ""
|
|||||||
msgid "Lens"
|
msgid "Lens"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:401
|
#: src/pages/settings/general.vue:509
|
||||||
msgid "Let PhotoPrism create albums from past events."
|
msgid "Let PhotoPrism create albums from past events."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/component/navigation.vue:276
|
#: src/component/navigation.vue:276
|
||||||
#: src/component/navigation.vue:285
|
#: src/component/navigation.vue:285
|
||||||
#: src/pages/settings/general.vue:6
|
#: src/pages/settings/general.vue:6
|
||||||
#: src/pages/settings/general.vue:444
|
#: src/pages/settings/general.vue:552
|
||||||
#: src/routes.js:255
|
#: src/routes.js:255
|
||||||
#: src/routes.js:262
|
#: src/routes.js:262
|
||||||
#: src/routes.js:269
|
#: src/routes.js:269
|
||||||
@@ -1093,7 +1097,7 @@ msgid "Logout"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/library.vue:17
|
#: src/pages/library.vue:17
|
||||||
#: src/pages/settings/general.vue:488
|
#: src/pages/settings/general.vue:596
|
||||||
msgid "Logs"
|
msgid "Logs"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1131,7 +1135,7 @@ msgid "Missing"
|
|||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/component/navigation.vue:218
|
#: src/component/navigation.vue:218
|
||||||
#: src/pages/settings/general.vue:400
|
#: src/pages/settings/general.vue:508
|
||||||
#: src/routes.js:98
|
#: src/routes.js:98
|
||||||
#: src/routes.js:105
|
#: src/routes.js:105
|
||||||
msgid "Moments"
|
msgid "Moments"
|
||||||
@@ -1280,7 +1284,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:99
|
#: src/pages/settings/general.vue:101
|
||||||
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 ""
|
||||||
|
|
||||||
@@ -1380,7 +1384,7 @@ msgstr ""
|
|||||||
|
|
||||||
#: src/component/navigation.vue:293
|
#: src/component/navigation.vue:293
|
||||||
#: src/pages/library/files.vue:6
|
#: src/pages/library/files.vue:6
|
||||||
#: src/pages/settings/general.vue:378
|
#: src/pages/settings/general.vue:486
|
||||||
msgid "Originals"
|
msgid "Originals"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1448,10 +1452,14 @@ msgstr ""
|
|||||||
msgid "Place"
|
msgid "Place"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/settings/general.vue:204
|
||||||
|
msgid "Place & Time"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/component/navigation.vue:231
|
#: src/component/navigation.vue:231
|
||||||
#: src/component/navigation.vue:240
|
#: src/component/navigation.vue:240
|
||||||
#: src/pages/settings/general.vue:124
|
#: src/pages/settings/general.vue:152
|
||||||
#: src/pages/settings/general.vue:510
|
#: src/pages/settings/general.vue:618
|
||||||
#: src/routes.js:192
|
#: src/routes.js:192
|
||||||
#: src/routes.js:198
|
#: src/routes.js:198
|
||||||
#: src/routes.js:204
|
#: src/routes.js:204
|
||||||
@@ -1524,7 +1532,7 @@ msgstr ""
|
|||||||
msgid "Purple"
|
msgid "Purple"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:98
|
#: src/pages/settings/general.vue:100
|
||||||
msgid "Quality Filter"
|
msgid "Quality Filter"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1653,7 +1661,7 @@ msgstr ""
|
|||||||
msgid "Search"
|
msgid "Search"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:511
|
#: src/pages/settings/general.vue:619
|
||||||
msgid "Search and display photos on a map."
|
msgid "Search and display photos on a map."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1732,7 +1740,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:312
|
#: src/pages/settings/general.vue:420
|
||||||
msgid "Share"
|
msgid "Share"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1748,7 +1756,7 @@ msgstr ""
|
|||||||
msgid "Show less"
|
msgid "Show less"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:445
|
#: src/pages/settings/general.vue:553
|
||||||
msgid "Show Library in navigation menu."
|
msgid "Show Library in navigation menu."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1756,7 +1764,7 @@ msgstr ""
|
|||||||
msgid "Show more"
|
msgid "Show more"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:489
|
#: src/pages/settings/general.vue:597
|
||||||
msgid "Show server logs in Library."
|
msgid "Show server logs in Library."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1805,14 +1813,27 @@ msgstr ""
|
|||||||
msgid "Spanish"
|
msgid "Spanish"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:142
|
#: src/pages/settings/general.vue:227
|
||||||
msgid "Stack Sequences"
|
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
|
||||||
|
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
|
||||||
msgid "Stacks"
|
msgid "Stacks"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/settings/general.vue:145
|
||||||
|
msgid "Stacks group files with a similar frame of reference, but differences of quality, format, size or color."
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/library/index.vue:30
|
#: src/pages/library/index.vue:30
|
||||||
msgid "Start"
|
msgid "Start"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -1837,7 +1858,7 @@ msgstr ""
|
|||||||
msgid "Streets"
|
msgid "Streets"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:568
|
#: src/pages/settings/general.vue:676
|
||||||
msgid "Style"
|
msgid "Style"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1879,7 +1900,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:198
|
#: src/pages/settings/general.vue:306
|
||||||
msgid "Theme"
|
msgid "Theme"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -1956,6 +1977,10 @@ msgstr ""
|
|||||||
msgid "Type"
|
msgid "Type"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
#: src/pages/settings/general.vue:226
|
||||||
|
msgid "Unique ID"
|
||||||
|
msgstr ""
|
||||||
|
|
||||||
#: src/dialog/photo/details.vue:16
|
#: src/dialog/photo/details.vue:16
|
||||||
#: src/dialog/photo/info.vue:21
|
#: src/dialog/photo/info.vue:21
|
||||||
#: src/model/album.js:122
|
#: src/model/album.js:122
|
||||||
@@ -1998,7 +2023,7 @@ msgstr ""
|
|||||||
#: src/dialog/upload.vue:54
|
#: src/dialog/upload.vue:54
|
||||||
#: src/pages/albums.vue:134
|
#: src/pages/albums.vue:134
|
||||||
#: src/pages/library/import.vue:38
|
#: src/pages/library/import.vue:38
|
||||||
#: src/pages/settings/general.vue:268
|
#: src/pages/settings/general.vue:376
|
||||||
#: src/pages/settings/sync.vue:24
|
#: src/pages/settings/sync.vue:24
|
||||||
msgid "Upload"
|
msgid "Upload"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
@@ -2019,7 +2044,7 @@ msgstr ""
|
|||||||
msgid "Upload local files"
|
msgid "Upload local files"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:313
|
#: src/pages/settings/general.vue:421
|
||||||
msgid "Upload to WebDAV and share links with friends."
|
msgid "Upload to WebDAV and share links with friends."
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
@@ -2045,7 +2070,7 @@ msgstr ""
|
|||||||
msgid "User"
|
msgid "User"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
#: src/pages/settings/general.vue:38
|
#: src/pages/settings/general.vue:66
|
||||||
msgid "User Interface"
|
msgid "User Interface"
|
||||||
msgstr ""
|
msgstr ""
|
||||||
|
|
||||||
|
|||||||
@@ -61,12 +61,70 @@
|
|||||||
<v-checkbox
|
<v-checkbox
|
||||||
@change="onChange"
|
@change="onChange"
|
||||||
:disabled="busy"
|
:disabled="busy"
|
||||||
class="ma-0 pa-0 input-sequences"
|
class="ma-0 pa-0 input-stacks"
|
||||||
v-model="settings.index.sequences"
|
v-model="settings.index.stacks"
|
||||||
color="secondary-dark"
|
color="secondary-dark"
|
||||||
:label="$gettext('Stack Sequences')"
|
:label="$gettext('Stacks')"
|
||||||
:hint="$gettext('Files with sequential names like \'IMG_1234 (2)\' or \'IMG_1234 copy 2\' belong to the same photo.')"
|
:hint="$gettext('Stacks group files with a similar frame of reference, but differences of quality, format, size or color.')"
|
||||||
prepend-icon="photo_library"
|
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">
|
||||||
|
<h3 class="body-2 mb-0">
|
||||||
|
<translate>Stack files with matching...</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-checkbox
|
||||||
|
@change="onChange"
|
||||||
|
:disabled="busy"
|
||||||
|
class="ma-0 pa-0 input-stack-meta"
|
||||||
|
v-model="settings.stack.meta"
|
||||||
|
color="secondary-dark"
|
||||||
|
:label="$gettext('Place & Time')"
|
||||||
|
:hint="$gettext('Stack pictures taken at the exact same time and location based on their metadata.')"
|
||||||
|
prepend-icon="schedule"
|
||||||
|
persistent-hint
|
||||||
|
>
|
||||||
|
</v-checkbox>
|
||||||
|
</v-flex>
|
||||||
|
|
||||||
|
<v-flex xs12 sm6 lg4 class="px-2 pb-2 pt-2">
|
||||||
|
<v-checkbox
|
||||||
|
@change="onChange"
|
||||||
|
:disabled="busy"
|
||||||
|
class="ma-0 pa-0 input-stack-uuid"
|
||||||
|
v-model="settings.stack.uuid"
|
||||||
|
color="secondary-dark"
|
||||||
|
:label="$gettext('Unique ID')"
|
||||||
|
:hint="$gettext('Stack files sharing the same unique image or instance identifier.')"
|
||||||
|
prepend-icon="fingerprint"
|
||||||
|
persistent-hint
|
||||||
|
>
|
||||||
|
</v-checkbox>
|
||||||
|
</v-flex>
|
||||||
|
|
||||||
|
|
||||||
|
<v-flex xs12 sm6 lg4 class="px-2 pb-2 pt-2">
|
||||||
|
<v-checkbox
|
||||||
|
@change="onChange"
|
||||||
|
:disabled="busy"
|
||||||
|
class="ma-0 pa-0 input-stack-sequences"
|
||||||
|
v-model="settings.stack.sequences"
|
||||||
|
color="secondary-dark"
|
||||||
|
:label="$gettext('File Name Prefix')"
|
||||||
|
:hint="$gettext('Files with sequential names like \'IMG_1234 (2)\' and \'IMG_1234 (3)\' belong to the same picture.')"
|
||||||
|
prepend-icon="spellcheck"
|
||||||
persistent-hint
|
persistent-hint
|
||||||
>
|
>
|
||||||
</v-checkbox>
|
</v-checkbox>
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ 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.Stack,
|
Stack: conf.Settings().Index.Stacks,
|
||||||
Path: filepath.Clean(f.Path),
|
Path: filepath.Clean(f.Path),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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.Stack,
|
Stack: conf.Settings().Index.Stacks,
|
||||||
}
|
}
|
||||||
|
|
||||||
indexed := ind.Start(indOpt)
|
indexed := ind.Start(indOpt)
|
||||||
|
|||||||
@@ -27,21 +27,6 @@ type MapsSettings struct {
|
|||||||
Style string `json:"style" yaml:"style"`
|
Style string `json:"style" yaml:"style"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// IndexSettings represents indexing settings.
|
|
||||||
type IndexSettings struct {
|
|
||||||
Path string `json:"path" yaml:"path"`
|
|
||||||
Convert bool `json:"convert" yaml:"convert"`
|
|
||||||
Rescan bool `json:"rescan" yaml:"rescan"`
|
|
||||||
Sequences bool `json:"sequences" yaml:"sequences"`
|
|
||||||
Stack bool `json:"stack" yaml:"stack"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// ImportSettings represents import settings.
|
|
||||||
type ImportSettings struct {
|
|
||||||
Path string `json:"path" yaml:"path"`
|
|
||||||
Move bool `json:"move" yaml:"move"`
|
|
||||||
}
|
|
||||||
|
|
||||||
// FeatureSettings represents feature flags, mainly for the Web UI.
|
// FeatureSettings represents feature flags, mainly for the Web UI.
|
||||||
type FeatureSettings struct {
|
type FeatureSettings struct {
|
||||||
Upload bool `json:"upload" yaml:"upload"`
|
Upload bool `json:"upload" yaml:"upload"`
|
||||||
@@ -60,6 +45,27 @@ type FeatureSettings struct {
|
|||||||
Logs bool `json:"logs" yaml:"logs"`
|
Logs bool `json:"logs" yaml:"logs"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ImportSettings represents import settings.
|
||||||
|
type ImportSettings struct {
|
||||||
|
Path string `json:"path" yaml:"path"`
|
||||||
|
Move bool `json:"move" yaml:"move"`
|
||||||
|
}
|
||||||
|
|
||||||
|
// IndexSettings represents indexing settings.
|
||||||
|
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 file stack settings.
|
||||||
|
type StackSettings struct {
|
||||||
|
UUID bool `json:"uuid" yaml:"uuid"`
|
||||||
|
Meta bool `json:"meta" yaml:"meta"`
|
||||||
|
Sequences bool `json:"sequences" yaml:"sequences"`
|
||||||
|
}
|
||||||
|
|
||||||
// Settings represents user settings for Web UI, indexing, and import.
|
// Settings represents user settings for Web UI, indexing, and import.
|
||||||
type Settings struct {
|
type Settings struct {
|
||||||
Theme string `json:"theme" yaml:"theme"`
|
Theme string `json:"theme" yaml:"theme"`
|
||||||
@@ -69,6 +75,7 @@ type Settings struct {
|
|||||||
Features FeatureSettings `json:"features" yaml:"features"`
|
Features FeatureSettings `json:"features" yaml:"features"`
|
||||||
Import ImportSettings `json:"import" yaml:"import"`
|
Import ImportSettings `json:"import" yaml:"import"`
|
||||||
Index IndexSettings `json:"index" yaml:"index"`
|
Index IndexSettings `json:"index" yaml:"index"`
|
||||||
|
Stack StackSettings `json:"stack" yaml:"stack"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewSettings creates a new Settings instance.
|
// NewSettings creates a new Settings instance.
|
||||||
@@ -107,8 +114,12 @@ func NewSettings() *Settings {
|
|||||||
Path: "/",
|
Path: "/",
|
||||||
Rescan: false,
|
Rescan: false,
|
||||||
Convert: true,
|
Convert: true,
|
||||||
Sequences: true,
|
Stacks: true,
|
||||||
Stack: true,
|
},
|
||||||
|
Stack: StackSettings{
|
||||||
|
UUID: true,
|
||||||
|
Meta: true,
|
||||||
|
Sequences: false,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
7
internal/config/testdata/configEmpty.yml
vendored
7
internal/config/testdata/configEmpty.yml
vendored
@@ -27,5 +27,8 @@ index:
|
|||||||
path: /
|
path: /
|
||||||
convert: true
|
convert: true
|
||||||
rescan: false
|
rescan: false
|
||||||
sequences: true
|
stacks: true
|
||||||
stack: true
|
stack:
|
||||||
|
uuid: true
|
||||||
|
meta: true
|
||||||
|
sequences: false
|
||||||
|
|||||||
@@ -1012,13 +1012,27 @@ func (m *Photo) MapKey() string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Stack merges the photo with identical ones.
|
// Stack merges the photo with identical ones.
|
||||||
func (m *Photo) Stack() (identical Photos, err error) {
|
func (m *Photo) Stack(meta, uuid bool) (identical Photos, err error) {
|
||||||
if err := Db().
|
if !meta && !uuid {
|
||||||
|
return identical, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
stmt := Db().
|
||||||
Where("id <> ?", m.ID).
|
Where("id <> ?", m.ID).
|
||||||
Where("photo_single = 0").
|
Where("photo_single = 0")
|
||||||
Where("(taken_at = ? AND cell_id = ? AND camera_serial = ? AND camera_id = ?) OR (uuid <> '' AND uuid = ?)",
|
|
||||||
m.TakenAt, m.CellID, m.CameraSerial, m.CameraID, m.UUID).
|
switch {
|
||||||
Find(&identical).Error; err != nil {
|
case meta && uuid:
|
||||||
|
stmt.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)
|
||||||
|
case meta:
|
||||||
|
stmt.Where("taken_at = ? AND taken_src = 'meta' AND cell_id = ? AND camera_serial = ? AND camera_id = ?",
|
||||||
|
m.TakenAt, m.CellID, m.CameraSerial, m.CameraID)
|
||||||
|
case uuid:
|
||||||
|
stmt.Where("uuid <> '' AND uuid = ?", m.UUID)
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := stmt.Find(&identical).Error; err != nil {
|
||||||
return identical, err
|
return identical, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -115,7 +115,7 @@ func (c *Convert) Start(path string) error {
|
|||||||
|
|
||||||
// ToJson uses exiftool to export metadata to a json file.
|
// ToJson uses exiftool to export metadata to a json file.
|
||||||
func (c *Convert) ToJson(mf *MediaFile) (*MediaFile, error) {
|
func (c *Convert) ToJson(mf *MediaFile) (*MediaFile, error) {
|
||||||
jsonName := fs.TypeJson.FindFirst(mf.FileName(), []string{c.conf.SidecarPath(), fs.HiddenPath}, c.conf.OriginalsPath(), c.conf.Settings().Index.Sequences)
|
jsonName := fs.TypeJson.FindFirst(mf.FileName(), []string{c.conf.SidecarPath(), fs.HiddenPath}, c.conf.OriginalsPath(), c.conf.Settings().Stack.Sequences)
|
||||||
|
|
||||||
result, err := NewMediaFile(jsonName)
|
result, err := NewMediaFile(jsonName)
|
||||||
|
|
||||||
@@ -127,7 +127,7 @@ func (c *Convert) ToJson(mf *MediaFile) (*MediaFile, error) {
|
|||||||
return nil, fmt.Errorf("convert: can't create json sidecar file for %s in read only mode", txt.Quote(mf.BaseName()))
|
return nil, fmt.Errorf("convert: can't create json sidecar file for %s in read only mode", txt.Quote(mf.BaseName()))
|
||||||
}
|
}
|
||||||
|
|
||||||
jsonName = fs.FileName(mf.FileName(), c.conf.SidecarPath(), c.conf.OriginalsPath(), ".json", c.conf.Settings().Index.Sequences)
|
jsonName = fs.FileName(mf.FileName(), c.conf.SidecarPath(), c.conf.OriginalsPath(), ".json", c.conf.Settings().Stack.Sequences)
|
||||||
|
|
||||||
fileName := mf.RelName(c.conf.OriginalsPath())
|
fileName := mf.RelName(c.conf.OriginalsPath())
|
||||||
|
|
||||||
@@ -220,7 +220,7 @@ func (c *Convert) ToJpeg(image *MediaFile) (*MediaFile, error) {
|
|||||||
return image, nil
|
return image, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
jpegName := fs.TypeJpeg.FindFirst(image.FileName(), []string{c.conf.SidecarPath(), fs.HiddenPath}, c.conf.OriginalsPath(), c.conf.Settings().Index.Sequences)
|
jpegName := fs.TypeJpeg.FindFirst(image.FileName(), []string{c.conf.SidecarPath(), fs.HiddenPath}, c.conf.OriginalsPath(), c.conf.Settings().Stack.Sequences)
|
||||||
|
|
||||||
mediaFile, err := NewMediaFile(jpegName)
|
mediaFile, err := NewMediaFile(jpegName)
|
||||||
|
|
||||||
@@ -232,12 +232,12 @@ func (c *Convert) ToJpeg(image *MediaFile) (*MediaFile, error) {
|
|||||||
return nil, fmt.Errorf("convert: disabled in read only mode (%s)", image.RelName(c.conf.OriginalsPath()))
|
return nil, fmt.Errorf("convert: disabled in read only mode (%s)", image.RelName(c.conf.OriginalsPath()))
|
||||||
}
|
}
|
||||||
|
|
||||||
jpegName = fs.FileName(image.FileName(), c.conf.SidecarPath(), c.conf.OriginalsPath(), fs.JpegExt, c.conf.Settings().Index.Sequences)
|
jpegName = fs.FileName(image.FileName(), c.conf.SidecarPath(), c.conf.OriginalsPath(), fs.JpegExt, c.conf.Settings().Stack.Sequences)
|
||||||
fileName := image.RelName(c.conf.OriginalsPath())
|
fileName := image.RelName(c.conf.OriginalsPath())
|
||||||
|
|
||||||
log.Debugf("convert: %s -> %s", fileName, filepath.Base(jpegName))
|
log.Debugf("convert: %s -> %s", fileName, filepath.Base(jpegName))
|
||||||
|
|
||||||
xmpName := fs.TypeXMP.Find(image.FileName(), c.conf.Settings().Index.Sequences)
|
xmpName := fs.TypeXMP.Find(image.FileName(), c.conf.Settings().Stack.Sequences)
|
||||||
|
|
||||||
event.Publish("index.converting", event.Data{
|
event.Publish("index.converting", event.Data{
|
||||||
"fileType": image.FileType(),
|
"fileType": image.FileType(),
|
||||||
@@ -308,7 +308,7 @@ func (c *Convert) ToAvc1(video *MediaFile) (*MediaFile, error) {
|
|||||||
return video, nil
|
return video, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
avcName := fs.TypeMp4.FindFirst(video.FileName(), []string{c.conf.SidecarPath(), fs.HiddenPath}, c.conf.OriginalsPath(), c.conf.Settings().Index.Sequences)
|
avcName := fs.TypeMp4.FindFirst(video.FileName(), []string{c.conf.SidecarPath(), fs.HiddenPath}, c.conf.OriginalsPath(), c.conf.Settings().Stack.Sequences)
|
||||||
|
|
||||||
mediaFile, err := NewMediaFile(avcName)
|
mediaFile, err := NewMediaFile(avcName)
|
||||||
|
|
||||||
@@ -320,7 +320,7 @@ func (c *Convert) ToAvc1(video *MediaFile) (*MediaFile, error) {
|
|||||||
return nil, fmt.Errorf("convert: disabled in read only mode (%s)", video.RelName(c.conf.OriginalsPath()))
|
return nil, fmt.Errorf("convert: disabled in read only mode (%s)", video.RelName(c.conf.OriginalsPath()))
|
||||||
}
|
}
|
||||||
|
|
||||||
avcName = fs.FileName(video.FileName(), c.conf.SidecarPath(), c.conf.OriginalsPath(), fs.AvcExt, c.conf.Settings().Index.Sequences)
|
avcName = fs.FileName(video.FileName(), c.conf.SidecarPath(), c.conf.OriginalsPath(), fs.AvcExt, c.conf.Settings().Stack.Sequences)
|
||||||
fileName := video.RelName(c.conf.OriginalsPath())
|
fileName := video.RelName(c.conf.OriginalsPath())
|
||||||
|
|
||||||
log.Debugf("convert: %s -> %s", fileName, filepath.Base(avcName))
|
log.Debugf("convert: %s -> %s", fileName, filepath.Base(avcName))
|
||||||
|
|||||||
@@ -151,7 +151,7 @@ func (imp *Import) Start(opt ImportOptions) fs.Done {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
related, err := mf.RelatedFiles(imp.conf.Settings().Index.Sequences)
|
related, err := mf.RelatedFiles(imp.conf.Settings().Stack.Sequences)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
event.Error(fmt.Sprintf("import: %s", err.Error()))
|
event.Error(fmt.Sprintf("import: %s", err.Error()))
|
||||||
|
|||||||
@@ -113,7 +113,7 @@ func ImportWorker(jobs <-chan ImportJob) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
related, err := f.RelatedFiles(imp.conf.Settings().Index.Sequences)
|
related, err := f.RelatedFiles(imp.conf.Settings().Stack.Sequences)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Errorf("import: %s in %s (find related files)", err.Error(), txt.Quote(fs.RelName(destinationMainFilename, imp.originalsPath())))
|
log.Errorf("import: %s in %s (find related files)", err.Error(), txt.Quote(fs.RelName(destinationMainFilename, imp.originalsPath())))
|
||||||
|
|||||||
@@ -167,7 +167,7 @@ func (ind *Index) Start(opt IndexOptions) fs.Done {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
related, err := mf.RelatedFiles(ind.conf.Settings().Index.Sequences)
|
related, err := mf.RelatedFiles(ind.conf.Settings().Stack.Sequences)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Warnf("index: %s", err.Error())
|
log.Warnf("index: %s", err.Error())
|
||||||
@@ -222,7 +222,7 @@ func (ind *Index) Start(opt IndexOptions) fs.Done {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if opt.Stack {
|
if opt.Stack {
|
||||||
if err := ind.StackIdenticalPhotos(); err != nil {
|
if err := ind.StackPhotos(); err != nil {
|
||||||
log.Errorf("index: %s", err)
|
log.Errorf("index: %s", err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -240,16 +240,16 @@ func (ind *Index) Start(opt IndexOptions) fs.Done {
|
|||||||
return done
|
return done
|
||||||
}
|
}
|
||||||
|
|
||||||
// StackIdenticalPhotos stacks files that belong to the same photo.
|
// StackPhotos stacks files that belong to the same photo.
|
||||||
func (ind *Index) StackIdenticalPhotos() error {
|
func (ind *Index) StackPhotos() error {
|
||||||
photos, err := query.IdenticalPhotos()
|
photos, err := query.MatchingPhotos(ind.conf.Settings().Stack.Meta, ind.conf.Settings().Stack.UUID)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, photo := range photos {
|
for _, photo := range photos {
|
||||||
if merged, err := photo.Stack(); err != nil {
|
if merged, err := photo.Stack(ind.conf.Settings().Stack.Meta, ind.conf.Settings().Stack.UUID); err != nil {
|
||||||
log.Errorf("index: %s", err)
|
log.Errorf("index: %s", err)
|
||||||
} else {
|
} else {
|
||||||
log.Infof("index: merged photo uid %s with %s", photo.PhotoUID, merged.UIDs())
|
log.Infof("index: merged photo uid %s with %s", photo.PhotoUID, merged.UIDs())
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
|||||||
|
|
||||||
photoExists := false
|
photoExists := false
|
||||||
|
|
||||||
stripSequence := Config().Settings().Index.Sequences
|
stripSequence := Config().Settings().Stack.Sequences
|
||||||
|
|
||||||
event.Publish("index.indexing", event.Data{
|
event.Publish("index.indexing", event.Data{
|
||||||
"fileHash": fileHash,
|
"fileHash": fileHash,
|
||||||
@@ -156,23 +156,24 @@ func (ind *Index) MediaFile(m *MediaFile, o IndexOptions, originalName string) (
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Try to find existing photo by file path and name.
|
// 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)
|
photoQuery = entity.UnscopedDb().First(&photo, "photo_path = ? AND photo_name = ?", filePath, fileBase)
|
||||||
|
|
||||||
// Add file to existing photo (file stack)?
|
// Stack file based on matching location and time metadata?
|
||||||
if o.Stack {
|
if o.Stack && Config().Settings().Stack.Meta {
|
||||||
// Try to find existing photo by exact time and location.
|
|
||||||
if photoQuery.Error != nil && m.MetaData().HasTimeAndPlace() {
|
if photoQuery.Error != nil && m.MetaData().HasTimeAndPlace() {
|
||||||
metaData = m.MetaData()
|
metaData = m.MetaData()
|
||||||
photoQuery = entity.UnscopedDb().First(&photo, "photo_lat = ? AND photo_lng = ? AND taken_at = ? AND camera_serial = ?", metaData.Lat, metaData.Lng, metaData.TakenAt, metaData.CameraSerial)
|
photoQuery = entity.UnscopedDb().First(&photo, "photo_lat = ? AND photo_lng = ? AND taken_at = ? AND taken_src = 'meta' AND camera_serial = ?", metaData.Lat, metaData.Lng, metaData.TakenAt, metaData.CameraSerial)
|
||||||
|
|
||||||
if photoQuery.Error == nil {
|
if photoQuery.Error == nil {
|
||||||
fileStacked = true
|
fileStacked = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Try to find existing photo by unique image id.
|
// Stack file based on the same unique ID?
|
||||||
|
if o.Stack && Config().Settings().Stack.UUID {
|
||||||
if photoQuery.Error != nil && m.MetaData().HasDocumentID() {
|
if photoQuery.Error != nil && m.MetaData().HasDocumentID() {
|
||||||
photoQuery = entity.UnscopedDb().First(&photo, "uuid = ?", m.MetaData().DocumentID)
|
photoQuery = entity.UnscopedDb().First(&photo, "uuid = ?", m.MetaData().DocumentID)
|
||||||
|
|
||||||
|
|||||||
@@ -379,7 +379,7 @@ func (m *MediaFile) PathNameInfo() (fileRoot, fileBase, relativePath, relativeNa
|
|||||||
rootPath = Config().OriginalsPath()
|
rootPath = Config().OriginalsPath()
|
||||||
}
|
}
|
||||||
|
|
||||||
fileBase = m.BasePrefix(Config().Settings().Index.Sequences)
|
fileBase = m.BasePrefix(Config().Settings().Stack.Sequences)
|
||||||
relativePath = m.RelPath(rootPath)
|
relativePath = m.RelPath(rootPath)
|
||||||
relativeName = m.RelName(rootPath)
|
relativeName = m.RelName(rootPath)
|
||||||
|
|
||||||
|
|||||||
@@ -110,23 +110,46 @@ func PhotosCheck(limit int, offset int) (entities entity.Photos, err error) {
|
|||||||
return entities, err
|
return entities, err
|
||||||
}
|
}
|
||||||
|
|
||||||
// IdenticalPhotos returns photos sharing the same exact time, location and camera serial.
|
// MatchingPhotos returns photos sharing the same exact time and location, or unique image id.
|
||||||
func IdenticalPhotos() (entities entity.Photos, err error) {
|
func MatchingPhotos(meta, uuid bool) (entities entity.Photos, err error) {
|
||||||
err = UnscopedDb().Table("photos").
|
if !meta && !uuid {
|
||||||
Select("photos.*").
|
return entities, nil
|
||||||
Joins(`JOIN photos dup ON photos.id < dup.id
|
}
|
||||||
AND photos.photo_single = 0
|
|
||||||
AND dup.photo_single = 0
|
stmt := UnscopedDb().Table("photos").
|
||||||
AND photos.deleted_at IS NULL
|
Select("photos.*")
|
||||||
AND dup.deleted_at IS NULL
|
|
||||||
AND ((photos.photo_lat = dup.photo_lat
|
switch {
|
||||||
|
case meta && uuid:
|
||||||
|
stmt.Joins(`JOIN photos dup ON photos.id < dup.id
|
||||||
|
AND photos.photo_single = 0 AND dup.photo_single = 0
|
||||||
|
AND photos.deleted_at IS NULL AND dup.deleted_at IS NULL
|
||||||
|
AND ((photos.taken_src = 'meta' AND dup.taken_src = 'meta'
|
||||||
|
AND photos.photo_lat = dup.photo_lat
|
||||||
AND photos.photo_lng = dup.photo_lng
|
AND photos.photo_lng = dup.photo_lng
|
||||||
AND photos.taken_at = dup.taken_at
|
AND photos.taken_at = dup.taken_at
|
||||||
AND photos.camera_id = dup.camera_id
|
AND photos.camera_id = dup.camera_id
|
||||||
AND photos.camera_serial = dup.camera_serial) OR
|
AND photos.camera_serial = dup.camera_serial) OR
|
||||||
(photos.uuid <> '' AND photos.uuid = dup.uuid))`).
|
(photos.uuid <> '' AND photos.uuid = dup.uuid))`)
|
||||||
Group("photos.id").
|
case meta:
|
||||||
Find(&entities).Error
|
stmt.Joins(`JOIN photos dup ON photos.id < dup.id
|
||||||
|
AND photos.photo_single = 0
|
||||||
|
AND dup.photo_single = 0
|
||||||
|
AND photos.deleted_at IS NULL AND dup.deleted_at IS NULL
|
||||||
|
AND ((photos.taken_src = 'meta' AND dup.taken_src = 'meta'
|
||||||
|
AND photos.photo_lat = dup.photo_lat
|
||||||
|
AND photos.photo_lng = dup.photo_lng
|
||||||
|
AND photos.taken_at = dup.taken_at
|
||||||
|
AND photos.camera_id = dup.camera_id
|
||||||
|
AND photos.camera_serial = dup.camera_serial))`)
|
||||||
|
case uuid:
|
||||||
|
stmt.Joins(`JOIN photos dup ON photos.id < dup.id
|
||||||
|
AND photos.photo_single = 0 AND dup.photo_single = 0
|
||||||
|
AND photos.deleted_at IS NULL AND dup.deleted_at IS NULL
|
||||||
|
AND (photos.uuid <> '' AND photos.uuid = dup.uuid)`)
|
||||||
|
}
|
||||||
|
|
||||||
|
err = stmt.Group("photos.id").Find(&entities).Error
|
||||||
|
|
||||||
return entities, err
|
return entities, err
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -80,12 +80,43 @@ func TestPhotosCheck(t *testing.T) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func TestIdenticalPhotos(t *testing.T) {
|
func TestIdenticalPhotos(t *testing.T) {
|
||||||
result, err := IdenticalPhotos()
|
t.Run("all", func(t *testing.T) {
|
||||||
|
result, err := MatchingPhotos(true, true)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
t.Fatal(err)
|
t.Fatal(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
assert.IsType(t, entity.Photos{}, result)
|
assert.IsType(t, entity.Photos{}, result)
|
||||||
// t.Logf("%+v", result)
|
})
|
||||||
|
|
||||||
|
t.Run("meta", func(t *testing.T) {
|
||||||
|
result, err := MatchingPhotos(true, false)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.IsType(t, entity.Photos{}, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("uuid", func(t *testing.T) {
|
||||||
|
result, err := MatchingPhotos(false, true)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.IsType(t, entity.Photos{}, result)
|
||||||
|
})
|
||||||
|
|
||||||
|
t.Run("none", func(t *testing.T) {
|
||||||
|
result, err := MatchingPhotos(false, false)
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
assert.IsType(t, entity.Photos{}, result)
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ func (worker *Sync) relatedDownloads(a entity.Account) (result Downloads, err er
|
|||||||
|
|
||||||
// Group results by directory and base name
|
// Group results by directory and base name
|
||||||
for i, file := range files {
|
for i, file := range files {
|
||||||
k := fs.AbsPrefix(file.RemoteName, worker.conf.Settings().Index.Sequences)
|
k := fs.AbsPrefix(file.RemoteName, worker.conf.Settings().Stack.Sequences)
|
||||||
|
|
||||||
result[k] = append(result[k], file)
|
result[k] = append(result[k], file)
|
||||||
|
|
||||||
@@ -137,7 +137,7 @@ func (worker *Sync) download(a entity.Account) (complete bool, err error) {
|
|||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
related, err := mf.RelatedFiles(worker.conf.Settings().Index.Sequences)
|
related, err := mf.RelatedFiles(worker.conf.Settings().Stack.Sequences)
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
worker.logWarn(err)
|
worker.logWarn(err)
|
||||||
|
|||||||
Reference in New Issue
Block a user