mirror of https://github.com/stashapp/stash.git
243 lines
6.4 KiB
Go
243 lines
6.4 KiB
Go
package api
|
|
|
|
import (
|
|
"context"
|
|
"database/sql"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/stashapp/stash/pkg/models"
|
|
"github.com/stashapp/stash/pkg/utils"
|
|
)
|
|
|
|
func (r *mutationResolver) MovieCreate(ctx context.Context, input models.MovieCreateInput) (*models.Movie, error) {
|
|
// generate checksum from movie name rather than image
|
|
checksum := utils.MD5FromString(input.Name)
|
|
|
|
var frontimageData []byte
|
|
var backimageData []byte
|
|
var err error
|
|
|
|
// HACK: if back image is being set, set the front image to the default.
|
|
// This is because we can't have a null front image with a non-null back image.
|
|
if input.FrontImage == nil && input.BackImage != nil {
|
|
input.FrontImage = &models.DefaultMovieImage
|
|
}
|
|
|
|
// Process the base 64 encoded image string
|
|
if input.FrontImage != nil {
|
|
frontimageData, err = utils.ProcessImageInput(*input.FrontImage)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// Process the base 64 encoded image string
|
|
if input.BackImage != nil {
|
|
backimageData, err = utils.ProcessImageInput(*input.BackImage)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
// Populate a new movie from the input
|
|
currentTime := time.Now()
|
|
newMovie := models.Movie{
|
|
Checksum: checksum,
|
|
Name: sql.NullString{String: input.Name, Valid: true},
|
|
CreatedAt: models.SQLiteTimestamp{Timestamp: currentTime},
|
|
UpdatedAt: models.SQLiteTimestamp{Timestamp: currentTime},
|
|
}
|
|
|
|
if input.Aliases != nil {
|
|
newMovie.Aliases = sql.NullString{String: *input.Aliases, Valid: true}
|
|
}
|
|
if input.Duration != nil {
|
|
duration := int64(*input.Duration)
|
|
newMovie.Duration = sql.NullInt64{Int64: duration, Valid: true}
|
|
}
|
|
|
|
if input.Date != nil {
|
|
newMovie.Date = models.SQLiteDate{String: *input.Date, Valid: true}
|
|
}
|
|
|
|
if input.Rating != nil {
|
|
rating := int64(*input.Rating)
|
|
newMovie.Rating = sql.NullInt64{Int64: rating, Valid: true}
|
|
}
|
|
|
|
if input.StudioID != nil {
|
|
studioID, _ := strconv.ParseInt(*input.StudioID, 10, 64)
|
|
newMovie.StudioID = sql.NullInt64{Int64: studioID, Valid: true}
|
|
}
|
|
|
|
if input.Director != nil {
|
|
newMovie.Director = sql.NullString{String: *input.Director, Valid: true}
|
|
}
|
|
|
|
if input.Synopsis != nil {
|
|
newMovie.Synopsis = sql.NullString{String: *input.Synopsis, Valid: true}
|
|
}
|
|
|
|
if input.URL != nil {
|
|
newMovie.URL = sql.NullString{String: *input.URL, Valid: true}
|
|
}
|
|
|
|
// Start the transaction and save the movie
|
|
var movie *models.Movie
|
|
if err := r.withTxn(ctx, func(repo models.Repository) error {
|
|
qb := repo.Movie()
|
|
movie, err = qb.Create(newMovie)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// update image table
|
|
if len(frontimageData) > 0 {
|
|
if err := qb.UpdateImages(movie.ID, frontimageData, backimageData); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return movie, nil
|
|
}
|
|
|
|
func (r *mutationResolver) MovieUpdate(ctx context.Context, input models.MovieUpdateInput) (*models.Movie, error) {
|
|
// Populate movie from the input
|
|
movieID, err := strconv.Atoi(input.ID)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
updatedMovie := models.MoviePartial{
|
|
ID: movieID,
|
|
UpdatedAt: &models.SQLiteTimestamp{Timestamp: time.Now()},
|
|
}
|
|
|
|
translator := changesetTranslator{
|
|
inputMap: getUpdateInputMap(ctx),
|
|
}
|
|
|
|
var frontimageData []byte
|
|
frontImageIncluded := translator.hasField("front_image")
|
|
if input.FrontImage != nil {
|
|
frontimageData, err = utils.ProcessImageInput(*input.FrontImage)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
backImageIncluded := translator.hasField("back_image")
|
|
var backimageData []byte
|
|
if input.BackImage != nil {
|
|
backimageData, err = utils.ProcessImageInput(*input.BackImage)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
}
|
|
|
|
if input.Name != nil {
|
|
// generate checksum from movie name rather than image
|
|
checksum := utils.MD5FromString(*input.Name)
|
|
updatedMovie.Name = &sql.NullString{String: *input.Name, Valid: true}
|
|
updatedMovie.Checksum = &checksum
|
|
}
|
|
|
|
updatedMovie.Aliases = translator.nullString(input.Aliases, "aliases")
|
|
updatedMovie.Duration = translator.nullInt64(input.Duration, "duration")
|
|
updatedMovie.Date = translator.sqliteDate(input.Date, "date")
|
|
updatedMovie.Rating = translator.nullInt64(input.Rating, "rating")
|
|
updatedMovie.StudioID = translator.nullInt64FromString(input.StudioID, "studio_id")
|
|
updatedMovie.Director = translator.nullString(input.Director, "director")
|
|
updatedMovie.Synopsis = translator.nullString(input.Synopsis, "synopsis")
|
|
updatedMovie.URL = translator.nullString(input.URL, "url")
|
|
|
|
// Start the transaction and save the movie
|
|
var movie *models.Movie
|
|
if err := r.withTxn(ctx, func(repo models.Repository) error {
|
|
qb := repo.Movie()
|
|
movie, err = qb.Update(updatedMovie)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
// update image table
|
|
if frontImageIncluded || backImageIncluded {
|
|
if !frontImageIncluded {
|
|
frontimageData, err = qb.GetFrontImage(updatedMovie.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
if !backImageIncluded {
|
|
backimageData, err = qb.GetBackImage(updatedMovie.ID)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
if len(frontimageData) == 0 && len(backimageData) == 0 {
|
|
// both images are being nulled. Destroy them.
|
|
if err := qb.DestroyImages(movie.ID); err != nil {
|
|
return err
|
|
}
|
|
} else {
|
|
// HACK - if front image is null and back image is not null, then set the front image
|
|
// to the default image since we can't have a null front image and a non-null back image
|
|
if frontimageData == nil && backimageData != nil {
|
|
frontimageData, _ = utils.ProcessImageInput(models.DefaultMovieImage)
|
|
}
|
|
|
|
if err := qb.UpdateImages(movie.ID, frontimageData, backimageData); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return movie, nil
|
|
}
|
|
|
|
func (r *mutationResolver) MovieDestroy(ctx context.Context, input models.MovieDestroyInput) (bool, error) {
|
|
id, err := strconv.Atoi(input.ID)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
if err := r.withTxn(ctx, func(repo models.Repository) error {
|
|
return repo.Movie().Destroy(id)
|
|
}); err != nil {
|
|
return false, err
|
|
}
|
|
return true, nil
|
|
}
|
|
|
|
func (r *mutationResolver) MoviesDestroy(ctx context.Context, movieIDs []string) (bool, error) {
|
|
ids, err := utils.StringSliceToIntSlice(movieIDs)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
if err := r.withTxn(ctx, func(repo models.Repository) error {
|
|
qb := repo.Movie()
|
|
for _, id := range ids {
|
|
if err := qb.Destroy(id); err != nil {
|
|
return err
|
|
}
|
|
}
|
|
|
|
return nil
|
|
}); err != nil {
|
|
return false, err
|
|
}
|
|
return true, nil
|
|
}
|