Giter VIP home page Giter VIP logo

photoview / photoview Goto Github PK

View Code? Open in Web Editor NEW
4.7K 40.0 354.0 49.19 MB

Photo gallery for self-hosted personal servers

Home Page: https://photoview.github.io/

License: GNU Affero General Public License v3.0

Dockerfile 0.38% JavaScript 0.57% HTML 0.11% Go 43.46% Shell 0.49% TypeScript 54.91% CSS 0.08%
photography raw docker nas selfhosted photo gallery photo-gallery photographers exif

photoview's Introduction

photoview logo

License GitHub contributors Docker Pulls Docker builds codecov

screenshot

Photoview is a simple and user-friendly photo gallery that's made for photographers and aims to provide an easy and fast way to navigate directories, with thousands of high-resolution photos.

You configure Photoview to look for photos and videos within a directory on your file system. The scanner automatically picks up your media and start to generate thumbnail images to make browsing super fast.

When your media has been scanned they show up on the website, organised in the same way as on the filesystem.

If you have questions regarding setup or development, feel free to join the Discord server https://discord.gg/jQ392948u9

Demo site

Visit https://photos.qpqp.dk/

Username: demo Password: demo

Contents

Main features

  • Closely tied to the file system. The website presents the images found on the local filesystem of the server, directories are mapped to albums.
  • User management. Each user is created along with a path on the local filesystem, photos within that path can be accessed by that user.
  • Sharing. Albums, as well as individual media, can easily be shared with a public link, the link can optionally be password protected.
  • Made for photography. Photoview is built with photographers in mind, and thus supports RAW file formats, and EXIF parsing.
  • Video support. Many common video formats are supported. Videos will automatically be optimized for web.
  • Face recognition. Faces will automatically be detected in photos, and photos of the same person will be grouped together.
  • Performant. Thumbnails are automatically generated and photos first load when they are visible on the screen. In full screen, thumbnails are displayed until the high resolution image has been fully loaded.
  • Secure. All media resources are protected with a cookie-token, all passwords are properly hashed, and the API uses a strict CORS policy.

Supported platforms

Why yet another self-hosted photo gallery

There exists a lot of open-source self-hosted photo galleries already. Here are some, just to mention a few.

So why another one? I love taking photos, and I store all of them on my local fileserver. This is great because I can organize my photos directly on the filesystem so it's easy to move them or take backups. I want to be able to control where and how the photos are stored.

The problem is however that RAW images are extremely tedious to navigate from a fileserver, even over the local network.

My server holds a lot of old family pictures, that I would like my family to have access to as well. And some of the pictures I would like to easily be able to share with other people without the hassle of them having to make an account first.

Thus I need a solution that can do the following:

  • A scan based approach that automatically organises my photos
  • Support RAW and EXIF parsing
  • Have support for multiple users and ways to share albums and photos also publicly
  • Be simple and fast to use

All of the photo galleries can do a lot of what I need, but no single one can do it all.

Getting started - Setup with Docker

This section describes how to get Photoview up and running on your server with Docker. Make sure you have Docker and docker-compose installed and running on your server

  1. Make a new docker-compose.yml file on your computer, and copy the content of docker-compose.example.yml to the new file.
  2. Edit docker-compose.yml, find the comments starting with Change This:, and change the values, to properly match your setup. If you are just testing locally, you don't have to change anything.
  3. Start the server by running the following command
$ docker-compose up -d

If the endpoint or the port hasn't been changed in the docker-compose.yml file, Photoview can now be accessed at http://localhost:8000

Initial Setup

If everything is setup correctly, you should be presented with an initial setup wizard, when accessing the website the first time.

Initial setup

Enter a new username and password.

For the photo path, enter the path in the docker container where your photos are located. This can be set from the docker-compose.yml file under api -> volumes. The default location is /photos

A new admin user will be created, with access to the photos located at the path provided under the initial setup.

The photos will have to be scanned before they show up, you can start a scan manually, by navigating to Settings and clicking on Scan All

Set up development environment

Local setup

  1. Install a local mysql server, and make a new database
  2. Rename /api/example.env to .env and update the MYSQL_URL field
  3. Rename /ui/example.env to .env

Start API server

Make sure golang is installed.

Some C libraries are needed to compile the API, see go-face requirements for more details. They can be installed as shown below:

# Ubuntu
sudo add-apt-repository ppa:strukturag/libheif
sudo add-apt-repository ppa:strukturag/libde265
sudo apt-get update
sudo apt-get install libdlib-dev libblas-dev libatlas-base-dev liblapack-dev libjpeg-turbo8-dev libheif-dev
# Debian
sudo apt-get install libdlib-dev libblas-dev libatlas-base-dev liblapack-dev libjpeg62-turbo-dev libheif-dev
# macOS
brew install dlib libheif

Then run the following commands:

cd ./api
go install
go run server.go

Start UI server

Make sure node is installed. In a new terminal window run the following commands:

cd ./ui
npm install
npm start

The site can now be accessed at localhost:1234. And the graphql playground at localhost:4001

Sponsors


@ericerkz

@robin-moser

@Revorge

@deexno

@FKrauss

@jupblb

photoview's People

Contributors

andrasmaroy avatar andreimk avatar bksoux avatar brnper avatar damix48 avatar davidecavestro avatar dependabot[bot] avatar djvaldez avatar elvece avatar feinedsquirrel avatar hartraft avatar hupfdule avatar john-devil avatar jordy2254 avatar kabakaev avatar katypurry avatar kjeldgaard avatar kkovaletp avatar orellazri avatar pj-watson avatar robin-moser avatar seam345 avatar stz184 avatar subdavis avatar tgrondier avatar tymmej avatar viktorstrate avatar windli001 avatar wswongat avatar zazou89 avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

photoview's Issues

Save GPS coordinates from EXIF data

Latitute and longitude should be added to the media_exif table, in preparation for v1.0.0.

This could be used in the future for grouping pictures by location, and displaying pictures on a map.

Options in admin settings

