Working on integrating backend with ui

This commit is contained in:
viktorstrate
2020-02-09 15:26:59 +01:00
parent d50b8034d1
commit e6593ee7f3
12 changed files with 407 additions and 40 deletions

View File

@@ -2,4 +2,5 @@
MYSQL_URL=user:password@/dbname
API_PORT=4001
API_PORT=4001
API_ENDPOINT=http://localhost:4001/

View File

@@ -53,7 +53,7 @@ type ComplexityRoot struct {
Owner func(childComplexity int) int
ParentAlbum func(childComplexity int) int
Path func(childComplexity int) int
Photos func(childComplexity int) int
Photos func(childComplexity int, filter *models.Filter) int
SubAlbums func(childComplexity int) int
Title func(childComplexity int) int
}
@@ -105,12 +105,12 @@ type ComplexityRoot struct {
Query struct {
Album func(childComplexity int, id *string) int
MyAlbums func(childComplexity int) int
MyPhotos func(childComplexity int) int
MyAlbums func(childComplexity int, filter *models.Filter) int
MyPhotos func(childComplexity int, filter *models.Filter) int
MyUser func(childComplexity int) int
Photo func(childComplexity int, id string) int
SiteInfo func(childComplexity int) int
Users func(childComplexity int) int
Users func(childComplexity int, filter *models.Filter) int
}
ScannerResult struct {
@@ -133,7 +133,7 @@ type ComplexityRoot struct {
}
type AlbumResolver interface {
Photos(ctx context.Context, obj *models.Album) ([]*models.Photo, error)
Photos(ctx context.Context, obj *models.Album, filter *models.Filter) ([]*models.Photo, error)
SubAlbums(ctx context.Context, obj *models.Album) ([]*models.Album, error)
ParentAlbum(ctx context.Context, obj *models.Album) (*models.Album, error)
Owner(ctx context.Context, obj *models.Album) (*models.User, error)
@@ -154,11 +154,11 @@ type PhotoResolver interface {
}
type QueryResolver interface {
SiteInfo(ctx context.Context) (*models.SiteInfo, error)
Users(ctx context.Context) ([]*models.User, error)
Users(ctx context.Context, filter *models.Filter) ([]*models.User, error)
MyUser(ctx context.Context) (*models.User, error)
MyAlbums(ctx context.Context) ([]*models.Album, error)
MyAlbums(ctx context.Context, filter *models.Filter) ([]*models.Album, error)
Album(ctx context.Context, id *string) (*models.Album, error)
MyPhotos(ctx context.Context) ([]*models.Photo, error)
MyPhotos(ctx context.Context, filter *models.Filter) ([]*models.Photo, error)
Photo(ctx context.Context, id string) (*models.Photo, error)
}
@@ -210,7 +210,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
return e.complexity.Album.Photos(childComplexity), true
args, err := ec.field_Album_photos_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Album.Photos(childComplexity, args["filter"].(*models.Filter)), true
case "Album.subAlbums":
if e.complexity.Album.SubAlbums == nil {
@@ -473,14 +478,24 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
return e.complexity.Query.MyAlbums(childComplexity), true
args, err := ec.field_Query_myAlbums_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Query.MyAlbums(childComplexity, args["filter"].(*models.Filter)), true
case "Query.myPhotos":
if e.complexity.Query.MyPhotos == nil {
break
}
return e.complexity.Query.MyPhotos(childComplexity), true
args, err := ec.field_Query_myPhotos_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Query.MyPhotos(childComplexity, args["filter"].(*models.Filter)), true
case "Query.myUser":
if e.complexity.Query.MyUser == nil {
@@ -513,7 +528,12 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
break
}
return e.complexity.Query.Users(childComplexity), true
args, err := ec.field_Query_users_args(context.TODO(), rawArgs)
if err != nil {
return 0, false
}
return e.complexity.Query.Users(childComplexity, args["filter"].(*models.Filter)), true
case "ScannerResult.finished":
if e.complexity.ScannerResult.Finished == nil {
@@ -644,21 +664,33 @@ var parsedSchema = gqlparser.MustLoadSchema(
scalar Time
enum OrderDirection {
ASC
DESC
}
input Filter {
order_by: String
order_direction: OrderDirection
limit: Int
offset: Int
}
type Query {
siteInfo: SiteInfo!
"List of registered users, must be admin to call"
users: [User!]! @isAdmin
users(filter: Filter): [User!]! @isAdmin
"Information about the currently logged in user"
myUser: User!
"List of albums owned by the logged in user"
myAlbums: [Album!]!
myAlbums(filter: Filter): [Album!]!
"Get album by id, user must own the album or be admin"
album(id: ID): Album!
"List of photos owned by the logged in user"
myPhotos: [Photo!]!
myPhotos(filter: Filter): [Photo!]!
"Get photo by id, user must own the photo or be admin"
photo(id: ID!): Photo!
}
@@ -717,7 +749,7 @@ type User {
type Album {
id: ID!
title: String!
photos: [Photo!]!
photos(filter: Filter): [Photo!]!
subAlbums: [Album!]!
parentAlbum: Album
owner: User!
@@ -783,6 +815,20 @@ type PhotoEXIF {
// region ***************************** args.gotpl *****************************
func (ec *executionContext) field_Album_photos_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 *models.Filter
if tmp, ok := rawArgs["filter"]; ok {
arg0, err = ec.unmarshalOFilter2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐFilter(ctx, tmp)
if err != nil {
return nil, err
}
}
args["filter"] = arg0
return args, nil
}
func (ec *executionContext) field_Mutation_authorizeUser_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@@ -907,6 +953,34 @@ func (ec *executionContext) field_Query_album_args(ctx context.Context, rawArgs
return args, nil
}
func (ec *executionContext) field_Query_myAlbums_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 *models.Filter
if tmp, ok := rawArgs["filter"]; ok {
arg0, err = ec.unmarshalOFilter2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐFilter(ctx, tmp)
if err != nil {
return nil, err
}
}
args["filter"] = arg0
return args, nil
}
func (ec *executionContext) field_Query_myPhotos_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 *models.Filter
if tmp, ok := rawArgs["filter"]; ok {
arg0, err = ec.unmarshalOFilter2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐFilter(ctx, tmp)
if err != nil {
return nil, err
}
}
args["filter"] = arg0
return args, nil
}
func (ec *executionContext) field_Query_photo_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@@ -921,6 +995,20 @@ func (ec *executionContext) field_Query_photo_args(ctx context.Context, rawArgs
return args, nil
}
func (ec *executionContext) field_Query_users_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
var arg0 *models.Filter
if tmp, ok := rawArgs["filter"]; ok {
arg0, err = ec.unmarshalOFilter2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐFilter(ctx, tmp)
if err != nil {
return nil, err
}
}
args["filter"] = arg0
return args, nil
}
func (ec *executionContext) field___Type_enumValues_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
var err error
args := map[string]interface{}{}
@@ -1047,10 +1135,17 @@ func (ec *executionContext) _Album_photos(ctx context.Context, field graphql.Col
IsMethod: true,
}
ctx = graphql.WithResolverContext(ctx, rctx)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Album_photos_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
rctx.Args = args
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Album().Photos(rctx, obj)
return ec.resolvers.Album().Photos(rctx, obj, args["filter"].(*models.Filter))
})
if err != nil {
ec.Error(ctx, err)
@@ -2362,11 +2457,18 @@ func (ec *executionContext) _Query_users(ctx context.Context, field graphql.Coll
IsMethod: true,
}
ctx = graphql.WithResolverContext(ctx, rctx)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_users_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
rctx.Args = args
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
directive0 := func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().Users(rctx)
return ec.resolvers.Query().Users(rctx, args["filter"].(*models.Filter))
}
directive1 := func(ctx context.Context) (interface{}, error) {
if ec.directives.IsAdmin == nil {
@@ -2456,10 +2558,17 @@ func (ec *executionContext) _Query_myAlbums(ctx context.Context, field graphql.C
IsMethod: true,
}
ctx = graphql.WithResolverContext(ctx, rctx)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_myAlbums_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
rctx.Args = args
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().MyAlbums(rctx)
return ec.resolvers.Query().MyAlbums(rctx, args["filter"].(*models.Filter))
})
if err != nil {
ec.Error(ctx, err)
@@ -2537,10 +2646,17 @@ func (ec *executionContext) _Query_myPhotos(ctx context.Context, field graphql.C
IsMethod: true,
}
ctx = graphql.WithResolverContext(ctx, rctx)
rawArgs := field.ArgumentMap(ec.Variables)
args, err := ec.field_Query_myPhotos_args(ctx, rawArgs)
if err != nil {
ec.Error(ctx, err)
return graphql.Null
}
rctx.Args = args
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
ctx = rctx // use context from middleware stack in children
return ec.resolvers.Query().MyPhotos(rctx)
return ec.resolvers.Query().MyPhotos(rctx, args["filter"].(*models.Filter))
})
if err != nil {
ec.Error(ctx, err)
@@ -4175,6 +4291,42 @@ func (ec *executionContext) ___Type_ofType(ctx context.Context, field graphql.Co
// region **************************** input.gotpl *****************************
func (ec *executionContext) unmarshalInputFilter(ctx context.Context, obj interface{}) (models.Filter, error) {
var it models.Filter
var asMap = obj.(map[string]interface{})
for k, v := range asMap {
switch k {
case "order_by":
var err error
it.OrderBy, err = ec.unmarshalOString2ᚖstring(ctx, v)
if err != nil {
return it, err
}
case "order_direction":
var err error
it.OrderDirection, err = ec.unmarshalOOrderDirection2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐOrderDirection(ctx, v)
if err != nil {
return it, err
}
case "limit":
var err error
it.Limit, err = ec.unmarshalOInt2ᚖint(ctx, v)
if err != nil {
return it, err
}
case "offset":
var err error
it.Offset, err = ec.unmarshalOInt2ᚖint(ctx, v)
if err != nil {
return it, err
}
}
}
return it, nil
}
// endregion **************************** input.gotpl *****************************
// region ************************** interface.gotpl ***************************
@@ -5554,6 +5706,18 @@ func (ec *executionContext) marshalOBoolean2ᚖbool(ctx context.Context, sel ast
return ec.marshalOBoolean2bool(ctx, sel, *v)
}
func (ec *executionContext) unmarshalOFilter2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐFilter(ctx context.Context, v interface{}) (models.Filter, error) {
return ec.unmarshalInputFilter(ctx, v)
}
func (ec *executionContext) unmarshalOFilter2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐFilter(ctx context.Context, v interface{}) (*models.Filter, error) {
if v == nil {
return nil, nil
}
res, err := ec.unmarshalOFilter2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐFilter(ctx, v)
return &res, err
}
func (ec *executionContext) unmarshalOFloat2float64(ctx context.Context, v interface{}) (float64, error) {
return graphql.UnmarshalFloat(v)
}
@@ -5623,6 +5787,30 @@ func (ec *executionContext) marshalOInt2ᚖint(ctx context.Context, sel ast.Sele
return ec.marshalOInt2int(ctx, sel, *v)
}
func (ec *executionContext) unmarshalOOrderDirection2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐOrderDirection(ctx context.Context, v interface{}) (models.OrderDirection, error) {
var res models.OrderDirection
return res, res.UnmarshalGQL(v)
}
func (ec *executionContext) marshalOOrderDirection2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐOrderDirection(ctx context.Context, sel ast.SelectionSet, v models.OrderDirection) graphql.Marshaler {
return v
}
func (ec *executionContext) unmarshalOOrderDirection2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐOrderDirection(ctx context.Context, v interface{}) (*models.OrderDirection, error) {
if v == nil {
return nil, nil
}
res, err := ec.unmarshalOOrderDirection2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐOrderDirection(ctx, v)
return &res, err
}
func (ec *executionContext) marshalOOrderDirection2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐOrderDirection(ctx context.Context, sel ast.SelectionSet, v *models.OrderDirection) graphql.Marshaler {
if v == nil {
return graphql.Null
}
return v
}
func (ec *executionContext) marshalOPhoto2githubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhoto(ctx context.Context, sel ast.SelectionSet, v models.Photo) graphql.Marshaler {
return ec._Photo(ctx, sel, &v)
}

View File

@@ -26,3 +26,17 @@ func NewAlbumFromRow(row *sql.Row) (*Album, error) {
return &album, nil
}
func NewAlbumsFromRows(rows *sql.Rows) ([]*Album, error) {
albums := make([]*Album, 0)
for rows.Next() {
var album Album
if err := rows.Scan(&album.AlbumID, &album.Title, &album.ParentAlbum, &album.OwnerID, &album.Path); err != nil {
return nil, err
}
albums = append(albums, &album)
}
return albums, nil
}

View File

@@ -3,6 +3,9 @@
package models
import (
"fmt"
"io"
"strconv"
"time"
)
@@ -12,6 +15,13 @@ type AuthorizeResult struct {
Token *string `json:"token"`
}
type Filter struct {
OrderBy *string `json:"order_by"`
OrderDirection *OrderDirection `json:"order_direction"`
Limit *int `json:"limit"`
Offset *int `json:"offset"`
}
// EXIF metadata from the camera
type PhotoExif struct {
Photo *Photo `json:"photo"`
@@ -47,3 +57,44 @@ type ScannerResult struct {
type SiteInfo struct {
InitialSetup bool `json:"initialSetup"`
}
type OrderDirection string
const (
OrderDirectionAsc OrderDirection = "ASC"
OrderDirectionDesc OrderDirection = "DESC"
)
var AllOrderDirection = []OrderDirection{
OrderDirectionAsc,
OrderDirectionDesc,
}
func (e OrderDirection) IsValid() bool {
switch e {
case OrderDirectionAsc, OrderDirectionDesc:
return true
}
return false
}
func (e OrderDirection) String() string {
return string(e)
}
func (e *OrderDirection) UnmarshalGQL(v interface{}) error {
str, ok := v.(string)
if !ok {
return fmt.Errorf("enums must be strings")
}
*e = OrderDirection(str)
if !e.IsValid() {
return fmt.Errorf("%s is not a valid OrderDirection", str)
}
return nil
}
func (e OrderDirection) MarshalGQL(w io.Writer) {
fmt.Fprint(w, strconv.Quote(e.String()))
}

View File

@@ -2,7 +2,9 @@ package models
import (
"database/sql"
"fmt"
"net/url"
"os"
"path"
"strconv"
)
@@ -61,7 +63,12 @@ func NewPhotosFromRows(rows *sql.Rows) ([]*Photo, error) {
}
func (p *PhotoURL) URL() string {
return fmt.Sprintf("/photo/%s", p.PhotoName)
imageUrl, err := url.Parse(os.Getenv("API_ENDPOINT"))
if err != nil {
return path.Join("/photo", p.PhotoName)
}
imageUrl.Path = path.Join(imageUrl.Path, "photo", p.PhotoName)
return imageUrl.String()
}
func NewPhotoURLFromRow(row *sql.Row) (*PhotoURL, error) {

View File

@@ -0,0 +1,47 @@
package models
import (
"fmt"
"log"
"regexp"
"strings"
)
func (filter *Filter) FormatSQL() (string, error) {
if filter == nil {
return "", nil
}
result := ""
if filter.Limit != nil {
log.Println("Limit")
offset := 0
if filter.Offset != nil && *filter.Offset >= 0 {
offset = *filter.Offset
}
result += fmt.Sprintf(" LIMIT %d OFFSET %d", *filter.Limit, offset)
}
if filter.OrderBy != nil {
log.Println("Order by")
order_by := filter.OrderBy
match, err := regexp.MatchString("^(\\w+(,\\s*))*\\w+$", strings.TrimSpace(*filter.OrderBy))
if err != nil {
return "", err
}
if match {
direction := "ASC"
if filter.OrderDirection != nil && filter.OrderDirection.IsValid() {
direction = filter.OrderDirection.String()
}
result += fmt.Sprintf(" ORDER BY %s %s", *order_by, direction)
}
}
log.Printf("Filter: " + result)
return result, nil
}

View File

@@ -8,9 +8,30 @@ import (
"github.com/viktorstrate/photoview/api/graphql/models"
)
func (r *queryResolver) MyAlbums(ctx context.Context) ([]*models.Album, error) {
panic("Not implemented")
func (r *queryResolver) MyAlbums(ctx context.Context, filter *models.Filter) ([]*models.Album, error) {
user := auth.UserFromContext(ctx)
if user == nil {
return nil, auth.ErrUnauthorized
}
filterSQL, err := filter.FormatSQL()
if err != nil {
return nil, err
}
rows, err := r.Database.Query("SELECT * FROM album WHERE owner_id = ? AND parent_album IS NULL"+filterSQL, user.UserID)
if err != nil {
return nil, err
}
albums, err := models.NewAlbumsFromRows(rows)
if err != nil {
return nil, err
}
return albums, nil
}
func (r *queryResolver) Album(ctx context.Context, id *string) (*models.Album, error) {
user := auth.UserFromContext(ctx)
if user == nil {
@@ -32,8 +53,14 @@ func (r *Resolver) Album() api.AlbumResolver {
type albumResolver struct{ *Resolver }
func (r *albumResolver) Photos(ctx context.Context, obj *models.Album) ([]*models.Photo, error) {
photoRows, err := r.Database.Query("SELECT photo.* FROM album, photo WHERE album.album_id = ? AND photo.album_id = album.album_id", obj.AlbumID)
func (r *albumResolver) Photos(ctx context.Context, obj *models.Album, filter *models.Filter) ([]*models.Photo, error) {
filterSQL, err := filter.FormatSQL()
if err != nil {
return nil, err
}
photoRows, err := r.Database.Query("SELECT photo.* FROM album, photo WHERE album.album_id = ? AND photo.album_id = album.album_id"+filterSQL, obj.AlbumID)
if err != nil {
return nil, err
}
@@ -48,7 +75,17 @@ func (r *albumResolver) Photos(ctx context.Context, obj *models.Album) ([]*model
}
func (r *albumResolver) SubAlbums(ctx context.Context, obj *models.Album) ([]*models.Album, error) {
panic("not implemented")
rows, err := r.Database.Query("SELECT * FROM album WHERE parent_album = ?", obj.AlbumID)
if err != nil {
return nil, err
}
albums, err := models.NewAlbumsFromRows(rows)
if err != nil {
return nil, err
}
return albums, nil
}
func (r *albumResolver) ParentAlbum(ctx context.Context, obj *models.Album) (*models.Album, error) {

View File

@@ -9,13 +9,18 @@ import (
"github.com/viktorstrate/photoview/api/graphql/models"
)
func (r *queryResolver) MyPhotos(ctx context.Context) ([]*models.Photo, error) {
func (r *queryResolver) MyPhotos(ctx context.Context, filter *models.Filter) ([]*models.Photo, error) {
user := auth.UserFromContext(ctx)
if user == nil {
return nil, errors.New("unauthorized")
}
rows, err := r.Database.Query("SELECT photo.* FROM photo, album WHERE photo.album_id = album.album_id AND album.owner_id = ?", user.UserID)
filterSQL, err := filter.FormatSQL()
if err != nil {
return nil, err
}
rows, err := r.Database.Query("SELECT photo.* FROM photo, album WHERE photo.album_id = album.album_id AND album.owner_id = ?"+filterSQL, user.UserID)
if err != nil {
return nil, err
}

View File

@@ -14,9 +14,14 @@ import (
// type userResolver struct{ *Resolver }
func (r *queryResolver) Users(ctx context.Context) ([]*models.User, error) {
func (r *queryResolver) Users(ctx context.Context, filter *models.Filter) ([]*models.User, error) {
rows, err := r.Database.Query("SELECT * FROM users")
filterSQL, err := filter.FormatSQL()
if err != nil {
return nil, err
}
rows, err := r.Database.Query("SELECT * FROM users" + filterSQL)
if err != nil {
return nil, err
}

View File

@@ -2,21 +2,33 @@ directive @isAdmin on FIELD_DEFINITION
scalar Time
enum OrderDirection {
ASC
DESC
}
input Filter {
order_by: String
order_direction: OrderDirection
limit: Int
offset: Int
}
type Query {
siteInfo: SiteInfo!
"List of registered users, must be admin to call"
users: [User!]! @isAdmin
users(filter: Filter): [User!]! @isAdmin
"Information about the currently logged in user"
myUser: User!
"List of albums owned by the logged in user"
myAlbums: [Album!]!
myAlbums(filter: Filter): [Album!]!
"Get album by id, user must own the album or be admin"
album(id: ID): Album!
"List of photos owned by the logged in user"
myPhotos: [Photo!]!
myPhotos(filter: Filter): [Photo!]!
"Get photo by id, user must own the photo or be admin"
photo(id: ID!): Photo!
}
@@ -75,7 +87,7 @@ type User {
type Album {
id: ID!
title: String!
photos: [Photo!]!
photos(filter: Filter): [Photo!]!
subAlbums: [Album!]!
parentAlbum: Album
owner: User!

View File

@@ -120,8 +120,6 @@ func scan(database *sql.DB, user *models.User) {
return
}
log.Printf("Content type: %s\n", *content_type)
if err := ProcessImage(tx, photoPath, albumId, *content_type); err != nil {
log.Printf("ERROR: processing image %s: %s", photoPath, err)
tx.Rollback()