2019-07-04 17:29:49 -07:00
|
|
|
Photolib
|
2019-06-21 09:22:42 -07:00
|
|
|
========
|
|
|
|
|
|
|
|
Cloud-native photo and related media library software, with a focus for photography hobbyists.
|
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
Photolib provides a simple, rich, and modern UI to manage your photo and video library. It can scale to host hundreds of
|
|
|
|
thousands of photos but is also light and simple enough to host just the couple photos you shoot with your smartphone.
|
|
|
|
|
|
|
|
Photolib stores images as a logical "photoset". This allows identical images and metadata to be grouped into one item.
|
|
|
|
Many photographers shoot in multiple formats - that is, to produce multiple files per click of the shutter. A JPEG and
|
|
|
|
a RAW of some sort (Like Canon's CR2) is common. The primary idea behind Photolib's organization is that one click of a
|
|
|
|
camera shutter equals one photoset.
|
|
|
|
|
|
|
|
When photos are imported - assuming they are done in the same batch - files are grouped based on their name and
|
|
|
|
extension, using rules that apply to almost every camera format. For example, a camera shooting under the "multiple
|
|
|
|
formats" mode described above would create, from one shot, `IMG_1234.JPG` and `IMG_1234.CR2`. Photolib would detect that
|
|
|
|
since these two images have the same file name (the `IMG_1234` part), they are the same photo and should be grouped into
|
|
|
|
a photoset.
|
|
|
|
|
|
|
|
In addition to controls in the web interface, Photolib provides both a REST API and command-line tools to manage your
|
|
|
|
photo library.
|
2019-06-21 09:22:42 -07:00
|
|
|
|
|
|
|
|
|
|
|
Installation
|
|
|
|
------------
|
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
Pre-built releases are not currently available. See `Dockerfile` for a step-by-step installation from source.
|
|
|
|
|
|
|
|
The general steps are:
|
|
|
|
|
|
|
|
* `npm install` - install modules needed to build the frontend assets
|
|
|
|
* `grunt` - build the frontend assets
|
|
|
|
* `pip3 install -r requirements.txt` - install python dependencies
|
|
|
|
* `python3 setup.py install` - install Photolib and command line tools
|
|
|
|
|
|
|
|
Note that the npm and grunt steps can be skipped if you're not planning to run the web UI (e.g. you want only the
|
|
|
|
command-line tools).
|
2019-06-21 09:22:42 -07:00
|
|
|
|
|
|
|
|
|
|
|
Usage
|
|
|
|
-----
|
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
After installation, run the server:
|
2019-06-21 09:22:42 -07:00
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
* `photoappd --port 8080 --library ./library --database ./photos.db --cache ./cache`
|
2019-06-21 09:22:42 -07:00
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
Arguments are as follows:
|
2019-06-21 09:22:42 -07:00
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
* `--library ./library` - store the hosted image files under this directory
|
|
|
|
* `--database ./photos.db` - store the SQLite database in this directory
|
|
|
|
* `--cache ./cache` - use this directory as a cache for things like thumbnails
|
|
|
|
* `--port 8080` - listen on http on port 8080
|
2019-06-21 09:22:42 -07:00
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
Depending on your setup, the `photousers` command can be used to create a user account. Login information is necessary
|
|
|
|
to see images marked as private or upload images.
|
2019-06-21 09:22:42 -07:00
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
* `photousers create -u dave -p mypassword`
|
|
|
|
|
|
|
|
That's it - you've set up Photolib! Next steps from here would be to the other command line tools to import media.
|
2019-06-21 09:22:42 -07:00
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
Besides browsing, most interaction with Photolib will be done using its CLI tool, `photocli`. Note that server address,
|
|
|
|
username, and password details need to be provided via flags not shown here to in a config file. See `photocli --help`
|
|
|
|
for more information.
|
2019-06-21 09:22:42 -07:00
|
|
|
|
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
Commands
|
|
|
|
--------
|
|
|
|
|
2019-06-21 09:22:42 -07:00
|
|
|
* `photocli ingest` - import new photos into the library:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
2019-07-04 17:29:49 -07:00
|
|
|
$ photocli ingest photos/*.jpg raws/*.cr2
|
|
|
|
```
|
|
|
|
|
|
|
|
or add a new format to an existing photo:
|
|
|
|
|
|
|
|
```
|
|
|
|
$ photocli ingest -c 52679a30-cee4-45c4-8d83-80ee92242e1c photos/*.jpg
|
|
|
|
```
|
|
|
|
|
2019-06-21 09:22:42 -07:00
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
* `photocli checkdupes` - scan files and print those not already in the library:
|
|
|
|
|
|
|
|
|
|
|
|
```
|
|
|
|
$ find source -type f -exec shasum -a 256 {} \; | tee shas.txt
|
|
|
|
544b5a4f3898abae73260930ee70931a3992c048649692cef89b37576e886f69 source/2018-12-09 13.52.22.jpg
|
|
|
|
d2c2c30ca4986d364026644881d667162031008e60aac6a69d7b18230b7ea98c source/2019-04-08 20.05.02.jpg
|
|
|
|
9d42859ed92d7fb978cf73b41293480e1eab03d2d3a14c185c4daf3a49d324ab source/2019-06-19 16.28.07.png
|
2019-06-21 09:22:42 -07:00
|
|
|
...
|
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
$ photocli checkdupes --sha-files shas.txt
|
2019-06-21 09:22:42 -07:00
|
|
|
```
|
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
TODO: support not using `--sha-files`.
|
|
|
|
|
|
|
|
This command, along with `ingest`, allows for fun tool combinations like so:
|
|
|
|
|
|
|
|
```
|
|
|
|
photocli checkdupes --sha-files shas.txt | xargs -d "\n" photocli -y ingest
|
|
|
|
```
|
2019-06-21 09:22:42 -07:00
|
|
|
|
2019-07-04 17:29:49 -07:00
|
|
|
This would ingest all the files listed in `shas.txt` that aren't already in the database.
|
|
|
|
|
|
|
|
|
|
|
|
Roadmap
|
|
|
|
-------
|
|
|
|
- Stateless aka docker support
|
|
|
|
- Photo storage
|
|
|
|
- ~~Abstract the storage api~~ done
|
|
|
|
- ~~Standardize on API ingest~~ done
|
|
|
|
- Display and retrieval of images from the abstracted image store
|
|
|
|
- Database support
|
2019-07-04 17:46:26 -07:00
|
|
|
- Get the web UI code (daemon.py) using the same db access method as the api
|
2019-07-04 17:29:49 -07:00
|
|
|
- Support any connection URI sqlalchemy is happy with
|
|
|
|
- Tune certain databases if their uri is detected (sqlite and threads lol)
|
|
|
|
- ~~Cache~~ done
|
|
|
|
- ~~Using the local fs seems fine?~~ done
|
|
|
|
- Option to cherrypy sessions - Redis?
|
|
|
|
- Flesh out CLI:
|
|
|
|
- Config that is saved somewhere
|
|
|
|
- Support additional fields on upload like title description tags etc
|
|
|
|
- delete features
|
|
|
|
- tag features
|
|
|
|
- modify features (tags & images)
|
|
|
|
|
|
|
|
- Longer term ideas:
|
|
|
|
- "fast ingest" method that touches the db/storage directly. This would scale better than the API ingest.
|