Options to be added to the admin settings page:

  • Number of concurrent workers for the scanner, currently fixed at 3
  • Per user permissions to allow/disallow the following (#571):
    • Change their password (#263)
    • Scan their own photos
    • Share media and albums (#435)
  • More scanner options (#31)

standard_init_linux.go:211: exec user process caused "exec format error"

I have just tried to get this running on OMV5 (Debian Buster) / ARMv7 using the Docker compose.

The Docker PhotoView logs show this:

standard_init_linux.go:211: exec user process caused "exec format error"

I can't access the server on the local network using it's IP (http://10.0.0.3:8088). I changed the port configuration in Docker below. The container itself keeps restarting.

curl http://10.0.0.3:8088
curl: (7) Failed to connect to 10.0.0.3 port 8088: Connection refused

I'm using the linuxserver/mariadb image because the stock mariadb image doesn't have an ARMv7 build.

Here's my docker-compose

version: "3"

services:
  db:
    image: linuxserver/mariadb
    container_name: mariadb
    environment:
      - PUID=1000
      - PGID=100
      - MYSQL_ROOT_PASSWORD=1234
      - TZ=America/Santiago
      - MYSQL_DATABASE=photoview
      - MYSQL_USER=photoview 
      - MYSQL_PASSWORD=abcd 
    volumes:
      - db_data:/config
    ports:
      - 3306:3306
    restart: unless-stopped

  photoview:
    image: viktorstrate/photoview:latest
    container_name: photoview
    restart: always
    ports:
      - "8088:80"
    depends_on:
      - db
    environment:
      - MYSQL_URL=photoview:abcd@tcp(db)/photoview
      - API_LISTEN_IP=photoview
      - API_LISTEN_PORT=80
      - PHOTO_CACHE=/app/cache
      - PUBLIC_ENDPOINT=http://10.0.0.3:80/
    volumes:
      - api_cache:/app/cache
      - /srv/dev-disk-by-label-NASHD/Photos/test:/photos:ro

volumes:
  db_data:
  api_cache:

I've tried the PUBLIC_ENDPOINT commented out completely, and on both ports 80 and 8088.

The mariadb logs don't show any errors

[s6-init] making user provided files available at /var/run/s6/etc...exited 0.,
[s6-init] ensuring user provided files have correct perms...exited 0.,
[fix-attrs.d] applying ownership & permissions fixes...,
[fix-attrs.d] done.,
[cont-init.d] executing container initialization scripts...,
[cont-init.d] 01-envfile: executing... ,
[cont-init.d] 01-envfile: exited 0.,
[cont-init.d] 10-adduser: executing... ,
,
-------------------------------------,
          _         (),
         | |  ___   _    __,
         | | / __| | |  /  \ ,
         | | \__ \ | | | () |,
         |_| |___/ |_|  \__/,
,
,
Brought to you by linuxserver.io,
-------------------------------------,
,
To support LSIO projects visit:,
https://www.linuxserver.io/donate/,
-------------------------------------,
GID/UID,
-------------------------------------,
,
User uid:    1000,
User gid:    100,
-------------------------------------,
,
[cont-init.d] 10-adduser: exited 0.,
[cont-init.d] 30-config: executing... ,
[cont-init.d] 30-config: exited 0.,
[cont-init.d] 40-initialise-db: executing... ,
[cont-init.d] 40-initialise-db: exited 0.,
[cont-init.d] 99-custom-scripts: executing... ,
[custom-init] no custom files found exiting...,
[cont-init.d] 99-custom-scripts: exited 0.,
[cont-init.d] done.,
[services.d] starting services,
[services.d] done.,
200922 16:27:11 mysqld_safe Logging to syslog.,
200922 16:27:11 mysqld_safe Starting mysqld daemon with databases from /config/databases,

Show image metadata

Right now when clicking on an image, a left panel appears. It would be great to display some metadata there, like:

  • date
  • location
  • file name
  • info of the camera that took the photo

Container crashes trying to run db migration

Updated to the latest image from an old image with a working setup. Now the container crashes while trying to run db migration.

2020/08/28 09:11:05 Connecting to database: user:password@tcp(mysql-host)/photoview?multiStatements=true&parseTime=true
photoview_1  | 2020/08/28 09:11:05 Could not migrate database: file does not exist
photoview_1  | panic: Could not migrate database: file does not exist
photoview_1  | 
photoview_1  | 
photoview_1  | goroutine 1 [running]:
photoview_1  | log.Panicf(0xa5ccca, 0x1f, 0xc0002557e8, 0x1, 0x1)
photoview_1  |  /usr/local/go/src/log/log.go:358 +0xc0
photoview_1  | main.main()
photoview_1  |  /app/server.go:41 +0x1a5

Advanced Search (search by exif)

Add a new page for more advanced searches.
Which allows the user to filter by:

  • Date range
  • Filter media type (video or photo or both)
  • General exif fields (camera, lens, flash settings etc.)

Maybe inspired by Github's advance search

Also add search tags in header search bar. like type:video date:>10-02-2020 landscape to search for videos after 10-02-2020 including the word landscape

Save filesize of media_url

The filesize of each media_url should be saved to the database, and shown on the UI in the sidebar under the "Download" section.

Improve selectable Album thumbnail

Hey,

thank you very much for this project. It is basically what I am looking for.
It would be great, if it would be possible to select the album thumbnail, instead of using the earliest Picture in a folder.
of course, I am willing to help, maybe you can hint me to the respective file, as I have never used JS or Go.

No Initial Setup screen on first build

I did a docker-compose installation following the steps on the ReadME file. Docker-compose builds everything fine, but the first screen is a normal login screen instead of a setup screen, so I have no way of logging in since I never did the setup for it. Any way to add an admin account or rebuild it in a way that will show the setup screen?

Delete share?

Can't see if I can delete a share once created?
The "More" button is just a placeholder?
Thanks a lot, like the simpleness and the featureset is exactly what I was looking for!

Allow hosting under subpath

I tried to host photoview under a subpath localhost/photos but couldn't get it to work. All the js/css resources are being loaded from /

Would be nice if photoview supported running under a subpath, since that would make hosting it in internal networks easy

Bug - Schema/SQL issues with manually deploying PhotoView

Trying to get photoview setup and running on a debian buster (10) bug, running mariadb version: 10.3.23-MariaDB-0+deb10u1 Debian 10.

was getting the following errors when photoview tried to do the db schema upgrade automatically:

2020/08/05 22:14:51 Could not migrate database: migration failed in line 0: ALTER TABLE photo RENAME TO media;
ALTER TABLE photo_url RENAME TO media_url;
ALTER TABLE photo_exif RENAME TO media_exif;

ALTER TABLE media RENAME COLUMN photo_id TO media_id;

ALTER TABLE media_url
  RENAME COLUMN photo_id TO media_id,
  RENAME COLUMN photo_name TO media_name;

ALTER TABLE share_token RENAME COLUMN photo_id TO media_id;

CREATE TABLE video_metadata (
  metadata_id int NOT NULL AUTO_INCREMENT,

  width int(6) NOT NULL,
  height int(6) NOT NULL,
  duration double NOT NULL,
  codec varchar(128),
  framerate double,
  bitrate int(24),
  color_profile varchar(128),
  audio varchar(128),

  PRIMARY KEY (metadata_id)
);

ALTER TABLE media
  ADD COLUMN media_type varchar(64) NOT NULL DEFAULT "photo",
  ADD COLUMN video_metadata_id int,
  ADD FOREIGN KEY (video_metadata_id) REFERENCES video_metadata(metadata_id);
 (details: Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COLUMN photo_id TO media_id;

ALTER TABLE media_url
  RENAME COLUMN photo_id ...' at line 1)
panic: Could not migrate database: migration failed in line 0: ALTER TABLE photo RENAME TO media;
ALTER TABLE photo_url RENAME TO media_url;
ALTER TABLE photo_exif RENAME TO media_exif;

ALTER TABLE media RENAME COLUMN photo_id TO media_id;

ALTER TABLE media_url
  RENAME COLUMN photo_id TO media_id,
  RENAME COLUMN photo_name TO media_name;

ALTER TABLE share_token RENAME COLUMN photo_id TO media_id;

CREATE TABLE video_metadata (
  metadata_id int NOT NULL AUTO_INCREMENT,

  width int(6) NOT NULL,
  height int(6) NOT NULL,
  duration double NOT NULL,
  codec varchar(128),
  framerate double,
  bitrate int(24),
  color_profile varchar(128),
  audio varchar(128),

  PRIMARY KEY (metadata_id)
);

ALTER TABLE media
  ADD COLUMN media_type varchar(64) NOT NULL DEFAULT "photo",
  ADD COLUMN video_metadata_id int,
  ADD FOREIGN KEY (video_metadata_id) REFERENCES video_metadata(metadata_id);
 (details: Error 1064: You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'COLUMN photo_id TO media_id;

ALTER TABLE media_url
  RENAME COLUMN photo_id ...' at line 1)


goroutine 1 [running]:
log.Panicf(0xa53733, 0x1f, 0xc0001417d8, 0x1, 0x1)
	/usr/lib/go-1.14/src/log/log.go:358 +0xc0
main.main()

when checking the state of the database at that point, the tables were as:

MariaDB [photoview]> show tables;
+---------------------+
| Tables_in_photoview |
+---------------------+
| access_token        |
| album               |
| media               |
| media_exif          |
| media_url           |
| schema_migrations   |
| share_token         |
| site_info           |
| user                |
+---------------------+
9 rows in set (0.000 sec)

If I manually source the upgrade files directly into the database to apply the schema changes, I get as far as 007_path_hash.up.sql, which errors with:

MariaDB [photoview]> source ./007_path_hash.up.sql
ERROR 1064 (42000) at line 3 in file: './007_path_hash.up.sql': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 12
ERROR 1060 (42S21) at line 17 in file: './007_path_hash.up.sql': Duplicate column name 'path_hash'
Query OK, 0 rows affected (0.000 sec)
Rows matched: 0  Changed: 0  Warnings: 0

Query OK, 0 rows affected, 1 warning (0.025 sec)
Records: 0  Duplicates: 0  Warnings: 1

ERROR 1064 (42000) at line 21 in file: './007_path_hash.up.sql': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'END IF' at line 1
ERROR 1064 (42000) at line 24 in file: './007_path_hash.up.sql': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near '' at line 8
ERROR 1060 (42S21) at line 34 in file: './007_path_hash.up.sql': Duplicate column name 'path_hash'
Query OK, 0 rows affected (0.000 sec)
Rows matched: 0  Changed: 0  Warnings: 0

Query OK, 0 rows affected, 1 warning (0.019 sec)
Records: 0  Duplicates: 0  Warnings: 1

ERROR 1064 (42000) at line 38 in file: './007_path_hash.up.sql': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'END IF' at line 1
ERROR 1064 (42000) at line 40 in file: './007_path_hash.up.sql': You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version for the right syntax to use near 'END' at line 1
ERROR 1305 (42000) at line 42 in file: './007_path_hash.up.sql': PROCEDURE photoview.MigratePathHashIfNeeded does not exist
ERROR 1305 (42000) at line 43 in file: './007_path_hash.up.sql': PROCEDURE photoview.MigratePathHashIfNeeded does not exist

Does photoview require a specific version of mysql/mariadb? have I missed a step somewhere? I've just been loosely following the Dockerfile script by manually running the commands (haven't created an app/ dir though) as I'm trying to avoid docker (personal preference, I feel it over complicates my life).

Any help is appreciated! otherwise it looks like a fantastic project.

docker-compose database connection error

I'm getting the following error when starting the container. I am using the hostname of the database because it doesn't use a static IP. I've tried different formatting unsuccessfully .

2020/08/14 12:21:43 Could not connect to database: Could not parse mysql url: parse "photoviewdb_user:photoviewdb_pass@tcp(mariadb)/photoview": first path segment in URL cannot contain colon,
panic: Could not connect to database: Could not parse mysql url: parse "photoviewdb_user:photoviewdb_pass@tcp(mariadb)/photoview": first path segment in URL cannot contain colon

Slideshow feature

Thanks for this project, it's really cool to see a simple folder based approach to photo browsing! The sharing photos are the icing on the cake.

I currently use ThumbsUp to generate static gallery websites, and it has a really cool slideshow feature that you can see for yourself at https://thumbsup.github.io/demos/themes/mosaic/albums/2015-March.html (just select a photo and press the play button on the top right).

It'd be awesome if Photoview had something similar!

Some portrait JPEGs are not rotated properly

I think this happends because photos are rotated acording to the exif data, but some browsers does this automatically as well, this results in the photo being rotated twice.

Since exif image rotation is not universal across browsers, the most stable solution would be to strip rotation from the exif data after the image has been rotated.

Content not loading because of insecure websocket endpoint

I'm trying to make photoview accessible through my reverse proxy (nginx). The location is loaded, however the content is not. My browser's inspector gives me the error below.

I don't really know much about websockets and I have tried out a couple of things I could find, but none worked. So, I am not sure if this is something you could or should do something about. Is it possible to make the endpoint available over WSS?

Or maybe someone already knows a solution?

(Real domain name redacted in the error below)

GRAPHQL ENDPOINT http://192.168.1.20:8080/api/graphql
client.ts:545 Mixed Content: The page at 'https://photos.example.com/' was loaded over HTTPS, but attempted to connect to the insecure WebSocket endpoint 'ws://192.168.1.20:8080/api/graphql'. This request has been blocked; this endpoint must be available over WSS.
e.connect @ client.ts:71
e @ client.ts:71
r @ webSocketLink.ts:30
parcelRequire.OaXc.@babel/runtime/helpers/toConsumableArray @ apolloClient.js:121
f @ ItemHeader.js:41
p @ ItemHeader.js:41
parcelRequire.Focm.react @ index.js:21
f @ ItemHeader.js:41
parcelRequire.J4Nk @ ItemHeader.js:41
(anonymous) @ ItemHeader.js:41
ItemDescription.js:41 Uncaught DOMException: Failed to construct 'WebSocket': An insecure WebSocket connection may not be initiated from a page loaded over HTTPS.
    at e.connect (https://photos.example.com/src.0fd3d741.js:1619:9265)
    at new e (https://photos.example.com/src.0fd3d741.js:1619:2980)
    at new r (https://photos.example.com/src.0fd3d741.js:1621:324)
    at Object.parcelRequire.OaXc.@babel/runtime/helpers/toConsumableArray (https://photos.example.com/src.0fd3d741.js:1627:1442)
    at f (https://photos.example.com/src.0fd3d741.js:1:468)
    at p (https://photos.example.com/src.0fd3d741.js:1:544)
    at Object.parcelRequire.Focm.react (https://photos.example.com/src.0fd3d741.js:1631:132)
    at f (https://photos.example.com/src.0fd3d741.js:1:468)
    at parcelRequire.J4Nk (https://photos.example.com/src.0fd3d741.js:1:771)
    at https://photos.example.com/src.0fd3d741.js:1:1023
parcelRequire.J4Nk @ ItemHeader.js:41
(anonymous) @ ItemHeader.js:41

add ignored path / excluded folders

I decided to run photoview on my personal photo library stored on the Synology NAS.
Most of the folders on the Synology have @eaDir folder with some system information.
That results in the scanner erros:

2020/04/16 01:35:16 ERROR: Could not read file /photos/2004/2004 10 Massachusets wedding/@eaDir/ะกะฒะฐะดัŒะฑะฐ ะ’ะธั‚ะฐะปะธ ะ›ะตะฝั‹''''''ะคะพั‚ะพ ะขะธะผะพั„ะตั 001.jpg@SynoEAStream: EOF
2020/04/16 01:35:16 Broadcasting notification: Scanner error
2020/04/16 01:35:16 ERROR: Could not read file /photos/2004/2004 10 Massachusets wedding/@eaDir/ะกะฒะฐะดัŒะฑะฐ ะ’ะธั‚ะฐะปะธ ะ›ะตะฝั‹''''''ะคะพั‚ะพ ะขะธะผะพั„ะตั 002.jpg@SynoEAStream: EOF
2020/04/16 01:35:16 Broadcasting notification: Scanner error

I suggest to have some env setting (in config / db / somewhere ...), with list of ignored folders.
And perhaps have some folder there included by defaults, such as:

@eaDir 
#snapshot
#recycle

Installation on Podman

As someone who ditched piwigo, I was excited to checkout photoview. But I'm on podman and not docker so docker compose won't work for me. I figured out the basics from the provided 'docker-compose.example.yml' and tried the command below:

sudo podman run -dt --pod fox --name=photoview -p 8000:80 -e MYSQL_URL='root:myrootpassword@tcp(127.0.0.1)'/photoview -e API_LISTEN_IP=127.0.0.1 -e API_LISTEN_PORT=8000 -e PHOTO_CACHE=/app/cache -e SERVE_UI=1 -e PUBLIC_ENDPOINT=http://127.0.0.1:8000/ -v /public/Photos/cache:/app/cache:z -v /public/Photos:/photos:z --net=host docker.io/photoview

Unfortunately I get this error when pulling the image:

Trying to pull docker.io/photoview...
  denied: requested access to the resource is denied
Error: error pulling image "docker.io/photoview": unable to pull docker.io/photoview: unable to pull image: Error initializing source docker://photoview:latest: Error reading manifest latest in docker.io/library/photoview: errors:
denied: requested access to the resource is denied
unauthorized: authentication required

Do I need a docker account to pull the image?
I tried searching the image manually in dockerhub but the only listed image that resembles what I'm looking for is 'r1chjames/photoview'.
I downloaded it just to test and I get the error below:

fox@ke1i ~]$ sudo podman logs photoview
2020/04/29 11:03:39 No .env file found
2020/04/29 11:03:39 Connecting to database: root:*******@tcp(127.0.0.1)/photoview?multiStatements=true&parseTime=true
2020/04/29 11:03:39 Database is up to date
2020/04/29 11:03:39 Photoview API endpoint listening at http://127.0.0.1:8000/api
2020/04/29 11:03:39 Photoview API public endpoint ready at http://ke1i.duckdns.org:8000/api
2020/04/29 11:03:39 Photoview UI public endpoint ready at http://ke1i.duckdns.org:8000/
2020/04/29 11:03:54 GET 304 ke1i.local:8000/ 5.90317ms unauthenticated

I get a blank page when I visit the public endpoint. So I know podman isn't the issue.

Additional information:

I already have a mariadb instance running (linuxserver.io one) and I've created a database named 'photoview' in it.

Options for sorting media from the UI

Adding a drop-down menu for sorting media by:

  • Date shot sorted by the date_shot database attribute on the media table
  • Date imported sorted by the date_imported attribute
  • Title the title attribute
  • Kind first sorted by media type (either photo or video), then by the file extension of the path attribute

This idea originated from #6 (comment)

Improve the web ui on mobiles

The web ui on mobile devices could be improved.

  • Left menu should be moved to the bottom on mobiles
  • A way to show right sidebar for images (and hide it again)
  • Navigation in fullscreen (exit, move left/right) see also #36

Scanner crash: panic: runtime error: slice bounds out of range

While scanning personal photo library, the scanner crashed on this photo:

DSC05995.zip

2020/04/16 06:32:51 Scanning directory: /photos/2005/2005 01 Ivan Reception
2020/04/16 06:32:51 Scanning image: /photos/2005/2005 01 Ivan Reception/DSC05995.JPG
2020/04/16 06:32:51 Scanning for EXIF
panic: runtime error: slice bounds out of range [:6] with capacity 0

goroutine 40820 [running]:
github.com/xor-gate/goexif2/mknote.(*nikonV3).Parse(0xebce00, 0xc00d722b40, 0x0, 0x0)
/go/pkg/mod/github.com/xor-gate/[email protected]/mknote/mknote.go:58 +0x268
github.com/xor-gate/goexif2/exif.Decode(0xaec1c0, 0xc00d136db0, 0x2, 0x2, 0xe81520)
/go/pkg/mod/github.com/xor-gate/[email protected]/exif/exif.go:331 +0x282
github.com/viktorstrate/photoview/api/scanner.ScanEXIF(0xc00d62cf80, 0xc00d6788c0, 0x0, 0x0, 0x1)
/app/scanner/exif.go:42 +0x280
github.com/viktorstrate/photoview/api/scanner.ScanPhoto(0xc00d62cf80, 0xc0000a0120, 0x30, 0x118, 0xc006452160, 0x8, 0x0, 0x4, 0xae8600, 0xc00d6d0840)
/app/scanner/photo_scanner.go:47 +0x4ed
github.com/viktorstrate/photoview/api/scanner.scan(0xc00015da40, 0xc00acdd600)
/app/scanner/album_scanner.go:193 +0x1081
created by github.com/viktorstrate/photoview/api/scanner.ScanUser
/app/scanner/album_scanner.go:95 +0x1ef
2020/04/16 06:32:55 No .env file found
2020/04/16 06:32:55 Connecting to database: photoview:photo-secret@tcp(db)/photoview?multiStatements=true&parseTime=true
2020/04/16 06:32:55 Database is up to date

I understand, that some images can be corrupt / has invalid EXIF info.
I think in such cases, scanning should skip just one image and continue with the rest.
The image above stopped the scanner in such a manner, that it didn't continue.

Button "Scan All" fails: GraphQL error: internal system error

I followed README to install system from scratch via Docker.
It started.

Result:

  • Nothing is scanned
  • Error in the browser console:
    Request URL: http://localhost:8000/api/graphql
    Request Method: POST
    Request Payload: {"operationName":"scanAllMutation","variables":{},"query":"mutation scanAllMutation {\n scanAll {\n success\n message\n __typename\n }\n}\n"}

Response Status Code: 200 OK
Response: {"errors":[{"message":"internal system error","path":["scanAll"]}],"data":null}

Browser error:

apolloClient.js:55
[GraphQL error]: Message: internal system error, Location: undefined Path: scanAll

ApolloError.ts:57 Uncaught (in promise) Error: GraphQL error: internal system error
at new r (ApolloError.ts:57)
at Object.next (QueryManager.ts:225)
at p (Observable.js:130)
at d (Observable.js:165)
at n.value (Observable.js:219)
at observables.ts:12
at Set.forEach ()
at Object.next (observables.ts:12)
at p (Observable.js:130)
at d (Observable.js:165)

Docker log:
Not implemented

goroutine 1536 [running]:
runtime/debug.Stack(0x1, 0x0, 0x0)
/usr/local/go/src/runtime/debug/stack.go:24 +0x9d
runtime/debug.PrintStack()
/usr/local/go/src/runtime/debug/stack.go:16 +0x22
github.com/99designs/gqlgen/graphql.DefaultRecover(0xae9840, 0xc000744c90, 0x94e160, 0xad2930, 0x3ca40, 0xeb8080)
/go/pkg/mod/github.com/99designs/[email protected]/graphql/recovery.go:16 +0xa7
github.com/viktorstrate/photoview/api/graphql.(*executionContext)._Mutation_scanAll.func1(0xc0003342e0, 0xc000334330, 0xc000269058)
/app/graphql/generated.go:2345 +0x78
panic(0x94e160, 0xad2930)
/usr/local/go/src/runtime/panic.go:969 +0x166
github.com/viktorstrate/photoview/api/graphql/resolvers.(*mutationResolver).ScanAll(0xc0001a6bb0, 0xae9840, 0xc000744c90, 0xe79230, 0x9847e0, 0xc0008f8480)
/app/graphql/resolvers/scanner.go:12 +0x39
github.com/viktorstrate/photoview/api/graphql.(*executionContext)._Mutation_scanAll.func2.1(0xae9840, 0xc000744c90, 0xe79230, 0x9847e0, 0xc0008f8480, 0x7efc65a027d0)
/app/graphql/generated.go:2360 +0x82
github.com/viktorstrate/photoview/api/graphql.IsAdmin.func1(0xae9840, 0xc000744c90, 0x0, 0x0, 0xc00035ce00, 0x20, 0x9b0760, 0xc000268f01, 0xc00035ce00)
/app/graphql/directive.go:20 +0xdc
github.com/viktorstrate/photoview/api/graphql.(*executionContext)._Mutation_scanAll.func2.2(0xae9840, 0xc000744c90, 0x30, 0x9d54c0, 0x18, 0x18)
/app/graphql/generated.go:2366 +0x5d
github.com/viktorstrate/photoview/api/graphql.(*executionContext)._Mutation_scanAll.func2(0xae9840, 0xc000744c90, 0x20, 0x9b0760, 0xae9801, 0xc00035cdc0)
/app/graphql/generated.go:2369 +0xbd
github.com/99designs/gqlgen/graphql/executor.processExtensions.func3(0xae9840, 0xc000744c90, 0xc00035cdc0, 0xae9840, 0xc000744c90, 0x7efc65a027d0, 0x0)
/go/pkg/mod/github.com/99designs/[email protected]/graphql/executor/extensions.go:62 +0x3a
github.com/viktorstrate/photoview/api/graphql.(*executionContext)._Mutation_scanAll(0xc0003342e0, 0xae9840, 0xc000744c60, 0xc00038dc80, 0xc000744c30, 0x3, 0x3, 0x0, 0x0)
/app/graphql/generated.go:2357 +0x1e0
github.com/viktorstrate/photoview/api/graphql.(*executionContext)._Mutation(0xc0003342e0, 0xae9840, 0xc000744c60, 0xc00001e5f0, 0x1, 0x1, 0x40c3f6, 0xc000744c00)
/app/graphql/generated.go:6299 +0x374
github.com/viktorstrate/photoview/api/graphql.(*executableSchema).Exec.func2(0xae9840, 0xc000744c00, 0x10)
/app/graphql/generated.go:996 +0x7b
github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1.1(0xae9840, 0xc000744c00, 0xc0003342f0)
/go/pkg/mod/github.com/99designs/[email protected]/graphql/executor/executor.go:105 +0x43
github.com/99designs/gqlgen/graphql/executor.processExtensions.func2(0xae9840, 0xc000744c00, 0xc0003342f0, 0xad2470)
/go/pkg/mod/github.com/99designs/[email protected]/graphql/executor/extensions.go:59 +0x3a
github.com/99designs/gqlgen/graphql/executor.(*Executor).DispatchOperation.func1.1(0xae9840, 0xc000744b10, 0xc000744990)
/go/pkg/mod/github.com/99designs/[email protected]/graphql/executor/executor.go:104 +0x12a
github.com/99designs/gqlgen/graphql/handler/transport.POST.Do(0xae7d80, 0xc0007448d0, 0xc0001fe700, 0xae7c00, 0xc0001ca120)
/go/pkg/mod/github.com/99designs/[email protected]/graphql/handler/transport/http_post.go:52 +0x353
github.com/99designs/gqlgen/graphql/handler.(*Server).ServeHTTP(0xc0001bc720, 0xae7d80, 0xc0007448d0, 0xc0001fe700)
/go/pkg/mod/github.com/99designs/[email protected]/graphql/handler/server.go:115 +0x1fd
net/http.HandlerFunc.ServeHTTP(0xc0001a2580, 0xae7d80, 0xc0007448d0, 0xc0001fe300)
/usr/local/go/src/net/http/server.go:2012 +0x44
github.com/viktorstrate/photoview/api/server.CORSMiddleware.func1.1(0xae7d80, 0xc0007448d0, 0xc0001fe300)
/app/server/cors_middleware.go:37 +0x7b1
net/http.HandlerFunc.ServeHTTP(0xc0001210a0, 0xae7d80, 0xc0007448d0, 0xc0001fe300)
/usr/local/go/src/net/http/server.go:2012 +0x44
github.com/viktorstrate/photoview/api/server.LoggingMiddleware.func1(0xae8400, 0xc0003ea7e0, 0xc0001fe300)
/app/server/logging.go:20 +0x152
net/http.HandlerFunc.ServeHTTP(0xc0001210c0, 0xae8400, 0xc0003ea7e0, 0xc0001fe300)
/usr/local/go/src/net/http/server.go:2012 +0x44
github.com/viktorstrate/photoview/api/graphql/auth.Middleware.func1.1(0xae8400, 0xc0003ea7e0, 0xc000107c00)
/app/graphql/auth/auth.go:55 +0x2d5
net/http.HandlerFunc.ServeHTTP(0xc0001210e0, 0xae8400, 0xc0003ea7e0, 0xc000107c00)
/usr/local/go/src/net/http/server.go:2012 +0x44
github.com/gorilla/mux.(*Router).ServeHTTP(0xc0002b8000, 0xae8400, 0xc0003ea7e0, 0xc0001fe200)
/go/pkg/mod/github.com/gorilla/[email protected]/mux.go:210 +0xe2
net/http.serverHandler.ServeHTTP(0xc0002c40e0, 0xae8400, 0xc0003ea7e0, 0xc0001fe200)
/usr/local/go/src/net/http/server.go:2807 +0xa3
net/http.(*conn).serve(0xc0002bb360, 0xae9780, 0xc0005fcc00)
/usr/local/go/src/net/http/server.go:1895 +0x86c
created by net/http.(*Server).Serve
/usr/local/go/src/net/http/server.go:2933 +0x35c

Feature request: Metadata templates

As a film photographer, I would like to have templates with Camera, Film. film ISO, etc, so I can apply those templates to the scanned photos ,

Password protected shares

Public shares can already be password protected with the Graphql api, but this hasn't been implemented in the web interface yet.

Share mutations can take an optional password, when the share is generated

type Mutation {
  shareAlbum(albumId: Int!, expire: Time, password: String): ShareToken
  sharePhoto(photoId: Int!, expire: Time, password: String): ShareToken
}

General scanner improvements

A list of general improvements for the scanner component

  • Periodic scans: An admin should be able to set up periodic automatic scans, to automatically look for new photos at a fixed time interval.

  • Better user feedback when scanner is looking for new photos: For large photo directories it can take a long time for the scanner to verify already scanned photos, in this time no notifications is shown to the user, which could make one think that it isn't scanning

  • Cancel scans: When a scanner progress notification is dismissed Add a cancel button to the scanner progress notification to cancel that job

  • Queue system: When users are requested to be scanned they should be added to a scanner queue such that only X users are scanned at a time, and if a users is requested to be scanned while the scanner is already in the progress of scanning that user the request should be ignored.

  • Live photo refresh: Load in new photos live as they are scanned, while the scanner is still running.

  • Show logs and current jobs in settings: From the settings page show a log of previous scans and what errors that was encounterd. Also show the current running and queued jobs.

  • Show overall scanner progress (#515)

Ignore hidden files

The scanner already ignores hidden directories and hidden files are often just metadata.

Database connection problems with docker-compose

Multiple have reported connection issues with docker-compose

I think it is a connection problem between the api and the database (mariadb).
Please note the database version 10.4.12-MariaDB-1:10.4.12+maria~bionic
This might be a related issue MariaDB/mariadb-docker#262

Replication

I have just tried to replicate the issue but everything seems to work fine. See console output below.

Can someone please try to replicate it by running

# Delete all previous volumes 
$ docker-compose down -v

# Recreate the containers from scratch
$ docker-compose up --force-recreate --build

When the api container prints database migrated, please navigate to http://localhost:8080, and you should be redirected to the initial setup wizard

Output log
$ cp docker-compose.example.yml docker-compose.yml
$ docker-compose up
Creating network "photoview_default" with the default driver
Creating volume "photoview_db_data" with default driver
Creating volume "photoview_api_cache" with default driver
Creating photoview_db_1 ... done
Creating photoview_api_1 ... done
Creating photoview_ui_1  ... done
Creating photoview_proxy_1 ... done
Attaching to photoview_db_1, photoview_api_1, photoview_ui_1, photoview_proxy_1
api_1    | 2020/03/02 14:22:03 Connecting to database: photoview:photo-secret@tcp(db)/photoview?multiStatements=true&parseTime=true
db_1     | 2020-03-02 14:22:03+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.4.12+maria~bionic started.
db_1     | 2020-03-02 14:22:03+00:00 [Note] [Entrypoint]: Switching to dedicated user 'mysql'
api_1    | 2020/03/02 14:22:03 Could not ping database: dial tcp 172.19.0.2:3306: connect: connection refused. Will retry after 1 second
db_1     | 2020-03-02 14:22:03+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 1:10.4.12+maria~bionic started.
db_1     | 2020-03-02 14:22:03+00:00 [Note] [Entrypoint]: Initializing database files
api_1    | 2020/03/02 14:22:04 Could not ping database: dial tcp 172.19.0.2:3306: connect: connection refused. Will retry after 1 second
api_1    | 2020/03/02 14:22:05 Could not ping database: dial tcp 172.19.0.2:3306: connect: connection refused. Will retry after 1 second
db_1     |
db_1     |
db_1     | PLEASE REMEMBER TO SET A PASSWORD FOR THE MariaDB root USER !
db_1     | To do so, start the server, then issue the following commands:
db_1     |
db_1     | '/usr/bin/mysqladmin' -u root password 'new-password'
db_1     | '/usr/bin/mysqladmin' -u root -h  password 'new-password'
db_1     |
db_1     | Alternatively you can run:
db_1     | '/usr/bin/mysql_secure_installation'
db_1     |
db_1     | which will also give you the option of removing the test
db_1     | databases and anonymous user created by default.  This is
db_1     | strongly recommended for production servers.
db_1     |
db_1     | See the MariaDB Knowledgebase at http://mariadb.com/kb or the
db_1     | MySQL manual for more instructions.
db_1     |
db_1     | Please report any problems at http://mariadb.org/jira
db_1     |
db_1     | The latest information about MariaDB is available at http://mariadb.org/.
db_1     | You can find additional information about the MySQL part at:
db_1     | http://dev.mysql.com
db_1     | Consider joining MariaDB's strong and vibrant community:
db_1     | https://mariadb.org/get-involved/
db_1     |
db_1     | 2020-03-02 14:22:06+00:00 [Note] [Entrypoint]: Database files initialized
db_1     | 2020-03-02 14:22:06+00:00 [Note] [Entrypoint]: Starting temporary server
db_1     | 2020-03-02 14:22:06+00:00 [Note] [Entrypoint]: Waiting for server startup
db_1     | 2020-03-02 14:22:06 0 [Note] mysqld (mysqld 10.4.12-MariaDB-1:10.4.12+maria~bionic) starting as process 122 ...
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Using Linux native AIO
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Uses event mutexes
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Number of pools: 1
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Using SSE2 crc32 instructions
db_1     | 2020-03-02 14:22:06 0 [Note] mysqld: O_TMPFILE is not supported on /tmp (disabling future attempts)
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Initializing buffer pool, total size = 256M, instances = 1, chunk size = 128M
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Completed initialization of buffer pool
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Creating shared tablespace for temporary tables
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Waiting for purge to start
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: 10.4.12 started; log sequence number 60972; transaction id 21
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
db_1     | 2020-03-02 14:22:06 0 [Note] Plugin 'FEEDBACK' is disabled.
db_1     | 2020-03-02 14:22:06 0 [Warning] 'user' entry 'root@0829d713736a' ignored in --skip-name-resolve mode.
db_1     | 2020-03-02 14:22:06 0 [Warning] 'user' entry '@0829d713736a' ignored in --skip-name-resolve mode.
db_1     | 2020-03-02 14:22:06 0 [Warning] 'proxies_priv' entry '@% root@0829d713736a' ignored in --skip-name-resolve mode.
db_1     | 2020-03-02 14:22:06 0 [Note] InnoDB: Buffer pool(s) load completed at 200302 14:22:06
db_1     | 2020-03-02 14:22:06 0 [Note] Reading of all Master_info entries succeeded
db_1     | 2020-03-02 14:22:06 0 [Note] Added new Master_info '' to hash table
db_1     | 2020-03-02 14:22:06 0 [Note] mysqld: ready for connections.
db_1     | Version: '10.4.12-MariaDB-1:10.4.12+maria~bionic'  socket: '/var/run/mysqld/mysqld.sock'  port: 0  mariadb.org binary distribution
api_1    | 2020/03/02 14:22:06 Could not ping database: dial tcp 172.19.0.2:3306: connect: connection refused. Will retry after 1 second
db_1     | 2020-03-02 14:22:07+00:00 [Note] [Entrypoint]: Temporary server started.
api_1    | 2020/03/02 14:22:07 ERROR: Could not ping database, exiting
db_1     | Warning: Unable to load '/usr/share/zoneinfo/leap-seconds.list' as time zone. Skipping it.
api_1    | 2020/03/02 14:22:08 Could not ping database: dial tcp 172.19.0.2:3306: connect: connection refused. Will retry after 1 second
api_1    | 2020/03/02 14:22:09 Could not ping database: dial tcp 172.19.0.2:3306: connect: connection refused. Will retry after 1 second
api_1    | 2020/03/02 14:22:10 Could not ping database: dial tcp 172.19.0.2:3306: connect: connection refused. Will retry after 1 second
api_1    | 2020/03/02 14:22:11 ERROR: Could not ping database, exiting
photoview_api_1 exited with code 1
db_1     | 2020-03-02 14:22:13+00:00 [Note] [Entrypoint]: GENERATED ROOT PASSWORD: jeixeiM8Ahjee4phiathai7beith8boh
db_1     | 2020-03-02 14:22:13 10 [Warning] 'proxies_priv' entry '@% root@0829d713736a' ignored in --skip-name-resolve mode.
db_1     | 2020-03-02 14:22:13+00:00 [Note] [Entrypoint]: Creating database photoview
db_1     | 2020-03-02 14:22:13+00:00 [Note] [Entrypoint]: Creating user photoview
db_1     | 2020-03-02 14:22:13+00:00 [Note] [Entrypoint]: Giving user photoview access to schema photoview
db_1     | 2020-03-02 14:22:13 14 [Warning] 'proxies_priv' entry '@% root@0829d713736a' ignored in --skip-name-resolve mode.
db_1     |
db_1     | 2020-03-02 14:22:13+00:00 [Note] [Entrypoint]: Stopping temporary server
db_1     | 2020-03-02 14:22:13 0 [Note] mysqld (initiated by: root[root] @ localhost []): Normal shutdown
db_1     | 2020-03-02 14:22:13 0 [Note] Event Scheduler: Purging the queue. 0 events
db_1     | 2020-03-02 14:22:13 0 [Note] InnoDB: FTS optimize thread exiting.
db_1     | 2020-03-02 14:22:13 0 [Note] InnoDB: Starting shutdown...
db_1     | 2020-03-02 14:22:13 0 [Note] InnoDB: Dumping buffer pool(s) to /var/lib/mysql/ib_buffer_pool
db_1     | 2020-03-02 14:22:13 0 [Note] InnoDB: Buffer pool(s) dump completed at 200302 14:22:13
api_1    | 2020/03/02 14:22:13 Could not ping database: dial tcp 172.19.0.2:3306: connect: connection refused. Will retry after 1 second
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Shutdown completed; log sequence number 60981; transaction id 24
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Removed temporary tablespace data file: "ibtmp1"
db_1     | 2020-03-02 14:22:14 0 [Note] mysqld: Shutdown complete
db_1     |
db_1     | 2020-03-02 14:22:14+00:00 [Note] [Entrypoint]: Temporary server stopped
db_1     |
db_1     | 2020-03-02 14:22:14+00:00 [Note] [Entrypoint]: MySQL init process done. Ready for start up.
db_1     |
db_1     | 2020-03-02 14:22:14 0 [Note] mysqld (mysqld 10.4.12-MariaDB-1:10.4.12+maria~bionic) starting as process 1 ...
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Using Linux native AIO
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Mutexes and rw_locks use GCC atomic builtins
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Uses event mutexes
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Compressed tables use zlib 1.2.11
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Number of pools: 1
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Using SSE2 crc32 instructions
db_1     | 2020-03-02 14:22:14 0 [Note] mysqld: O_TMPFILE is not supported on /tmp (disabling future attempts)
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Initializing buffer pool, total size = 256M, instances = 1, chunk size = 128M
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Completed initialization of buffer pool
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: If the mysqld execution user is authorized, page cleaner thread priority can be changed. See the man page of setpriority().
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: 128 out of 128 rollback segments are active.
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Creating shared tablespace for temporary tables
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Setting file './ibtmp1' size to 12 MB. Physically writing the file full; Please wait ...
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: File './ibtmp1' size is now 12 MB.
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Waiting for purge to start
api_1    | 2020/03/02 14:22:14 Could not ping database: dial tcp 172.19.0.2:3306: connect: connection refused. Will retry after 1 second
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: 10.4.12 started; log sequence number 60981; transaction id 21
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Loading buffer pool(s) from /var/lib/mysql/ib_buffer_pool
db_1     | 2020-03-02 14:22:14 0 [Note] Plugin 'FEEDBACK' is disabled.
db_1     | 2020-03-02 14:22:14 0 [Note] Server socket created on IP: '::'.
db_1     | 2020-03-02 14:22:14 0 [Warning] 'proxies_priv' entry '@% root@0829d713736a' ignored in --skip-name-resolve mode.
db_1     | 2020-03-02 14:22:14 0 [Note] InnoDB: Buffer pool(s) load completed at 200302 14:22:14
db_1     | 2020-03-02 14:22:14 0 [Note] Reading of all Master_info entries succeeded
db_1     | 2020-03-02 14:22:14 0 [Note] Added new Master_info '' to hash table
db_1     | 2020-03-02 14:22:14 0 [Note] mysqld: ready for connections.
db_1     | Version: '10.4.12-MariaDB-1:10.4.12+maria~bionic'  socket: '/var/run/mysqld/mysqld.sock'  port: 3306  mariadb.org binary distribution
api_1    | 2020/03/02 14:22:15 Database migrated
api_1    | 2020/03/02 14:22:15 ๐Ÿš€ Graphql playground ready at http://localhost:8080/api

Don't scan hidden folders

When hidden folders contain images, they are scanned and put into an album.

In my case a .sync folder was created at the root of my photos directory by resilio sync. I know other syncing and file management applications (like filerun for example) use hidden folders as a cache for browsing pictures.

I think Photoview should ignore hidden folders and files, or have an option to do so.

Add OpenGraph metadata to public shares

Add OpenGraph meta tags to the header on public shares, with the album or media thumbnail.

This would improve the presentation when urls are shared on social media.

UI issues: "View all photos of the album"

I really like the general UI of the photoview.
That's what's special about this product. I think no other apps can show such a nice and fast overview.

However, there are few workflows which supported rather poorly.
Specifically, this workflow: "View all photos of the album"

A. I'm using mouse (or touch screen) to navigate to the album.
B. I'm opening 1st photo fullsize (fullscreen)
C. Now, there is no way to proceed to the next photo with the mouse (or touch screen). Also, you can't close full view using a mouse or touchscreen.

  • On the desktop computer I have to use the keyboard (and click => or <= ), which is inconvenient.
  • But on the mobile device, you really are stuck, because there is no keyboard.
    And since the BACK button doesn't work, too (see #35) - it is really an issue.

Suggestion:

  • add PREV and NEXT action by mouse click (or tap/slide) on the left or right side of the image.
  • I'm not sure, how to handle ESC case (closing fullview without keyboard). May be "X" icon at the top corner? or something else?

Timeline Photos View

Hi @viktorstrate,

I am enjoying this project a lot. The emphasis on maintaining the existing album structure is really important to me, and is one of the things that sets this project apart. Nevertheless, I find that exploring my photos in a timeline-style adds a nice alternative way of navigating photos. Currently the Photos page and Albums page are offering quite a bit of overlapping functionality, so I tried loading all my pictures into a single PhotoGallery and the performance was reasonably good (vdwees@974ea5f). I could see this looking a bit like Google Photos, with pictures delimited by year. What do you think of this functionality?

Add a date-shot and date-imported property to all media

The date shot property should represent the date the media was shot, this should be extracted from the exif data if present, otherwise the file creation date should be used.

The date imported should be set to the date and time of when the media was imported into Photoview.

These additions are required to later implement a proper timeline page, see #48.

Scan error on column index 0, name "orientation": converting NULL to int is unsupported

I added few photos and started "Scan".

For most of the photos, I'm getting same scan error:

2020/04/14 20:11:34 Scanning for EXIF
2020/04/14 20:11:34 WARN: Could not read LensModel from EXIF: IMG_6433.JPG
2020/04/14 20:11:34 WARN: Could not read Orientation from EXIF: IMG_6433.JPG
2020/04/14 20:11:34 WARN: Could not read ExposureProgram from EXIF: IMG_6433.JPG
2020/04/14 20:11:34 Broadcasting notification: Scan completed
2020/04/14 20:11:34 Broadcasting notification: Processing photos (0 of 137)
2020/04/14 20:11:34 Processing photo: /photos/2010 11 Thanksgiving - SNOW/IMG_1438.JPG
2020/04/14 20:11:34 ERROR: Could not process photo (/photos/2010 11 Thanksgiving - SNOW/IMG_1438.JPG): sql: Scan error on column index 0, name "orientation": converting NULL to int is unsupported
2020/04/14 20:11:34 Broadcasting notification: Scanner error

Any workaround for this issue?

Additional users cannot see photos (single photo path)

I probably have a misunderstanding about how multiple users are supposed to work. Can multiple users share the same photo path?

I have a single directory of photos mapped to /photos in the Docker container. For the admin user I set /photos as the photo path. All the photos appear for that user. I then added a second user (another family member) and also configured that user's photo path to /photos, but no photos are visible. Are the photo paths exclusive to each user?

Show photos by location on a map

Add "Places" to the sidebar, which when clicked will show a map with all geo-tagged photos.
Inspired by the Photos app by Apple.

Mapbox could be used with its clusters feature, to render the photos onto the map.

Running with armhf (v7)

Hi,

First, great project idea ! I was looking for that kind of app for my personal server and my photos.

I'm trying to run it with an armv7 processor.

I have done some specific modifications in the dockercompose:

  • the mariadb version is not compatible and I already have a Mariadb on my server so I removed the mariadb part and add the IP of the database
$ mariadb --version
mariadb  Ver 15.1 Distrib 10.3.22-MariaDB, for debian-linux-gnueabihf (armv8l) using readline 5.2
  • I had to modify the go build to build into arm v7.
RUN CGO_ENABLED=0 GOOS=linux GOARM=7 GOARCH=arm go build -o photoview .

It runs, connects to Mariadb (I suppose) but after I have an error :

CREATE TABLE IF NOT EXISTS photo_url (
  url_id int NOT NULL AUTO_INCREMENT,
  photo_id int NOT NULL,
  photo_name varchar(512) NOT NULL,
  width int NOT NULL,
  height int NOT NULL,
  purpose varchar(64) NOT NULL,
  content_type varchar(64) NOT NULL,

  PRIMARY KEY (url_id),
  FOREIGN KEY (photo_id) REFERENCES photo(photo_id) ON DELETE CASCADE
); (details: Error 1071: Specified key was too long; max key length is 3072 bytes)
2020/04/13 10:49:49 No .env file found
2020/04/13 10:49:49 Connecting to database: username:password@tcp(192.168.1.38)/photoview?multiStatements=true&parseTime=true
2020/04/13 10:49:49 Could not migrate database: Dirty database version 2. Fix and force version.

The database was empty.

Maybe you'll have an idea !
I continue to look.

Invalid root path for pictures?

Hey there.

Thank you very much for this project but I have the following problem.

Always when I want to change the "Photo path" in the Web-GUI I get the following error:
servererror

I don't have much experience with Docker. Probably a small mistake made by me.

I would like to change my photo path to: /etc/photos

What do I need to change?

Thank you for your help.

Comparison with Lychee

I'm pleased to discover this cool application that corresponds to what I've been looking for since a long time. It seems that you didn't include lychee (https://lychee.electerious.com/) in the list of available alternatives. What is the advantage of photoview compared to Lychee ?

Favourite images

  • When the heart icon on a photo is clicked, the image should be favourited so it is easier to find.
  • There should be a way to filter favourited photos. Maybe a link in the sidebar?

Photo duplication detection

Some cameras can be set to save both raw and jpeg photos.

Detect duplicate photos with different types but identical names.
And only show one photo in the UI but let users be able to download all versions, from the side menu.

Support more RAW formats

Currently Cannon's CR2 format is the only RAW format that is supported.

Possible solutions

  • Image conversion could probably be done using govips
    Edit: I couldn't get this to work for RAW photos as govips thought they were TIFF format (related issue davidbyttow/govips/issues/51)

  • RAW photos could be converted into TIFF before decoding, using somthing like dcraw.
    Possibly slow and complicated

  • RAW photos could be converted into JPG by an external cli program (like photoprism does here)

Other references:
https://github.com/photoprism/photoprism/wiki/Converting-RAW-to-JPEG
https://github.com/h2non/bimg

Photoview behind Traefik v2

I can't seem to be able to run Photoview behind traefik. It's just stuck loading and timed out.

Here's my compose file:

version: "3"

services:
  db:
    container_name: photoview-db
    image: mariadb
    restart: always
    environment:
      - MYSQL_DATABASE=photoview
      - MYSQL_USER=photoview
      - MYSQL_PASSWORD=photo-secret
      - MYSQL_RANDOM_ROOT_PASSWORD=1
    volumes:
      - db_data:/var/lib/mysql

  photoview:
    container_name: photoview-app
    image: viktorstrate/photoview:latest
    restart: always
    depends_on:
      - db

    environment:
      - MYSQL_URL=photoview:photo-secret@tcp(db)/photoview
      - API_LISTEN_IP=photoview
      - API_LISTEN_PORT=80
      - PHOTO_CACHE=/app/cache

      # Change This: The publicly exposed url
      # For example if the server is available from the domain example.com,
      # change this value to http://example.com/
      - API_ENDPOINT=https://my.domain.tld/api/
      - PUBLIC_ENDPOINT=https://my.domain.tld/

    volumes:
      - api_cache:/app/cache

      # Change this to the directory where your photos are located on your server.
      # If the photos are located at `/home/user/photos`, then change this value
      # to the following: `/home/user/photos:/photos:ro`.
      # You can mount multiple paths, if your photos are spread across multiple directories.
      - /tmp/photos:/photos:ro

    labels:
      - "traefik.http.routers.photoview.entrypoints=http"
      - "traefik.http.routers.photoview.middlewares=redirect-to-https@docker"
      - "traefik.http.routers.photoview.rule=Host(`my.domain.tld`)"
      - "traefik.http.routers.photoview-secure.entrypoints=https"
      - "traefik.http.routers.photoview-secure.rule=Host(`my.domain.tld`)"
      - "traefik.http.routers.photoview-secure.tls=true"
      - "traefik.http.routers.photoview-secure.tls.certresolver=letsencrypt"

volumes:
  db_data:
  api_cache:

BACK browser button doesn't work on Fullscreen view

Steps:

  • open any photo fullsize (fullscreen)
  • click browser BACK button

Defect:

  • URL doesn't change (if you click BACK once). Other times - it changes to previous page (if press BACK twice)
  • but in all cases - the page is not rendered. Just blank screen showed

Error in the console:

react-dom.production.min.js:209 TypeError: Cannot read property 'thumbnail' of undefined
    at s (PresentView.js:50)
    at ua (react-dom.production.min.js:153)
    at Ro (react-dom.production.min.js:261)
    at Lu (react-dom.production.min.js:246)
    at Ru (react-dom.production.min.js:246)
    at Cu (react-dom.production.min.js:239)
    at react-dom.production.min.js:123
    at exports.unstable_runWithPriority (scheduler.production.min.js:19)
    at ri (react-dom.production.min.js:122)
    at oi (react-dom.production.min.js:123)
go @ react-dom.production.min.js:13


PresentView.js:50 Uncaught TypeError: Cannot read property 'thumbnail' of undefined
    at s (PresentView.js:50)
    at ua (react-dom.production.min.js:153)
    at Ro (react-dom.production.min.js:261)
    at Lu (react-dom.production.min.js:246)
    at Ru (react-dom.production.min.js:246)
    at Cu (react-dom.production.min.js:239)
    at react-dom.production.min.js:123
    at exports.unstable_runWithPriority (scheduler.production.min.js:19)
    at ri (react-dom.production.min.js:122)
    at oi (react-dom.production.min.js:123)

TIFF Support

Add support for TIFF images in process_photo.go

The image decoder has to be manually selected based on content_type, as the cr2 decoder go package will not work, if the tiff decoder is loaded

Known limitations: Because TIFF files and CR2 files share the same first few bytes, the image package's file type detection will fail to recognize a cr2 if the tiff reader is also imported.

Search

Add a search field to the top bar, where photo names, exif data, album names etc. can be searched from.

When typing a drop-down with results should appear.
For photos and albums, thumbnails should be shown along with the names.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.