2020-02-05 14:51:46 +01:00
package resolvers
import (
"context"
2020-02-24 23:56:28 +01:00
"database/sql"
2020-02-09 14:21:53 +01:00
"errors"
2020-02-10 12:05:58 +01:00
"log"
2020-02-14 13:31:44 +01:00
"strings"
2020-02-05 14:51:46 +01:00
api "github.com/viktorstrate/photoview/api/graphql"
"github.com/viktorstrate/photoview/api/graphql/auth"
"github.com/viktorstrate/photoview/api/graphql/models"
2020-02-14 13:31:44 +01:00
"github.com/viktorstrate/photoview/api/scanner"
2020-02-05 14:51:46 +01:00
)
2020-02-09 15:26:59 +01:00
func ( r * queryResolver ) MyPhotos ( ctx context . Context , filter * models . Filter ) ( [ ] * models . Photo , error ) {
2020-02-09 14:21:53 +01:00
user := auth . UserFromContext ( ctx )
if user == nil {
return nil , errors . New ( "unauthorized" )
}
2020-02-09 15:26:59 +01:00
filterSQL , err := filter . FormatSQL ( )
if err != nil {
return nil , err
}
2020-02-27 16:26:53 +01:00
rows , err := r . Database . Query ( `
SELECT photo . * FROM photo , album
WHERE photo . album_id = album . album_id AND album . owner_id = ?
AND photo . photo_id IN (
SELECT photo_id FROM photo_url WHERE photo_url . photo_id = photo . photo_id
)
` + filterSQL , user . UserID )
2020-02-09 14:21:53 +01:00
if err != nil {
return nil , err
}
return models . NewPhotosFromRows ( rows )
2020-02-05 14:51:46 +01:00
}
2020-02-09 21:25:33 +01:00
func ( r * queryResolver ) Photo ( ctx context . Context , id int ) ( * models . Photo , error ) {
2020-02-05 14:51:46 +01:00
user := auth . UserFromContext ( ctx )
if user == nil {
return nil , auth . ErrUnauthorized
}
row := r . Database . QueryRow ( `
SELECT photo . * FROM photo
2020-02-27 16:26:53 +01:00
JOIN album ON photo . album_id = album . album_id
2020-02-05 14:51:46 +01:00
WHERE photo . photo_id = ? AND album . owner_id = ?
2020-02-27 16:26:53 +01:00
AND photo . photo_id IN (
SELECT photo_id FROM photo_url WHERE photo_url . photo_id = photo . photo_id
)
2020-02-05 14:51:46 +01:00
` , id , user . UserID )
photo , err := models . NewPhotoFromRow ( row )
if err != nil {
return nil , err
}
return photo , nil
}
type photoResolver struct {
* Resolver
}
func ( r * Resolver ) Photo ( ) api . PhotoResolver {
return & photoResolver { r }
}
2020-02-10 12:05:58 +01:00
func ( r * photoResolver ) Shares ( ctx context . Context , obj * models . Photo ) ( [ ] * models . ShareToken , error ) {
2020-02-11 15:36:12 +01:00
rows , err := r . Database . Query ( "SELECT * FROM share_token WHERE photo_id = ?" , obj . PhotoID )
if err != nil {
return nil , err
}
return models . NewShareTokensFromRows ( rows )
2020-02-10 12:05:58 +01:00
}
func ( r * photoResolver ) Downloads ( ctx context . Context , obj * models . Photo ) ( [ ] * models . PhotoDownload , error ) {
2020-02-21 22:42:39 +01:00
rows , err := r . Database . Query ( "SELECT * FROM photo_url WHERE photo_id = ?" , obj . PhotoID )
if err != nil {
return nil , err
}
photoUrls , err := models . NewPhotoURLFromRows ( rows )
if err != nil {
return nil , err
}
2020-02-10 12:05:58 +01:00
downloads := make ( [ ] * models . PhotoDownload , 0 )
2020-02-21 22:42:39 +01:00
for _ , url := range photoUrls {
var title string
switch {
case url . Purpose == models . PhotoOriginal :
title = "Original"
case url . Purpose == models . PhotoThumbnail :
title = "Small"
case url . Purpose == models . PhotoHighRes :
title = "Large"
}
downloads = append ( downloads , & models . PhotoDownload {
Title : title ,
Width : url . Width ,
Height : url . Height ,
URL : url . URL ( ) ,
} )
}
2020-02-10 12:05:58 +01:00
return downloads , nil
2020-02-09 12:53:21 +01:00
}
2020-02-10 12:05:58 +01:00
func ( r * photoResolver ) HighRes ( ctx context . Context , obj * models . Photo ) ( * models . PhotoURL , error ) {
2020-02-14 13:31:44 +01:00
// Try high res first, then
web_types_questions := strings . Repeat ( "?," , len ( scanner . WebMimetypes ) ) [ : len ( scanner . WebMimetypes ) * 2 - 1 ]
args := make ( [ ] interface { } , 0 )
args = append ( args , obj . PhotoID , models . PhotoHighRes , models . PhotoOriginal )
for _ , webtype := range scanner . WebMimetypes {
args = append ( args , webtype )
}
row := r . Database . QueryRow ( `
SELECT * FROM photo_url WHERE photo_id = ? AND
(
purpose = ? OR ( purpose = ? AND content_type IN ( ` +web_types_questions+ ` ) )
) LIMIT 1
` , args ... )
2020-02-05 14:51:46 +01:00
2020-02-09 14:21:53 +01:00
url , err := models . NewPhotoURLFromRow ( row )
if err != nil {
2020-02-14 14:29:41 +01:00
log . Printf ( "Error: Could not query highres: %s\n" , err )
2020-02-09 14:21:53 +01:00
return nil , err
}
2020-02-05 14:51:46 +01:00
2020-02-09 14:21:53 +01:00
return url , nil
2020-02-05 14:51:46 +01:00
}
func ( r * photoResolver ) Thumbnail ( ctx context . Context , obj * models . Photo ) ( * models . PhotoURL , error ) {
2020-02-09 14:21:53 +01:00
row := r . Database . QueryRow ( "SELECT * FROM photo_url WHERE photo_id = ? AND purpose = ?" , obj . PhotoID , models . PhotoThumbnail )
2020-02-05 14:51:46 +01:00
2020-02-09 14:21:53 +01:00
url , err := models . NewPhotoURLFromRow ( row )
if err != nil {
2020-02-14 14:29:41 +01:00
log . Printf ( "Error: Could not query thumbnail: %s\n" , err )
2020-02-09 14:21:53 +01:00
return nil , err
}
2020-02-05 14:51:46 +01:00
2020-02-09 14:21:53 +01:00
return url , nil
2020-02-05 14:51:46 +01:00
}
func ( r * photoResolver ) Album ( ctx context . Context , obj * models . Photo ) ( * models . Album , error ) {
2020-03-05 20:34:19 +01:00
row := r . Database . QueryRow ( "SELECT album.* from photo JOIN album ON photo.album_id = album.album_id WHERE photo_id = ?" , obj . PhotoID )
return models . NewAlbumFromRow ( row )
2020-02-05 14:51:46 +01:00
}
2020-02-24 23:30:08 +01:00
func ( r * photoResolver ) Exif ( ctx context . Context , obj * models . Photo ) ( * models . PhotoEXIF , error ) {
row := r . Database . QueryRow ( "SELECT photo_exif.* FROM photo NATURAL JOIN photo_exif WHERE photo.photo_id = ?" , obj . PhotoID )
2020-02-24 23:56:28 +01:00
exif , err := models . NewPhotoExifFromRow ( row )
if err != nil {
if err == sql . ErrNoRows {
return nil , nil
} else {
return nil , err
}
}
return exif , nil
2020-02-05 14:51:46 +01:00
}
2020-06-17 18:00:58 +02:00
func ( r * mutationResolver ) FavoritePhoto ( ctx context . Context , photoID int , favourite bool ) ( * models . Photo , error ) {
user := auth . UserFromContext ( ctx )
row := r . Database . QueryRow ( "SELECT photo.* FROM photo JOIN album ON photo.album_id = album.album_id WHERE photo.photo_id = ? AND album.owner_id = ?" , photoID , user . UserID )
photo , err := models . NewPhotoFromRow ( row )
if err != nil {
return nil , err
}
// TODO: Update photo row
return photo , nil
}