diff --git a/api/internal/graph/generated/generated.go b/api/internal/graph/generated/generated.go index 3d164c5..b947c78 100644 --- a/api/internal/graph/generated/generated.go +++ b/api/internal/graph/generated/generated.go @@ -37,6 +37,7 @@ type Config struct { type ResolverRoot interface { Entity() EntityResolver + MediaItem() MediaItemResolver Mutation() MutationResolver Query() QueryResolver } @@ -72,6 +73,7 @@ type ComplexityRoot struct { MediaItem struct { CreatedAt func(childComplexity int) int Description func(childComplexity int) int + Entities func(childComplexity int) int FileName func(childComplexity int) int FileSize func(childComplexity int) int ID func(childComplexity int) int @@ -121,6 +123,9 @@ type ComplexityRoot struct { type EntityResolver interface { MediaItems(ctx context.Context, obj *models.Entity, page *int, limit *int) (*models.MediaItemConnection, error) } +type MediaItemResolver interface { + Entities(ctx context.Context, obj *models.MediaItem) ([]*models.Entity, error) +} type MutationResolver interface { Upload(ctx context.Context, file graphql.Upload) (bool, error) UpdateEntity(ctx context.Context, id string, name string) (bool, error) @@ -252,6 +257,13 @@ func (e *executableSchema) Complexity(typeName, field string, childComplexity in return e.complexity.MediaItem.Description(childComplexity), true + case "MediaItem.entities": + if e.complexity.MediaItem.Entities == nil { + break + } + + return e.complexity.MediaItem.Entities(childComplexity), true + case "MediaItem.fileName": if e.complexity.MediaItem.FileName == nil { break @@ -558,6 +570,7 @@ type MediaItem { fileName: String! fileSize: Int! mediaMetadata: MediaMetaData + entities: [Entity!] createdAt: Time! updatedAt: Time! } @@ -1516,6 +1529,38 @@ func (ec *executionContext) _MediaItem_mediaMetadata(ctx context.Context, field return ec.marshalOMediaMetaData2ᚖirisᚋapiᚋinternalᚋmodelsᚐMediaMetaData(ctx, field.Selections, res) } +func (ec *executionContext) _MediaItem_entities(ctx context.Context, field graphql.CollectedField, obj *models.MediaItem) (ret graphql.Marshaler) { + defer func() { + if r := recover(); r != nil { + ec.Error(ctx, ec.Recover(ctx, r)) + ret = graphql.Null + } + }() + fc := &graphql.FieldContext{ + Object: "MediaItem", + Field: field, + Args: nil, + IsMethod: true, + IsResolver: true, + } + + ctx = graphql.WithFieldContext(ctx, fc) + resTmp, err := ec.ResolverMiddleware(ctx, func(rctx context.Context) (interface{}, error) { + ctx = rctx // use context from middleware stack in children + return ec.resolvers.MediaItem().Entities(rctx, obj) + }) + if err != nil { + ec.Error(ctx, err) + return graphql.Null + } + if resTmp == nil { + return graphql.Null + } + res := resTmp.([]*models.Entity) + fc.Result = res + return ec.marshalOEntity2ᚕᚖirisᚋapiᚋinternalᚋmodelsᚐEntityᚄ(ctx, field.Selections, res) +} + func (ec *executionContext) _MediaItem_createdAt(ctx context.Context, field graphql.CollectedField, obj *models.MediaItem) (ret graphql.Marshaler) { defer func() { if r := recover(); r != nil { @@ -3653,44 +3698,55 @@ func (ec *executionContext) _MediaItem(ctx context.Context, sel ast.SelectionSet case "id": out.Values[i] = ec._MediaItem_id(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } case "description": out.Values[i] = ec._MediaItem_description(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } case "imageUrl": out.Values[i] = ec._MediaItem_imageUrl(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } case "mimeType": out.Values[i] = ec._MediaItem_mimeType(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } case "fileName": out.Values[i] = ec._MediaItem_fileName(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } case "fileSize": out.Values[i] = ec._MediaItem_fileSize(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } case "mediaMetadata": out.Values[i] = ec._MediaItem_mediaMetadata(ctx, field, obj) + case "entities": + 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._MediaItem_entities(ctx, field, obj) + return res + }) case "createdAt": out.Values[i] = ec._MediaItem_createdAt(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } case "updatedAt": out.Values[i] = ec._MediaItem_updatedAt(ctx, field, obj) if out.Values[i] == graphql.Null { - invalids++ + atomic.AddUint32(&invalids, 1) } default: panic("unknown field " + strconv.Quote(field.Name)) diff --git a/api/internal/graph/resolvers/schema.resolvers.go b/api/internal/graph/resolvers/schema.resolvers.go index 5a4ae19..c6d5c79 100644 --- a/api/internal/graph/resolvers/schema.resolvers.go +++ b/api/internal/graph/resolvers/schema.resolvers.go @@ -82,6 +82,27 @@ func (r *entityResolver) MediaItems(ctx context.Context, obj *models.Entity, pag }, nil } +func (r *mediaItemResolver) Entities(ctx context.Context, obj *models.MediaItem) ([]*models.Entity, error) { + entityIDs := make([]primitive.ObjectID, len(obj.Entities)) + + for idx, strID := range obj.Entities { + oid, _ := primitive.ObjectIDFromHex(strID) + entityIDs[idx] = oid + } + + cur, err := r.DB.Collection(models.ColEntity).Find(ctx, bson.M{"_id": bson.M{"$in": entityIDs}}) + if err != nil { + return nil, err + } + + var result []*models.Entity + if err = cur.All(ctx, &result); err != nil { + return nil, err + } + + return result, nil +} + func (r *mutationResolver) Upload(ctx context.Context, file graphql.Upload) (bool, error) { result, err := r.CDN.Upload(file.File, file.Filename, file.Size, "", "") if err != nil { @@ -302,6 +323,9 @@ func (r *queryResolver) Entity(ctx context.Context, id string) (*models.Entity, // Entity returns generated.EntityResolver implementation. func (r *Resolver) Entity() generated.EntityResolver { return &entityResolver{r} } +// MediaItem returns generated.MediaItemResolver implementation. +func (r *Resolver) MediaItem() generated.MediaItemResolver { return &mediaItemResolver{r} } + // Mutation returns generated.MutationResolver implementation. func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResolver{r} } @@ -309,5 +333,6 @@ func (r *Resolver) Mutation() generated.MutationResolver { return &mutationResol func (r *Resolver) Query() generated.QueryResolver { return &queryResolver{r} } type entityResolver struct{ *Resolver } +type mediaItemResolver struct{ *Resolver } type mutationResolver struct{ *Resolver } type queryResolver struct{ *Resolver } diff --git a/api/internal/models/entity.go b/api/internal/models/entity.go index 7cee24c..50acb13 100644 --- a/api/internal/models/entity.go +++ b/api/internal/models/entity.go @@ -3,10 +3,11 @@ package models const ColEntity = "entities" type Entity struct { - ID string `json:"id" bson:"_id"` - Name string `json:"name"` - ImageURL string `json:"imageUrl"` - EntityType string `json:"entityType"` - CreatedAt string `json:"createdAt"` - UpdatedAt string `json:"updatedAt"` + ID string `json:"id" bson:"_id"` + Name string `json:"name"` + ImageURL string `json:"imageUrl"` + EntityType string `json:"entityType"` + MediaItems []string `json:"mediaItems"` + CreatedAt string `json:"createdAt"` + UpdatedAt string `json:"updatedAt"` } diff --git a/api/internal/models/mediaitem.go b/api/internal/models/mediaitem.go index bb5cda5..c1fe92d 100644 --- a/api/internal/models/mediaitem.go +++ b/api/internal/models/mediaitem.go @@ -13,6 +13,7 @@ type ( FileName string `json:"fileName"` FileSize int64 `json:"fileSize"` MediaMetadata *MediaMetaData `json:"mediaMetadata"` + Entities []string `json:"entities"` CreatedAt time.Time `json:"createdAt"` UpdatedAt time.Time `json:"updatedAt"` } diff --git a/api/schema.graphql b/api/schema.graphql index 9795478..b9eaabc 100644 --- a/api/schema.graphql +++ b/api/schema.graphql @@ -9,6 +9,7 @@ type MediaItem { fileName: String! fileSize: Int! mediaMetadata: MediaMetaData + entities: [Entity!] createdAt: Time! updatedAt: Time! } diff --git a/worker/pipeline/places.py b/worker/pipeline/places.py index abb85e0..ea2cd80 100644 --- a/worker/pipeline/places.py +++ b/worker/pipeline/places.py @@ -2,6 +2,7 @@ import json import urllib.request import exiftool +from bson.objectid import ObjectId from pymongo import ReturnDocument from .component import Component @@ -23,6 +24,10 @@ def upsert_entity(self, data): upsert=True, return_document=ReturnDocument.AFTER ) + self.db['entities'].update_one( + {'_id': result['_id']}, + {'$addToSet': {'mediaItems': ObjectId(self.oid)}}, + ) print(f'[place]: {result}') return result['_id']