Work on shares
This commit is contained in:
parent
5a0f03268d
commit
687b4f4f7f
|
@ -2,11 +2,11 @@ CREATE TABLE IF NOT EXISTS share_token (
|
||||||
token_id int AUTO_INCREMENT,
|
token_id int AUTO_INCREMENT,
|
||||||
value char(24) NOT NULL UNIQUE,
|
value char(24) NOT NULL UNIQUE,
|
||||||
owner_id int NOT NULL,
|
owner_id int NOT NULL,
|
||||||
expire timestamp,
|
expire timestamp NULL DEFAULT NULL,
|
||||||
password varchar(256) NOT NULL,
|
password varchar(256),
|
||||||
album_id int,
|
album_id int,
|
||||||
photo_id int,
|
photo_id int,
|
||||||
|
|
||||||
PRIMARY KEY (token_id),
|
PRIMARY KEY (token_id)
|
||||||
CHECK (album_id IS NOT NULL OR photo_id IS NOT NULL)
|
-- CHECK (album_id IS NOT NULL OR photo_id IS NOT NULL)
|
||||||
);
|
);
|
||||||
|
|
|
@ -25,6 +25,7 @@ func SetupDatabase() *sql.DB {
|
||||||
|
|
||||||
queryValues := address.Query()
|
queryValues := address.Query()
|
||||||
queryValues.Add("multiStatements", "true")
|
queryValues.Add("multiStatements", "true")
|
||||||
|
queryValues.Add("parseTime", "true")
|
||||||
|
|
||||||
address.RawQuery = queryValues.Encode()
|
address.RawQuery = queryValues.Encode()
|
||||||
|
|
||||||
|
|
|
@ -55,6 +55,7 @@ type ComplexityRoot struct {
|
||||||
ParentAlbum func(childComplexity int) int
|
ParentAlbum func(childComplexity int) int
|
||||||
Path func(childComplexity int) int
|
Path func(childComplexity int) int
|
||||||
Photos func(childComplexity int, filter *models.Filter) int
|
Photos func(childComplexity int, filter *models.Filter) int
|
||||||
|
Shares func(childComplexity int) int
|
||||||
SubAlbums func(childComplexity int, filter *models.Filter) int
|
SubAlbums func(childComplexity int, filter *models.Filter) int
|
||||||
Thumbnail func(childComplexity int) int
|
Thumbnail func(childComplexity int) int
|
||||||
Title func(childComplexity int) int
|
Title func(childComplexity int) int
|
||||||
|
@ -115,12 +116,11 @@ type ComplexityRoot struct {
|
||||||
|
|
||||||
Query struct {
|
Query struct {
|
||||||
Album func(childComplexity int, id int) int
|
Album func(childComplexity int, id int) int
|
||||||
AlbumShares func(childComplexity int, id int, password *string) int
|
|
||||||
MyAlbums func(childComplexity int, filter *models.Filter) int
|
MyAlbums func(childComplexity int, filter *models.Filter) int
|
||||||
MyPhotos func(childComplexity int, filter *models.Filter) int
|
MyPhotos func(childComplexity int, filter *models.Filter) int
|
||||||
MyUser func(childComplexity int) int
|
MyUser func(childComplexity int) int
|
||||||
Photo func(childComplexity int, id int) int
|
Photo func(childComplexity int, id int) int
|
||||||
PhotoShares func(childComplexity int, id int, password *string) int
|
ShareToken func(childComplexity int, token string, password *string) int
|
||||||
SiteInfo func(childComplexity int) int
|
SiteInfo func(childComplexity int) int
|
||||||
Users func(childComplexity int, filter *models.Filter) int
|
Users func(childComplexity int, filter *models.Filter) int
|
||||||
}
|
}
|
||||||
|
@ -160,6 +160,7 @@ type AlbumResolver interface {
|
||||||
Owner(ctx context.Context, obj *models.Album) (*models.User, error)
|
Owner(ctx context.Context, obj *models.Album) (*models.User, error)
|
||||||
|
|
||||||
Thumbnail(ctx context.Context, obj *models.Album) (*models.Photo, error)
|
Thumbnail(ctx context.Context, obj *models.Album) (*models.Photo, error)
|
||||||
|
Shares(ctx context.Context, obj *models.Album) ([]*models.ShareToken, error)
|
||||||
}
|
}
|
||||||
type MutationResolver interface {
|
type MutationResolver interface {
|
||||||
AuthorizeUser(ctx context.Context, username string, password string) (*models.AuthorizeResult, error)
|
AuthorizeUser(ctx context.Context, username string, password string) (*models.AuthorizeResult, error)
|
||||||
|
@ -186,8 +187,7 @@ type QueryResolver interface {
|
||||||
Album(ctx context.Context, id int) (*models.Album, error)
|
Album(ctx context.Context, id int) (*models.Album, error)
|
||||||
MyPhotos(ctx context.Context, filter *models.Filter) ([]*models.Photo, error)
|
MyPhotos(ctx context.Context, filter *models.Filter) ([]*models.Photo, error)
|
||||||
Photo(ctx context.Context, id int) (*models.Photo, error)
|
Photo(ctx context.Context, id int) (*models.Photo, error)
|
||||||
AlbumShares(ctx context.Context, id int, password *string) ([]*models.ShareToken, error)
|
ShareToken(ctx context.Context, token string, password *string) (*models.ShareToken, error)
|
||||||
PhotoShares(ctx context.Context, id int, password *string) ([]*models.ShareToken, error)
|
|
||||||
}
|
}
|
||||||
type ShareTokenResolver interface {
|
type ShareTokenResolver interface {
|
||||||
Owner(ctx context.Context, obj *models.ShareToken) (*models.User, error)
|
Owner(ctx context.Context, obj *models.ShareToken) (*models.User, error)
|
||||||
|
@ -251,6 +251,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Album.Photos(childComplexity, args["filter"].(*models.Filter)), true
|
return e.complexity.Album.Photos(childComplexity, args["filter"].(*models.Filter)), true
|
||||||
|
|
||||||
|
case "Album.shares":
|
||||||
|
if e.complexity.Album.Shares == nil {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
return e.complexity.Album.Shares(childComplexity), true
|
||||||
|
|
||||||
case "Album.subAlbums":
|
case "Album.subAlbums":
|
||||||
if e.complexity.Album.SubAlbums == nil {
|
if e.complexity.Album.SubAlbums == nil {
|
||||||
break
|
break
|
||||||
|
@ -564,18 +571,6 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Query.Album(childComplexity, args["id"].(int)), true
|
return e.complexity.Query.Album(childComplexity, args["id"].(int)), true
|
||||||
|
|
||||||
case "Query.albumShares":
|
|
||||||
if e.complexity.Query.AlbumShares == nil {
|
|
||||||
break
|
|
||||||
}
|
|
||||||
|
|
||||||
args, err := ec.field_Query_albumShares_args(context.TODO(), rawArgs)
|
|
||||||
if err != nil {
|
|
||||||
return 0, false
|
|
||||||
}
|
|
||||||
|
|
||||||
return e.complexity.Query.AlbumShares(childComplexity, args["id"].(int), args["password"].(*string)), true
|
|
||||||
|
|
||||||
case "Query.myAlbums":
|
case "Query.myAlbums":
|
||||||
if e.complexity.Query.MyAlbums == nil {
|
if e.complexity.Query.MyAlbums == nil {
|
||||||
break
|
break
|
||||||
|
@ -619,17 +614,17 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in
|
||||||
|
|
||||||
return e.complexity.Query.Photo(childComplexity, args["id"].(int)), true
|
return e.complexity.Query.Photo(childComplexity, args["id"].(int)), true
|
||||||
|
|
||||||
case "Query.photoShares":
|
case "Query.shareToken":
|
||||||
if e.complexity.Query.PhotoShares == nil {
|
if e.complexity.Query.ShareToken == nil {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
|
|
||||||
args, err := ec.field_Query_photoShares_args(context.TODO(), rawArgs)
|
args, err := ec.field_Query_shareToken_args(context.TODO(), rawArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return 0, false
|
return 0, false
|
||||||
}
|
}
|
||||||
|
|
||||||
return e.complexity.Query.PhotoShares(childComplexity, args["id"].(int), args["password"].(*string)), true
|
return e.complexity.Query.ShareToken(childComplexity, args["token"].(string), args["password"].(*string)), true
|
||||||
|
|
||||||
case "Query.siteInfo":
|
case "Query.siteInfo":
|
||||||
if e.complexity.Query.SiteInfo == nil {
|
if e.complexity.Query.SiteInfo == nil {
|
||||||
|
@ -851,8 +846,7 @@ type Query {
|
||||||
"Get photo by id, user must own the photo or be admin"
|
"Get photo by id, user must own the photo or be admin"
|
||||||
photo(id: Int!): Photo!
|
photo(id: Int!): Photo!
|
||||||
|
|
||||||
albumShares(id: Int!, password: String): [ShareToken!]!
|
shareToken(token: String!, password: String): ShareToken!
|
||||||
photoShares(id: Int!, password: String): [ShareToken!]!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
|
@ -942,7 +936,7 @@ type Album {
|
||||||
"An image in this album used for previewing this album"
|
"An image in this album used for previewing this album"
|
||||||
thumbnail: Photo
|
thumbnail: Photo
|
||||||
|
|
||||||
# shares: [ShareToken]
|
shares: [ShareToken]
|
||||||
}
|
}
|
||||||
|
|
||||||
type PhotoURL {
|
type PhotoURL {
|
||||||
|
@ -1204,28 +1198,6 @@ func (ec *executionContext) field_Query___type_args(ctx context.Context, rawArgs
|
||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) field_Query_albumShares_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
|
||||||
var err error
|
|
||||||
args := map[string]interface{}{}
|
|
||||||
var arg0 int
|
|
||||||
if tmp, ok := rawArgs["id"]; ok {
|
|
||||||
arg0, err = ec.unmarshalNInt2int(ctx, tmp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args["id"] = arg0
|
|
||||||
var arg1 *string
|
|
||||||
if tmp, ok := rawArgs["password"]; ok {
|
|
||||||
arg1, err = ec.unmarshalOString2ᚖstring(ctx, tmp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args["password"] = arg1
|
|
||||||
return args, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) field_Query_album_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
func (ec *executionContext) field_Query_album_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
var err error
|
var err error
|
||||||
args := map[string]interface{}{}
|
args := map[string]interface{}{}
|
||||||
|
@ -1268,28 +1240,6 @@ func (ec *executionContext) field_Query_myPhotos_args(ctx context.Context, rawAr
|
||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) field_Query_photoShares_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
|
||||||
var err error
|
|
||||||
args := map[string]interface{}{}
|
|
||||||
var arg0 int
|
|
||||||
if tmp, ok := rawArgs["id"]; ok {
|
|
||||||
arg0, err = ec.unmarshalNInt2int(ctx, tmp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args["id"] = arg0
|
|
||||||
var arg1 *string
|
|
||||||
if tmp, ok := rawArgs["password"]; ok {
|
|
||||||
arg1, err = ec.unmarshalOString2ᚖstring(ctx, tmp)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
args["password"] = arg1
|
|
||||||
return args, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) field_Query_photo_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
func (ec *executionContext) field_Query_photo_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
var err error
|
var err error
|
||||||
args := map[string]interface{}{}
|
args := map[string]interface{}{}
|
||||||
|
@ -1304,6 +1254,28 @@ func (ec *executionContext) field_Query_photo_args(ctx context.Context, rawArgs
|
||||||
return args, nil
|
return args, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) field_Query_shareToken_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
|
var err error
|
||||||
|
args := map[string]interface{}{}
|
||||||
|
var arg0 string
|
||||||
|
if tmp, ok := rawArgs["token"]; ok {
|
||||||
|
arg0, err = ec.unmarshalNString2string(ctx, tmp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args["token"] = arg0
|
||||||
|
var arg1 *string
|
||||||
|
if tmp, ok := rawArgs["password"]; ok {
|
||||||
|
arg1, err = ec.unmarshalOString2ᚖstring(ctx, tmp)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
args["password"] = arg1
|
||||||
|
return args, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) field_Query_users_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
func (ec *executionContext) field_Query_users_args(ctx context.Context, rawArgs map[string]interface{}) (map[string]interface{}, error) {
|
||||||
var err error
|
var err error
|
||||||
args := map[string]interface{}{}
|
args := map[string]interface{}{}
|
||||||
|
@ -1658,6 +1630,40 @@ func (ec *executionContext) _Album_thumbnail(ctx context.Context, field graphql.
|
||||||
return ec.marshalOPhoto2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhoto(ctx, field.Selections, res)
|
return ec.marshalOPhoto2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhoto(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) _Album_shares(ctx context.Context, field graphql.CollectedField, obj *models.Album) (ret graphql.Marshaler) {
|
||||||
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = graphql.Null
|
||||||
|
}
|
||||||
|
ec.Tracer.EndFieldExecution(ctx)
|
||||||
|
}()
|
||||||
|
rctx := &graphql.ResolverContext{
|
||||||
|
Object: "Album",
|
||||||
|
Field: field,
|
||||||
|
Args: nil,
|
||||||
|
IsMethod: true,
|
||||||
|
}
|
||||||
|
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||||
|
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().Shares(rctx, obj)
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
ec.Error(ctx, err)
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
if resTmp == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
res := resTmp.([]*models.ShareToken)
|
||||||
|
rctx.Result = res
|
||||||
|
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||||
|
return ec.marshalOShareToken2ᚕᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx, field.Selections, res)
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _AuthorizeResult_success(ctx context.Context, field graphql.CollectedField, obj *models.AuthorizeResult) (ret graphql.Marshaler) {
|
func (ec *executionContext) _AuthorizeResult_success(ctx context.Context, field graphql.CollectedField, obj *models.AuthorizeResult) (ret graphql.Marshaler) {
|
||||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -3261,7 +3267,7 @@ func (ec *executionContext) _Query_photo(ctx context.Context, field graphql.Coll
|
||||||
return ec.marshalNPhoto2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhoto(ctx, field.Selections, res)
|
return ec.marshalNPhoto2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐPhoto(ctx, field.Selections, res)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Query_albumShares(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Query_shareToken(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
|
@ -3278,7 +3284,7 @@ func (ec *executionContext) _Query_albumShares(ctx context.Context, field graphq
|
||||||
}
|
}
|
||||||
ctx = graphql.WithResolverContext(ctx, rctx)
|
ctx = graphql.WithResolverContext(ctx, rctx)
|
||||||
rawArgs := field.ArgumentMap(ec.Variables)
|
rawArgs := field.ArgumentMap(ec.Variables)
|
||||||
args, err := ec.field_Query_albumShares_args(ctx, rawArgs)
|
args, err := ec.field_Query_shareToken_args(ctx, rawArgs)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ec.Error(ctx, err)
|
ec.Error(ctx, err)
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
|
@ -3287,7 +3293,7 @@ func (ec *executionContext) _Query_albumShares(ctx context.Context, field graphq
|
||||||
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
ctx = ec.Tracer.StartFieldResolverExecution(ctx, rctx)
|
||||||
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) {
|
||||||
ctx = rctx // use context from middleware stack in children
|
ctx = rctx // use context from middleware stack in children
|
||||||
return ec.resolvers.Query().AlbumShares(rctx, args["id"].(int), args["password"].(*string))
|
return ec.resolvers.Query().ShareToken(rctx, args["token"].(string), args["password"].(*string))
|
||||||
})
|
})
|
||||||
if err != nil {
|
if err != nil {
|
||||||
ec.Error(ctx, err)
|
ec.Error(ctx, err)
|
||||||
|
@ -3299,54 +3305,10 @@ func (ec *executionContext) _Query_albumShares(ctx context.Context, field graphq
|
||||||
}
|
}
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
}
|
}
|
||||||
res := resTmp.([]*models.ShareToken)
|
res := resTmp.(*models.ShareToken)
|
||||||
rctx.Result = res
|
rctx.Result = res
|
||||||
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
||||||
return ec.marshalNShareToken2ᚕᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareTokenᚄ(ctx, field.Selections, res)
|
return ec.marshalNShareToken2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx, field.Selections, res)
|
||||||
}
|
|
||||||
|
|
||||||
func (ec *executionContext) _Query_photoShares(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
|
||||||
ctx = ec.Tracer.StartFieldExecution(ctx, field)
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
ec.Error(ctx, ec.Recover(ctx, r))
|
|
||||||
ret = graphql.Null
|
|
||||||
}
|
|
||||||
ec.Tracer.EndFieldExecution(ctx)
|
|
||||||
}()
|
|
||||||
rctx := &graphql.ResolverContext{
|
|
||||||
Object: "Query",
|
|
||||||
Field: field,
|
|
||||||
Args: nil,
|
|
||||||
IsMethod: true,
|
|
||||||
}
|
|
||||||
ctx = graphql.WithResolverContext(ctx, rctx)
|
|
||||||
rawArgs := field.ArgumentMap(ec.Variables)
|
|
||||||
args, err := ec.field_Query_photoShares_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().PhotoShares(rctx, args["id"].(int), args["password"].(*string))
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
ec.Error(ctx, err)
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
if resTmp == nil {
|
|
||||||
if !ec.HasError(rctx) {
|
|
||||||
ec.Errorf(ctx, "must not be null")
|
|
||||||
}
|
|
||||||
return graphql.Null
|
|
||||||
}
|
|
||||||
res := resTmp.([]*models.ShareToken)
|
|
||||||
rctx.Result = res
|
|
||||||
ctx = ec.Tracer.StartFieldChildExecution(ctx)
|
|
||||||
return ec.marshalNShareToken2ᚕᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareTokenᚄ(ctx, field.Selections, res)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
func (ec *executionContext) _Query___type(ctx context.Context, field graphql.CollectedField) (ret graphql.Marshaler) {
|
||||||
|
@ -5269,6 +5231,17 @@ func (ec *executionContext) _Album(ctx context.Context, sel ast.SelectionSet, ob
|
||||||
res = ec._Album_thumbnail(ctx, field, obj)
|
res = ec._Album_thumbnail(ctx, field, obj)
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
|
case "shares":
|
||||||
|
field := field
|
||||||
|
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
res = ec._Album_shares(ctx, field, obj)
|
||||||
|
return res
|
||||||
|
})
|
||||||
default:
|
default:
|
||||||
panic("unknown field " + strconv.Quote(field.Name))
|
panic("unknown field " + strconv.Quote(field.Name))
|
||||||
}
|
}
|
||||||
|
@ -5710,7 +5683,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||||
}
|
}
|
||||||
return res
|
return res
|
||||||
})
|
})
|
||||||
case "albumShares":
|
case "shareToken":
|
||||||
field := field
|
field := field
|
||||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
out.Concurrently(i, func() (res graphql.Marshaler) {
|
||||||
defer func() {
|
defer func() {
|
||||||
|
@ -5718,21 +5691,7 @@ func (ec *executionContext) _Query(ctx context.Context, sel ast.SelectionSet) gr
|
||||||
ec.Error(ctx, ec.Recover(ctx, r))
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
res = ec._Query_albumShares(ctx, field)
|
res = ec._Query_shareToken(ctx, field)
|
||||||
if res == graphql.Null {
|
|
||||||
atomic.AddUint32(&invalids, 1)
|
|
||||||
}
|
|
||||||
return res
|
|
||||||
})
|
|
||||||
case "photoShares":
|
|
||||||
field := field
|
|
||||||
out.Concurrently(i, func() (res graphql.Marshaler) {
|
|
||||||
defer func() {
|
|
||||||
if r := recover(); r != nil {
|
|
||||||
ec.Error(ctx, ec.Recover(ctx, r))
|
|
||||||
}
|
|
||||||
}()
|
|
||||||
res = ec._Query_photoShares(ctx, field)
|
|
||||||
if res == graphql.Null {
|
if res == graphql.Null {
|
||||||
atomic.AddUint32(&invalids, 1)
|
atomic.AddUint32(&invalids, 1)
|
||||||
}
|
}
|
||||||
|
@ -6905,6 +6864,46 @@ func (ec *executionContext) marshalOShareToken2githubᚗcomᚋviktorstrateᚋpho
|
||||||
return ec._ShareToken(ctx, sel, &v)
|
return ec._ShareToken(ctx, sel, &v)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (ec *executionContext) marshalOShareToken2ᚕᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx context.Context, sel ast.SelectionSet, v []*models.ShareToken) graphql.Marshaler {
|
||||||
|
if v == nil {
|
||||||
|
return graphql.Null
|
||||||
|
}
|
||||||
|
ret := make(graphql.Array, len(v))
|
||||||
|
var wg sync.WaitGroup
|
||||||
|
isLen1 := len(v) == 1
|
||||||
|
if !isLen1 {
|
||||||
|
wg.Add(len(v))
|
||||||
|
}
|
||||||
|
for i := range v {
|
||||||
|
i := i
|
||||||
|
rctx := &graphql.ResolverContext{
|
||||||
|
Index: &i,
|
||||||
|
Result: &v[i],
|
||||||
|
}
|
||||||
|
ctx := graphql.WithResolverContext(ctx, rctx)
|
||||||
|
f := func(i int) {
|
||||||
|
defer func() {
|
||||||
|
if r := recover(); r != nil {
|
||||||
|
ec.Error(ctx, ec.Recover(ctx, r))
|
||||||
|
ret = nil
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
if !isLen1 {
|
||||||
|
defer wg.Done()
|
||||||
|
}
|
||||||
|
ret[i] = ec.marshalOShareToken2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx, sel, v[i])
|
||||||
|
}
|
||||||
|
if isLen1 {
|
||||||
|
f(i)
|
||||||
|
} else {
|
||||||
|
go f(i)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
wg.Wait()
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
func (ec *executionContext) marshalOShareToken2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx context.Context, sel ast.SelectionSet, v *models.ShareToken) graphql.Marshaler {
|
func (ec *executionContext) marshalOShareToken2ᚖgithubᚗcomᚋviktorstrateᚋphotoviewᚋapiᚋgraphqlᚋmodelsᚐShareToken(ctx context.Context, sel ast.SelectionSet, v *models.ShareToken) graphql.Marshaler {
|
||||||
if v == nil {
|
if v == nil {
|
||||||
return graphql.Null
|
return graphql.Null
|
||||||
|
|
|
@ -1,6 +1,9 @@
|
||||||
package models
|
package models
|
||||||
|
|
||||||
import "time"
|
import (
|
||||||
|
"database/sql"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
type ShareToken struct {
|
type ShareToken struct {
|
||||||
TokenID int
|
TokenID int
|
||||||
|
@ -19,3 +22,27 @@ func (share *ShareToken) Token() string {
|
||||||
func (share *ShareToken) ID() int {
|
func (share *ShareToken) ID() int {
|
||||||
return share.TokenID
|
return share.TokenID
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func NewShareTokenFromRow(row *sql.Row) (*ShareToken, error) {
|
||||||
|
token := ShareToken{}
|
||||||
|
|
||||||
|
if err := row.Scan(&token.TokenID, &token.Value, &token.OwnerID, &token.Expire, &token.Password, &token.AlbumID, &token.PhotoID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
return &token, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
func NewShareTokensFromRows(rows *sql.Rows) ([]*ShareToken, error) {
|
||||||
|
tokens := make([]*ShareToken, 0)
|
||||||
|
|
||||||
|
for rows.Next() {
|
||||||
|
var token ShareToken
|
||||||
|
if err := rows.Scan(&token.TokenID, &token.Value, &token.OwnerID, &token.Expire, &token.Password, &token.AlbumID, &token.PhotoID); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
tokens = append(tokens, &token)
|
||||||
|
}
|
||||||
|
|
||||||
|
return tokens, nil
|
||||||
|
}
|
||||||
|
|
|
@ -117,3 +117,13 @@ func (r *albumResolver) ParentAlbum(ctx context.Context, obj *models.Album) (*mo
|
||||||
func (r *albumResolver) Owner(ctx context.Context, obj *models.Album) (*models.User, error) {
|
func (r *albumResolver) Owner(ctx context.Context, obj *models.Album) (*models.User, error) {
|
||||||
panic("not implemented")
|
panic("not implemented")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *albumResolver) Shares(ctx context.Context, obj *models.Album) ([]*models.ShareToken, error) {
|
||||||
|
rows, err := r.Database.Query("SELECT * FROM share_token WHERE album_id = ?", obj.ID())
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
defer rows.Close()
|
||||||
|
|
||||||
|
return models.NewShareTokensFromRows(rows)
|
||||||
|
}
|
||||||
|
|
|
@ -54,14 +54,22 @@ func (r *shareTokenResolver) Photo(ctx context.Context, obj *models.ShareToken)
|
||||||
return photo, nil
|
return photo, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) AlbumShares(ctx context.Context, id int, password *string) ([]*models.ShareToken, error) {
|
func (r *queryResolver) ShareToken(ctx context.Context, token string, password *string) (*models.ShareToken, error) {
|
||||||
log.Println("Query AlbumShares: not implemented")
|
|
||||||
|
|
||||||
tokens := make([]*models.ShareToken, 0)
|
row := r.Database.QueryRow("SELECT * FROM share_token WHERE value = ? AND (password = ? OR password IS NULL)", token, password)
|
||||||
return tokens, nil
|
result, err := models.NewShareTokenFromRow(row)
|
||||||
|
if err != nil {
|
||||||
|
if err == sql.ErrNoRows {
|
||||||
|
return nil, nil
|
||||||
|
} else {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) PhotoShares(ctx context.Context, id int, password *string) ([]*models.ShareToken, error) {
|
func (r *queryResolver) PhotoShares(ctx context.Context, token string, password *string) ([]*models.ShareToken, error) {
|
||||||
log.Println("Query PhotoShares: not implemented")
|
log.Println("Query PhotoShares: not implemented")
|
||||||
|
|
||||||
tokens := make([]*models.ShareToken, 0)
|
tokens := make([]*models.ShareToken, 0)
|
||||||
|
|
|
@ -32,8 +32,7 @@ type Query {
|
||||||
"Get photo by id, user must own the photo or be admin"
|
"Get photo by id, user must own the photo or be admin"
|
||||||
photo(id: Int!): Photo!
|
photo(id: Int!): Photo!
|
||||||
|
|
||||||
albumShares(id: Int!, password: String): [ShareToken!]!
|
shareToken(token: String!, password: String): ShareToken!
|
||||||
photoShares(id: Int!, password: String): [ShareToken!]!
|
|
||||||
}
|
}
|
||||||
|
|
||||||
type Mutation {
|
type Mutation {
|
||||||
|
@ -123,7 +122,7 @@ type Album {
|
||||||
"An image in this album used for previewing this album"
|
"An image in this album used for previewing this album"
|
||||||
thumbnail: Photo
|
thumbnail: Photo
|
||||||
|
|
||||||
# shares: [ShareToken]
|
shares: [ShareToken]
|
||||||
}
|
}
|
||||||
|
|
||||||
type PhotoURL {
|
type PhotoURL {
|
||||||
|
|
|
@ -7,7 +7,7 @@ import { Query } from 'react-apollo'
|
||||||
import gql from 'graphql-tag'
|
import gql from 'graphql-tag'
|
||||||
|
|
||||||
const tokenQuery = gql`
|
const tokenQuery = gql`
|
||||||
query SharePageToken($token: Int!) {
|
query SharePageToken($token: String!) {
|
||||||
shareToken(token: $token) {
|
shareToken(token: $token) {
|
||||||
token
|
token
|
||||||
album {
|
album {
|
||||||
|
@ -28,7 +28,7 @@ const tokenQuery = gql`
|
||||||
fragment AlbumProps on Album {
|
fragment AlbumProps on Album {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
photos(orderBy: title_desc) {
|
photos(filter: { order_by: "title", order_direction: DESC }) {
|
||||||
...PhotoProps
|
...PhotoProps
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -41,16 +41,14 @@ const tokenQuery = gql`
|
||||||
width
|
width
|
||||||
height
|
height
|
||||||
}
|
}
|
||||||
original {
|
highRes {
|
||||||
url
|
url
|
||||||
}
|
}
|
||||||
exif {
|
exif {
|
||||||
camera
|
camera
|
||||||
maker
|
maker
|
||||||
lens
|
lens
|
||||||
dateShot {
|
dateShot
|
||||||
formatted
|
|
||||||
}
|
|
||||||
fileSize
|
fileSize
|
||||||
exposure
|
exposure
|
||||||
aperture
|
aperture
|
||||||
|
|
|
@ -9,10 +9,13 @@ export async function fetchProtectedImage(src, { signal } = { signal: null }) {
|
||||||
return imageCache[src]
|
return imageCache[src]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let headers = {}
|
||||||
|
if (localStorage.getItem('token')) {
|
||||||
|
headers['Authorization'] = `Bearer ${localStorage.getItem('token')}`
|
||||||
|
}
|
||||||
|
|
||||||
let image = await fetch(src, {
|
let image = await fetch(src, {
|
||||||
headers: {
|
headers,
|
||||||
Authorization: `Bearer ${localStorage.getItem('token')}`,
|
|
||||||
},
|
|
||||||
signal,
|
signal,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
|
@ -37,7 +37,7 @@ const AlbumSidebar = ({ albumId }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
AlbumSidebar.propTypes = {
|
AlbumSidebar.propTypes = {
|
||||||
albumId: PropTypes.string.isRequired,
|
albumId: PropTypes.number.isRequired,
|
||||||
}
|
}
|
||||||
|
|
||||||
export default AlbumSidebar
|
export default AlbumSidebar
|
||||||
|
|
|
@ -7,26 +7,28 @@ import copy from 'copy-to-clipboard'
|
||||||
|
|
||||||
const sharePhotoQuery = gql`
|
const sharePhotoQuery = gql`
|
||||||
query sidbarGetPhotoShares($id: Int!) {
|
query sidbarGetPhotoShares($id: Int!) {
|
||||||
photoShares(id: $id) {
|
photo(id: $id) {
|
||||||
|
id
|
||||||
|
shares {
|
||||||
token
|
token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const shareAlbumQuery = gql`
|
const shareAlbumQuery = gql`
|
||||||
query sidbarGetAlbumShares($id: Int!) {
|
query sidbarGetAlbumShares($id: Int!) {
|
||||||
albumShares(id: $id) {
|
album(id: $id) {
|
||||||
|
id
|
||||||
|
shares {
|
||||||
token
|
token
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
`
|
`
|
||||||
|
|
||||||
const addPhotoShareMutation = gql`
|
const addPhotoShareMutation = gql`
|
||||||
mutation sidebarPhotoAddShare(
|
mutation sidebarPhotoAddShare($id: Int!, $password: String, $expire: Time) {
|
||||||
$id: Int!
|
|
||||||
$password: String
|
|
||||||
$expire: _Neo4jDateInput
|
|
||||||
) {
|
|
||||||
sharePhoto(photoId: $id, password: $password, expire: $expire) {
|
sharePhoto(photoId: $id, password: $password, expire: $expire) {
|
||||||
token
|
token
|
||||||
}
|
}
|
||||||
|
@ -34,11 +36,7 @@ const addPhotoShareMutation = gql`
|
||||||
`
|
`
|
||||||
|
|
||||||
const addAlbumShareMutation = gql`
|
const addAlbumShareMutation = gql`
|
||||||
mutation sidebarAlbumAddShare(
|
mutation sidebarAlbumAddShare($id: Int!, $password: String, $expire: Time) {
|
||||||
$id: Int!
|
|
||||||
$password: String
|
|
||||||
$expire: _Neo4jDateInput
|
|
||||||
) {
|
|
||||||
shareAlbum(albumId: $id, password: $password, expire: $expire) {
|
shareAlbum(albumId: $id, password: $password, expire: $expire) {
|
||||||
token
|
token
|
||||||
}
|
}
|
||||||
|
@ -71,9 +69,9 @@ const SidebarShare = ({ photo, album }) => {
|
||||||
<Query query={query} variables={{ id }}>
|
<Query query={query} variables={{ id }}>
|
||||||
{({ loading, error, data, refetch }) => {
|
{({ loading, error, data, refetch }) => {
|
||||||
if (loading) return <div>Loading...</div>
|
if (loading) return <div>Loading...</div>
|
||||||
if (error) return <div>Error: {error}</div>
|
if (error) return <div>Error: {error.message}</div>
|
||||||
|
|
||||||
let shares = isPhoto ? data.photoShares : data.albumShares
|
let shares = isPhoto ? data.photo.shares : data.album.shares
|
||||||
|
|
||||||
const rows = shares.map(share => (
|
const rows = shares.map(share => (
|
||||||
<Table.Row key={share.token}>
|
<Table.Row key={share.token}>
|
||||||
|
|
Loading…
Reference in New Issue