|
@ -1,18 +1,17 @@
|
|||
/assets/photos/*
|
||||
/assets/cache/*
|
||||
/photos/*
|
||||
/frontend/node_modules/*
|
||||
/node_modules
|
||||
/assets/resources/database/*
|
||||
/assets/resources/static/build/*
|
||||
/assets/resources/nasnet
|
||||
/assets/resources/nsfw
|
||||
/assets/testdata
|
||||
/assets/backups
|
||||
Dockerfile
|
||||
/assets/static/build/*
|
||||
/assets/nasnet
|
||||
/assets/nsfw
|
||||
/storage
|
||||
/photoprism
|
||||
docker-compose*
|
||||
/coverage.*
|
||||
/frontend/tests/acceptance/screenshots
|
||||
.dockerignore
|
||||
.idea
|
||||
.DS_Store
|
||||
/frontend/tests/acceptance/screenshots
|
||||
*.db
|
||||
*.db-journal
|
||||
Dockerfile
|
||||
docker-compose*
|
||||
|
|
17
.gitignore
vendored
|
@ -1,22 +1,21 @@
|
|||
# Application files and directories
|
||||
/photoprism
|
||||
/assets/photos/originals/*
|
||||
/assets/photos/import/*
|
||||
/assets/photos/export/*
|
||||
/assets/resources/database/*
|
||||
!/assets/resources/database/.gitignore
|
||||
/photos/originals/*
|
||||
/photos/import/*
|
||||
/storage/*
|
||||
/node_modules
|
||||
/frontend/.eslintcache
|
||||
/frontend/node_modules/*
|
||||
/frontend/tests/*.html
|
||||
/frontend/tests/*.log
|
||||
/frontend/tests/screenshots
|
||||
/assets/testdata
|
||||
/assets/backups
|
||||
/assets/resources/nasnet
|
||||
/assets/resources/nsfw
|
||||
/assets/nasnet
|
||||
/assets/nsfw
|
||||
/package-lock.json
|
||||
/frontend/tests_output
|
||||
*.log
|
||||
*.db
|
||||
*.db-journal
|
||||
|
||||
# Binaries for programs and plugins
|
||||
*.exe
|
||||
|
|
|
@ -19,7 +19,7 @@ Of all the tools we tested, Twitter works best to get and give continuous feedba
|
|||
|
||||
Issues labeled [help wanted](https://github.com/photoprism/photoprism/labels/help%20wanted) /
|
||||
[easy](https://github.com/photoprism/photoprism/labels/easy) can be good (first) contributions.
|
||||
Our [Developer Guide](https://docs.photoprism.org/en/latest/developer-guide/) contains all information necessary to get you started.
|
||||
Our [Developer Guide](https://docs.photoprism.org/developer-guide/) contains all information necessary to get you started.
|
||||
|
||||
Our [step-by-step guide](https://github.com/photoprism/photoprism/wiki/Pull-Requests) explains how to submit new features, bugfixes and documentation.
|
||||
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
FROM photoprism/development:20200509
|
||||
FROM photoprism/development:20200721
|
||||
|
||||
# Set up project directory
|
||||
WORKDIR "/go/src/github.com/photoprism/photoprism"
|
||||
|
|
148
LICENSE
|
@ -1,5 +1,5 @@
|
|||
GNU GENERAL PUBLIC LICENSE
|
||||
Version 3, 29 June 2007
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
|
@ -7,17 +7,15 @@
|
|||
|
||||
Preamble
|
||||
|
||||
The GNU General Public License is a free, copyleft license for
|
||||
software and other kinds of works.
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
the GNU General Public License is intended to guarantee your freedom to
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users. We, the Free Software Foundation, use the
|
||||
GNU General Public License for most of our software; it applies also to
|
||||
any other work released this way by its authors. You can apply it to
|
||||
your programs, too.
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
|
@ -26,44 +24,34 @@ them if you wish), that you receive source code or can get it if you
|
|||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
To protect your rights, we need to prevent others from denying you
|
||||
these rights or asking you to surrender the rights. Therefore, you have
|
||||
certain responsibilities if you distribute copies of the software, or if
|
||||
you modify it: responsibilities to respect the freedom of others.
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
For example, if you distribute copies of such a program, whether
|
||||
gratis or for a fee, you must pass on to the recipients the same
|
||||
freedoms that you received. You must make sure that they, too, receive
|
||||
or can get the source code. And you must show them these terms so they
|
||||
know their rights.
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
Developers that use the GNU GPL protect your rights with two steps:
|
||||
(1) assert copyright on the software, and (2) offer you this License
|
||||
giving you legal permission to copy, distribute and/or modify it.
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
For the developers' and authors' protection, the GPL clearly explains
|
||||
that there is no warranty for this free software. For both users' and
|
||||
authors' sake, the GPL requires that modified versions be marked as
|
||||
changed, so that their problems will not be attributed erroneously to
|
||||
authors of previous versions.
|
||||
|
||||
Some devices are designed to deny users access to install or run
|
||||
modified versions of the software inside them, although the manufacturer
|
||||
can do so. This is fundamentally incompatible with the aim of
|
||||
protecting users' freedom to change the software. The systematic
|
||||
pattern of such abuse occurs in the area of products for individuals to
|
||||
use, which is precisely where it is most unacceptable. Therefore, we
|
||||
have designed this version of the GPL to prohibit the practice for those
|
||||
products. If such problems arise substantially in other domains, we
|
||||
stand ready to extend this provision to those domains in future versions
|
||||
of the GPL, as needed to protect the freedom of users.
|
||||
|
||||
Finally, every program is threatened constantly by software patents.
|
||||
States should not allow patents to restrict development and use of
|
||||
software on general-purpose computers, but in those that do, we wish to
|
||||
avoid the special danger that patents applied to a free program could
|
||||
make it effectively proprietary. To prevent this, the GPL assures that
|
||||
patents cannot be used to render the program non-free.
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
@ -72,7 +60,7 @@ modification follow.
|
|||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU General Public License.
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
@ -549,35 +537,45 @@ to collect a royalty for further conveying from those to whom you convey
|
|||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Use with the GNU Affero General Public License.
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU Affero General Public License into a single
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the special requirements of the GNU Affero General Public License,
|
||||
section 13, concerning interaction through a network will apply to the
|
||||
combination as such.
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU General Public License from time to time. Such new versions will
|
||||
be similar in spirit to the present version, but may differ in detail to
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU General
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU General Public License, you may choose any version ever published
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU General Public License can be used, that proxy's
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
|
@ -635,40 +633,36 @@ the "copyright" line and a pointer to where the full notice is found.
|
|||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If the program does terminal interaction, make it output a short
|
||||
notice like this when it starts in an interactive mode:
|
||||
|
||||
<program> Copyright (C) <year> <name of author>
|
||||
This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||
This is free software, and you are welcome to redistribute it
|
||||
under certain conditions; type `show c' for details.
|
||||
|
||||
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||
parts of the General Public License. Of course, your program's commands
|
||||
might be different; for a GUI interface, you would use an "about box".
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU GPL, see
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
|
||||
The GNU General Public License does not permit incorporating your program
|
||||
into proprietary programs. If your program is a subroutine library, you
|
||||
may consider it more useful to permit linking proprietary applications with
|
||||
the library. If this is what you want to do, use the GNU Lesser General
|
||||
Public License instead of this License. But first, please read
|
||||
<https://www.gnu.org/licenses/why-not-lgpl.html>.
|
||||
Trademarks
|
||||
|
||||
PhotoPrism™ is a registered trademark of Michael Mayer. You may use it
|
||||
as required to describe our software, run your own server, for educational
|
||||
purposes, but not for offering commercial goods, products, or services
|
||||
without prior written permission. In other words, please ask.
|
||||
|
|
69
Makefile
|
@ -14,13 +14,29 @@ all: dep build
|
|||
dep: dep-tensorflow dep-js dep-go
|
||||
build: generate build-js build-go
|
||||
install: install-bin install-assets
|
||||
test: reset-test-db test-js test-go
|
||||
acceptance-all: start acceptance acceptance-firefox stop
|
||||
test: test-js test-go
|
||||
test-go: reset-test-db run-test-go
|
||||
test-short: reset-test-db run-test-short
|
||||
acceptance-all: acceptance-start acceptance-firefox acceptance-restart acceptance stop
|
||||
test-all: test acceptance-all
|
||||
fmt: fmt-js fmt-go
|
||||
upgrade: dep-upgrade-js dep-upgrade
|
||||
clean-local: clean-local-config clean-local-share clean-local-cache
|
||||
clean-install: clean-local dep build-js install-bin install-assets
|
||||
acceptance-start:
|
||||
go run cmd/photoprism/photoprism.go --public --database-driver sqlite --database-dsn ./storage/acceptance/index.db --import-path ./storage/acceptance/import --http-port=2343 --settings-path ./storage/acceptance/settings --originals-path ./storage/acceptance/originals --sidecar-hidden=false --sidecar-json=false --sidecar-yaml=false start -d
|
||||
acceptance-restart:
|
||||
go run cmd/photoprism/photoprism.go stop
|
||||
cp -f storage/acceptance/backup.db storage/acceptance/index.db
|
||||
cp -f storage/acceptance/settings/settingsBackup.yml storage/acceptance/settings/settings.yml
|
||||
rm -rf storage/acceptance/originals/2010
|
||||
rm -rf storage/acceptance/originals/2013
|
||||
go run cmd/photoprism/photoprism.go --public --database-driver sqlite --database-dsn ./storage/acceptance/index.db --import-path ./storage/acceptance/import --http-port=2343 --settings-path ./storage/acceptance/settings --originals-path ./storage/acceptance/originals --sidecar-hidden=false --sidecar-json=false --sidecar-yaml=false start -d
|
||||
acceptance-restore-db:
|
||||
cp -f storage/acceptance/settings/settingsBackup.yml storage/acceptance/settings/settings.yml
|
||||
cp -f storage/acceptance/backup.db storage/acceptance/index.db
|
||||
rm -rf storage/acceptance/originals/2010
|
||||
rm -rf storage/acceptance/originals/2013
|
||||
start:
|
||||
go run cmd/photoprism/photoprism.go start -d
|
||||
stop:
|
||||
|
@ -36,20 +52,20 @@ install-bin:
|
|||
scripts/build.sh prod ~/.local/bin/$(BINARY_NAME)
|
||||
install-assets:
|
||||
$(info Installing assets)
|
||||
mkdir -p ~/.config/photoprism
|
||||
mkdir -p ~/.cache/photoprism
|
||||
mkdir -p ~/.photoprism/storage/settings
|
||||
mkdir -p ~/.photoprism/storage/cache
|
||||
mkdir -p ~/.photoprism/storage
|
||||
mkdir -p ~/.photoprism/assets
|
||||
mkdir -p ~/Pictures/Originals
|
||||
mkdir -p ~/Pictures/Import
|
||||
mkdir -p ~/.local/share/photoprism/resources/database
|
||||
cp -r assets/resources/static assets/resources/templates assets/resources/nasnet assets/resources/nsfw ~/.local/share/photoprism/resources
|
||||
rsync -a -v --ignore-existing assets/config/*.yml ~/.config/photoprism
|
||||
find ~/.local/share/photoprism -name '.*' -type f -delete
|
||||
clean-local-share:
|
||||
rm -rf ~/.local/share/photoprism
|
||||
cp -r assets/static assets/templates assets/nasnet assets/nsfw ~/.photoprism/assets
|
||||
find ~/.photoprism/assets -name '.*' -type f -delete
|
||||
clean-local-assets:
|
||||
rm -rf ~/.photoprism/assets/*
|
||||
clean-local-cache:
|
||||
rm -rf ~/.cache/photoprism
|
||||
rm -rf ~/.photoprism/storage/cache/*
|
||||
clean-local-config:
|
||||
rm -f ~/.config/photoprism/*
|
||||
rm -f ~/.photoprism/storage/settings/*
|
||||
dep-js:
|
||||
(cd frontend && npm install --silent)
|
||||
dep-go:
|
||||
|
@ -62,14 +78,17 @@ dep-tensorflow:
|
|||
scripts/download-nasnet.sh
|
||||
scripts/download-nsfw.sh
|
||||
zip-nasnet:
|
||||
(cd assets/resources && zip -r nasnet.zip nasnet -x "*/.*" -x "*/version.txt")
|
||||
(cd assets && zip -r nasnet.zip nasnet -x "*/.*" -x "*/version.txt")
|
||||
zip-nsfw:
|
||||
(cd assets/resources && zip -r nsfw.zip nsfw -x "*/.*" -x "*/version.txt")
|
||||
(cd assets && zip -r nsfw.zip nsfw -x "*/.*" -x "*/version.txt")
|
||||
build-js:
|
||||
(cd frontend && env NODE_ENV=production npm run build)
|
||||
build-go:
|
||||
rm -f $(BINARY_NAME)
|
||||
scripts/build.sh debug $(BINARY_NAME)
|
||||
build-race:
|
||||
rm -f $(BINARY_NAME)
|
||||
scripts/build.sh race $(BINARY_NAME)
|
||||
build-static:
|
||||
rm -f $(BINARY_NAME)
|
||||
scripts/build.sh static $(BINARY_NAME)
|
||||
|
@ -86,13 +105,21 @@ test-js:
|
|||
(cd frontend && env NODE_ENV=development BABEL_ENV=test npm run test)
|
||||
acceptance:
|
||||
$(info Running JS acceptance tests in Chrome...)
|
||||
(cd frontend && npm run acceptance)
|
||||
(cd frontend && npm run acceptance && cd ..)
|
||||
acceptance-firefox:
|
||||
$(info Running JS acceptance tests in Firefox...)
|
||||
(cd frontend && npm run acceptance-firefox)
|
||||
(cd frontend && npm run acceptance-firefox && cd ..)
|
||||
reset-photoprism-db:
|
||||
$(info Purging photoprism database...)
|
||||
mysql < scripts/reset-photoprism-db.sql
|
||||
reset-test-db:
|
||||
$(info Purging test databases...)
|
||||
mysql < scripts/reset-test-db.sql
|
||||
test-go:
|
||||
find ./internal -type f -name '.test.*' -delete
|
||||
run-test-short:
|
||||
$(info Running short Go unit tests in parallel mode...)
|
||||
$(GOTEST) -parallel 2 -count 1 -cpu 2 -short -timeout 5m ./pkg/... ./internal/...
|
||||
run-test-go:
|
||||
$(info Running all Go unit tests...)
|
||||
$(GOTEST) -parallel 1 -count 1 -cpu 1 -tags slow -timeout 20m ./pkg/... ./internal/...
|
||||
test-parallel:
|
||||
|
@ -101,9 +128,6 @@ test-parallel:
|
|||
test-verbose:
|
||||
$(info Running all Go unit tests in verbose mode...)
|
||||
$(GOTEST) -parallel 1 -count 1 -cpu 1 -tags slow -timeout 20m -v ./pkg/... ./internal/...
|
||||
test-short:
|
||||
$(info Running short Go unit tests in parallel mode...)
|
||||
$(GOTEST) -parallel 2 -count 1 -cpu 2 -short -timeout 5m ./pkg/... ./internal/...
|
||||
test-race:
|
||||
$(info Running all Go unit tests with race detection in verbose mode...)
|
||||
$(GOTEST) -tags slow -race -timeout 60m -v ./pkg/... ./internal/...
|
||||
|
@ -119,8 +143,9 @@ clean:
|
|||
rm -f $(BINARY_NAME)
|
||||
rm -f *.log
|
||||
rm -rf node_modules
|
||||
rm -rf assets/testdata
|
||||
rm -rf assets/backups
|
||||
rm -rf storage/testdata
|
||||
rm -rf storage/backups
|
||||
rm -rf storage/cache
|
||||
rm -rf frontend/node_modules
|
||||
docker-development:
|
||||
scripts/docker-build.sh development $(DOCKER_TAG)
|
||||
|
|
107
README.md
|
@ -1,74 +1,60 @@
|
|||
PhotoPrism: Browse your life in pictures
|
||||
PhotoPrism: Browse Your Life in Pictures
|
||||
========================================
|
||||
|
||||
[![License: GPL](https://img.shields.io/badge/license-GPL-blue.svg)][license]
|
||||
[![License: AGPL](https://img.shields.io/badge/license-AGPL-blue.svg)][license]
|
||||
[![Code Quality](https://goreportcard.com/badge/github.com/photoprism/photoprism)][goreport]
|
||||
[![Build Status](https://travis-ci.org/photoprism/photoprism.png?branch=develop)][ci]
|
||||
[![Documentation](https://readthedocs.org/projects/photoprism-docs/badge/?version=latest&style=flat)][docs]
|
||||
[![GitHub contributors](https://img.shields.io/github/contributors/photoprism/photoprism.svg)](https://github.com/photoprism/photoprism/graphs/contributors/)
|
||||
[![Documentation](https://img.shields.io/badge/read-the%20docs-4aa087.svg)][docs]
|
||||
[![Community Chat](https://img.shields.io/badge/chat-on%20gitter-4aa087.svg)][chat]
|
||||
[![Twitter](https://img.shields.io/badge/follow-@browseyourlife-00acee.svg)][twitter]
|
||||
|
||||
PhotoPrism is a server-based application for browsing, organizing and sharing your personal photo collection.
|
||||
PhotoPrism™ is a server-based application for browsing, organizing and sharing your personal photo collection.
|
||||
It makes use of the latest technologies to automatically tag and find pictures without getting in your way.
|
||||
Say goodbye to solutions that force you to upload your visual memories to the cloud.
|
||||
|
||||
![](https://dl.photoprism.org/assets/img/preview.jpg)
|
||||
|
||||
More screenshots: https://github.com/photoprism/photoprism/wiki/Screenshots
|
||||
## What to expect... ##
|
||||
|
||||
## What to expect ##
|
||||
|
||||
* Clearly structured Web interface for browsing, organizing and sharing your personal photo collection
|
||||
* Import everything without worrying about duplicates or [RAW to JPEG conversion][wiki:raw]
|
||||
* [Geocoding][wiki:geocoding], [XMP support][wiki:xmp] and [automated tagging][wiki:classification]
|
||||
* clearly structured Web interface for browsing, organizing and sharing your personal photo collection
|
||||
* import everything without worrying about duplicates or [RAW to JPEG conversion](https://docs.photoprism.org/developer-guide/library/converting/)
|
||||
* [geocoding](https://docs.photoprism.org/developer-guide/metadata/geocoding/), [XMP support](https://docs.photoprism.org/developer-guide/metadata/xmp/) and [automated tagging](https://docs.photoprism.org/developer-guide/metadata/classification/)
|
||||
based on Google TensorFlow
|
||||
|
||||
## Try our demo ##
|
||||
|
||||
You're welcome to play with the demo at [demo.photoprism.org](https://demo.photoprism.org).
|
||||
Leave your email to get a [release notification](https://goo.gl/forms/KBPVGl9PCsOKrAv33).
|
||||
|
||||
## For the early birds ##
|
||||
|
||||
You're welcome to play with our demo at [demo.photoprism.org](https://demo.photoprism.org).
|
||||
Leave your email to get a [release notification](https://goo.gl/forms/KBPVGl9PCsOKrAv33).
|
||||
Step-by-step installation instructions can be found on [docs.photoprism.org](https://docs.photoprism.org/getting-started/) -
|
||||
all you need is a Web browser and Docker to run the server. It is available for Mac, Linux and Windows.
|
||||
|
||||
Step-by-step [installation instructions](https://docs.photoprism.org/en/latest/getting-started/) can be found
|
||||
in our [User Guide](https://docs.photoprism.org/en/latest/).
|
||||
Developers can skip this and move on to the [Developer Guide](https://docs.photoprism.org/en/latest/developer-guide/).
|
||||
Next, you'll have to [index or import](https://docs.photoprism.org/user-guide/library/import-vs-index/)
|
||||
existing files. Please be patient, this will take a while depending on the size of your library.
|
||||
|
||||
All you need is a Web browser and [Docker](https://store.docker.com/search?type=edition&offering=community)
|
||||
to run the server. It is available for Mac, Linux and Windows.
|
||||
Already indexed photos can be browsed in [Photos](https://docs.photoprism.org/user-guide/organize/browse/)
|
||||
while videos show up in [Videos](https://docs.photoprism.org/user-guide/organize/video/).
|
||||
Counts are continuously updated in the navigation.
|
||||
|
||||
There is also a [pre-installed Raspberry Pi image here](https://github.com/guysoft/PhotoPrismPi).
|
||||
If photos are missing, they might be in [review](https://docs.photoprism.org/user-guide/organize/review/) due to low quality or missing metadata.
|
||||
You can turn this and other features off in [Settings](https://docs.photoprism.org/user-guide/settings/ui/), depending on
|
||||
your specific use case.
|
||||
|
||||
Note that this is work in progress. We do our best to provide a complete, stable version.
|
||||
If you have a question, don't hesitate to ask in our [help forum][help]
|
||||
or [contact us via email](mailto:hello@photoprism.org).
|
||||
|
||||
## Why this has to be free software ##
|
||||
|
||||
The development of every commercial product is focused on monetization.
|
||||
We've [built similar apps more than once](https://github.com/photoprism/photoprism/wiki/Mediencenter)
|
||||
and every single time the constraints of working
|
||||
in a profit-oriented corporate environment were an impediment.
|
||||
|
||||
We are sure we can do better with only a fraction of the budget. Simplicity - the art of maximizing the
|
||||
amount of work not done - can be very powerful.
|
||||
Go itself is a [great example](https://talks.golang.org/2015/simplicity-is-complicated.slide).
|
||||
|
||||
Our long-term goal is to become an open platform for machine
|
||||
learning [research](https://github.com/photoprism/photoprism/wiki/Research) based on real-world photo collections.
|
||||
We're already in contact with data scientists who like our idea.
|
||||
|
||||
## How to contribute ##
|
||||
## Contributions ##
|
||||
|
||||
We welcome contributions of any kind. If you have a bug or an idea, read our
|
||||
[guide](https://docs.photoprism.org/en/latest/developer-guide/) before opening an issue.
|
||||
[guide](https://docs.photoprism.org/developer-guide/) before opening an issue.
|
||||
Issues labeled [help wanted](https://github.com/photoprism/photoprism/labels/help%20wanted) /
|
||||
[easy](https://github.com/photoprism/photoprism/issues?q=is%3Aissue+is%3Aopen+label%3Aeasy) can be
|
||||
good (first) contributions.
|
||||
|
||||
Please follow us on [Twitter][twitter] and join our [developers mailing list](https://groups.google.com/a/photoprism.org/forum/#!forum/developers)
|
||||
to receive regular project updates and discuss development related topics. Don't be afraid to ask stupid questions.
|
||||
Follow us on [Twitter][twitter] to receive regular project updates and discuss development
|
||||
related topics. Don't be afraid to ask stupid questions.
|
||||
|
||||
## Free beer ##
|
||||
## Funding ##
|
||||
|
||||
This project is about freedom and privacy but not necessarily about free beer. We feel like it
|
||||
would be a mistake to state there will be no costs, because clearly we have huge expenses, your server hardware
|
||||
|
@ -78,49 +64,42 @@ It's fair to say that users with basic needs will have no monthly costs. We were
|
|||
per dollar than commercial projects and learned a lot on top of it.
|
||||
An earlier version of this document contained a rough number, but at the end of the day it doesn't matter.
|
||||
|
||||
Basically all established OSS companies make 90% of their revenue with enterprise customers, that's why private users
|
||||
Most established OSS companies make the bulk of their revenue with enterprise customers, that's why private users
|
||||
and single developers typically get everything for free. Obviously that doesn't work if you have only private users
|
||||
that refuse to share their data on top of it. In our opinion it would have made sense to finance this like all
|
||||
public infrastructure, our expenses are peanuts compared to building a road.
|
||||
that refuse to share their data on top of it.
|
||||
|
||||
Looking forward, specific solutions for funding development and maintenance could be to...
|
||||
|
||||
- sell a tested & supported version in the app store while our contributors and other developers can
|
||||
continue to use Docker or build from source
|
||||
- provide additional features to users who support us financially, maybe with a different license similar to GitLab
|
||||
- develop a one-click solution for private cloud hosting together with selected providers we trust
|
||||
- offer a geodata, public events and maps subscription since OpenStreetMap doesn't want us to use their development
|
||||
API for production, which is perfectly fine
|
||||
|
||||
## Donations ##
|
||||
|
||||
You're most welcome to support us via [GitHub Sponsors](https://github.com/sponsors/lastzero),
|
||||
especially if you need help with using our software. They will match every donation in the first year.
|
||||
You're welcome to support us via [GitHub Sponsors](https://github.com/sponsors/lastzero),
|
||||
especially if you have feature requests or need help with using our software.
|
||||
They will match every donation in the first year.
|
||||
In addition, you can find us on [Patreon](https://www.patreon.com/photoprism) and [PayPal](https://www.paypal.me/photoprism).
|
||||
Our [sponsors](https://github.com/photoprism/photoprism/blob/develop/SPONSORS.md) and
|
||||
[contributors](https://github.com/photoprism/photoprism/graphs/contributors/) will get for free whatever we might
|
||||
have to charge for a geodata subscription later.
|
||||
have to charge for a geodata subscription and/or additional features later (see [tiers](https://github.com/sponsors/lastzero/dashboard/tiers)).
|
||||
|
||||
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.
|
||||
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.
|
||||
|
||||
Ideas backed by a sponsor are marked with a golden [sponsor](https://github.com/photoprism/photoprism/issues?q=is%3Aissue+is%3Aopen+label%3Asponsor) label.
|
||||
Let us know if we mistakenly label an idea as [unfunded](https://github.com/photoprism/photoprism/issues?q=is%3Aissue+is%3Aopen+label%3Aunfunded).
|
||||
|
||||
Thank you very much! <3
|
||||
|
||||
## Public and corporate sponsorship ##
|
||||
## Trademarks ##
|
||||
|
||||
We spent weeks asking organizations like [The Prototype Fund](https://prototypefund.de/en/) for help
|
||||
and also tried to cooperate with companies like Mapbox and Cewe.
|
||||
You would think it's easier to get a few dollars with [our background](http://docs.photoprism.org/en/latest/team/)
|
||||
and [working code](https://demo.photoprism.org/).
|
||||
|
||||
If any of those organizations changes their mind, they are welcome to [reach out to us](mailto:hello@photoprism.org).
|
||||
|
||||
## Disclaimer ##
|
||||
|
||||
We'd like to remind everyone that we are not full-time marketing specialists but developers who work a lot and
|
||||
enjoy a bit of sarcasm from time to time. Please let us know when there is an issue with our "nuance and tone"
|
||||
and we'll find a solution.
|
||||
PhotoPrism™ is a registered trademark of Michael Mayer. You may use it as required to describe
|
||||
our software, run your own server, for educational purposes, but not for offering commercial
|
||||
goods, products, or services without prior written permission. In other words, please ask.
|
||||
|
||||
[wiki:classification]: https://github.com/photoprism/photoprism/wiki/Image-Classification
|
||||
[wiki:xmp]: https://github.com/photoprism/photoprism/wiki/XMP
|
||||
|
@ -133,7 +112,7 @@ and we'll find a solution.
|
|||
[goreport]: https://goreportcard.com/report/github.com/photoprism/photoprism
|
||||
[coverage]: https://codecov.io/gh/photoprism/photoprism
|
||||
[ci]: https://travis-ci.org/photoprism/photoprism
|
||||
[docs]: https://docs.photoprism.org/en/latest/
|
||||
[docs]: https://docs.photoprism.org/
|
||||
[issuehunt]: https://issuehunt.io/repos/119160553
|
||||
[chat]: https://gitter.im/browseyourlife/community
|
||||
[twitter]: https://twitter.com/browseyourlife
|
||||
|
|
|
@ -1,11 +1,12 @@
|
|||
Let's join forces
|
||||
=================
|
||||
|
||||
You're most welcome to support us via [GitHub Sponsors](https://github.com/sponsors/lastzero),
|
||||
especially if you need help with using our software. They will match every donation in the first year.
|
||||
You're welcome to support us via [GitHub Sponsors](https://github.com/sponsors/lastzero),
|
||||
especially if you have feature requests or need help with using our software.
|
||||
They will match every donation in the first year.
|
||||
In addition, you can find us on [Patreon][patreon] and [PayPal][paypal].
|
||||
Our sponsors and contributors will get for free whatever we might have to
|
||||
[charge](https://docs.photoprism.org/en/latest/funding/) for a geodata, public events and maps
|
||||
[charge](https://docs.photoprism.org/funding/) for a geodata, public events and maps
|
||||
subscription later.
|
||||
|
||||
Also please [leave a star](https://github.com/photoprism/photoprism/stargazers) here on GitHub if you like this project,
|
||||
|
@ -28,6 +29,8 @@ Thank you very much to all of our sponsors and donors (including those that want
|
|||
|
||||
[Thomas Eg](https://github.com/ThomasEg) (GitHub Sponsors, April 2020)
|
||||
|
||||
[@mpodshivalin](https://github.com/mpodshivalin) (GitHub Sponsors, July 2020)
|
||||
|
||||
For a full list of GitHub sponsors, see https://github.com/sponsors/lastzero.
|
||||
|
||||
## Donations ##
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
url: "https://demo.photoprism.org/"
|
||||
title: "PhotoPrism"
|
||||
subtitle: "Browse your life"
|
||||
description: "Personal Photo Management powered by Go and Google TensorFlow. Free and open-source."
|
||||
author: "Anonymous"
|
||||
twitter: "@browseyourlife"
|
||||
debug: false
|
||||
read-only: false
|
||||
public: false
|
||||
experimental: false
|
||||
admin-password: photoprism
|
||||
config-path: ~/.config/photoprism
|
||||
cache-path: ~/.cache/photoprism
|
||||
assets-path: ~/.local/share/photoprism
|
||||
resources-path: ~/.local/share/photoprism/resources
|
||||
originals-path: ~/Pictures/Originals
|
||||
import-path: ~/Pictures/Import
|
||||
http-host:
|
||||
http-mode: release
|
||||
http-port: 2342
|
||||
tidb-host: localhost
|
||||
tidb-port: 2343
|
||||
tidb-password: photoprism
|
||||
database-driver: tidb
|
||||
database-dsn: root:photoprism@tcp(localhost:2343)/photoprism?parseTime=true
|
||||
pid-filename: ~/.local/share/photoprism/photoprism.pid
|
||||
log-filename: ~/.local/share/photoprism/photoprism.log
|
||||
detach-server: false
|
|
@ -1,27 +0,0 @@
|
|||
theme: default
|
||||
language: en
|
||||
templates:
|
||||
default: index.tmpl
|
||||
maps:
|
||||
animate: 0
|
||||
style: streets
|
||||
features:
|
||||
archive: true
|
||||
private: true
|
||||
review: true
|
||||
upload: true
|
||||
import: true
|
||||
labels: true
|
||||
places: true
|
||||
download: true
|
||||
edit: true
|
||||
share: true
|
||||
logs: true
|
||||
import:
|
||||
path: /
|
||||
move: false
|
||||
index:
|
||||
path: /
|
||||
convert: true
|
||||
rescan: false
|
||||
group: true
|
BIN
assets/examples/.photoprism/example.jpg
Normal file
After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 159 KiB After Width: | Height: | Size: 159 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 58 KiB After Width: | Height: | Size: 58 KiB |
Before Width: | Height: | Size: 66 KiB After Width: | Height: | Size: 66 KiB |
Before Width: | Height: | Size: 91 KiB After Width: | Height: | Size: 91 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 123 KiB After Width: | Height: | Size: 123 KiB |
Before Width: | Height: | Size: 109 KiB After Width: | Height: | Size: 109 KiB |
Before Width: | Height: | Size: 24 KiB After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
85
assets/examples/blue-go-video.json
Normal file
|
@ -0,0 +1,85 @@
|
|||
[{
|
||||
"SourceFile": "/Users/michael/Downloads/20200511-141648-Berlin-Germany-2020-3ku.mp4",
|
||||
"ExifToolVersion": 11.85,
|
||||
"FileName": "blue-go-video.mp4",
|
||||
"Directory": "/Users/michael/Downloads",
|
||||
"FileSize": "4.4 MB",
|
||||
"FileModifyDate": "2020:05:14 14:02:58+02:00",
|
||||
"FileAccessDate": "2020:05:14 14:02:58+02:00",
|
||||
"FileInodeChangeDate": "2020:05:14 14:02:58+02:00",
|
||||
"FilePermissions": "rw-r--r--",
|
||||
"FileType": "MP4",
|
||||
"FileTypeExtension": "mp4",
|
||||
"MIMEType": "video/mp4",
|
||||
"MajorBrand": "MP4 v2 [ISO 14496-14]",
|
||||
"MinorVersion": "0.0.0",
|
||||
"CompatibleBrands": ["isom","mp42"],
|
||||
"MovieHeaderVersion": 0,
|
||||
"CreateDate": "2020:05:11 14:16:48",
|
||||
"ModifyDate": "2020:05:11 14:16:48",
|
||||
"TimeScale": 1000,
|
||||
"Duration": "2.42 s",
|
||||
"PreferredRate": 1,
|
||||
"PreferredVolume": "100.00%",
|
||||
"PreviewTime": "0 s",
|
||||
"PreviewDuration": "0 s",
|
||||
"PosterTime": "0 s",
|
||||
"SelectionTime": "0 s",
|
||||
"SelectionDuration": "0 s",
|
||||
"CurrentTime": "0 s",
|
||||
"NextTrackID": 3,
|
||||
"GPSCoordinates": "52 deg 27' 34.56\" N, 13 deg 19' 18.48\" E",
|
||||
"AndroidVersion": 10,
|
||||
"TrackHeaderVersion": 0,
|
||||
"TrackCreateDate": "2020:05:11 14:16:48",
|
||||
"TrackModifyDate": "2020:05:11 14:16:48",
|
||||
"TrackID": 1,
|
||||
"TrackDuration": "2.42 s",
|
||||
"TrackLayer": 0,
|
||||
"TrackVolume": "0.00%",
|
||||
"ImageWidth": 1920,
|
||||
"ImageHeight": 1080,
|
||||
"GraphicsMode": "srcCopy",
|
||||
"OpColor": "0 0 0",
|
||||
"CompressorID": "avc1",
|
||||
"SourceImageWidth": 1920,
|
||||
"SourceImageHeight": 1080,
|
||||
"XResolution": 72,
|
||||
"YResolution": 72,
|
||||
"BitDepth": 24,
|
||||
"PixelAspectRatio": "65536:65536",
|
||||
"ColorRepresentation": "nclx 1 1 1",
|
||||
"VideoFrameRate": 28.101,
|
||||
"MatrixStructure": "1 0 0 0 1 0 0 0 1",
|
||||
"MediaHeaderVersion": 0,
|
||||
"MediaCreateDate": "2020:05:11 14:16:48",
|
||||
"MediaModifyDate": "2020:05:11 14:16:48",
|
||||
"MediaTimeScale": 48000,
|
||||
"MediaDuration": "2.41 s",
|
||||
"HandlerType": "Audio Track",
|
||||
"HandlerDescription": "SoundHandle",
|
||||
"Balance": 0,
|
||||
"AudioFormat": "mp4a",
|
||||
"AudioChannels": 2,
|
||||
"AudioBitsPerSample": 16,
|
||||
"AudioSampleRate": 48000,
|
||||
"MediaDataSize": 3818513,
|
||||
"MediaDataOffset": 810340,
|
||||
"ImageSize": "1920x1080",
|
||||
"Megapixels": 2.1,
|
||||
"AvgBitrate": "12.6 Mbps",
|
||||
"GPSLatitude": "52 deg 27' 34.56\" N",
|
||||
"GPSLongitude": "13 deg 19' 18.48\" E",
|
||||
"Rotation": 90,
|
||||
"GPSPosition": "52 deg 27' 34.56\" N, 13 deg 19' 18.48\" E",
|
||||
"Title": "Blue Gopher",
|
||||
"Description": "Cute gopher",
|
||||
"Comment": "We love go",
|
||||
"Subject": "gopher",
|
||||
"Keywords": "blue, desk",
|
||||
"Artist": "Micha",
|
||||
"CameraOwner": "Micha",
|
||||
"CameraSerial": "123",
|
||||
"DocumentID": "12398365",
|
||||
"InstanceID": "9058055",
|
||||
}]
|
6
assets/examples/blue-go-video.mp4.json
Normal file
|
@ -0,0 +1,6 @@
|
|||
[{
|
||||
"SourceFile": "/Users/michael/Downloads/20200511-141648-Berlin-Germany-2020-3ku.mp4",
|
||||
"ExifToolVersion": 11.85,
|
||||
"FileName": "blue-go-video.mp4",
|
||||
"Directory": "/Users/michael/Downloads"
|
||||
}]
|
Before Width: | Height: | Size: 101 KiB After Width: | Height: | Size: 101 KiB |
Before Width: | Height: | Size: 61 KiB After Width: | Height: | Size: 61 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 87 KiB After Width: | Height: | Size: 87 KiB |
Before Width: | Height: | Size: 69 KiB After Width: | Height: | Size: 69 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 96 KiB After Width: | Height: | Size: 96 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 34 KiB |
Before Width: | Height: | Size: 46 KiB After Width: | Height: | Size: 46 KiB |
Before Width: | Height: | Size: 42 KiB After Width: | Height: | Size: 42 KiB |
Before Width: | Height: | Size: 55 KiB After Width: | Height: | Size: 55 KiB |
BIN
assets/examples/earth.avi
Normal file
BIN
assets/examples/earth.mov
Normal file
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 76 KiB After Width: | Height: | Size: 76 KiB |
Before Width: | Height: | Size: 50 KiB After Width: | Height: | Size: 50 KiB |
BIN
assets/examples/example.bmp
Normal file
After Width: | Height: | Size: 20 KiB |
BIN
assets/examples/example.gif
Normal file
After Width: | Height: | Size: 5.6 KiB |
BIN
assets/examples/example.png
Normal file
After Width: | Height: | Size: 18 KiB |
BIN
assets/examples/example.tif
Normal file
Before Width: | Height: | Size: 43 KiB After Width: | Height: | Size: 43 KiB |
Before Width: | Height: | Size: 86 KiB After Width: | Height: | Size: 86 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 25 KiB |
Before Width: | Height: | Size: 65 KiB After Width: | Height: | Size: 65 KiB |
BIN
assets/examples/gopher-video.mp4
Normal file
Before Width: | Height: | Size: 79 KiB After Width: | Height: | Size: 79 KiB |
Before Width: | Height: | Size: 20 KiB After Width: | Height: | Size: 20 KiB |
Before Width: | Height: | Size: 72 KiB After Width: | Height: | Size: 72 KiB |
Before Width: | Height: | Size: 62 KiB After Width: | Height: | Size: 62 KiB |
Before Width: | Height: | Size: 47 KiB After Width: | Height: | Size: 47 KiB |
Before Width: | Height: | Size: 44 KiB After Width: | Height: | Size: 44 KiB |
Before Width: | Height: | Size: 71 KiB After Width: | Height: | Size: 71 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 54 KiB After Width: | Height: | Size: 54 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 866 B After Width: | Height: | Size: 866 B |
Before Width: | Height: | Size: 41 KiB After Width: | Height: | Size: 41 KiB |
Before Width: | Height: | Size: 56 KiB After Width: | Height: | Size: 56 KiB |
Before Width: | Height: | Size: 35 KiB After Width: | Height: | Size: 35 KiB |
Before Width: | Height: | Size: 38 KiB After Width: | Height: | Size: 38 KiB |
Before Width: | Height: | Size: 45 KiB After Width: | Height: | Size: 45 KiB |
BIN
assets/examples/telegram_2020-01-30_09-57-18.jpg
Normal file
After Width: | Height: | Size: 132 KiB |
BIN
assets/examples/this-is-a-jpeg.png
Normal file
After Width: | Height: | Size: 24 KiB |
Before Width: | Height: | Size: 28 KiB After Width: | Height: | Size: 28 KiB |
Before Width: | Height: | Size: 51 KiB After Width: | Height: | Size: 51 KiB |
Before Width: | Height: | Size: 83 KiB After Width: | Height: | Size: 83 KiB |
Before Width: | Height: | Size: 822 B After Width: | Height: | Size: 822 B |
Before Width: | Height: | Size: 81 KiB After Width: | Height: | Size: 81 KiB |
37
assets/locales/README.md
Normal file
|
@ -0,0 +1,37 @@
|
|||
# Backend Translations
|
||||
|
||||
PhotoPrism uses [gettext](https://en.wikipedia.org/wiki/Gettext) for localizing frontend and backend.
|
||||
It's one of the most widely adopted standards for translating user interfaces.
|
||||
|
||||
Human readable messages like `File not found` are used as ids for finding matching translations,
|
||||
and used as defaults whenever there is no translation available.
|
||||
|
||||
Messages may optionally contain placeholders, like `Found %d files`, for numbers and
|
||||
other variables.
|
||||
|
||||
We strongly recommend [Poedit](https://poedit.net/download) for creating and updating translations.
|
||||
Download is free for Mac, Windows and Linux.
|
||||
It's source code can be obtained on [GitHub](https://github.com/vslavik/poedit).
|
||||
|
||||
Only asynchronous notifications and certain API responses need translation to provide a
|
||||
consistent user experience.
|
||||
Technical log messages should be in English to avoid ambiguities and (even slightly) wrong translations.
|
||||
|
||||
`default.po` files in sub directories contain localized messages for each
|
||||
[language](https://www.gnu.org/software/gettext/manual/html_node/Usual-Language-Codes.html#Usual-Language-Codes),
|
||||
identified by their [two-letter locale](https://www.gnu.org/software/gettext/manual/html_node/Locale-Names.html),
|
||||
like `de/default.po` for German. You can open, edit and save them with Poedit. Please
|
||||
also add and commit binary `*.mo` files, which will be automatically created by Poedit.
|
||||
|
||||
To add a new translation, open `messages.pot`, click on "Create New Translation" at the bottom, select
|
||||
the language, and start translating.
|
||||
When done, create a new directory (using the locale as name) and save your translation there as `default.po`.
|
||||
|
||||
The POT file `/assets/locales/messages.pot` will be automatically updated when
|
||||
running `go generate` in `/internal/i18n` or `make generate` in the main project directory.
|
||||
Note that this will only work when you have gettext installed on your system.
|
||||
We recommend using our latest development image as described in the Developer Guide.
|
||||
|
||||
Apply changes to existing translations by clicking on "Catalogue" > "Update from POT File..."
|
||||
in the Poedit app menu.
|
||||
|
BIN
assets/locales/de/default.mo
Normal file
266
assets/locales/de/default.po
Normal file
|
@ -0,0 +1,266 @@
|
|||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-07-14 19:44+0000\n"
|
||||
"PO-Revision-Date: 2020-07-14 22:16+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: de\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.3.1\n"
|
||||
"X-Poedit-Basepath: .\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
|
||||
#: messages.go:69
|
||||
msgid "Unexpected error, please try again"
|
||||
msgstr "Unerwarteter Fehler, bitte erneut versuchen"
|
||||
|
||||
#: messages.go:70
|
||||
msgid "Invalid request"
|
||||
msgstr "Ungültige Anfrage"
|
||||
|
||||
#: messages.go:71
|
||||
msgid "Changes could not be saved"
|
||||
msgstr "Fehler beim Speichern der Daten"
|
||||
|
||||
#: messages.go:72
|
||||
msgid "Could not be deleted"
|
||||
msgstr "Konnte nicht gelöscht werden"
|
||||
|
||||
#: messages.go:73
|
||||
#, c-format
|
||||
msgid "%s already exists"
|
||||
msgstr "%s existiert bereits"
|
||||
|
||||
#: messages.go:74 messages.go:77
|
||||
msgid "Not found on server, deleted?"
|
||||
msgstr "Nicht auf Server gefunden, gelöscht?"
|
||||
|
||||
#: messages.go:75
|
||||
msgid "File not found"
|
||||
msgstr "Datei konnte nicht gefunden werden"
|
||||
|
||||
#: messages.go:76
|
||||
msgid "Selection not found"
|
||||
msgstr "Auswahl nicht gefunden"
|
||||
|
||||
#: messages.go:78
|
||||
msgid "Account not found"
|
||||
msgstr "Unbekannter Account"
|
||||
|
||||
#: messages.go:79
|
||||
msgid "User not found"
|
||||
msgstr "Nutzer nicht gefunden"
|
||||
|
||||
#: messages.go:80
|
||||
msgid "Label not found"
|
||||
msgstr "Kategorie nicht gefunden"
|
||||
|
||||
#: messages.go:81
|
||||
msgid "Album not found"
|
||||
msgstr "Album nicht gefunden - gelöscht?"
|
||||
|
||||
#: messages.go:82
|
||||
msgid "Not available in public mode"
|
||||
msgstr "Im öffentlichen Modus nicht verfügbar"
|
||||
|
||||
#: messages.go:83
|
||||
msgid "not available in read-only mode"
|
||||
msgstr "Funktion im ‘read-only’ Modus nicht verfügbar"
|
||||
|
||||
#: messages.go:84
|
||||
msgid "Please log in and try again"
|
||||
msgstr "Anmeldung erforderlich"
|
||||
|
||||
#: messages.go:85
|
||||
msgid "Upload might be offensive"
|
||||
msgstr "Inhalt könnte anstößig sein und wurde abgelehnt"
|
||||
|
||||
#: messages.go:86
|
||||
msgid "No items selected"
|
||||
msgstr "Nichts ausgewählt"
|
||||
|
||||
#: messages.go:87
|
||||
msgid "Failed creating file, please check permissions"
|
||||
msgstr "Datei konnte nicht angelegt werden"
|
||||
|
||||
#: messages.go:88
|
||||
msgid "Failed creating folder, please check permissions"
|
||||
msgstr "Verzeichnis konnte nicht angelegt werden"
|
||||
|
||||
#: messages.go:89
|
||||
msgid "Could not connect, please try again"
|
||||
msgstr "Verbindung fehlgeschlagen"
|
||||
|
||||
#: messages.go:90
|
||||
msgid "Invalid password, please try again"
|
||||
msgstr "Ungültiges Passwort"
|
||||
|
||||
#: messages.go:91
|
||||
msgid "Feature disabled"
|
||||
msgstr "Funktion deaktiviert"
|
||||
|
||||
#: messages.go:92
|
||||
msgid "No labels selected"
|
||||
msgstr "Keine Kategorien ausgewählt"
|
||||
|
||||
#: messages.go:93
|
||||
msgid "No albums selected"
|
||||
msgstr "Keine Alben ausgewählt"
|
||||
|
||||
#: messages.go:94
|
||||
msgid "No files available for download"
|
||||
msgstr "Nicht zum Download verfügbar"
|
||||
|
||||
#: messages.go:95
|
||||
msgid "Failed to create zip file"
|
||||
msgstr "Zip-Datei konnte nicht erstellt werden"
|
||||
|
||||
#: messages.go:98
|
||||
msgid "Changes successfully saved"
|
||||
msgstr "Änderungen erfolgreich gespeichert"
|
||||
|
||||
#: messages.go:99
|
||||
msgid "Album created"
|
||||
msgstr "Album erstellt"
|
||||
|
||||
#: messages.go:100
|
||||
msgid "Album saved"
|
||||
msgstr "Album gespeichert"
|
||||
|
||||
#: messages.go:101
|
||||
#, c-format
|
||||
msgid "Album %s deleted"
|
||||
msgstr "Album %s gelöscht"
|
||||
|
||||
#: messages.go:102
|
||||
msgid "Album contents cloned"
|
||||
msgstr "Album-Einträge kopiert"
|
||||
|
||||
#: messages.go:103
|
||||
msgid "File removed from stack"
|
||||
msgstr "Datei aus Stapel entfernt"
|
||||
|
||||
#: messages.go:104
|
||||
#, c-format
|
||||
msgid "Selection added to %s"
|
||||
msgstr "Auswahl zu %s hinzugefügt"
|
||||
|
||||
#: messages.go:105
|
||||
#, c-format
|
||||
msgid "One entry added to %s"
|
||||
msgstr "Ein Eintrag zu %s hinzugefügt"
|
||||
|
||||
#: messages.go:106
|
||||
#, c-format
|
||||
msgid "%d entries added to %s"
|
||||
msgstr "%d Einträge zu %s hinzugefügt"
|
||||
|
||||
#: messages.go:107
|
||||
#, c-format
|
||||
msgid "One entry removed from %s"
|
||||
msgstr "Ein Eintrag aus %s entfernt"
|
||||
|
||||
#: messages.go:108
|
||||
#, c-format
|
||||
msgid "%d entries removed from %s"
|
||||
msgstr "%d Einträge aus %s entfernt"
|
||||
|
||||
#: messages.go:109
|
||||
msgid "Account created"
|
||||
msgstr "Server-Konfiguration angelegt"
|
||||
|
||||
#: messages.go:110
|
||||
msgid "Account saved"
|
||||
msgstr "Server-Konfiguration gespeichert"
|
||||
|
||||
#: messages.go:111
|
||||
msgid "Account deleted"
|
||||
msgstr "Server-Konfiguration gelöscht"
|
||||
|
||||
#: messages.go:112
|
||||
msgid "Settings saved"
|
||||
msgstr "Einstellungen gespeichert"
|
||||
|
||||
#: messages.go:113
|
||||
msgid "Password changed"
|
||||
msgstr "Passwort geändert"
|
||||
|
||||
#: messages.go:114
|
||||
#, c-format
|
||||
msgid "Import completed in %d s"
|
||||
msgstr "Import in %d s abgeschlossen"
|
||||
|
||||
#: messages.go:115
|
||||
msgid "Import canceled"
|
||||
msgstr "Import abgebrochen"
|
||||
|
||||
#: messages.go:116
|
||||
#, c-format
|
||||
msgid "Indexing completed in %d s"
|
||||
msgstr "Indizierung in %d s abgeschlossen"
|
||||
|
||||
#: messages.go:117
|
||||
msgid "Indexing originals..."
|
||||
msgstr "Indiziere Dateien…"
|
||||
|
||||
#: messages.go:118
|
||||
#, c-format
|
||||
msgid "Indexing files in %s"
|
||||
msgstr "Indiziere Dateien in %s"
|
||||
|
||||
#: messages.go:119
|
||||
msgid "Indexing canceled"
|
||||
msgstr "Indizierung abgebrochen"
|
||||
|
||||
#: messages.go:120
|
||||
#, c-format
|
||||
msgid "Removed %d files and %d photos"
|
||||
msgstr "%d Dateien und %d Fotos wurden entfernt"
|
||||
|
||||
#: messages.go:121
|
||||
#, c-format
|
||||
msgid "Moving files from %s"
|
||||
msgstr "Verschiebe Dateien von %s"
|
||||
|
||||
#: messages.go:122
|
||||
#, c-format
|
||||
msgid "Copying files from %s"
|
||||
msgstr "Kopiere Dateien von %s"
|
||||
|
||||
#: messages.go:123
|
||||
msgid "Labels deleted"
|
||||
msgstr "Kategorien gelöscht”"
|
||||
|
||||
#: messages.go:124
|
||||
msgid "Label saved"
|
||||
msgstr "Kategorie gespeichert"
|
||||
|
||||
#: messages.go:125
|
||||
#, c-format
|
||||
msgid "%d files uploaded in %d s"
|
||||
msgstr "%d Dateien hochgeladen in %d s"
|
||||
|
||||
#: messages.go:126
|
||||
msgid "Selection archived"
|
||||
msgstr "Auswahl archiviert"
|
||||
|
||||
#: messages.go:127
|
||||
msgid "Selection restored"
|
||||
msgstr "Auswahl wiederhergestellt"
|
||||
|
||||
#: messages.go:128
|
||||
msgid "Selection marked as private"
|
||||
msgstr "Auswahl als privat markiert"
|
||||
|
||||
#: messages.go:129
|
||||
msgid "Albums deleted"
|
||||
msgstr "Alben gelöscht"
|
||||
|
||||
#: messages.go:130
|
||||
#, c-format
|
||||
msgid "Zip created in %d s"
|
||||
msgstr "Zip-Datei erstellt in %d s"
|
BIN
assets/locales/en/default.mo
Normal file
270
assets/locales/en/default.po
Normal file
|
@ -0,0 +1,270 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-07-14 19:44+0000\n"
|
||||
"PO-Revision-Date: 2020-07-14 22:03+0200\n"
|
||||
"Language-Team: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.3.1\n"
|
||||
"Last-Translator: \n"
|
||||
"Plural-Forms: nplurals=2; plural=(n != 1);\n"
|
||||
"Language: en\n"
|
||||
|
||||
#: messages.go:69
|
||||
msgid "Unexpected error, please try again"
|
||||
msgstr "Unexpected error, please try again"
|
||||
|
||||
#: messages.go:70
|
||||
msgid "Invalid request"
|
||||
msgstr "Invalid request"
|
||||
|
||||
#: messages.go:71
|
||||
msgid "Changes could not be saved"
|
||||
msgstr "Changes could not be saved"
|
||||
|
||||
#: messages.go:72
|
||||
msgid "Could not be deleted"
|
||||
msgstr "Could not be deleted"
|
||||
|
||||
#: messages.go:73
|
||||
#, c-format
|
||||
msgid "%s already exists"
|
||||
msgstr "%s already exists"
|
||||
|
||||
#: messages.go:74 messages.go:77
|
||||
msgid "Not found on server, deleted?"
|
||||
msgstr "Not found on server, deleted?"
|
||||
|
||||
#: messages.go:75
|
||||
msgid "File not found"
|
||||
msgstr "File not found"
|
||||
|
||||
#: messages.go:76
|
||||
msgid "Selection not found"
|
||||
msgstr "Selection not found"
|
||||
|
||||
#: messages.go:78
|
||||
msgid "Account not found"
|
||||
msgstr "Account not found"
|
||||
|
||||
#: messages.go:79
|
||||
msgid "User not found"
|
||||
msgstr "User not found"
|
||||
|
||||
#: messages.go:80
|
||||
msgid "Label not found"
|
||||
msgstr "Label not found"
|
||||
|
||||
#: messages.go:81
|
||||
msgid "Album not found"
|
||||
msgstr "Album not found"
|
||||
|
||||
#: messages.go:82
|
||||
msgid "Not available in public mode"
|
||||
msgstr "Not available in public mode"
|
||||
|
||||
#: messages.go:83
|
||||
msgid "not available in read-only mode"
|
||||
msgstr "not available in read-only mode"
|
||||
|
||||
#: messages.go:84
|
||||
msgid "Please log in and try again"
|
||||
msgstr "Please log in and try again"
|
||||
|
||||
#: messages.go:85
|
||||
msgid "Upload might be offensive"
|
||||
msgstr "Upload might be offensive"
|
||||
|
||||
#: messages.go:86
|
||||
msgid "No items selected"
|
||||
msgstr "No items selected"
|
||||
|
||||
#: messages.go:87
|
||||
msgid "Failed creating file, please check permissions"
|
||||
msgstr "Failed creating file, please check permissions"
|
||||
|
||||
#: messages.go:88
|
||||
msgid "Failed creating folder, please check permissions"
|
||||
msgstr "Failed creating folder, please check permissions"
|
||||
|
||||
#: messages.go:89
|
||||
msgid "Could not connect, please try again"
|
||||
msgstr "Could not connect, please try again"
|
||||
|
||||
#: messages.go:90
|
||||
msgid "Invalid password, please try again"
|
||||
msgstr "Invalid password, please try again"
|
||||
|
||||
#: messages.go:91
|
||||
msgid "Feature disabled"
|
||||
msgstr "Feature disabled"
|
||||
|
||||
#: messages.go:92
|
||||
msgid "No labels selected"
|
||||
msgstr "No labels selected"
|
||||
|
||||
#: messages.go:93
|
||||
msgid "No albums selected"
|
||||
msgstr "No albums selected"
|
||||
|
||||
#: messages.go:94
|
||||
msgid "No files available for download"
|
||||
msgstr "No files available for download"
|
||||
|
||||
#: messages.go:95
|
||||
msgid "Failed to create zip file"
|
||||
msgstr "Failed to create zip file"
|
||||
|
||||
#: messages.go:98
|
||||
msgid "Changes successfully saved"
|
||||
msgstr "Changes successfully saved"
|
||||
|
||||
#: messages.go:99
|
||||
msgid "Album created"
|
||||
msgstr "Album created"
|
||||
|
||||
#: messages.go:100
|
||||
msgid "Album saved"
|
||||
msgstr "Album saved"
|
||||
|
||||
#: messages.go:101
|
||||
#, c-format
|
||||
msgid "Album %s deleted"
|
||||
msgstr "Album %s deleted"
|
||||
|
||||
#: messages.go:102
|
||||
msgid "Album contents cloned"
|
||||
msgstr "Album contents cloned"
|
||||
|
||||
#: messages.go:103
|
||||
msgid "File removed from stack"
|
||||
msgstr "File removed from stack"
|
||||
|
||||
#: messages.go:104
|
||||
#, c-format
|
||||
msgid "Selection added to %s"
|
||||
msgstr "Selection added to %s"
|
||||
|
||||
#: messages.go:105
|
||||
#, c-format
|
||||
msgid "One entry added to %s"
|
||||
msgstr "One entry added to %s"
|
||||
|
||||
#: messages.go:106
|
||||
#, c-format
|
||||
msgid "%d entries added to %s"
|
||||
msgstr "%d entries added to %s"
|
||||
|
||||
#: messages.go:107
|
||||
#, c-format
|
||||
msgid "One entry removed from %s"
|
||||
msgstr "One entry removed from %s"
|
||||
|
||||
#: messages.go:108
|
||||
#, c-format
|
||||
msgid "%d entries removed from %s"
|
||||
msgstr "%d entries removed from %s"
|
||||
|
||||
#: messages.go:109
|
||||
msgid "Account created"
|
||||
msgstr "Account created"
|
||||
|
||||
#: messages.go:110
|
||||
msgid "Account saved"
|
||||
msgstr "Account saved"
|
||||
|
||||
#: messages.go:111
|
||||
msgid "Account deleted"
|
||||
msgstr "Account deleted"
|
||||
|
||||
#: messages.go:112
|
||||
msgid "Settings saved"
|
||||
msgstr "Settings saved"
|
||||
|
||||
#: messages.go:113
|
||||
msgid "Password changed"
|
||||
msgstr "Password changed"
|
||||
|
||||
#: messages.go:114
|
||||
#, c-format
|
||||
msgid "Import completed in %d s"
|
||||
msgstr "Import completed in %d s"
|
||||
|
||||
#: messages.go:115
|
||||
msgid "Import canceled"
|
||||
msgstr "Import canceled"
|
||||
|
||||
#: messages.go:116
|
||||
#, c-format
|
||||
msgid "Indexing completed in %d s"
|
||||
msgstr "Indexing completed in %d s"
|
||||
|
||||
#: messages.go:117
|
||||
msgid "Indexing originals..."
|
||||
msgstr "Indexing originals..."
|
||||
|
||||
#: messages.go:118
|
||||
#, c-format
|
||||
msgid "Indexing files in %s"
|
||||
msgstr "Indexing files in %s"
|
||||
|
||||
#: messages.go:119
|
||||
msgid "Indexing canceled"
|
||||
msgstr "Indexing canceled"
|
||||
|
||||
#: messages.go:120
|
||||
#, c-format
|
||||
msgid "Removed %d files and %d photos"
|
||||
msgstr "Removed %d files and %d photos"
|
||||
|
||||
#: messages.go:121
|
||||
#, c-format
|
||||
msgid "Moving files from %s"
|
||||
msgstr "Moving files from %s"
|
||||
|
||||
#: messages.go:122
|
||||
#, c-format
|
||||
msgid "Copying files from %s"
|
||||
msgstr "Copying files from %s"
|
||||
|
||||
#: messages.go:123
|
||||
msgid "Labels deleted"
|
||||
msgstr "Labels deleted"
|
||||
|
||||
#: messages.go:124
|
||||
msgid "Label saved"
|
||||
msgstr "Label saved"
|
||||
|
||||
#: messages.go:125
|
||||
#, c-format
|
||||
msgid "%d files uploaded in %d s"
|
||||
msgstr "%d files uploaded in %d s"
|
||||
|
||||
#: messages.go:126
|
||||
msgid "Selection archived"
|
||||
msgstr "Selection archived"
|
||||
|
||||
#: messages.go:127
|
||||
msgid "Selection restored"
|
||||
msgstr "Selection restored"
|
||||
|
||||
#: messages.go:128
|
||||
msgid "Selection marked as private"
|
||||
msgstr "Selection marked as private"
|
||||
|
||||
#: messages.go:129
|
||||
msgid "Albums deleted"
|
||||
msgstr "Albums deleted"
|
||||
|
||||
#: messages.go:130
|
||||
#, c-format
|
||||
msgid "Zip created in %d s"
|
||||
msgstr "Zip created in %d s"
|
BIN
assets/locales/fr/default.mo
Normal file
271
assets/locales/fr/default.po
Normal file
|
@ -0,0 +1,271 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: \n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-07-20 09:48+0000\n"
|
||||
"PO-Revision-Date: 2020-07-21 07:55+0200\n"
|
||||
"Last-Translator: \n"
|
||||
"Language-Team: \n"
|
||||
"Language: fr\n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=UTF-8\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
"X-Generator: Poedit 2.3.1\n"
|
||||
"Plural-Forms: nplurals=2; plural=(n > 1);\n"
|
||||
|
||||
#: messages.go:69
|
||||
msgid "Unexpected error, please try again"
|
||||
msgstr "Erreur imprévue, veuillez recommencer"
|
||||
|
||||
#: messages.go:70
|
||||
msgid "Invalid request"
|
||||
msgstr "Requête incorrecte"
|
||||
|
||||
#: messages.go:71
|
||||
msgid "Changes could not be saved"
|
||||
msgstr "Les modifications n'ont pas pu être sauvegardées"
|
||||
|
||||
#: messages.go:72
|
||||
msgid "Could not be deleted"
|
||||
msgstr "N'a pu être supprimé"
|
||||
|
||||
#: messages.go:73
|
||||
#, c-format
|
||||
msgid "%s already exists"
|
||||
msgstr "%s existe déjà"
|
||||
|
||||
#: messages.go:74 messages.go:77
|
||||
msgid "Not found on server, deleted?"
|
||||
msgstr "Non trouvé sur le serveur. Supprimé?"
|
||||
|
||||
#: messages.go:75
|
||||
msgid "File not found"
|
||||
msgstr "Fichier non trouvé"
|
||||
|
||||
#: messages.go:76
|
||||
msgid "Selection not found"
|
||||
msgstr "Sélection non trouvée"
|
||||
|
||||
#: messages.go:78
|
||||
msgid "Account not found"
|
||||
msgstr "Compte non trouvé"
|
||||
|
||||
#: messages.go:79
|
||||
msgid "User not found"
|
||||
msgstr "Utilisateur non trouvé"
|
||||
|
||||
#: messages.go:80
|
||||
msgid "Label not found"
|
||||
msgstr "Étiquette non trouvée"
|
||||
|
||||
#: messages.go:81
|
||||
msgid "Album not found"
|
||||
msgstr "Album non trouvé"
|
||||
|
||||
#: messages.go:82
|
||||
msgid "Not available in public mode"
|
||||
msgstr "Non disponible en mode public"
|
||||
|
||||
#: messages.go:83
|
||||
msgid "not available in read-only mode"
|
||||
msgstr "non disponible en mode lecture seule"
|
||||
|
||||
#: messages.go:84
|
||||
msgid "Please log in and try again"
|
||||
msgstr "Veuillez vous identifier et recommencer"
|
||||
|
||||
#: messages.go:85
|
||||
msgid "Upload might be offensive"
|
||||
msgstr "Le chargement peut être choquant"
|
||||
|
||||
#: messages.go:86
|
||||
msgid "No items selected"
|
||||
msgstr "Aucun élément sélectionné"
|
||||
|
||||
#: messages.go:87
|
||||
msgid "Failed creating file, please check permissions"
|
||||
msgstr "Échec lors de la création du fichier, veuillez vérifier les autorisations"
|
||||
|
||||
#: messages.go:88
|
||||
msgid "Failed creating folder, please check permissions"
|
||||
msgstr "Échec lors de la création du dossier, veuillez vérifier les autorisations"
|
||||
|
||||
#: messages.go:89
|
||||
msgid "Could not connect, please try again"
|
||||
msgstr "Échec lors de la connexion, veuillez réessayer"
|
||||
|
||||
#: messages.go:90
|
||||
msgid "Invalid password, please try again"
|
||||
msgstr "Mot de passe incorrect, veuillez réessayer"
|
||||
|
||||
#: messages.go:91
|
||||
msgid "Feature disabled"
|
||||
msgstr "Fonctionnalité désactivée"
|
||||
|
||||
#: messages.go:92
|
||||
msgid "No labels selected"
|
||||
msgstr "Aucune étiquette sélectionnée"
|
||||
|
||||
#: messages.go:93
|
||||
msgid "No albums selected"
|
||||
msgstr "Aucun album sélectionné"
|
||||
|
||||
#: messages.go:94
|
||||
msgid "No files available for download"
|
||||
msgstr "Aucun fichier disponible au téléchargement"
|
||||
|
||||
#: messages.go:95
|
||||
msgid "Failed to create zip file"
|
||||
msgstr "Échec de la création de l'archive zip"
|
||||
|
||||
#: messages.go:98
|
||||
msgid "Changes successfully saved"
|
||||
msgstr "Les modification ont bien été enregistrées"
|
||||
|
||||
#: messages.go:99
|
||||
msgid "Album created"
|
||||
msgstr "Album créé"
|
||||
|
||||
#: messages.go:100
|
||||
msgid "Album saved"
|
||||
msgstr "Album sauvegardé"
|
||||
|
||||
#: messages.go:101
|
||||
#, c-format
|
||||
msgid "Album %s deleted"
|
||||
msgstr "Album %s supprimé"
|
||||
|
||||
#: messages.go:102
|
||||
msgid "Album contents cloned"
|
||||
msgstr "Le contenu de l'album a été cloné"
|
||||
|
||||
#: messages.go:103
|
||||
msgid "File removed from stack"
|
||||
msgstr "Fichier supprimé de la pile"
|
||||
|
||||
#: messages.go:104
|
||||
#, c-format
|
||||
msgid "Selection added to %s"
|
||||
msgstr "Sélection ajoutée à %s"
|
||||
|
||||
#: messages.go:105
|
||||
#, c-format
|
||||
msgid "One entry added to %s"
|
||||
msgstr "Une entrée a été ajoutée à %s"
|
||||
|
||||
#: messages.go:106
|
||||
#, c-format
|
||||
msgid "%d entries added to %s"
|
||||
msgstr "%d entrées ont été ajoutées à %s"
|
||||
|
||||
#: messages.go:107
|
||||
#, c-format
|
||||
msgid "One entry removed from %s"
|
||||
msgstr "Une entrée a été supprimée de %s"
|
||||
|
||||
#: messages.go:108
|
||||
#, c-format
|
||||
msgid "%d entries removed from %s"
|
||||
msgstr "%d entrées ont été supprimées de %s"
|
||||
|
||||
#: messages.go:109
|
||||
msgid "Account created"
|
||||
msgstr "Compte créé"
|
||||
|
||||
#: messages.go:110
|
||||
msgid "Account saved"
|
||||
msgstr "Compte sauvegardé"
|
||||
|
||||
#: messages.go:111
|
||||
msgid "Account deleted"
|
||||
msgstr "Compte supprimé"
|
||||
|
||||
#: messages.go:112
|
||||
msgid "Settings saved"
|
||||
msgstr "Paramètres sauvegardés"
|
||||
|
||||
#: messages.go:113
|
||||
msgid "Password changed"
|
||||
msgstr "Mode de passe changé"
|
||||
|
||||
#: messages.go:114
|
||||
#, c-format
|
||||
msgid "Import completed in %d s"
|
||||
msgstr "Importation terminée en %d s"
|
||||
|
||||
#: messages.go:115
|
||||
msgid "Import canceled"
|
||||
msgstr "Importation annulée"
|
||||
|
||||
#: messages.go:116
|
||||
#, c-format
|
||||
msgid "Indexing completed in %d s"
|
||||
msgstr "Indexation terminée en %d s"
|
||||
|
||||
#: messages.go:117
|
||||
#, fuzzy
|
||||
msgid "Indexing originals..."
|
||||
msgstr "Indexation des originaux…"
|
||||
|
||||
#: messages.go:118
|
||||
#, c-format
|
||||
msgid "Indexing files in %s"
|
||||
msgstr "Indexation des fichiers de %s"
|
||||
|
||||
#: messages.go:119
|
||||
msgid "Indexing canceled"
|
||||
msgstr "Indexation annulée"
|
||||
|
||||
#: messages.go:120
|
||||
#, c-format
|
||||
msgid "Removed %d files and %d photos"
|
||||
msgstr "Suppression de %d fichiers et %d photos"
|
||||
|
||||
#: messages.go:121
|
||||
#, c-format
|
||||
msgid "Moving files from %s"
|
||||
msgstr "Déplacement de fichiers depuis %s"
|
||||
|
||||
#: messages.go:122
|
||||
#, c-format
|
||||
msgid "Copying files from %s"
|
||||
msgstr "Copie de fichiers depuis %s"
|
||||
|
||||
#: messages.go:123
|
||||
msgid "Labels deleted"
|
||||
msgstr "Étiquettes supprimées"
|
||||
|
||||
#: messages.go:124
|
||||
msgid "Label saved"
|
||||
msgstr "Étiquettes sauvegardées"
|
||||
|
||||
#: messages.go:125
|
||||
#, c-format
|
||||
msgid "%d files uploaded in %d s"
|
||||
msgstr "%d fichiers chargés en %d s"
|
||||
|
||||
#: messages.go:126
|
||||
msgid "Selection archived"
|
||||
msgstr "Sélection archivée"
|
||||
|
||||
#: messages.go:127
|
||||
msgid "Selection restored"
|
||||
msgstr "Sélection restaurée"
|
||||
|
||||
#: messages.go:128
|
||||
msgid "Selection marked as private"
|
||||
msgstr "Sélection marquée comme privée"
|
||||
|
||||
#: messages.go:129
|
||||
msgid "Albums deleted"
|
||||
msgstr "Albums supprimés"
|
||||
|
||||
#: messages.go:130
|
||||
#, c-format
|
||||
msgid "Zip created in %d s"
|
||||
msgstr "Archive zip créée en %d s"
|
269
assets/locales/messages.pot
Normal file
|
@ -0,0 +1,269 @@
|
|||
# SOME DESCRIPTIVE TITLE.
|
||||
# Copyright (C) YEAR THE PACKAGE'S COPYRIGHT HOLDER
|
||||
# This file is distributed under the same license as the PACKAGE package.
|
||||
# FIRST AUTHOR <EMAIL@ADDRESS>, YEAR.
|
||||
#
|
||||
#, fuzzy
|
||||
msgid ""
|
||||
msgstr ""
|
||||
"Project-Id-Version: PACKAGE VERSION\n"
|
||||
"Report-Msgid-Bugs-To: \n"
|
||||
"POT-Creation-Date: 2020-07-22 13:54+0200\n"
|
||||
"PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n"
|
||||
"Last-Translator: FULL NAME <EMAIL@ADDRESS>\n"
|
||||
"Language-Team: LANGUAGE <LL@li.org>\n"
|
||||
"Language: \n"
|
||||
"MIME-Version: 1.0\n"
|
||||
"Content-Type: text/plain; charset=CHARSET\n"
|
||||
"Content-Transfer-Encoding: 8bit\n"
|
||||
|
||||
#: messages.go:69
|
||||
msgid "Unexpected error, please try again"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:70
|
||||
msgid "Invalid request"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:71
|
||||
msgid "Changes could not be saved"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:72
|
||||
msgid "Could not be deleted"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:73
|
||||
#, c-format
|
||||
msgid "%s already exists"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:74 messages.go:77
|
||||
msgid "Not found on server, deleted?"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:75
|
||||
msgid "File not found"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:76
|
||||
msgid "Selection not found"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:78
|
||||
msgid "Account not found"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:79
|
||||
msgid "User not found"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:80
|
||||
msgid "Label not found"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:81
|
||||
msgid "Album not found"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:82
|
||||
msgid "Not available in public mode"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:83
|
||||
msgid "not available in read-only mode"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:84
|
||||
msgid "Please log in and try again"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:85
|
||||
msgid "Upload might be offensive"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:86
|
||||
msgid "No items selected"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:87
|
||||
msgid "Failed creating file, please check permissions"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:88
|
||||
msgid "Failed creating folder, please check permissions"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:89
|
||||
msgid "Could not connect, please try again"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:90
|
||||
msgid "Invalid password, please try again"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:91
|
||||
msgid "Feature disabled"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:92
|
||||
msgid "No labels selected"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:93
|
||||
msgid "No albums selected"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:94
|
||||
msgid "No files available for download"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:95
|
||||
msgid "Failed to create zip file"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:98
|
||||
msgid "Changes successfully saved"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:99
|
||||
msgid "Album created"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:100
|
||||
msgid "Album saved"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:101
|
||||
#, c-format
|
||||
msgid "Album %s deleted"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:102
|
||||
msgid "Album contents cloned"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:103
|
||||
msgid "File removed from stack"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:104
|
||||
#, c-format
|
||||
msgid "Selection added to %s"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:105
|
||||
#, c-format
|
||||
msgid "One entry added to %s"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:106
|
||||
#, c-format
|
||||
msgid "%d entries added to %s"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:107
|
||||
#, c-format
|
||||
msgid "One entry removed from %s"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:108
|
||||
#, c-format
|
||||
msgid "%d entries removed from %s"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:109
|
||||
msgid "Account created"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:110
|
||||
msgid "Account saved"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:111
|
||||
msgid "Account deleted"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:112
|
||||
msgid "Settings saved"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:113
|
||||
msgid "Password changed"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:114
|
||||
#, c-format
|
||||
msgid "Import completed in %d s"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:115
|
||||
msgid "Import canceled"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:116
|
||||
#, c-format
|
||||
msgid "Indexing completed in %d s"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:117
|
||||
msgid "Indexing originals..."
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:118
|
||||
#, c-format
|
||||
msgid "Indexing files in %s"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:119
|
||||
msgid "Indexing canceled"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:120
|
||||
#, c-format
|
||||
msgid "Removed %d files and %d photos"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:121
|
||||
#, c-format
|
||||
msgid "Moving files from %s"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:122
|
||||
#, c-format
|
||||
msgid "Copying files from %s"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:123
|
||||
msgid "Labels deleted"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:124
|
||||
msgid "Label saved"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:125
|
||||
#, c-format
|
||||
msgid "%d files uploaded in %d s"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:126
|
||||
msgid "Selection archived"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:127
|
||||
msgid "Selection restored"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:128
|
||||
msgid "Selection marked as private"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:129
|
||||
msgid "Albums deleted"
|
||||
msgstr ""
|
||||
|
||||
#: messages.go:130
|
||||
#, c-format
|
||||
msgid "Zip created in %d s"
|
||||
msgstr ""
|