stash/pkg/api/resolver.go

216 lines
6.4 KiB
Go
Raw Normal View History

2019-02-09 12:30:49 +00:00
package api
import (
"context"
"sort"
"strconv"
2019-08-21 04:47:48 +00:00
"github.com/99designs/gqlgen/graphql"
"github.com/stashapp/stash/pkg/logger"
2019-08-21 04:47:48 +00:00
"github.com/stashapp/stash/pkg/models"
2019-02-09 12:30:49 +00:00
)
type Resolver struct{}
func (r *Resolver) Gallery() models.GalleryResolver {
return &galleryResolver{r}
}
func (r *Resolver) Mutation() models.MutationResolver {
return &mutationResolver{r}
}
func (r *Resolver) Performer() models.PerformerResolver {
return &performerResolver{r}
}
func (r *Resolver) Query() models.QueryResolver {
return &queryResolver{r}
}
func (r *Resolver) Scene() models.SceneResolver {
return &sceneResolver{r}
}
func (r *Resolver) SceneMarker() models.SceneMarkerResolver {
return &sceneMarkerResolver{r}
}
func (r *Resolver) Studio() models.StudioResolver {
return &studioResolver{r}
}
func (r *Resolver) Movie() models.MovieResolver {
return &movieResolver{r}
}
2019-02-09 12:30:49 +00:00
func (r *Resolver) Subscription() models.SubscriptionResolver {
return &subscriptionResolver{r}
}
func (r *Resolver) Tag() models.TagResolver {
return &tagResolver{r}
}
func (r *Resolver) ScrapedSceneTag() models.ScrapedSceneTagResolver {
return &scrapedSceneTagResolver{r}
}
func (r *Resolver) ScrapedSceneMovie() models.ScrapedSceneMovieResolver {
return &scrapedSceneMovieResolver{r}
}
func (r *Resolver) ScrapedScenePerformer() models.ScrapedScenePerformerResolver {
return &scrapedScenePerformerResolver{r}
}
func (r *Resolver) ScrapedSceneStudio() models.ScrapedSceneStudioResolver {
return &scrapedSceneStudioResolver{r}
}
2019-02-09 12:30:49 +00:00
type mutationResolver struct{ *Resolver }
type queryResolver struct{ *Resolver }
type subscriptionResolver struct{ *Resolver }
type galleryResolver struct{ *Resolver }
type performerResolver struct{ *Resolver }
type sceneResolver struct{ *Resolver }
type sceneMarkerResolver struct{ *Resolver }
type studioResolver struct{ *Resolver }
type movieResolver struct{ *Resolver }
2019-02-09 12:30:49 +00:00
type tagResolver struct{ *Resolver }
type scrapedSceneTagResolver struct{ *Resolver }
type scrapedSceneMovieResolver struct{ *Resolver }
type scrapedScenePerformerResolver struct{ *Resolver }
type scrapedSceneStudioResolver struct{ *Resolver }
2019-02-09 12:30:49 +00:00
2019-05-27 19:34:26 +00:00
func (r *queryResolver) MarkerWall(ctx context.Context, q *string) ([]*models.SceneMarker, error) {
2019-02-09 12:30:49 +00:00
qb := models.NewSceneMarkerQueryBuilder()
return qb.Wall(q)
}
2019-05-27 19:34:26 +00:00
func (r *queryResolver) SceneWall(ctx context.Context, q *string) ([]*models.Scene, error) {
2019-02-09 12:30:49 +00:00
qb := models.NewSceneQueryBuilder()
return qb.Wall(q)
}
func (r *queryResolver) MarkerStrings(ctx context.Context, q *string, sort *string) ([]*models.MarkerStringsResultType, error) {
qb := models.NewSceneMarkerQueryBuilder()
return qb.GetMarkerStrings(q, sort)
}
2019-05-27 19:34:26 +00:00
func (r *queryResolver) ValidGalleriesForScene(ctx context.Context, scene_id *string) ([]*models.Gallery, error) {
2019-02-09 12:30:49 +00:00
if scene_id == nil {
panic("nil scene id") // TODO make scene_id mandatory
}
sceneID, _ := strconv.Atoi(*scene_id)
sqb := models.NewSceneQueryBuilder()
scene, err := sqb.Find(sceneID)
if err != nil {
return nil, err
}
qb := models.NewGalleryQueryBuilder()
validGalleries, err := qb.ValidGalleriesForScenePath(scene.Path)
sceneGallery, _ := qb.FindBySceneID(sceneID, nil)
if sceneGallery != nil {
2019-05-27 19:34:26 +00:00
validGalleries = append(validGalleries, sceneGallery)
2019-02-09 12:30:49 +00:00
}
return validGalleries, nil
}
func (r *queryResolver) Stats(ctx context.Context) (*models.StatsResultType, error) {
2019-02-11 20:36:10 +00:00
scenesQB := models.NewSceneQueryBuilder()
scenesCount, _ := scenesQB.Count()
scenesSizeCount, _ := scenesQB.SizeCount()
2019-02-11 20:36:10 +00:00
galleryQB := models.NewGalleryQueryBuilder()
galleryCount, _ := galleryQB.Count()
performersQB := models.NewPerformerQueryBuilder()
performersCount, _ := performersQB.Count()
studiosQB := models.NewStudioQueryBuilder()
studiosCount, _ := studiosQB.Count()
moviesQB := models.NewMovieQueryBuilder()
moviesCount, _ := moviesQB.Count()
2019-02-11 20:36:10 +00:00
tagsQB := models.NewTagQueryBuilder()
tagsCount, _ := tagsQB.Count()
return &models.StatsResultType{
SceneCount: scenesCount,
SceneSizeCount: scenesSizeCount,
GalleryCount: galleryCount,
2019-02-11 20:36:10 +00:00
PerformerCount: performersCount,
StudioCount: studiosCount,
MovieCount: moviesCount,
TagCount: tagsCount,
2019-02-11 20:36:10 +00:00
}, nil
2019-02-09 12:30:49 +00:00
}
2019-08-21 04:47:48 +00:00
func (r *queryResolver) Version(ctx context.Context) (*models.Version, error) {
version, hash, buildtime := GetVersion()
2019-08-21 04:47:48 +00:00
return &models.Version{
Version: &version,
2019-08-21 04:47:48 +00:00
Hash: hash,
BuildTime: buildtime,
}, nil
}
//Gets latest version (git shorthash commit for now)
func (r *queryResolver) Latestversion(ctx context.Context) (*models.ShortVersion, error) {
ver, url, err := GetLatestVersion(true)
if err == nil {
logger.Infof("Retrieved latest hash: %s", ver)
} else {
logger.Errorf("Error while retrieving latest hash: %s", err)
}
return &models.ShortVersion{
Shorthash: ver,
URL: url,
}, err
}
2019-02-09 12:30:49 +00:00
// Get scene marker tags which show up under the video.
2019-05-27 19:34:26 +00:00
func (r *queryResolver) SceneMarkerTags(ctx context.Context, scene_id string) ([]*models.SceneMarkerTag, error) {
2019-02-09 12:30:49 +00:00
sceneID, _ := strconv.Atoi(scene_id)
sqb := models.NewSceneMarkerQueryBuilder()
sceneMarkers, err := sqb.FindBySceneID(sceneID, nil)
if err != nil {
return nil, err
}
tags := make(map[int]*models.SceneMarkerTag)
var keys []int
tqb := models.NewTagQueryBuilder()
for _, sceneMarker := range sceneMarkers {
markerPrimaryTag, err := tqb.Find(sceneMarker.PrimaryTagID, nil)
2019-02-09 12:30:49 +00:00
if err != nil {
return nil, err
}
_, hasKey := tags[markerPrimaryTag.ID]
var sceneMarkerTag *models.SceneMarkerTag
if !hasKey {
2019-05-27 19:34:26 +00:00
sceneMarkerTag = &models.SceneMarkerTag{Tag: markerPrimaryTag}
2019-02-09 12:30:49 +00:00
tags[markerPrimaryTag.ID] = sceneMarkerTag
keys = append(keys, markerPrimaryTag.ID)
} else {
sceneMarkerTag = tags[markerPrimaryTag.ID]
}
tags[markerPrimaryTag.ID].SceneMarkers = append(tags[markerPrimaryTag.ID].SceneMarkers, sceneMarker)
}
// Sort so that primary tags that show up earlier in the video are first.
sort.Slice(keys, func(i, j int) bool {
a := tags[keys[i]]
b := tags[keys[j]]
return a.SceneMarkers[0].Seconds < b.SceneMarkers[0].Seconds
})
2019-05-27 19:34:26 +00:00
var result []*models.SceneMarkerTag
2019-02-09 12:30:49 +00:00
for _, key := range keys {
2019-05-27 19:34:26 +00:00
result = append(result, tags[key])
2019-02-09 12:30:49 +00:00
}
return result, nil
}
// wasFieldIncluded returns true if the given field was included in the request.
// Slices are unmarshalled to empty slices even if the field was omitted. This
// method determines if it was omitted altogether.
func wasFieldIncluded(ctx context.Context, field string) bool {
rctx := graphql.GetRequestContext(ctx)
_, ret := rctx.Variables[field]
return ret
}