Merge remote-tracking branch 'origin/develop' into feature/oidc-v2

# Conflicts:
#	internal/config/flags.go
This commit is contained in:
Timo Volkmann 2021-10-07 17:51:10 +02:00
commit d1cfa2f3d9
33 changed files with 564 additions and 464 deletions

View file

@ -19,22 +19,21 @@ To get a first impression, you're welcome to play with our public demo at [demo.
## Key Features ##
* Our intuitive [user interface](https://demo.photoprism.org/) makes browsing and organizing your photo collection as easy as
it should be — whether its on a phone, tablet, or desktop computer.
* Index everything without worrying about duplicates or [RAW to JPEG conversion](https://docs.photoprism.org/developer-guide/library/converting/).
* Privacy-preserving face detection and recognition.
* Automatic [image classification](https://docs.photoprism.org/developer-guide/metadata/classification/)
based on Google TensorFlow. In addition, our indexer detects _colors_, _chroma_, _luminance_, _quality_, _panoramic projection_,
_location type_, and many other properties.
* Our intuitive [Web UI](https://demo.photoprism.org/) makes browsing and organizing your photo collection as easy as
it should be — whether its on a phone, tablet, or desktop computer
* Index all your photos and videos without worrying about duplicates, [RAW to JPEG conversion](https://docs.photoprism.org/user-guide/settings/library/), or video transcoding
* Includes four high-resolution [world maps](https://demo.photoprism.org/places) to see where you've been,
and for rediscovering long-forgotten shots.
* WebDAV clients, like Microsofts Windows Explorer or Apple's Finder, may
[connect](https://docs.photoprism.org/user-guide/sync/webdav/) directly to PhotoPrism so that you to can open,
edit, and delete files from your computer or phone as if they were local.
You may easily sync your pictures with [PhotoSync](https://www.photosync-app.com/) as well.
* Because PhotoPrism is built as a [progressive web app](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps),
it provides a native app-like experience, and you may install it on your home screen.
There's also a [community-maintained native app in development](https://github.com/photoprism/photoprism-mobile).
and for rediscovering long-forgotten shots
* Enjoy privacy-preserving face detection and recognition 💎
* Automatic [image classification](https://docs.photoprism.org/developer-guide/metadata/classification/)
based on Google TensorFlow in addition, PhotoPrism detects many other properties such as _colors_, _chroma_, _luminance_, _quality_, _panoramic projection_,
and _location type_
* Use [PhotoSync](https://www.photosync-app.com/) to securely backup iOS and Android mobile devices in the background
* WebDAV clients, like Microsofts Windows Explorer or Apple's Finder, may
[connect](https://docs.photoprism.org/user-guide/sync/webdav/) directly to PhotoPrism so that you to can open,
edit, and delete files from your computer or phone as if they were local
* Because PhotoPrism is built as a [Progressive Web App](https://developer.mozilla.org/en-US/docs/Web/Progressive_web_apps),
it provides a native app-like experience, and you can install it on your home screen without struggling with compatibility issues
## Getting Started ##
@ -43,8 +42,6 @@ on [docs.photoprism.org](https://docs.photoprism.org/getting-started/) -
all you need is a Web browser and [Docker](https://docs.docker.com/get-docker/) to run the server.
It is available for Mac, Linux, and Windows.
## New Release 🌈 ##
The [latest release](https://docs.photoprism.org/release-notes/) not only includes
**facial recognition**, it also comes as a
**single [multi-arch image](https://hub.docker.com/r/photoprism/photoprism) for AMD64, ARM64, and ARMv7**.
@ -52,6 +49,21 @@ That means you don't need to pull from different Docker repositories anymore.
We recommend updating your existing `docker-compose.yml` config based on
[our examples](https://dl.photoprism.org/docker/).
## Funding ##
**This open-source project is made possible thanks to our generous sponsors.**
If you enjoy using PhotoPrism, please consider supporting us via [Patreon](https://www.patreon.com/photoprism)
or [GitHub Sponsors](https://github.com/sponsors/photoprism) — especially if you have
feature requests<sup>1</sup> or need help with using our software.
Your continued support helps us fund operating costs, external services like satellite maps,
and develop new features. Thank you very much!
Also, please [leave a star](https://github.com/photoprism/photoprism/stargazers) on GitHub if you like this project.
It provides additional motivation to keep going.
<sup>1</sup> Ideas backed by one or more [eligible sponsors](SPONSORS.md) are marked with a [golden label](https://github.com/photoprism/photoprism/issues?q=is%3Aissue+is%3Aopen+label%3Asponsor).
Let us know if we mistakenly [label an idea as unfunded](https://github.com/photoprism/photoprism/issues?q=is%3Aissue+is%3Aopen+label%3Aunfunded).
## Roadmap ##
Our vision is to provide the most user-friendly solution for browsing, organizing, and sharing your photo collection.
@ -71,26 +83,6 @@ good (first) contributions.
Follow us on [Twitter][twitter] to receive regular project updates and discuss development related topics. Don't be afraid to ask stupid questions.
## Funding ##
You're welcome to support us via [GitHub Sponsors](https://github.com/sponsors/photoprism),
especially if you have feature requests<sup>1</sup> or need help with using our software.
In addition, you can find us on [Patreon](https://www.patreon.com/photoprism) and
[PayPal](https://www.paypal.me/photoprism). We've also set up [crypto wallets](SPONSORS.md).
Your continuous support helps...
* pay for operating expenses and external services like satellite maps 🛰 🌏
* **developing new features and keeping them free for everyone**
Also, please [leave a star](https://github.com/photoprism/photoprism/stargazers) on GitHub if you like this project.
It provides additional motivation to keep going.
Thank you very much! ❤️
<sup>1</sup> Ideas backed by one or more [eligible sponsors](SPONSORS.md) are marked with a [golden label](https://github.com/photoprism/photoprism/issues?q=is%3Aissue+is%3Aopen+label%3Asponsor).
Let us know if we mistakenly [label an idea as unfunded](https://github.com/photoprism/photoprism/issues?q=is%3Aissue+is%3Aopen+label%3Aunfunded).
## Trademarks ##
PhotoPrism® is a registered trademark of Michael Mayer. You may use it as required to describe

View file

@ -139,9 +139,9 @@
}
},
"node_modules/@babel/code-frame": {
"version": "7.14.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
"integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz",
"integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==",
"dependencies": {
"@babel/highlight": "^7.14.5"
},
@ -158,19 +158,19 @@
}
},
"node_modules/@babel/core": {
"version": "7.15.5",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.5.tgz",
"integrity": "sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz",
"integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==",
"dependencies": {
"@babel/code-frame": "^7.14.5",
"@babel/generator": "^7.15.4",
"@babel/code-frame": "^7.15.8",
"@babel/generator": "^7.15.8",
"@babel/helper-compilation-targets": "^7.15.4",
"@babel/helper-module-transforms": "^7.15.4",
"@babel/helper-module-transforms": "^7.15.8",
"@babel/helpers": "^7.15.4",
"@babel/parser": "^7.15.5",
"@babel/parser": "^7.15.8",
"@babel/template": "^7.15.4",
"@babel/traverse": "^7.15.4",
"@babel/types": "^7.15.4",
"@babel/types": "^7.15.6",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@ -187,9 +187,9 @@
}
},
"node_modules/@babel/eslint-parser": {
"version": "7.15.7",
"resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.7.tgz",
"integrity": "sha512-yJkHyomClm6A2Xzb8pdAo4HzYMSXFn1O5zrCYvbFP0yQFvHueLedV8WiEno8yJOKStjUXzBZzJFeWQ7b3YMsqQ==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.8.tgz",
"integrity": "sha512-fYP7QFngCvgxjUuw8O057SVH5jCXsbFFOoE77CFDcvzwBVgTOkMD/L4mIC5Ud1xf8chK/no2fRbSSn1wvNmKuQ==",
"dependencies": {
"eslint-scope": "^5.1.1",
"eslint-visitor-keys": "^2.1.0",
@ -204,11 +204,11 @@
}
},
"node_modules/@babel/generator": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz",
"integrity": "sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz",
"integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==",
"dependencies": {
"@babel/types": "^7.15.4",
"@babel/types": "^7.15.6",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
},
@ -377,9 +377,9 @@
}
},
"node_modules/@babel/helper-module-transforms": {
"version": "7.15.7",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.7.tgz",
"integrity": "sha512-ZNqjjQG/AuFfekFTY+7nY4RgBSklgTu970c7Rj3m/JOhIu5KPBUuTA9AY6zaKcUvk4g6EbDXdBnhi35FAssdSw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz",
"integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==",
"dependencies": {
"@babel/helper-module-imports": "^7.15.4",
"@babel/helper-replace-supers": "^7.15.4",
@ -530,9 +530,9 @@
}
},
"node_modules/@babel/parser": {
"version": "7.15.7",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.7.tgz",
"integrity": "sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz",
"integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA==",
"bin": {
"parser": "bin/babel-parser.js"
},
@ -557,9 +557,9 @@
}
},
"node_modules/@babel/plugin-proposal-async-generator-functions": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.4.tgz",
"integrity": "sha512-2zt2g5vTXpMC3OmK6uyjvdXptbhBXfA77XGrd3gh93zwG8lZYBLOBImiGBEG0RANu3JqKEACCz5CGk73OJROBw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.8.tgz",
"integrity": "sha512-2Z5F2R2ibINTc63mY7FLqGfEbmofrHU9FitJW1Q7aPaKFhiPvSq6QEt/BoWN5oME3GVyjcRuNNSRbb9LC0CSWA==",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5",
"@babel/helper-remap-async-to-generator": "^7.15.4",
@ -1325,14 +1325,14 @@
}
},
"node_modules/@babel/plugin-transform-runtime": {
"version": "7.15.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.15.0.tgz",
"integrity": "sha512-sfHYkLGjhzWTq6xsuQ01oEsUYjkHRux9fW1iUA68dC7Qd8BS1Unq4aZ8itmQp95zUzIcyR2EbNMTzAicFj+guw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.15.8.tgz",
"integrity": "sha512-+6zsde91jMzzvkzuEA3k63zCw+tm/GvuuabkpisgbDMTPQsIMHllE3XczJFFtEHLjjhKQFZmGQVRdELetlWpVw==",
"dependencies": {
"@babel/helper-module-imports": "^7.14.5",
"@babel/helper-module-imports": "^7.15.4",
"@babel/helper-plugin-utils": "^7.14.5",
"babel-plugin-polyfill-corejs2": "^0.2.2",
"babel-plugin-polyfill-corejs3": "^0.2.2",
"babel-plugin-polyfill-corejs3": "^0.2.5",
"babel-plugin-polyfill-regenerator": "^0.2.2",
"semver": "^6.3.0"
},
@ -1358,12 +1358,12 @@
}
},
"node_modules/@babel/plugin-transform-spread": {
"version": "7.14.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz",
"integrity": "sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.15.8.tgz",
"integrity": "sha512-/daZ8s2tNaRekl9YJa9X4bzjpeRZLt122cpgFnQPLGUe61PH8zMEBmYqKkW5xF5JUEh5buEGXJoQpqBmIbpmEQ==",
"dependencies": {
"@babel/helper-plugin-utils": "^7.14.5",
"@babel/helper-skip-transparent-expression-wrappers": "^7.14.5"
"@babel/helper-skip-transparent-expression-wrappers": "^7.15.4"
},
"engines": {
"node": ">=6.9.0"
@ -1461,16 +1461,16 @@
"hasInstallScript": true
},
"node_modules/@babel/preset-env": {
"version": "7.15.6",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.6.tgz",
"integrity": "sha512-L+6jcGn7EWu7zqaO2uoTDjjMBW+88FXzV8KvrBl2z6MtRNxlsmUNRlZPaNNPUTgqhyC5DHNFk/2Jmra+ublZWw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.8.tgz",
"integrity": "sha512-rCC0wH8husJgY4FPbHsiYyiLxSY8oMDJH7Rl6RQMknbN9oDDHhM9RDFvnGM2MgkbUJzSQB4gtuwygY5mCqGSsA==",
"dependencies": {
"@babel/compat-data": "^7.15.0",
"@babel/helper-compilation-targets": "^7.15.4",
"@babel/helper-plugin-utils": "^7.14.5",
"@babel/helper-validator-option": "^7.14.5",
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.15.4",
"@babel/plugin-proposal-async-generator-functions": "^7.15.4",
"@babel/plugin-proposal-async-generator-functions": "^7.15.8",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-class-static-block": "^7.15.4",
"@babel/plugin-proposal-dynamic-import": "^7.14.5",
@ -1525,7 +1525,7 @@
"@babel/plugin-transform-regenerator": "^7.14.5",
"@babel/plugin-transform-reserved-words": "^7.14.5",
"@babel/plugin-transform-shorthand-properties": "^7.14.5",
"@babel/plugin-transform-spread": "^7.14.6",
"@babel/plugin-transform-spread": "^7.15.8",
"@babel/plugin-transform-sticky-regex": "^7.14.5",
"@babel/plugin-transform-template-literals": "^7.14.5",
"@babel/plugin-transform-typeof-symbol": "^7.14.5",
@ -1534,7 +1534,7 @@
"@babel/preset-modules": "^0.1.4",
"@babel/types": "^7.15.6",
"babel-plugin-polyfill-corejs2": "^0.2.2",
"babel-plugin-polyfill-corejs3": "^0.2.2",
"babel-plugin-polyfill-corejs3": "^0.2.5",
"babel-plugin-polyfill-regenerator": "^0.2.2",
"core-js-compat": "^3.16.0",
"semver": "^6.3.0"
@ -2171,18 +2171,18 @@
}
},
"node_modules/@webpack-cli/configtest": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.4.tgz",
"integrity": "sha512-cs3XLy+UcxiP6bj0A6u7MLLuwdXJ1c3Dtc0RkKg+wiI1g/Ti1om8+/2hc2A2B60NbBNAbMgyBMHvyymWm/j4wQ==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz",
"integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==",
"peerDependencies": {
"webpack": "4.x.x || 5.x.x",
"webpack-cli": "4.x.x"
}
},
"node_modules/@webpack-cli/info": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.3.0.tgz",
"integrity": "sha512-ASiVB3t9LOKHs5DyVUcxpraBXDOKubYu/ihHhU+t1UPpxsivg6Od2E2qU4gJCekfEddzRBzHhzA/Acyw/mlK/w==",
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz",
"integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==",
"dependencies": {
"envinfo": "^7.7.3"
},
@ -2191,9 +2191,9 @@
}
},
"node_modules/@webpack-cli/serve": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.5.2.tgz",
"integrity": "sha512-vgJ5OLWadI8aKjDlOH3rb+dYyPd2GTZuQC/Tihjct6F9GpXGZINo3Y/IVuZVTM1eDQB+/AOsjPUWH/WySDaXvw==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz",
"integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==",
"peerDependencies": {
"webpack-cli": "4.x.x"
},
@ -3206,9 +3206,9 @@
"integrity": "sha512-kNkVV4KFta3TYQv0bzs4xNwLaeag261pxgzGQSh4cQ1rEhYjcTJfFRP0SDlbhLONg0eSoLzrDd79PosjbltufA=="
},
"node_modules/colorette": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
"integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g=="
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.14.tgz",
"integrity": "sha512-TLcu0rCLNjDIdKGLGqMtPEAOAZmavC1QCX4mEs3P0mrA/DDoU/tA+Y4UQK/862FkX2TTlbyVIkREZNbf7Y9YwA=="
},
"node_modules/colors": {
"version": "1.4.0",
@ -4281,9 +4281,9 @@
}
},
"node_modules/electron-to-chromium": {
"version": "1.3.860",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.860.tgz",
"integrity": "sha512-gWwGZ+Wv4Mou2SJRH6JQzhTPjL5f95SX7n6VkLTQ/Q/INsZLZNQ1vH2GlZjozKyvT0kkFuCmWTwIoCj+/hUDPw=="
"version": "1.3.861",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.861.tgz",
"integrity": "sha512-GZyflmpMnZRdZ1e2yAyvuFwz1MPSVQelwHX4TJZyXypB8NcxdPvPNwy5lOTxnlkrK13EiQzyTPugRSnj6cBgKg=="
},
"node_modules/emoji-regex": {
"version": "8.0.0",
@ -7001,9 +7001,9 @@
}
},
"node_modules/istanbul-lib-coverage": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.1.tgz",
"integrity": "sha512-GvCYYTxaCPqwMjobtVcVKvSHtAGe48MNhGjpK8LtVF8K0ISX7hCKl85LgtuaSneWVyQmaGcW3iXVV3GaZSLpmQ==",
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
"integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==",
"engines": {
"node": ">=8"
}
@ -7111,9 +7111,9 @@
}
},
"node_modules/istanbul-reports": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
"integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.3.tgz",
"integrity": "sha512-0i77ZFLsb9U3DHi22WzmIngVzfoyxxbQcZRqlF3KoKmCJGq9nhFHoGi8FqBztN2rE8w6hURnZghetn0xpkVb6A==",
"dependencies": {
"html-escaper": "^2.0.0",
"istanbul-lib-report": "^3.0.0"
@ -13313,15 +13313,15 @@
}
},
"node_modules/webpack-cli": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.8.0.tgz",
"integrity": "sha512-+iBSWsX16uVna5aAYN6/wjhJy1q/GKk4KjKvfg90/6hykCTSgozbfz5iRgDTSJt/LgSbYxdBX3KBHeobIs+ZEw==",
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.0.tgz",
"integrity": "sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw==",
"dependencies": {
"@discoveryjs/json-ext": "^0.5.0",
"@webpack-cli/configtest": "^1.0.4",
"@webpack-cli/info": "^1.3.0",
"@webpack-cli/serve": "^1.5.2",
"colorette": "^1.2.1",
"@webpack-cli/configtest": "^1.1.0",
"@webpack-cli/info": "^1.4.0",
"@webpack-cli/serve": "^1.6.0",
"colorette": "^2.0.14",
"commander": "^7.0.0",
"execa": "^5.0.0",
"fastest-levenshtein": "^1.0.12",
@ -13732,9 +13732,9 @@
}
},
"@babel/code-frame": {
"version": "7.14.5",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.14.5.tgz",
"integrity": "sha512-9pzDqyc6OLDaqe+zbACgFkb6fKMNG6CObKpnYXChRsvYGyEdc7CA2BaqeOM+vOtCS5ndmJicPJhKAwYRI6UfFw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.15.8.tgz",
"integrity": "sha512-2IAnmn8zbvC/jKYhq5Ki9I+DwjlrtMPUCH/CpHvqI4dNnlwHwsxoIhlc8WcYY5LSYknXQtAlFYuHfqAFCvQ4Wg==",
"requires": {
"@babel/highlight": "^7.14.5"
}
@ -13745,19 +13745,19 @@
"integrity": "sha512-0NqAC1IJE0S0+lL1SWFMxMkz1pKCNCjI4tr2Zx4LJSXxCLAdr6KyArnY+sno5m3yH9g737ygOyPABDsnXkpxiA=="
},
"@babel/core": {
"version": "7.15.5",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.5.tgz",
"integrity": "sha512-pYgXxiwAgQpgM1bNkZsDEq85f0ggXMA5L7c+o3tskGMh2BunCI9QUwB9Z4jpvXUOuMdyGKiGKQiRe11VS6Jzvg==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.15.8.tgz",
"integrity": "sha512-3UG9dsxvYBMYwRv+gS41WKHno4K60/9GPy1CJaH6xy3Elq8CTtvtjT5R5jmNhXfCYLX2mTw+7/aq5ak/gOE0og==",
"requires": {
"@babel/code-frame": "^7.14.5",
"@babel/generator": "^7.15.4",
"@babel/code-frame": "^7.15.8",
"@babel/generator": "^7.15.8",
"@babel/helper-compilation-targets": "^7.15.4",
"@babel/helper-module-transforms": "^7.15.4",
"@babel/helper-module-transforms": "^7.15.8",
"@babel/helpers": "^7.15.4",
"@babel/parser": "^7.15.5",
"@babel/parser": "^7.15.8",
"@babel/template": "^7.15.4",
"@babel/traverse": "^7.15.4",
"@babel/types": "^7.15.4",
"@babel/types": "^7.15.6",
"convert-source-map": "^1.7.0",
"debug": "^4.1.0",
"gensync": "^1.0.0-beta.2",
@ -13767,9 +13767,9 @@
}
},
"@babel/eslint-parser": {
"version": "7.15.7",
"resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.7.tgz",
"integrity": "sha512-yJkHyomClm6A2Xzb8pdAo4HzYMSXFn1O5zrCYvbFP0yQFvHueLedV8WiEno8yJOKStjUXzBZzJFeWQ7b3YMsqQ==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/eslint-parser/-/eslint-parser-7.15.8.tgz",
"integrity": "sha512-fYP7QFngCvgxjUuw8O057SVH5jCXsbFFOoE77CFDcvzwBVgTOkMD/L4mIC5Ud1xf8chK/no2fRbSSn1wvNmKuQ==",
"requires": {
"eslint-scope": "^5.1.1",
"eslint-visitor-keys": "^2.1.0",
@ -13777,11 +13777,11 @@
}
},
"@babel/generator": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.4.tgz",
"integrity": "sha512-d3itta0tu+UayjEORPNz6e1T3FtvWlP5N4V5M+lhp/CxT4oAA7/NcScnpRyspUMLK6tu9MNHmQHxRykuN2R7hw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.15.8.tgz",
"integrity": "sha512-ECmAKstXbp1cvpTTZciZCgfOt6iN64lR0d+euv3UZisU5awfRawOvg07Utn/qBGuH4bRIEZKrA/4LzZyXhZr8g==",
"requires": {
"@babel/types": "^7.15.4",
"@babel/types": "^7.15.6",
"jsesc": "^2.5.1",
"source-map": "^0.5.0"
}
@ -13902,9 +13902,9 @@
}
},
"@babel/helper-module-transforms": {
"version": "7.15.7",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.7.tgz",
"integrity": "sha512-ZNqjjQG/AuFfekFTY+7nY4RgBSklgTu970c7Rj3m/JOhIu5KPBUuTA9AY6zaKcUvk4g6EbDXdBnhi35FAssdSw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.15.8.tgz",
"integrity": "sha512-DfAfA6PfpG8t4S6npwzLvTUpp0sS7JrcuaMiy1Y5645laRJIp/LiLGIBbQKaXSInK8tiGNI7FL7L8UvB8gdUZg==",
"requires": {
"@babel/helper-module-imports": "^7.15.4",
"@babel/helper-replace-supers": "^7.15.4",
@ -14016,9 +14016,9 @@
}
},
"@babel/parser": {
"version": "7.15.7",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.7.tgz",
"integrity": "sha512-rycZXvQ+xS9QyIcJ9HXeDWf1uxqlbVFAUq0Rq0dbc50Zb/+wUe/ehyfzGfm9KZZF0kBejYgxltBXocP+gKdL2g=="
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.15.8.tgz",
"integrity": "sha512-BRYa3wcQnjS/nqI8Ac94pYYpJfojHVvVXJ97+IDCImX4Jc8W8Xv1+47enbruk+q1etOpsQNwnfFcNGw+gtPGxA=="
},
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": {
"version": "7.15.4",
@ -14031,9 +14031,9 @@
}
},
"@babel/plugin-proposal-async-generator-functions": {
"version": "7.15.4",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.4.tgz",
"integrity": "sha512-2zt2g5vTXpMC3OmK6uyjvdXptbhBXfA77XGrd3gh93zwG8lZYBLOBImiGBEG0RANu3JqKEACCz5CGk73OJROBw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.15.8.tgz",
"integrity": "sha512-2Z5F2R2ibINTc63mY7FLqGfEbmofrHU9FitJW1Q7aPaKFhiPvSq6QEt/BoWN5oME3GVyjcRuNNSRbb9LC0CSWA==",
"requires": {
"@babel/helper-plugin-utils": "^7.14.5",
"@babel/helper-remap-async-to-generator": "^7.15.4",
@ -14508,14 +14508,14 @@
}
},
"@babel/plugin-transform-runtime": {
"version": "7.15.0",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.15.0.tgz",
"integrity": "sha512-sfHYkLGjhzWTq6xsuQ01oEsUYjkHRux9fW1iUA68dC7Qd8BS1Unq4aZ8itmQp95zUzIcyR2EbNMTzAicFj+guw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-runtime/-/plugin-transform-runtime-7.15.8.tgz",
"integrity": "sha512-+6zsde91jMzzvkzuEA3k63zCw+tm/GvuuabkpisgbDMTPQsIMHllE3XczJFFtEHLjjhKQFZmGQVRdELetlWpVw==",
"requires": {
"@babel/helper-module-imports": "^7.14.5",
"@babel/helper-module-imports": "^7.15.4",
"@babel/helper-plugin-utils": "^7.14.5",
"babel-plugin-polyfill-corejs2": "^0.2.2",
"babel-plugin-polyfill-corejs3": "^0.2.2",
"babel-plugin-polyfill-corejs3": "^0.2.5",
"babel-plugin-polyfill-regenerator": "^0.2.2",
"semver": "^6.3.0"
}
@ -14529,12 +14529,12 @@
}
},
"@babel/plugin-transform-spread": {
"version": "7.14.6",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.14.6.tgz",
"integrity": "sha512-Zr0x0YroFJku7n7+/HH3A2eIrGMjbmAIbJSVv0IZ+t3U2WUQUA64S/oeied2e+MaGSjmt4alzBCsK9E8gh+fag==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.15.8.tgz",
"integrity": "sha512-/daZ8s2tNaRekl9YJa9X4bzjpeRZLt122cpgFnQPLGUe61PH8zMEBmYqKkW5xF5JUEh5buEGXJoQpqBmIbpmEQ==",
"requires": {
"@babel/helper-plugin-utils": "^7.14.5",
"@babel/helper-skip-transparent-expression-wrappers": "^7.14.5"
"@babel/helper-skip-transparent-expression-wrappers": "^7.15.4"
}
},
"@babel/plugin-transform-sticky-regex": {
@ -14595,16 +14595,16 @@
}
},
"@babel/preset-env": {
"version": "7.15.6",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.6.tgz",
"integrity": "sha512-L+6jcGn7EWu7zqaO2uoTDjjMBW+88FXzV8KvrBl2z6MtRNxlsmUNRlZPaNNPUTgqhyC5DHNFk/2Jmra+ublZWw==",
"version": "7.15.8",
"resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.15.8.tgz",
"integrity": "sha512-rCC0wH8husJgY4FPbHsiYyiLxSY8oMDJH7Rl6RQMknbN9oDDHhM9RDFvnGM2MgkbUJzSQB4gtuwygY5mCqGSsA==",
"requires": {
"@babel/compat-data": "^7.15.0",
"@babel/helper-compilation-targets": "^7.15.4",
"@babel/helper-plugin-utils": "^7.14.5",
"@babel/helper-validator-option": "^7.14.5",
"@babel/plugin-bugfix-v8-spread-parameters-in-optional-chaining": "^7.15.4",
"@babel/plugin-proposal-async-generator-functions": "^7.15.4",
"@babel/plugin-proposal-async-generator-functions": "^7.15.8",
"@babel/plugin-proposal-class-properties": "^7.14.5",
"@babel/plugin-proposal-class-static-block": "^7.15.4",
"@babel/plugin-proposal-dynamic-import": "^7.14.5",
@ -14659,7 +14659,7 @@
"@babel/plugin-transform-regenerator": "^7.14.5",
"@babel/plugin-transform-reserved-words": "^7.14.5",
"@babel/plugin-transform-shorthand-properties": "^7.14.5",
"@babel/plugin-transform-spread": "^7.14.6",
"@babel/plugin-transform-spread": "^7.15.8",
"@babel/plugin-transform-sticky-regex": "^7.14.5",
"@babel/plugin-transform-template-literals": "^7.14.5",
"@babel/plugin-transform-typeof-symbol": "^7.14.5",
@ -14668,7 +14668,7 @@
"@babel/preset-modules": "^0.1.4",
"@babel/types": "^7.15.6",
"babel-plugin-polyfill-corejs2": "^0.2.2",
"babel-plugin-polyfill-corejs3": "^0.2.2",
"babel-plugin-polyfill-corejs3": "^0.2.5",
"babel-plugin-polyfill-regenerator": "^0.2.2",
"core-js-compat": "^3.16.0",
"semver": "^6.3.0"
@ -15217,23 +15217,23 @@
}
},
"@webpack-cli/configtest": {
"version": "1.0.4",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.0.4.tgz",
"integrity": "sha512-cs3XLy+UcxiP6bj0A6u7MLLuwdXJ1c3Dtc0RkKg+wiI1g/Ti1om8+/2hc2A2B60NbBNAbMgyBMHvyymWm/j4wQ==",
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/configtest/-/configtest-1.1.0.tgz",
"integrity": "sha512-ttOkEkoalEHa7RaFYpM0ErK1xc4twg3Am9hfHhL7MVqlHebnkYd2wuI/ZqTDj0cVzZho6PdinY0phFZV3O0Mzg==",
"requires": {}
},
"@webpack-cli/info": {
"version": "1.3.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.3.0.tgz",
"integrity": "sha512-ASiVB3t9LOKHs5DyVUcxpraBXDOKubYu/ihHhU+t1UPpxsivg6Od2E2qU4gJCekfEddzRBzHhzA/Acyw/mlK/w==",
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/info/-/info-1.4.0.tgz",
"integrity": "sha512-F6b+Man0rwE4n0409FyAJHStYA5OIZERxmnUfLVwv0mc0V1wLad3V7jqRlMkgKBeAq07jUvglacNaa6g9lOpuw==",
"requires": {
"envinfo": "^7.7.3"
}
},
"@webpack-cli/serve": {
"version": "1.5.2",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.5.2.tgz",
"integrity": "sha512-vgJ5OLWadI8aKjDlOH3rb+dYyPd2GTZuQC/Tihjct6F9GpXGZINo3Y/IVuZVTM1eDQB+/AOsjPUWH/WySDaXvw==",
"version": "1.6.0",
"resolved": "https://registry.npmjs.org/@webpack-cli/serve/-/serve-1.6.0.tgz",
"integrity": "sha512-ZkVeqEmRpBV2GHvjjUZqEai2PpUbuq8Bqd//vEYsp63J8WyexI8ppCqVS3Zs0QADf6aWuPdU+0XsPI647PVlQA==",
"requires": {}
},
"@xtuc/ieee754": {
@ -15981,9 +15981,9 @@
"integrity": "sha512-kNkVV4KFta3TYQv0bzs4xNwLaeag261pxgzGQSh4cQ1rEhYjcTJfFRP0SDlbhLONg0eSoLzrDd79PosjbltufA=="
},
"colorette": {
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz",
"integrity": "sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g=="
"version": "2.0.14",
"resolved": "https://registry.npmjs.org/colorette/-/colorette-2.0.14.tgz",
"integrity": "sha512-TLcu0rCLNjDIdKGLGqMtPEAOAZmavC1QCX4mEs3P0mrA/DDoU/tA+Y4UQK/862FkX2TTlbyVIkREZNbf7Y9YwA=="
},
"colors": {
"version": "1.4.0",
@ -16770,9 +16770,9 @@
"integrity": "sha512-7vmuyh5+kuUyJKePhQfRQBhXV5Ce+RnaeeQArKu1EAMpL3WbgMt5WG6uQZpEVvYSSsxMXRKOewtDk9RaTKXRlA=="
},
"electron-to-chromium": {
"version": "1.3.860",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.860.tgz",
"integrity": "sha512-gWwGZ+Wv4Mou2SJRH6JQzhTPjL5f95SX7n6VkLTQ/Q/INsZLZNQ1vH2GlZjozKyvT0kkFuCmWTwIoCj+/hUDPw=="
"version": "1.3.861",
"resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.861.tgz",
"integrity": "sha512-GZyflmpMnZRdZ1e2yAyvuFwz1MPSVQelwHX4TJZyXypB8NcxdPvPNwy5lOTxnlkrK13EiQzyTPugRSnj6cBgKg=="
},
"emoji-regex": {
"version": "8.0.0",
@ -18742,9 +18742,9 @@
"integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8="
},
"istanbul-lib-coverage": {
"version": "3.0.1",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.1.tgz",
"integrity": "sha512-GvCYYTxaCPqwMjobtVcVKvSHtAGe48MNhGjpK8LtVF8K0ISX7hCKl85LgtuaSneWVyQmaGcW3iXVV3GaZSLpmQ=="
"version": "3.0.0",
"resolved": "https://registry.npmjs.org/istanbul-lib-coverage/-/istanbul-lib-coverage-3.0.0.tgz",
"integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg=="
},
"istanbul-lib-instrument": {
"version": "4.0.3",
@ -18823,9 +18823,9 @@
}
},
"istanbul-reports": {
"version": "3.0.2",
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.2.tgz",
"integrity": "sha512-9tZvz7AiR3PEDNGiV9vIouQ/EAcqMXFmkcA1CDFTwOB98OZVDL0PH9glHotf5Ugp6GCOTypfzGWI/OqjWNCRUw==",
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/istanbul-reports/-/istanbul-reports-3.0.3.tgz",
"integrity": "sha512-0i77ZFLsb9U3DHi22WzmIngVzfoyxxbQcZRqlF3KoKmCJGq9nhFHoGi8FqBztN2rE8w6hURnZghetn0xpkVb6A==",
"requires": {
"html-escaper": "^2.0.0",
"istanbul-lib-report": "^3.0.0"
@ -23447,15 +23447,15 @@
}
},
"webpack-cli": {
"version": "4.8.0",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.8.0.tgz",
"integrity": "sha512-+iBSWsX16uVna5aAYN6/wjhJy1q/GKk4KjKvfg90/6hykCTSgozbfz5iRgDTSJt/LgSbYxdBX3KBHeobIs+ZEw==",
"version": "4.9.0",
"resolved": "https://registry.npmjs.org/webpack-cli/-/webpack-cli-4.9.0.tgz",
"integrity": "sha512-n/jZZBMzVEl4PYIBs+auy2WI0WTQ74EnJDiyD98O2JZY6IVIHJNitkYp/uTXOviIOMfgzrNvC9foKv/8o8KSZw==",
"requires": {
"@discoveryjs/json-ext": "^0.5.0",
"@webpack-cli/configtest": "^1.0.4",
"@webpack-cli/info": "^1.3.0",
"@webpack-cli/serve": "^1.5.2",
"colorette": "^1.2.1",
"@webpack-cli/configtest": "^1.1.0",
"@webpack-cli/info": "^1.4.0",
"@webpack-cli/serve": "^1.6.0",
"colorette": "^2.0.14",
"commander": "^7.0.0",
"execa": "^5.0.0",
"fastest-levenshtein": "^1.0.12",

Binary file not shown.

View file

@ -13,7 +13,7 @@ msgstr ""
"X-Generator: Poedit 2.3\n"
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
#: src/dialog/photo/files.vue:137 src/dialog/photo/files.vue:134
#: src/dialog/photo/files.vue:132 src/dialog/photo/files.vue:129
msgid "{{ file.Orientation }}"
msgstr ""
@ -37,8 +37,8 @@ msgstr "%{n} Ordner gefunden"
msgid "%{n} labels found"
msgstr "%{n} Kategorien gefunden"
#: src/pages/people/faces.vue:275 src/pages/people/faces.vue:361
#: src/pages/people/subjects.vue:408
#: src/pages/people/faces.vue:282 src/pages/people/faces.vue:368
#: src/pages/people/subjects.vue:432
msgid "%{n} people found"
msgstr "%{n} Personen gefunden"
@ -81,7 +81,7 @@ msgstr "Genauigkeit"
msgid "Action"
msgstr "Aktion"
#: src/dialog/photo/files.vue:27 src/dialog/photo/files.vue:24
#: src/dialog/photo/files.vue:28 src/dialog/photo/files.vue:25
msgid "Actions"
msgstr "Aktionen"
@ -111,7 +111,7 @@ msgstr "Server hinzufügen"
msgid "Add to album"
msgstr "Hinzufügen"
#: src/dialog/photo/files.vue:162 src/dialog/photo/files.vue:159
#: src/dialog/photo/files.vue:157 src/dialog/photo/files.vue:154
msgid "Added"
msgstr "Hinzugefügt"
@ -185,7 +185,7 @@ msgstr "Alle %{n} Einträge werden angezeigt"
msgid "All %{n} labels loaded"
msgstr "Alle %{n} Kategorien werden angezeigt"
#: src/pages/people/subjects.vue:311
#: src/pages/people/subjects.vue:335
msgid "All %{n} people loaded"
msgstr "Alle %{n} Personen geladen"
@ -311,7 +311,7 @@ msgstr "Diese Datei unwiderruflich löschen?"
msgid "Artist"
msgstr "Ersteller"
#: src/dialog/photo/files.vue:128 src/dialog/photo/files.vue:125
#: src/dialog/photo/files.vue:123 src/dialog/photo/files.vue:120
msgid "Aspect Ratio"
msgstr "Seitenverhältnis"
@ -331,7 +331,7 @@ msgstr ""
msgid "Automatically creates albums of special moments, trips, and places."
msgstr "Erstellt automatisch Alben mit besonderen Momenten, Reisen und Orten."
#: src/pages/people/subjects.vue:428
#: src/pages/people/subjects.vue:430
msgid "Bio"
msgstr "Biographie"
@ -394,9 +394,9 @@ msgstr "Limit erreicht, bitte Suche eingrenzen"
#: src/common/clipboard.js:105 src/common/clipboard.js:142
#: src/pages/albums.vue:387 src/pages/albums.vue:403 src/pages/labels.vue:182
#: src/pages/labels.vue:198 src/pages/library/files.vue:193
#: src/pages/library/files.vue:209 src/pages/people/faces.vue:204
#: src/pages/people/faces.vue:220 src/pages/people/subjects.vue:245
#: src/pages/people/subjects.vue:261 src/share/albums.vue:345
#: src/pages/library/files.vue:209 src/pages/people/faces.vue:211
#: src/pages/people/faces.vue:227 src/pages/people/subjects.vue:269
#: src/pages/people/subjects.vue:285 src/share/albums.vue:345
#: src/share/albums.vue:361
msgid "Can't select more items"
msgstr "Maximale Anzahl wurde selektiert"
@ -444,7 +444,7 @@ msgstr "Vereinfachtes Chinesisch"
msgid "Chinese Traditional"
msgstr "Traditionelles Chinesisch"
#: src/dialog/photo/files.vue:148 src/dialog/photo/files.vue:145
#: src/dialog/photo/files.vue:143 src/dialog/photo/files.vue:140
msgid "Chroma"
msgstr "Farbsättigung"
@ -453,7 +453,7 @@ msgstr "Farbsättigung"
msgid "Close"
msgstr "Schließen"
#: src/dialog/photo/files.vue:100 src/dialog/photo/files.vue:97
#: src/dialog/photo/files.vue:95 src/dialog/photo/files.vue:92
msgid "Codec"
msgstr "Codec"
@ -596,7 +596,7 @@ msgstr "Standard Ordner"
#: src/component/photo/clipboard.vue:283 src/dialog/account/remove.vue:18
#: src/dialog/album/delete.vue:18 src/dialog/file/delete.vue:18
#: src/dialog/label/delete.vue:18 src/dialog/photo/delete.vue:18
#: src/dialog/photo/files.vue:40 src/dialog/photo/files.vue:37
#: src/dialog/photo/files.vue:41 src/dialog/photo/files.vue:38
#: src/dialog/share.vue:232 src/pages/settings/general.vue:206
msgid "Delete"
msgstr "Löschen"
@ -723,7 +723,7 @@ msgstr "Fertig."
#: src/component/album/clipboard.vue:113 src/component/album/toolbar.vue:107
#: src/component/file/clipboard.vue:66 src/component/photo/clipboard.vue:169
#: src/component/photo/viewer.vue:86 src/component/subject/clipboard.vue:66
#: src/dialog/photo/files.vue:31 src/dialog/photo/files.vue:28
#: src/dialog/photo/files.vue:32 src/dialog/photo/files.vue:29
#: src/pages/settings/general.vue:162 src/share/album/clipboard.vue:61
#: src/share/photo/clipboard.vue:63 src/share/photos.vue:77
msgid "Download"
@ -821,10 +821,6 @@ msgstr ""
msgid "English"
msgstr "Englisch"
#: src/dialog/photo/files.vue:52 src/dialog/photo/files.vue:49
msgid "Error"
msgstr "Fehler"
#: src/component/navigation.vue:338
msgid "Errors"
msgstr "Fehler"
@ -849,6 +845,10 @@ msgstr ""
"Als privat markierte Inhalte werden nicht in Suchergebnissen und geteilten "
"Alben angezeigt."
#: src/pages/people/faces.vue:100 src/pages/people/subjects.vue:138
msgid "Exclude hidden"
msgstr "Verborgene ausblenden"
#: src/component/navigation.vue:248
msgid "Expand"
msgstr "Ausklappen"
@ -999,7 +999,7 @@ msgstr "Grau"
msgid "Group by similarity"
msgstr "Ähnlichkeit"
#: src/dialog/photo/files.vue:64 src/dialog/photo/files.vue:61
#: src/dialog/photo/files.vue:59 src/dialog/photo/files.vue:56
msgid "Hash"
msgstr "Prüfsumme"
@ -1019,7 +1019,7 @@ msgstr "Versteckt"
msgid "Hidden Files"
msgstr "Unsichtbare Dateien"
#: src/pages/people/faces.vue:237 src/pages/people/subjects.vue:294
#: src/pages/people/faces.vue:237 src/pages/people/subjects.vue:295
msgid "Hide"
msgstr "Verbergen"
@ -1086,8 +1086,8 @@ msgstr "Importiere %{name}…"
msgid "Importing files to originals…"
msgstr "Importiere Dateien nach Originals…"
#: src/dialog/photo/files.vue:165 src/dialog/photo/files.vue:174
#: src/dialog/photo/files.vue:162 src/dialog/photo/files.vue:171
#: src/dialog/photo/files.vue:160 src/dialog/photo/files.vue:169
#: src/dialog/photo/files.vue:157 src/dialog/photo/files.vue:166
msgid "in"
msgstr "in"
@ -1107,7 +1107,7 @@ msgstr "Indexierung fehlgeschlagen"
msgid "Indexing media and sidecar files…"
msgstr "Indexiere Bilder, Videos und Sidecar-Dateien…"
#: src/dialog/photo/files.vue:58 src/dialog/photo/files.vue:55
#: src/dialog/photo/files.vue:53 src/dialog/photo/files.vue:50
msgid "Instance ID"
msgstr "Instanz ID"
@ -1283,7 +1283,7 @@ msgstr "Längengrad"
msgid "Magenta"
msgstr "Magenta"
#: src/dialog/photo/files.vue:142 src/dialog/photo/files.vue:139
#: src/dialog/photo/files.vue:137 src/dialog/photo/files.vue:134
msgid "Main Color"
msgstr "Hauptfarbe"
@ -1315,7 +1315,7 @@ msgstr "Nachricht versendet"
msgid "Minimize"
msgstr "Minimieren"
#: src/dialog/photo/files.vue:154 src/dialog/photo/files.vue:151
#: src/dialog/photo/files.vue:149 src/dialog/photo/files.vue:146
msgid "Missing"
msgstr "Fehlend"
@ -1344,7 +1344,7 @@ msgstr "Mehr als 20 Alben gefunden"
msgid "More than 20 labels found"
msgstr "Mehr als 20 Labels gefunden"
#: src/pages/people/subjects.vue:411
#: src/pages/people/subjects.vue:435
msgid "More than 20 people found"
msgstr "Mehr als 20 Personen gefunden"
@ -1371,13 +1371,13 @@ msgstr "Dateien verschieben"
#: src/component/photo/cards.vue:30 src/component/photo/list.vue:38
#: src/component/photo/list.vue:237 src/dialog/account/edit.vue:397
#: src/dialog/album/edit.vue:106 src/dialog/photo/files.vue:76
#: src/dialog/photo/files.vue:73 src/dialog/photo/files.vue:30
#: src/dialog/album/edit.vue:106 src/dialog/photo/files.vue:71
#: src/dialog/photo/files.vue:68 src/dialog/photo/files.vue:30
#: src/dialog/photo/info.vue:31 src/dialog/photo/labels.vue:48
#: src/dialog/photo/people.vue:18 src/dialog/photo/people.vue:229
#: src/pages/about/feedback.vue:144 src/pages/labels.vue:337
#: src/pages/login.vue:73 src/pages/people/faces.vue:48
#: src/pages/people/faces.vue:309 src/pages/people/subjects.vue:391
#: src/pages/people/faces.vue:307 src/pages/people/subjects.vue:393
#: src/share/photo/cards.vue:30 src/share/photo/list.vue:34
#: src/share/photo/list.vue:216
msgid "Name"
@ -1430,8 +1430,8 @@ msgid "No labels found"
msgstr "Keine Kategorien gefunden"
#: src/dialog/photo/people.vue:5 src/pages/people/faces.vue:30
#: src/pages/people/faces.vue:271 src/pages/people/faces.vue:357
#: src/pages/people/subjects.vue:33 src/pages/people/subjects.vue:404
#: src/pages/people/faces.vue:278 src/pages/people/faces.vue:364
#: src/pages/people/subjects.vue:33 src/pages/people/subjects.vue:428
msgid "No people found"
msgstr "Keine Personen gefunden"
@ -1552,8 +1552,8 @@ msgstr "Ein Ordner gefunden"
msgid "One label found"
msgstr "Eine Kategorie gefunden"
#: src/pages/people/faces.vue:273 src/pages/people/faces.vue:359
#: src/pages/people/subjects.vue:406
#: src/pages/people/faces.vue:280 src/pages/people/faces.vue:366
#: src/pages/people/subjects.vue:430
msgid "One person found"
msgstr "Eine Person gefunden"
@ -1573,7 +1573,7 @@ msgstr "Optionen"
msgid "Orange"
msgstr "Orange"
#: src/dialog/photo/files.vue:134 src/dialog/photo/files.vue:131
#: src/dialog/photo/files.vue:129 src/dialog/photo/files.vue:126
msgid "Orientation"
msgstr "Ausrichtung"
@ -1585,7 +1585,7 @@ msgstr "Original"
msgid "Original file names will be stored and indexed."
msgstr "Die ursprünglichen Dateinamen werden im Index gespeichert."
#: src/dialog/photo/files.vue:82 src/dialog/photo/files.vue:79
#: src/dialog/photo/files.vue:77 src/dialog/photo/files.vue:74
#: src/dialog/photo/info.vue:37
msgid "Original Name"
msgstr "Originalname"
@ -1710,7 +1710,7 @@ msgstr "Bitte lade keine anstößigen Bilder hoch."
msgid "Polish"
msgstr "Polnisch"
#: src/dialog/photo/files.vue:114 src/dialog/photo/files.vue:111
#: src/dialog/photo/files.vue:109 src/dialog/photo/files.vue:106
msgid "Portrait"
msgstr "Portrait"
@ -1734,12 +1734,12 @@ msgstr "Auf “Start” klicken, um Dateien zu indexieren…"
msgid "Press enter to create a new album."
msgstr "Enter drücken, um ein neues Album zu erstellen."
#: src/dialog/photo/files.vue:18 src/dialog/photo/files.vue:15
#: src/dialog/photo/files.vue:19 src/dialog/photo/files.vue:16
msgid "Preview"
msgstr "Voransicht"
#: src/dialog/photo/files.vue:34 src/dialog/photo/files.vue:106
#: src/dialog/photo/files.vue:31 src/dialog/photo/files.vue:103
#: src/dialog/photo/files.vue:35 src/dialog/photo/files.vue:101
#: src/dialog/photo/files.vue:32 src/dialog/photo/files.vue:98
#: src/dialog/photo/files.vue:24
msgid "Primary"
msgstr "Primärdatei"
@ -1754,7 +1754,7 @@ msgstr "Privat"
msgid "Product Feedback"
msgstr "Allgemeines Feedback"
#: src/dialog/photo/files.vue:122 src/dialog/photo/files.vue:119
#: src/dialog/photo/files.vue:117 src/dialog/photo/files.vue:114
msgid "Projection"
msgstr "Projektion"
@ -1829,11 +1829,11 @@ msgstr "Rot"
#: src/component/album/toolbar.vue:54 src/component/photo/toolbar.vue:57
#: src/dialog/reload.vue:15 src/pages/albums.vue:134 src/pages/labels.vue:91
#: src/pages/library/errors.vue:69 src/pages/library/files.vue:100
#: src/pages/people/faces.vue:65 src/pages/people/subjects.vue:102
#: src/pages/people/faces.vue:65 src/pages/people/subjects.vue:103
msgid "Reload"
msgstr "Neu laden"
#: src/dialog/reload.vue:26 src/pages/settings/general.vue:70
#: src/dialog/reload.vue:26 src/pages/settings/general.vue:71
#: src/pages/settings/library.vue:46
msgid "Reloading…"
msgstr "Wird neu geladen…"
@ -1912,7 +1912,7 @@ msgstr "Scans"
#: src/component/navigation.vue:4 src/component/navigation.vue:280
#: src/component/photo/toolbar.vue:48 src/pages/albums.vue:109
#: src/pages/labels.vue:81 src/pages/library/errors.vue:60
#: src/pages/people/subjects.vue:85 src/pages/places.vue:30 src/routes.js:107
#: src/pages/people/subjects.vue:86 src/pages/places.vue:30 src/routes.js:107
msgid "Search"
msgstr "Suche"
@ -1977,7 +1977,7 @@ msgstr "Service URL"
msgid "Settings"
msgstr "Einstellungen"
#: src/pages/settings/advanced.vue:39 src/pages/settings/general.vue:74
#: src/pages/settings/advanced.vue:39 src/pages/settings/general.vue:75
#: src/pages/settings/library.vue:50
msgid "Settings saved"
msgstr "Einstellungen gespeichert"
@ -2003,20 +2003,19 @@ msgstr "%{name} teilen"
msgid "Shared with you."
msgstr "Mit dir geteilt."
#: src/pages/people/faces.vue:227 src/pages/people/subjects.vue:284
#: src/pages/people/faces.vue:227 src/pages/people/subjects.vue:285
msgid "Show"
msgstr "Anzeigen"
#: src/pages/people/faces.vue:83 src/pages/people/subjects.vue:120
msgid "Show all"
msgstr "Alle anzeigen"
#: src/pages/people/faces.vue:66
msgid "Show all new faces"
msgstr "Alle neuen Gesichter anzeigen"
#: src/pages/labels.vue:126 src/pages/people/faces.vue:100
#: src/pages/people/subjects.vue:137
#: src/pages/people/faces.vue:83 src/pages/people/subjects.vue:121
msgid "Show hidden"
msgstr "Verborgene anzeigen"
#: src/pages/labels.vue:126
msgid "Show less"
msgstr "Weniger zeigen"
@ -2058,8 +2057,8 @@ msgstr "Anmelden"
msgid "Similar"
msgstr "Ähnlich"
#: src/dialog/account/edit.vue:220 src/dialog/photo/files.vue:88
#: src/dialog/photo/files.vue:85 src/dialog/photo/files.vue:32
#: src/dialog/account/edit.vue:220 src/dialog/photo/files.vue:83
#: src/dialog/photo/files.vue:80 src/dialog/photo/files.vue:32
msgid "Size"
msgstr "Größe"
@ -2139,7 +2138,7 @@ msgstr "Statische Maximalgröße: %{n}px"
msgid "Status"
msgstr "Status"
#: src/dialog/photo/files.vue:70 src/dialog/photo/files.vue:67
#: src/dialog/photo/files.vue:65 src/dialog/photo/files.vue:62
msgid "Storage Folder"
msgstr "Ablageverzeichnis"
@ -2237,7 +2236,7 @@ msgstr "Titel"
msgid "Title too long"
msgstr "Titel zu lang"
#: src/app.js:165 src/share.js:164
#: src/app.js:174 src/share.js:164
msgid "to"
msgstr "nach"
@ -2268,8 +2267,8 @@ msgstr "Markenrechte"
msgid "Try again using other filters or keywords."
msgstr "Versuche es mit anderen Filtern oder Suchbegriffen."
#: src/dialog/account/edit.vue:490 src/dialog/photo/files.vue:94
#: src/dialog/photo/files.vue:91 src/dialog/photo/files.vue:33
#: src/dialog/account/edit.vue:490 src/dialog/photo/files.vue:89
#: src/dialog/photo/files.vue:86 src/dialog/photo/files.vue:33
#: src/dialog/photo/info.vue:15
msgid "Type"
msgstr "Typ"
@ -2296,11 +2295,11 @@ msgstr "Unbekannt"
msgid "Unsorted"
msgstr "Unsortiert"
#: src/dialog/photo/files.vue:37 src/dialog/photo/files.vue:34
#: src/dialog/photo/files.vue:38 src/dialog/photo/files.vue:35
msgid "Unstack"
msgstr "Einzelaufnahme"
#: src/dialog/photo/files.vue:171 src/dialog/photo/files.vue:168
#: src/dialog/photo/files.vue:166 src/dialog/photo/files.vue:163
#: src/dialog/photo/info.vue:175
msgid "Updated"
msgstr "Geändert"
@ -2459,9 +2458,9 @@ msgid "Yellowstone"
msgstr "Yellowstone"
#: src/dialog/people/merge.vue:18 src/dialog/photo/archive.vue:18
#: src/dialog/photo/files.vue:109 src/dialog/photo/files.vue:117
#: src/dialog/photo/files.vue:157 src/dialog/photo/files.vue:106
#: src/dialog/photo/files.vue:114 src/dialog/photo/files.vue:154
#: src/dialog/photo/files.vue:104 src/dialog/photo/files.vue:112
#: src/dialog/photo/files.vue:152 src/dialog/photo/files.vue:101
#: src/dialog/photo/files.vue:109 src/dialog/photo/files.vue:149
#: src/dialog/photo/info.vue:284 src/dialog/photo/info.vue:305
#: src/dialog/photo/info.vue:325 src/dialog/photo/info.vue:345
#: src/dialog/photo/info.vue:365
@ -2517,6 +2516,12 @@ msgstr "Deine Nachricht wurde gesendet"
msgid "Zoom in/out"
msgstr "Zoom in/out"
#~ msgid "Error"
#~ msgstr "Fehler"
#~ msgid "Show all"
#~ msgstr "Alle anzeigen"
#~ msgid "More than 20 faces found"
#~ msgstr "Mehr als 20 Gesichter gefunden"

File diff suppressed because one or more lines are too long

View file

@ -9,8 +9,8 @@ msgstr ""
msgid ""
msgstr ""
#: src/dialog/photo/files.vue:137
#: src/dialog/photo/files.vue:134
#: src/dialog/photo/files.vue:132
#: src/dialog/photo/files.vue:129
msgid "{{ file.Orientation }}"
msgstr ""
@ -36,9 +36,9 @@ msgstr ""
msgid "%{n} labels found"
msgstr ""
#: src/pages/people/faces.vue:275
#: src/pages/people/faces.vue:361
#: src/pages/people/subjects.vue:408
#: src/pages/people/faces.vue:282
#: src/pages/people/faces.vue:368
#: src/pages/people/subjects.vue:432
msgid "%{n} people found"
msgstr ""
@ -84,8 +84,8 @@ msgstr ""
msgid "Action"
msgstr ""
#: src/dialog/photo/files.vue:27
#: src/dialog/photo/files.vue:24
#: src/dialog/photo/files.vue:28
#: src/dialog/photo/files.vue:25
msgid "Actions"
msgstr ""
@ -120,8 +120,8 @@ msgstr ""
msgid "Add to album"
msgstr ""
#: src/dialog/photo/files.vue:162
#: src/dialog/photo/files.vue:159
#: src/dialog/photo/files.vue:157
#: src/dialog/photo/files.vue:154
msgid "Added"
msgstr ""
@ -199,7 +199,7 @@ msgstr ""
msgid "All %{n} labels loaded"
msgstr ""
#: src/pages/people/subjects.vue:311
#: src/pages/people/subjects.vue:335
msgid "All %{n} people loaded"
msgstr ""
@ -329,8 +329,8 @@ msgstr ""
msgid "Artist"
msgstr ""
#: src/dialog/photo/files.vue:128
#: src/dialog/photo/files.vue:125
#: src/dialog/photo/files.vue:123
#: src/dialog/photo/files.vue:120
msgid "Aspect Ratio"
msgstr ""
@ -346,7 +346,7 @@ msgstr ""
msgid "Automatically creates albums of special moments, trips, and places."
msgstr ""
#: src/pages/people/subjects.vue:428
#: src/pages/people/subjects.vue:430
msgid "Bio"
msgstr ""
@ -420,10 +420,10 @@ msgstr ""
#: src/pages/labels.vue:198
#: src/pages/library/files.vue:193
#: src/pages/library/files.vue:209
#: src/pages/people/faces.vue:204
#: src/pages/people/faces.vue:220
#: src/pages/people/subjects.vue:245
#: src/pages/people/subjects.vue:261
#: src/pages/people/faces.vue:211
#: src/pages/people/faces.vue:227
#: src/pages/people/subjects.vue:269
#: src/pages/people/subjects.vue:285
#: src/share/albums.vue:345
#: src/share/albums.vue:361
msgid "Can't select more items"
@ -482,8 +482,8 @@ msgstr ""
msgid "Chinese Traditional"
msgstr ""
#: src/dialog/photo/files.vue:148
#: src/dialog/photo/files.vue:145
#: src/dialog/photo/files.vue:143
#: src/dialog/photo/files.vue:140
msgid "Chroma"
msgstr ""
@ -494,8 +494,8 @@ msgstr ""
msgid "Close"
msgstr ""
#: src/dialog/photo/files.vue:100
#: src/dialog/photo/files.vue:97
#: src/dialog/photo/files.vue:95
#: src/dialog/photo/files.vue:92
msgid "Codec"
msgstr ""
@ -654,8 +654,8 @@ msgstr ""
#: src/dialog/file/delete.vue:18
#: src/dialog/label/delete.vue:18
#: src/dialog/photo/delete.vue:18
#: src/dialog/photo/files.vue:40
#: src/dialog/photo/files.vue:37
#: src/dialog/photo/files.vue:41
#: src/dialog/photo/files.vue:38
#: src/dialog/share.vue:232
#: src/pages/settings/general.vue:206
msgid "Delete"
@ -789,8 +789,8 @@ msgstr ""
#: src/component/photo/clipboard.vue:169
#: src/component/photo/viewer.vue:86
#: src/component/subject/clipboard.vue:66
#: src/dialog/photo/files.vue:31
#: src/dialog/photo/files.vue:28
#: src/dialog/photo/files.vue:32
#: src/dialog/photo/files.vue:29
#: src/pages/settings/general.vue:162
#: src/share/album/clipboard.vue:61
#: src/share/photo/clipboard.vue:63
@ -894,11 +894,6 @@ msgstr ""
msgid "English"
msgstr ""
#: src/dialog/photo/files.vue:52
#: src/dialog/photo/files.vue:49
msgid "Error"
msgstr ""
#: src/component/navigation.vue:338
msgid "Errors"
msgstr ""
@ -919,6 +914,11 @@ msgstr ""
msgid "Exclude content marked as private from search results, shared albums, labels, and places."
msgstr ""
#: src/pages/people/faces.vue:100
#: src/pages/people/subjects.vue:138
msgid "Exclude hidden"
msgstr ""
#: src/component/navigation.vue:248
msgid "Expand"
msgstr ""
@ -1076,8 +1076,8 @@ msgstr ""
msgid "Group by similarity"
msgstr ""
#: src/dialog/photo/files.vue:64
#: src/dialog/photo/files.vue:61
#: src/dialog/photo/files.vue:59
#: src/dialog/photo/files.vue:56
msgid "Hash"
msgstr ""
@ -1098,7 +1098,7 @@ msgid "Hidden Files"
msgstr ""
#: src/pages/people/faces.vue:237
#: src/pages/people/subjects.vue:294
#: src/pages/people/subjects.vue:295
msgid "Hide"
msgstr ""
@ -1160,10 +1160,10 @@ msgstr ""
msgid "Importing files to originals…"
msgstr ""
#: src/dialog/photo/files.vue:165
#: src/dialog/photo/files.vue:174
#: src/dialog/photo/files.vue:162
#: src/dialog/photo/files.vue:171
#: src/dialog/photo/files.vue:160
#: src/dialog/photo/files.vue:169
#: src/dialog/photo/files.vue:157
#: src/dialog/photo/files.vue:166
msgid "in"
msgstr ""
@ -1185,8 +1185,8 @@ msgstr ""
msgid "Indexing media and sidecar files…"
msgstr ""
#: src/dialog/photo/files.vue:58
#: src/dialog/photo/files.vue:55
#: src/dialog/photo/files.vue:53
#: src/dialog/photo/files.vue:50
msgid "Instance ID"
msgstr ""
@ -1382,8 +1382,8 @@ msgstr ""
msgid "Magenta"
msgstr ""
#: src/dialog/photo/files.vue:142
#: src/dialog/photo/files.vue:139
#: src/dialog/photo/files.vue:137
#: src/dialog/photo/files.vue:134
msgid "Main Color"
msgstr ""
@ -1415,8 +1415,8 @@ msgstr ""
msgid "Minimize"
msgstr ""
#: src/dialog/photo/files.vue:154
#: src/dialog/photo/files.vue:151
#: src/dialog/photo/files.vue:149
#: src/dialog/photo/files.vue:146
msgid "Missing"
msgstr ""
@ -1450,7 +1450,7 @@ msgstr ""
msgid "More than 20 labels found"
msgstr ""
#: src/pages/people/subjects.vue:411
#: src/pages/people/subjects.vue:435
msgid "More than 20 people found"
msgstr ""
@ -1483,8 +1483,8 @@ msgstr ""
#: src/component/photo/list.vue:237
#: src/dialog/account/edit.vue:397
#: src/dialog/album/edit.vue:106
#: src/dialog/photo/files.vue:76
#: src/dialog/photo/files.vue:73
#: src/dialog/photo/files.vue:71
#: src/dialog/photo/files.vue:68
#: src/dialog/photo/files.vue:30
#: src/dialog/photo/info.vue:31
#: src/dialog/photo/labels.vue:48
@ -1494,8 +1494,8 @@ msgstr ""
#: src/pages/labels.vue:337
#: src/pages/login.vue:73
#: src/pages/people/faces.vue:48
#: src/pages/people/faces.vue:309
#: src/pages/people/subjects.vue:391
#: src/pages/people/faces.vue:307
#: src/pages/people/subjects.vue:393
#: src/share/photo/cards.vue:30
#: src/share/photo/list.vue:34
#: src/share/photo/list.vue:216
@ -1563,10 +1563,10 @@ msgstr ""
#: src/dialog/photo/people.vue:5
#: src/pages/people/faces.vue:30
#: src/pages/people/faces.vue:271
#: src/pages/people/faces.vue:357
#: src/pages/people/faces.vue:278
#: src/pages/people/faces.vue:364
#: src/pages/people/subjects.vue:33
#: src/pages/people/subjects.vue:404
#: src/pages/people/subjects.vue:428
msgid "No people found"
msgstr ""
@ -1678,9 +1678,9 @@ msgstr ""
msgid "One label found"
msgstr ""
#: src/pages/people/faces.vue:273
#: src/pages/people/faces.vue:359
#: src/pages/people/subjects.vue:406
#: src/pages/people/faces.vue:280
#: src/pages/people/faces.vue:366
#: src/pages/people/subjects.vue:430
msgid "One person found"
msgstr ""
@ -1700,8 +1700,8 @@ msgstr ""
msgid "Orange"
msgstr ""
#: src/dialog/photo/files.vue:134
#: src/dialog/photo/files.vue:131
#: src/dialog/photo/files.vue:129
#: src/dialog/photo/files.vue:126
msgid "Orientation"
msgstr ""
@ -1713,8 +1713,8 @@ msgstr ""
msgid "Original file names will be stored and indexed."
msgstr ""
#: src/dialog/photo/files.vue:82
#: src/dialog/photo/files.vue:79
#: src/dialog/photo/files.vue:77
#: src/dialog/photo/files.vue:74
#: src/dialog/photo/info.vue:37
msgid "Original Name"
msgstr ""
@ -1847,8 +1847,8 @@ msgstr ""
msgid "Polish"
msgstr ""
#: src/dialog/photo/files.vue:114
#: src/dialog/photo/files.vue:111
#: src/dialog/photo/files.vue:109
#: src/dialog/photo/files.vue:106
msgid "Portrait"
msgstr ""
@ -1873,15 +1873,15 @@ msgstr ""
msgid "Press enter to create a new album."
msgstr ""
#: src/dialog/photo/files.vue:18
#: src/dialog/photo/files.vue:15
#: src/dialog/photo/files.vue:19
#: src/dialog/photo/files.vue:16
msgid "Preview"
msgstr ""
#: src/dialog/photo/files.vue:34
#: src/dialog/photo/files.vue:106
#: src/dialog/photo/files.vue:31
#: src/dialog/photo/files.vue:103
#: src/dialog/photo/files.vue:35
#: src/dialog/photo/files.vue:101
#: src/dialog/photo/files.vue:32
#: src/dialog/photo/files.vue:98
#: src/dialog/photo/files.vue:24
msgid "Primary"
msgstr ""
@ -1898,8 +1898,8 @@ msgstr ""
msgid "Product Feedback"
msgstr ""
#: src/dialog/photo/files.vue:122
#: src/dialog/photo/files.vue:119
#: src/dialog/photo/files.vue:117
#: src/dialog/photo/files.vue:114
msgid "Projection"
msgstr ""
@ -1984,12 +1984,12 @@ msgstr ""
#: src/pages/library/errors.vue:69
#: src/pages/library/files.vue:100
#: src/pages/people/faces.vue:65
#: src/pages/people/subjects.vue:102
#: src/pages/people/subjects.vue:103
msgid "Reload"
msgstr ""
#: src/dialog/reload.vue:26
#: src/pages/settings/general.vue:70
#: src/pages/settings/general.vue:71
#: src/pages/settings/library.vue:46
msgid "Reloading…"
msgstr ""
@ -2071,7 +2071,7 @@ msgstr ""
#: src/pages/albums.vue:109
#: src/pages/labels.vue:81
#: src/pages/library/errors.vue:60
#: src/pages/people/subjects.vue:85
#: src/pages/people/subjects.vue:86
#: src/pages/places.vue:30
#: src/routes.js:107
msgid "Search"
@ -2146,7 +2146,7 @@ msgid "Settings"
msgstr ""
#: src/pages/settings/advanced.vue:39
#: src/pages/settings/general.vue:74
#: src/pages/settings/general.vue:75
#: src/pages/settings/library.vue:50
msgid "Settings saved"
msgstr ""
@ -2175,22 +2175,20 @@ msgid "Shared with you."
msgstr ""
#: src/pages/people/faces.vue:227
#: src/pages/people/subjects.vue:284
#: src/pages/people/subjects.vue:285
msgid "Show"
msgstr ""
#: src/pages/people/faces.vue:83
#: src/pages/people/subjects.vue:120
msgid "Show all"
msgstr ""
#: src/pages/people/faces.vue:66
msgid "Show all new faces"
msgstr ""
#: src/pages/people/faces.vue:83
#: src/pages/people/subjects.vue:121
msgid "Show hidden"
msgstr ""
#: src/pages/labels.vue:126
#: src/pages/people/faces.vue:100
#: src/pages/people/subjects.vue:137
msgid "Show less"
msgstr ""
@ -2231,8 +2229,8 @@ msgid "Similar"
msgstr ""
#: src/dialog/account/edit.vue:220
#: src/dialog/photo/files.vue:88
#: src/dialog/photo/files.vue:85
#: src/dialog/photo/files.vue:83
#: src/dialog/photo/files.vue:80
#: src/dialog/photo/files.vue:32
msgid "Size"
msgstr ""
@ -2312,8 +2310,8 @@ msgstr ""
msgid "Status"
msgstr ""
#: src/dialog/photo/files.vue:70
#: src/dialog/photo/files.vue:67
#: src/dialog/photo/files.vue:65
#: src/dialog/photo/files.vue:62
msgid "Storage Folder"
msgstr ""
@ -2405,7 +2403,7 @@ msgstr ""
msgid "Title too long"
msgstr ""
#: src/app.js:165
#: src/app.js:174
#: src/share.js:164
msgid "to"
msgstr ""
@ -2447,8 +2445,8 @@ msgid "Try again using other filters or keywords."
msgstr ""
#: src/dialog/account/edit.vue:490
#: src/dialog/photo/files.vue:94
#: src/dialog/photo/files.vue:91
#: src/dialog/photo/files.vue:89
#: src/dialog/photo/files.vue:86
#: src/dialog/photo/files.vue:33
#: src/dialog/photo/info.vue:15
msgid "Type"
@ -2487,13 +2485,13 @@ msgstr ""
msgid "Unsorted"
msgstr ""
#: src/dialog/photo/files.vue:37
#: src/dialog/photo/files.vue:34
#: src/dialog/photo/files.vue:38
#: src/dialog/photo/files.vue:35
msgid "Unstack"
msgstr ""
#: src/dialog/photo/files.vue:171
#: src/dialog/photo/files.vue:168
#: src/dialog/photo/files.vue:166
#: src/dialog/photo/files.vue:163
#: src/dialog/photo/info.vue:175
msgid "Updated"
msgstr ""
@ -2660,12 +2658,12 @@ msgstr ""
#: src/dialog/people/merge.vue:18
#: src/dialog/photo/archive.vue:18
#: src/dialog/photo/files.vue:104
#: src/dialog/photo/files.vue:112
#: src/dialog/photo/files.vue:152
#: src/dialog/photo/files.vue:101
#: src/dialog/photo/files.vue:109
#: src/dialog/photo/files.vue:117
#: src/dialog/photo/files.vue:157
#: src/dialog/photo/files.vue:106
#: src/dialog/photo/files.vue:114
#: src/dialog/photo/files.vue:154
#: src/dialog/photo/files.vue:149
#: src/dialog/photo/info.vue:284
#: src/dialog/photo/info.vue:305
#: src/dialog/photo/info.vue:325

View file

@ -10,10 +10,10 @@
<v-icon>refresh</v-icon>
</v-btn>
<v-btn v-if="!filter.hidden" icon class="action-show-all" :title="$gettext('Show all')" @click.stop="showAll">
<v-btn v-if="!filter.hidden" icon class="action-show-hidden" :title="$gettext('Show hidden')" @click.stop="onShowHidden">
<v-icon>visibility</v-icon>
</v-btn>
<v-btn v-else icon class="action-show-default" :title="$gettext('Show less')" @click.stop="showDefault">
<v-btn v-else icon class="action-exclude-hidden" :title="$gettext('Exclude hidden')" @click.stop="onExcludeHidden">
<v-icon>visibility_off</v-icon>
</v-btn>
</v-toolbar>
@ -316,12 +316,14 @@ export default {
onSave(m) {
m.update();
},
showAll() {
this.filter.hidden = "true";
this.updateQuery();
onShowHidden() {
this.showHidden("yes");
},
showDefault() {
this.filter.hidden = "";
onExcludeHidden() {
this.showHidden("");
},
showHidden(value) {
this.filter.hidden = value;
this.updateQuery();
},
clearQuery() {

View file

@ -20,15 +20,14 @@
<v-divider vertical></v-divider>
<v-btn icon overflow flat depressed color="secondary-dark" class="action-reload" :title="$gettext('Reload')"
@click.stop="refresh">
<v-btn icon overflow flat depressed color="secondary-dark" class="action-reload" :title="$gettext('Reload')" @click.stop="refresh">
<v-icon>refresh</v-icon>
</v-btn>
<v-btn v-if="!filter.hidden" icon class="action-show-all" :title="$gettext('Show all')" @click.stop="showHidden('yes')">
<v-btn v-if="!filter.hidden" icon class="action-show-hidden" :title="$gettext('Show hidden')" @click.stop="onShowHidden">
<v-icon>visibility</v-icon>
</v-btn>
<v-btn v-else icon class="action-show-default" :title="$gettext('Show less')" @click.stop="showHidden('')">
<v-btn v-else icon class="action-exclude-hidden" :title="$gettext('Exclude hidden')" @click.stop="onExcludeHidden">
<v-icon>visibility_off</v-icon>
</v-btn>
</v-toolbar>
@ -394,6 +393,12 @@ export default {
}
}
},
onShowHidden() {
this.showHidden("yes");
},
onExcludeHidden() {
this.showHidden("");
},
showHidden(value) {
this.$earlyAccess().then(() => {
this.filter.hidden = value;

View file

@ -250,7 +250,7 @@ test.meta("testID", "people-005")("Hide face", async (t) => {
.wait(6000)
.expect(Selector("div[data-id=" + FirstFaceID + "]").visible)
.notOk()
.click(Selector("button.action-show-all"));
.click(Selector("button.action-show-hidden"));
await t.eval(() => location.reload());
await t
.wait(6000)
@ -258,7 +258,7 @@ test.meta("testID", "people-005")("Hide face", async (t) => {
.ok()
.hover(Selector("div[data-id=" + FirstFaceID + "]"))
.click(Selector("div[data-id=" + FirstFaceID + "] button.input-hidden"))
.click(Selector("button.action-show-default"));
.click(Selector("button.action-exclude-hidden"));
await t.eval(() => location.reload());
await t
.wait(6000)
@ -280,7 +280,7 @@ test.meta("testID", "people-006")("Hide person", async (t) => {
.wait(6000)
.expect(Selector("a[data-uid=" + FirstPerson + "]").visible)
.notOk()
.click(Selector("button.action-show-all"));
.click(Selector("button.action-show-hidden"));
await t.eval(() => location.reload());
await t
.wait(6000)
@ -288,7 +288,7 @@ test.meta("testID", "people-006")("Hide person", async (t) => {
.ok()
.hover(Selector("a[data-uid=" + FirstPerson + "]"))
.click(Selector("a[data-uid=" + FirstPerson + "] button.input-hidden"))
.click(Selector("button.action-show-default"));
.click(Selector("button.action-exclude-hidden"));
await t.eval(() => location.reload());
await t
.wait(6000)

View file

@ -10,6 +10,7 @@ import (
"path/filepath"
"time"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/photoprism/photoprism/internal/config"
@ -22,8 +23,8 @@ import (
// BackupCommand configures the backup cli command.
var BackupCommand = cli.Command{
Name: "backup",
Usage: "Creates album and index backups",
UsageText: `A custom index sql backup FILENAME may be passed as first argument. Use - for stdout. By default, the backup path is searched.`,
Usage: "Creates index database dumps and optional YAML album backups",
UsageText: `A custom database SQL dump FILENAME may be passed as first argument. Use - for stdout. The backup paths will be detected automatically if not provided.`,
Flags: backupFlags,
Action: backupAction,
}
@ -31,23 +32,23 @@ var BackupCommand = cli.Command{
var backupFlags = []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "overwrite existing backup files",
Usage: "replace existing backup files",
},
cli.BoolFlag{
Name: "albums, a",
Usage: "create album yaml file backups",
Usage: "create YAML album backups",
},
cli.StringFlag{
Name: "albums-path",
Usage: "custom album yaml file backup `PATH`",
Usage: "custom albums backup `PATH`",
},
cli.BoolFlag{
Name: "index, i",
Usage: "create index sql database backup",
Usage: "create index database SQL dump",
},
cli.StringFlag{
Name: "index-path",
Usage: "custom index sql database backup `PATH`",
Usage: "custom database backup `PATH`",
},
}
@ -168,7 +169,7 @@ func backupAction(ctx *cli.Context) error {
if !fs.PathWritable(albumsPath) {
if albumsPath != "" {
log.Warnf("custom albums backup path not writable, using default")
log.Warnf("albums backup path not writable, using default")
}
albumsPath = conf.AlbumsPath()
@ -179,7 +180,7 @@ func backupAction(ctx *cli.Context) error {
if count, err := photoprism.BackupAlbums(albumsPath, true); err != nil {
return err
} else {
log.Infof("%d albums saved as yaml files", count)
log.Infof("created %s", english.Plural(count, "YAML album backup", "YAML album backups"))
}
}

View file

@ -16,7 +16,7 @@ import (
// ConvertCommand registers the convert cli command.
var ConvertCommand = cli.Command{
Name: "convert",
Usage: "Converts media files in other formats to JPEG / AVC",
Usage: "Transcodes files in other formats to JPEG / AVC",
ArgsUsage: "[path]",
Action: convertAction,
}

View file

@ -14,7 +14,7 @@ import (
// OptimizeCommand registers the index cli command.
var OptimizeCommand = cli.Command{
Name: "optimize",
Usage: "Performs index metadata maintenance",
Usage: "Performs photo metadata maintenance",
Action: optimizeAction,
}

View file

@ -20,7 +20,7 @@ import (
// PurgeCommand registers the index cli command.
var PurgeCommand = cli.Command{
Name: "purge",
Usage: "Flags missing files, updates counts and covers",
Usage: "Updates missing files, photo counts, and album covers",
Flags: purgeFlags,
Action: purgeAction,
}

View file

@ -18,16 +18,16 @@ import (
// ResetCommand resets the index and removes sidecar files after confirmation.
var ResetCommand = cli.Command{
Name: "reset",
Usage: "Resets the index and removes sidecar files after confirmation",
Usage: "Resets the index and removes JSON / YAML sidecar files",
Action: resetAction,
}
// resetAction resets the index and removes sidecar files after confirmation.
func resetAction(ctx *cli.Context) error {
log.Warnf("'photoprism reset' resets the index and removes sidecar files after confirmation")
log.Warnf("YOU ARE ABOUT TO RESET THE INDEX AND REMOVE ALL JSON / YAML SIDECAR FILES")
removeIndexPrompt := promptui.Prompt{
Label: "Reset index database incl albums, labels, users and metadata?",
Label: "Reset index database incl all albums and metadata?",
IsConfirm: true,
}
@ -63,7 +63,7 @@ func resetAction(ctx *cli.Context) error {
}
removeSidecarJsonPrompt := promptui.Prompt{
Label: "Permanently remove all JSON photo sidecar files?",
Label: "Permanently delete existing JSON metadata sidecar files?",
IsConfirm: true,
}
@ -77,7 +77,7 @@ func resetAction(ctx *cli.Context) error {
}
if len(matches) > 0 {
log.Infof("removing %d JSON photo sidecar files", len(matches))
log.Infof("removing %d JSON metadata sidecar files", len(matches))
for _, name := range matches {
if err := os.Remove(name); err != nil {
@ -89,16 +89,16 @@ func resetAction(ctx *cli.Context) error {
fmt.Println("")
log.Infof("removed JSON sidecar files [%s]", time.Since(start))
log.Infof("removed JSON metadata sidecar files [%s]", time.Since(start))
} else {
log.Infof("found no JSON sidecar files")
log.Infof("found no JSON metadata sidecar files")
}
} else {
log.Infof("keeping JSON sidecar files")
log.Infof("keeping JSON metadata sidecar files")
}
removeSidecarYamlPrompt := promptui.Prompt{
Label: "Permanently remove all YAML photo metadata backup files?",
Label: "Permanently delete existing YAML metadata backups?",
IsConfirm: true,
}
@ -112,7 +112,7 @@ func resetAction(ctx *cli.Context) error {
}
if len(matches) > 0 {
log.Infof("%d YAML photo metadata backup files will be removed", len(matches))
log.Infof("%d YAML metadata backups will be removed", len(matches))
for _, name := range matches {
if err := os.Remove(name); err != nil {
@ -124,16 +124,16 @@ func resetAction(ctx *cli.Context) error {
fmt.Println("")
log.Infof("removed YAML photo metadata backup files [%s]", time.Since(start))
log.Infof("removed all YAML metadata backups [%s]", time.Since(start))
} else {
log.Infof("found no YAML photo metadata backup files")
log.Infof("found no YAML metadata backups")
}
} else {
log.Infof("keeping YAML photo metadata backup files")
log.Infof("keeping YAML metadata backups")
}
removeAlbumYamlPrompt := promptui.Prompt{
Label: "Permanently remove all YAML album backup files?",
Label: "Permanently delete existing YAML album backups?",
IsConfirm: true,
}
@ -159,7 +159,7 @@ func resetAction(ctx *cli.Context) error {
fmt.Println("")
log.Infof("removed YAML album backup files [%s]", time.Since(start))
log.Infof("removed all YAML album backups [%s]", time.Since(start))
} else {
log.Infof("found no YAML album backup files")
}

View file

@ -11,6 +11,8 @@ import (
"regexp"
"time"
"github.com/dustin/go-humanize/english"
"github.com/urfave/cli"
"github.com/photoprism/photoprism/internal/config"
@ -24,8 +26,8 @@ import (
// RestoreCommand configures the backup cli command.
var RestoreCommand = cli.Command{
Name: "restore",
Usage: "Restores album and index backups",
UsageText: `A custom index sql backup FILENAME may be passed as first argument. By default, the backup path is searched.`,
Usage: "Restores the index from database dumps and YAML album backups",
UsageText: `A custom database SQL dump FILENAME may be passed as first argument. The backup paths will be detected automatically if not provided.`,
Flags: restoreFlags,
Action: restoreAction,
}
@ -33,23 +35,23 @@ var RestoreCommand = cli.Command{
var restoreFlags = []cli.Flag{
cli.BoolFlag{
Name: "force, f",
Usage: "overwrite existing index",
Usage: "replace existing index",
},
cli.BoolFlag{
Name: "albums, a",
Usage: "restore album yaml file backups",
Usage: "restore albums from YAML backups",
},
cli.StringFlag{
Name: "albums-path",
Usage: "custom album yaml file backup `PATH`",
Usage: "custom albums backup `PATH`",
},
cli.BoolFlag{
Name: "index, i",
Usage: "restore index sql database backup",
Usage: "restore index from database SQL dump",
},
cli.StringFlag{
Name: "index-path",
Usage: "custom index sql database backup `PATH`",
Usage: "custom database backup `PATH`",
},
}
@ -186,7 +188,7 @@ func restoreAction(ctx *cli.Context) error {
}
}
log.Infoln("migrating database")
log.Infoln("migrating index database schema")
conf.InitDb()
@ -198,14 +200,14 @@ func restoreAction(ctx *cli.Context) error {
}
if !fs.PathExists(albumsPath) {
log.Warnf("albums path %s not found", txt.Quote(albumsPath))
log.Warnf("albums backup path %s not found", txt.Quote(albumsPath))
} else {
log.Infof("restoring albums from %s", txt.Quote(albumsPath))
if count, err := photoprism.RestoreAlbums(albumsPath, true); err != nil {
return err
} else {
log.Infof("%d albums restored from yaml files", count)
log.Infof("restored %s from YAML backups", english.Plural(count, "album", "albums"))
}
}
}

View file

@ -8,11 +8,11 @@ import (
func TestConfig_FaceSize(t *testing.T) {
c := NewConfig(CliTestContext())
assert.Equal(t, 40, c.FaceSize())
assert.Equal(t, 50, c.FaceSize())
c.options.FaceSize = 30
assert.Equal(t, 30, c.FaceSize())
c.options.FaceSize = 1
assert.Equal(t, 40, c.FaceSize())
assert.Equal(t, 50, c.FaceSize())
}
func TestConfig_FaceScore(t *testing.T) {

View file

@ -11,12 +11,12 @@ import (
var GlobalFlags = []cli.Flag{
cli.BoolFlag{
Name: "debug",
Usage: "enable debug mode, shows additional log messages",
Usage: "enable debug mode, show additional log messages",
EnvVar: "PHOTOPRISM_DEBUG",
},
cli.StringFlag{
Name: "log-level, l",
Usage: "log verbosity `LEVEL` (trace, debug, info, warning, error, fatal or panic)",
Usage: "trace, debug, info, warning, error, fatal, or panic",
Value: "info",
EnvVar: "PHOTOPRISM_LOG_LEVEL",
},
@ -26,6 +26,11 @@ var GlobalFlags = []cli.Flag{
EnvVar: "PHOTOPRISM_LOG_FILENAME",
Value: "",
},
cli.StringFlag{
Name: "pid-filename",
Usage: "process id `FILENAME` when running in daemon mode",
EnvVar: "PHOTOPRISM_PID_FILENAME",
},
cli.BoolFlag{
Name: "test",
Hidden: true,
@ -50,7 +55,7 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "admin-password",
Usage: "initial admin `PASSWORD`, min 4 characters",
Usage: "initial admin user `PASSWORD`, minimum 4 characters",
EnvVar: "PHOTOPRISM_ADMIN_PASSWORD",
},
cli.BoolFlag{
@ -70,7 +75,7 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "config-path",
Usage: "config `PATH` where settings and other config files can be found",
Usage: "config `PATH` to be searched for additional configuration and settings files",
EnvVar: "PHOTOPRISM_CONFIG_PATH",
},
cli.StringFlag{
@ -111,17 +116,17 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "backup-path",
Usage: "optional custom backup file `PATH`",
Usage: "optional custom backup `PATH` for index backup files",
EnvVar: "PHOTOPRISM_BACKUP_PATH",
},
cli.StringFlag{
Name: "assets-path",
Usage: "static assets `PATH` containing resources like icons and templates",
Usage: "assets `PATH` containing static resources like icons, models, and translations",
EnvVar: "PHOTOPRISM_ASSETS_PATH",
},
cli.IntFlag{
Name: "workers, w",
Usage: "max `NUMBER` of indexing workers",
Usage: "maximum `NUMBER` of indexing workers, default depends on the number of physical cores",
EnvVar: "PHOTOPRISM_WORKERS",
Value: cpuid.CPU.PhysicalCores / 2,
},
@ -133,13 +138,13 @@ var GlobalFlags = []cli.Flag{
},
cli.IntFlag{
Name: "auto-index",
Usage: "WebDAV auto indexing safety delay in `SECONDS` (-1 to disable)",
Usage: "WebDAV auto indexing safety delay in `SECONDS`, disable with -1",
Value: DefaultAutoIndexDelay,
EnvVar: "PHOTOPRISM_AUTO_INDEX",
},
cli.IntFlag{
Name: "auto-import",
Usage: "WebDAV auto import safety delay in `SECONDS` (-1 to disable)",
Usage: "WebDAV auto import safety delay in `SECONDS`, disable with -1",
Value: DefaultAutoImportDelay,
EnvVar: "PHOTOPRISM_AUTO_IMPORT",
},
@ -148,11 +153,6 @@ var GlobalFlags = []cli.Flag{
Usage: "disable built-in WebDAV server",
EnvVar: "PHOTOPRISM_DISABLE_WEBDAV",
},
cli.BoolFlag{
Name: "disable-backups",
Usage: "disable creating YAML metadata backup sidecar files",
EnvVar: "PHOTOPRISM_DISABLE_BACKUPS",
},
cli.BoolFlag{
Name: "disable-settings",
Usage: "disable settings UI and API",
@ -163,34 +163,39 @@ var GlobalFlags = []cli.Flag{
Usage: "disable reverse geocoding and maps",
EnvVar: "PHOTOPRISM_DISABLE_PLACES",
},
cli.BoolFlag{
Name: "disable-backups",
Usage: "disable creating YAML metadata backup files",
EnvVar: "PHOTOPRISM_DISABLE_BACKUPS",
},
cli.BoolFlag{
Name: "disable-exiftool",
Usage: "disable metadata extraction with ExifTool",
Usage: "disable creating JSON metadata sidecar files with ExifTool",
EnvVar: "PHOTOPRISM_DISABLE_EXIFTOOL",
},
cli.BoolFlag{
Name: "disable-ffmpeg",
Usage: "disable video transcoding and thumbnail generation with FFmpeg",
Usage: "disable video transcoding and still image extraction with FFmpeg",
EnvVar: "PHOTOPRISM_DISABLE_FFMPEG",
},
cli.BoolFlag{
Name: "disable-darktable",
Usage: "disable RAW file conversion with Darktable",
Usage: "disable converting RAW files with Darktable",
EnvVar: "PHOTOPRISM_DISABLE_DARKTABLE",
},
cli.BoolFlag{
Name: "disable-rawtherapee",
Usage: "disable RAW file conversion with RawTherapee",
Usage: "disable converting RAW files with RawTherapee",
EnvVar: "PHOTOPRISM_DISABLE_RAWTHERAPEE",
},
cli.BoolFlag{
Name: "disable-sips",
Usage: "disable RAW file conversion with Sips on macOS",
Usage: "disable converting RAW files with Sips (macOS only)",
EnvVar: "PHOTOPRISM_DISABLE_SIPS",
},
cli.BoolFlag{
Name: "disable-heifconvert",
Usage: "disable HEIC/HEIF file conversion",
Usage: "disable converting HEIC/HEIF files",
EnvVar: "PHOTOPRISM_DISABLE_HEIFCONVERT",
},
cli.BoolFlag{
@ -220,7 +225,7 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "cdn-url",
Usage: "optional content delivery network `URL` (optional)",
Usage: "optional content delivery network `URL`",
EnvVar: "PHOTOPRISM_CDN_URL",
},
cli.StringFlag{
@ -229,14 +234,9 @@ var GlobalFlags = []cli.Flag{
Value: "http://localhost:2342/",
EnvVar: "PHOTOPRISM_SITE_URL",
},
cli.StringFlag{
Name: "site-preview",
Usage: "custom site preview image `URL`",
EnvVar: "PHOTOPRISM_SITE_PREVIEW",
},
cli.StringFlag{
Name: "site-author",
Usage: "site owner or `COPYRIGHT`",
Usage: "site `COPYRIGHT`, artist, or owner name",
EnvVar: "PHOTOPRISM_SITE_AUTHOR",
},
cli.StringFlag{
@ -253,9 +253,14 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "site-description",
Usage: "site `DESCRIPTION`",
Usage: "optional site `DESCRIPTION`",
EnvVar: "PHOTOPRISM_SITE_DESCRIPTION",
},
cli.StringFlag{
Name: "site-preview",
Usage: "optional preview image `URL`",
EnvVar: "PHOTOPRISM_SITE_PREVIEW",
},
cli.IntFlag{
Name: "http-port",
Value: 2342,
@ -274,7 +279,7 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "http-compression, z",
Usage: "http compression `METHOD` (none or gzip)",
Usage: "http server compression `METHOD` (none or gzip)",
EnvVar: "PHOTOPRISM_HTTP_COMPRESSION",
},
cli.StringFlag{
@ -285,12 +290,12 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "database-dsn",
Usage: "sqlite file name, specifying a `DSN` is optional other drivers",
Usage: "sqlite file name, providing a `DSN` is optional for other drivers",
EnvVar: "PHOTOPRISM_DATABASE_DSN",
},
cli.StringFlag{
Name: "database-server",
Usage: "database server `HOST` and port e.g. mysql:3306",
Usage: "database server `HOST` with optional port e.g. mysql:3306",
EnvVar: "PHOTOPRISM_DATABASE_SERVER",
},
cli.StringFlag{
@ -312,12 +317,12 @@ var GlobalFlags = []cli.Flag{
},
cli.IntFlag{
Name: "database-conns",
Usage: "max `NUMBER` of open database connections",
Usage: "maximum `NUMBER` of open database connections",
EnvVar: "PHOTOPRISM_DATABASE_CONNS",
},
cli.IntFlag{
Name: "database-conns-idle",
Usage: "max `NUMBER` of idle database connections",
Usage: "maximum `NUMBER` of idle database connections",
EnvVar: "PHOTOPRISM_DATABASE_CONNS_IDLE",
},
cli.BoolFlag{
@ -351,7 +356,7 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "sips-bin",
Usage: "Sips `COMMAND` for RAW file conversion on macOS",
Usage: "Sips `COMMAND` for RAW file conversion (macOS only)",
Value: "sips",
EnvVar: "PHOTOPRISM_SIPS_BIN",
},
@ -363,7 +368,7 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "ffmpeg-bin",
Usage: "FFmpeg `COMMAND` for video transcoding and cover images",
Usage: "FFmpeg `COMMAND` for video transcoding and still image extraction",
Value: "ffmpeg",
EnvVar: "PHOTOPRISM_FFMPEG_BIN",
},
@ -375,7 +380,7 @@ var GlobalFlags = []cli.Flag{
},
cli.IntFlag{
Name: "ffmpeg-bitrate",
Usage: "max FFmpeg encoding `BITRATE` (Mbit/s)",
Usage: "maximum FFmpeg encoding `BITRATE` (Mbit/s)",
Value: 50,
EnvVar: "PHOTOPRISM_FFMPEG_BITRATE",
},
@ -393,12 +398,12 @@ var GlobalFlags = []cli.Flag{
},
cli.StringFlag{
Name: "download-token",
Usage: "custom download URL `TOKEN` (generated automatically by default)",
Usage: "custom download URL `TOKEN` (default: random)",
EnvVar: "PHOTOPRISM_DOWNLOAD_TOKEN",
},
cli.StringFlag{
Name: "preview-token",
Usage: "custom thumbnail and streaming URL `TOKEN` (generated automatically by default)",
Usage: "custom thumbnail and streaming URL `TOKEN` (default: random)",
EnvVar: "PHOTOPRISM_PREVIEW_TOKEN",
},
cli.StringFlag{
@ -409,7 +414,7 @@ var GlobalFlags = []cli.Flag{
},
cli.IntFlag{
Name: "thumb-size, s",
Usage: "max pre-cached thumbnail size in `PIXELS` (720-7680)",
Usage: "maximum pre-cached thumbnail image size in `PIXELS` (720-7680)",
Value: 2048,
EnvVar: "PHOTOPRISM_THUMB_SIZE",
},
@ -420,31 +425,31 @@ var GlobalFlags = []cli.Flag{
},
cli.IntFlag{
Name: "thumb-size-uncached, x",
Usage: "max on-demand thumbnail size in `PIXELS` (720-7680)",
Usage: "maximum size of on-demand generated thumbnails in `PIXELS` (720-7680)",
Value: 7680,
EnvVar: "PHOTOPRISM_THUMB_SIZE_UNCACHED",
},
cli.IntFlag{
Name: "jpeg-size",
Usage: "max size of generated JPEG files in `PIXELS` (720-30000)",
Usage: "maximum size of generated JPEG images in `PIXELS` (720-30000)",
Value: 7680,
EnvVar: "PHOTOPRISM_JPEG_SIZE",
},
cli.IntFlag{
Name: "jpeg-quality, q",
Usage: "`QUALITY` of generated JPEG files, a higher value reduces compression (25-100)",
Usage: "`QUALITY` of generated JPEG images, a higher value reduces compression (25-100)",
Value: 92,
EnvVar: "PHOTOPRISM_JPEG_QUALITY",
},
cli.IntFlag{
Name: "face-size",
Usage: "min face size in `PIXELS`",
Usage: "minimum face size in `PIXELS`",
Value: face.SizeThreshold,
EnvVar: "PHOTOPRISM_FACE_SIZE",
},
cli.Float64Flag{
Name: "face-score",
Usage: "quality `THRESHOLD` for faces",
Usage: "minimum face `QUALITY` score",
Value: face.ScoreThreshold,
EnvVar: "PHOTOPRISM_FACE_SCORE",
},
@ -456,13 +461,13 @@ var GlobalFlags = []cli.Flag{
},
cli.IntFlag{
Name: "face-cluster-size",
Usage: "min size of faces forming a cluster in `PIXELS`",
Usage: "minimum size of automatically clustered faces in `PIXELS`",
Value: face.ClusterSizeThreshold,
EnvVar: "PHOTOPRISM_FACE_CLUSTER_SIZE",
},
cli.IntFlag{
Name: "face-cluster-score",
Usage: "quality `THRESHOLD` for faces forming a cluster",
Usage: "minimum `QUALITY` score of automatically clustered faces",
Value: face.ClusterScoreThreshold,
EnvVar: "PHOTOPRISM_FACE_CLUSTER_SCORE",
},
@ -484,11 +489,6 @@ var GlobalFlags = []cli.Flag{
Value: face.MatchDist,
EnvVar: "PHOTOPRISM_FACE_MATCH_DIST",
},
cli.StringFlag{
Name: "pid-filename",
Usage: "daemon process id `FILENAME`",
EnvVar: "PHOTOPRISM_PID_FILENAME",
},
cli.StringFlag{
Name: "client-id",
Usage: "OpenID Connect Client ID",

View file

@ -221,12 +221,12 @@ func (c *Config) ExifToolBin() string {
return findExecutable(c.options.ExifToolBin, "exiftool")
}
// Automatically create JSON sidecar files using Exiftool.
// ExifToolJson tests if creating JSON metadata sidecar files with Exiftool is enabled.
func (c *Config) ExifToolJson() bool {
return !c.DisableExifTool()
}
// Automatically backup metadata to YAML sidecar files.
// BackupYaml tests if creating YAML backups is enabled.
func (c *Config) BackupYaml() bool {
return !c.DisableBackups()
}

View file

@ -26,7 +26,7 @@ var thumbFileNames = []string{
"%s_7680x4320_fit.jpg",
}
// Usable thumb file sizes.
// Suitable thumb file sizes.
var thumbFileSizes = []thumb.Size{
thumb.Sizes[thumb.Fit720],
thumb.Sizes[thumb.Fit1280],

View file

@ -54,6 +54,11 @@ func NewFace(subjUID, faceSrc string, embeddings face.Embeddings) *Face {
return result
}
// Unsuitable tests if the face is unsuitable for clustering and matching.
func (m *Face) Unsuitable() bool {
return m.Embedding().Unsuitable()
}
// SetEmbeddings assigns face embeddings.
func (m *Face) SetEmbeddings(embeddings face.Embeddings) (err error) {
m.embedding, m.SampleRadius, m.Samples = face.EmbeddingsMidpoint(embeddings)

File diff suppressed because one or more lines are too long

View file

@ -506,6 +506,8 @@ func (m *Marker) Face() (f *Face) {
} else if f = NewFace(m.SubjUID, m.SubjSrc, emb); f == nil {
log.Warnf("marker %s: failed assigning face", txt.Quote(m.MarkerUID))
return nil
} else if f.Unsuitable() {
log.Infof("marker %s: face %s is unsuitable for clustering and matching", txt.Quote(m.MarkerUID), f.ID)
} else if f = FirstOrCreateFace(f); f == nil {
log.Warnf("marker %s: failed assigning face", txt.Quote(m.MarkerUID))
return nil

File diff suppressed because one or more lines are too long

10
internal/face/children.go Normal file

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -86,7 +86,7 @@ func Detect(fileName string, findLandmarks bool, minSize int) (faces Faces, err
angle: 0.0,
shiftFactor: 0.1,
scaleFactor: 1.1,
iouThreshold: 0.2,
iouThreshold: float64(OverlapThresholdFloor) / 100,
scoreThreshold: float32(ScoreThreshold),
perturb: 63,
}

View file

@ -26,27 +26,37 @@ func NewEmbedding(inference []float32) Embedding {
return result
}
// Blacklisted tests if the embedding is blacklisted.
// Blacklisted tests if the face embedding is blacklisted.
func (m Embedding) Blacklisted() bool {
return Blacklist.Contains(m, BlacklistRadius)
}
// Distance calculates the distance to another embedding.
// Child tests if the face embedding belongs to a child.
func (m Embedding) Child() bool {
return Children.Contains(m, ChildrenRadius)
}
// Unsuitable tests if the face embedding is unsuitable for clustering and matching.
func (m Embedding) Unsuitable() bool {
return m.Child() || m.Blacklisted()
}
// Distance calculates the distance to another face embedding.
func (m Embedding) Distance(other Embedding) float64 {
return clusters.EuclideanDistance(m, other)
}
// Magnitude returns the embedding vector length (magnitude).
// Magnitude returns the face embedding vector length (magnitude).
func (m Embedding) Magnitude() float64 {
return m.Distance(NullEmbedding)
}
// NotBlacklisted tests if the embedding is not blacklisted.
// NotBlacklisted tests if the face embedding is not blacklisted.
func (m Embedding) NotBlacklisted() bool {
return !m.Blacklisted()
}
// JSON returns the embedding as JSON bytes.
// JSON returns the face embedding as JSON bytes.
func (m Embedding) JSON() []byte {
var noResult = []byte("")

File diff suppressed because one or more lines are too long

View file

@ -52,6 +52,15 @@ func (embeddings Embeddings) One() bool {
return embeddings.Count() == 1
}
// First returns the first face embedding.
func (embeddings Embeddings) First() Embedding {
if embeddings.Empty() {
return NullEmbedding
}
return embeddings[0]
}
// Float64 returns embeddings as a float64 slice.
func (embeddings Embeddings) Float64() [][]float64 {
result := make([][]float64, len(embeddings))

File diff suppressed because one or more lines are too long

View file

@ -130,6 +130,6 @@ func TestNet(t *testing.T) {
t.Logf("Correct for %d", correct)
// there are a few incorrect results
// 4 out of 55 with the 1.21 threshold
assert.Equal(t, 51, correct)
// 3 out of 55 with the 1.21 threshold
assert.Equal(t, 52, correct)
}

View file

@ -9,7 +9,7 @@ var OverlapThreshold = 42 // Face area overlap threshold
var OverlapThresholdFloor = OverlapThreshold - 1 // Reduced overlap area to avoid rounding inconsistencies.
var ScoreThreshold = 9.0 // Min face score.
var ClusterScoreThreshold = 15 // Min score for faces forming a cluster.
var SizeThreshold = 40 // Min face size in pixels.
var SizeThreshold = 50 // Min face size in pixels.
var ClusterSizeThreshold = 80 // Min size for faces forming a cluster in pixels.
var ClusterDist = 0.64 // Similarity distance threshold of faces forming a cluster core.
var MatchDist = 0.46 // Distance offset threshold for matching new faces with clusters.

View file

@ -73,6 +73,8 @@ func (w *Faces) Cluster(opt FacesOptions) (added entity.Faces, err error) {
for _, cluster := range results {
if f := entity.NewFace("", entity.SrcAuto, cluster); f == nil {
log.Errorf("faces: face should not be nil - bug?")
} else if f.Unsuitable() {
log.Infof("faces: ignoring %s, cluster unsuitable for matching", f.ID)
} else if err := f.Create(); err == nil {
added = append(added, *f)
log.Debugf("faces: added cluster %s based on %s, radius %f", f.ID, english.Plural(f.Samples, "sample", "samples"), f.SampleRadius)