Model refactor, part 2 (#4092)

* Move conversions into changesetTranslator
* Improve mutation error messages
* Use models.New and models.NewPartial everywhere
* Replace getStashIDsFor functions
* Remove ImageCreateInput
* Remove unused parameters
* Refactor matching functions
---------
Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
DingDongSoLong4
2023-09-11 04:24:15 +02:00
committed by GitHub
parent cf3301c8bc
commit 24e4719abc
61 changed files with 1514 additions and 1407 deletions

View File

@@ -114,13 +114,13 @@ func (_m *ImageReaderWriter) CountByGalleryID(ctx context.Context, galleryID int
return r0, r1
}
// Create provides a mock function with given fields: ctx, newImage
func (_m *ImageReaderWriter) Create(ctx context.Context, newImage *models.ImageCreateInput) error {
ret := _m.Called(ctx, newImage)
// Create provides a mock function with given fields: ctx, newImage, fileIDs
func (_m *ImageReaderWriter) Create(ctx context.Context, newImage *models.Image, fileIDs []models.FileID) error {
ret := _m.Called(ctx, newImage, fileIDs)
var r0 error
if rf, ok := ret.Get(0).(func(context.Context, *models.ImageCreateInput) error); ok {
r0 = rf(ctx, newImage)
if rf, ok := ret.Get(0).(func(context.Context, *models.Image, []models.FileID) error); ok {
r0 = rf(ctx, newImage, fileIDs)
} else {
r0 = ret.Error(0)
}

View File

@@ -36,6 +36,45 @@ type Gallery struct {
PerformerIDs RelatedIDs `json:"performer_ids"`
}
func NewGallery() Gallery {
currentTime := time.Now()
return Gallery{
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
}
// GalleryPartial represents part of a Gallery object. It is used to update
// the database entry. Only non-nil fields will be updated.
type GalleryPartial struct {
// Path OptionalString
// Checksum OptionalString
// Zip OptionalBool
Title OptionalString
URL OptionalString
Date OptionalDate
Details OptionalString
// Rating expressed in 1-100 scale
Rating OptionalInt
Organized OptionalBool
StudioID OptionalInt
// FileModTime OptionalTime
CreatedAt OptionalTime
UpdatedAt OptionalTime
SceneIDs *UpdateIDs
TagIDs *UpdateIDs
PerformerIDs *UpdateIDs
PrimaryFileID *FileID
}
func NewGalleryPartial() GalleryPartial {
currentTime := time.Now()
return GalleryPartial{
UpdatedAt: NewOptionalTime(currentTime),
}
}
// IsUserCreated returns true if the gallery was created by the user.
// This is determined by whether the gallery has a primary file or folder.
func (g *Gallery) IsUserCreated() bool {
@@ -97,37 +136,6 @@ func (g Gallery) PrimaryChecksum() string {
return ""
}
// GalleryPartial represents part of a Gallery object. It is used to update
// the database entry. Only non-nil fields will be updated.
type GalleryPartial struct {
// Path OptionalString
// Checksum OptionalString
// Zip OptionalBool
Title OptionalString
URL OptionalString
Date OptionalDate
Details OptionalString
// Rating expressed in 1-100 scale
Rating OptionalInt
Organized OptionalBool
StudioID OptionalInt
// FileModTime OptionalTime
CreatedAt OptionalTime
UpdatedAt OptionalTime
SceneIDs *UpdateIDs
TagIDs *UpdateIDs
PerformerIDs *UpdateIDs
PrimaryFileID *FileID
}
func NewGalleryPartial() GalleryPartial {
updatedTime := time.Now()
return GalleryPartial{
UpdatedAt: NewOptionalTime(updatedTime),
}
}
// GetTitle returns the title of the scene. If the Title field is empty,
// then the base filename is returned.
func (g Gallery) GetTitle() string {
@@ -153,13 +161,3 @@ func (g Gallery) DisplayName() string {
}
const DefaultGthumbWidth int = 640
type Galleries []*Gallery
func (g *Galleries) Append(o interface{}) {
*g = append(*g, o.(*Gallery))
}
func (g *Galleries) New() interface{} {
return &Gallery{}
}

View File

@@ -13,6 +13,14 @@ type GalleryChapter struct {
UpdatedAt time.Time `json:"updated_at"`
}
func NewGalleryChapter() GalleryChapter {
currentTime := time.Now()
return GalleryChapter{
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
}
// GalleryChapterPartial represents part of a GalleryChapter object.
// It is used to update the database entry.
type GalleryChapterPartial struct {
@@ -24,8 +32,8 @@ type GalleryChapterPartial struct {
}
func NewGalleryChapterPartial() GalleryChapterPartial {
updatedTime := time.Now()
currentTime := time.Now()
return GalleryChapterPartial{
UpdatedAt: NewOptionalTime(updatedTime),
UpdatedAt: NewOptionalTime(currentTime),
}
}

View File

@@ -36,6 +36,39 @@ type Image struct {
PerformerIDs RelatedIDs `json:"performer_ids"`
}
func NewImage() Image {
currentTime := time.Now()
return Image{
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
}
type ImagePartial struct {
Title OptionalString
// Rating expressed in 1-100 scale
Rating OptionalInt
URL OptionalString
Date OptionalDate
Organized OptionalBool
OCounter OptionalInt
StudioID OptionalInt
CreatedAt OptionalTime
UpdatedAt OptionalTime
GalleryIDs *UpdateIDs
TagIDs *UpdateIDs
PerformerIDs *UpdateIDs
PrimaryFileID *FileID
}
func NewImagePartial() ImagePartial {
currentTime := time.Now()
return ImagePartial{
UpdatedAt: NewOptionalTime(currentTime),
}
}
func (i *Image) LoadFiles(ctx context.Context, l FileLoader) error {
return i.Files.load(func() ([]File, error) {
return l.GetFiles(ctx, i.ID)
@@ -102,43 +135,3 @@ func (i Image) DisplayName() string {
return strconv.Itoa(i.ID)
}
type ImageCreateInput struct {
*Image
FileIDs []FileID
}
type ImagePartial struct {
Title OptionalString
// Rating expressed in 1-100 scale
Rating OptionalInt
URL OptionalString
Date OptionalDate
Organized OptionalBool
OCounter OptionalInt
StudioID OptionalInt
CreatedAt OptionalTime
UpdatedAt OptionalTime
GalleryIDs *UpdateIDs
TagIDs *UpdateIDs
PerformerIDs *UpdateIDs
PrimaryFileID *FileID
}
func NewImagePartial() ImagePartial {
updatedTime := time.Now()
return ImagePartial{
UpdatedAt: NewOptionalTime(updatedTime),
}
}
type Images []*Image
func (i *Images) Append(o interface{}) {
*i = append(*i, o.(*Image))
}
func (i *Images) New() interface{} {
return &Image{}
}

View File

@@ -11,8 +11,8 @@ type MoviesScenes struct {
SceneIndex *int `json:"scene_index"`
}
func (s MoviesScenes) SceneMovieInput() *SceneMovieInput {
return &SceneMovieInput{
func (s MoviesScenes) SceneMovieInput() SceneMovieInput {
return SceneMovieInput{
MovieID: strconv.Itoa(s.MovieID),
SceneIndex: s.SceneIndex,
}
@@ -28,12 +28,12 @@ type UpdateMovieIDs struct {
Mode RelationshipUpdateMode `json:"mode"`
}
func (u *UpdateMovieIDs) SceneMovieInputs() []*SceneMovieInput {
func (u *UpdateMovieIDs) SceneMovieInputs() []SceneMovieInput {
if u == nil {
return nil
}
ret := make([]*SceneMovieInput, len(u.Movies))
ret := make([]SceneMovieInput, len(u.Movies))
for _, id := range u.Movies {
ret = append(ret, id.SceneMovieInput())
}
@@ -51,21 +51,7 @@ func (u *UpdateMovieIDs) AddUnique(v MoviesScenes) {
u.Movies = append(u.Movies, v)
}
func UpdateMovieIDsFromInput(i []*SceneMovieInput) (*UpdateMovieIDs, error) {
ret := &UpdateMovieIDs{
Mode: RelationshipUpdateModeSet,
}
var err error
ret.Movies, err = MoviesScenesFromInput(i)
if err != nil {
return nil, err
}
return ret, nil
}
func MoviesScenesFromInput(input []*SceneMovieInput) ([]MoviesScenes, error) {
func MoviesScenesFromInput(input []SceneMovieInput) ([]MoviesScenes, error) {
ret := make([]MoviesScenes, len(input))
for i, v := range input {

View File

@@ -20,6 +20,14 @@ type Movie struct {
UpdatedAt time.Time `json:"updated_at"`
}
func NewMovie() Movie {
currentTime := time.Now()
return Movie{
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
}
type MoviePartial struct {
Name OptionalString
Aliases OptionalString
@@ -35,30 +43,11 @@ type MoviePartial struct {
UpdatedAt OptionalTime
}
var DefaultMovieImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4wgVBQsJl1CMZAAAASJJREFUeNrt3N0JwyAYhlEj3cj9R3Cm5rbkqtAP+qrnGaCYHPwJpLlaa++mmLpbAERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAHZuVflj40x4i94zhk9vqsVvEq6AsQqMP1EjORx20OACAgQRRx7T+zzcFBxcjNDfoB4ntQqTm5Awo7MlqywZxcgYQ+RlqywJ3ozJAQCSBiEJSsQA0gYBpDAgAARECACAkRAgAgIEAERECACAmSjUv6eAOSB8m8YIGGzBUjYbAESBgMkbBkDEjZbgITBAClcxiqQvEoatreYIWEBASIgJ4Gkf11ntXH3nS9uxfGWfJ5J9hAgAgJEQAQEiIAAERAgAgJEQAQEiIAAERAgAgJEQAQEiL7qBuc6RKLHxr0CAAAAAElFTkSuQmCC"
func NewMovie(name string) *Movie {
currentTime := time.Now()
return &Movie{
Name: name,
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
}
func NewMoviePartial() MoviePartial {
updatedTime := time.Now()
currentTime := time.Now()
return MoviePartial{
UpdatedAt: NewOptionalTime(updatedTime),
UpdatedAt: NewOptionalTime(currentTime),
}
}
type Movies []*Movie
func (m *Movies) Append(o interface{}) {
*m = append(*m, o.(*Movie))
}
func (m *Movies) New() interface{} {
return &Movie{}
}
var DefaultMovieImage = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAGQAAABkCAYAAABw4pVUAAAABmJLR0QA/wD/AP+gvaeTAAAACXBIWXMAAA3XAAAN1wFCKJt4AAAAB3RJTUUH4wgVBQsJl1CMZAAAASJJREFUeNrt3N0JwyAYhlEj3cj9R3Cm5rbkqtAP+qrnGaCYHPwJpLlaa++mmLpbAERAgAgIEAEBIiBABERAgAgIEAEBIiBABERAgAgIEAHZuVflj40x4i94zhk9vqsVvEq6AsQqMP1EjORx20OACAgQRRx7T+zzcFBxcjNDfoB4ntQqTm5Awo7MlqywZxcgYQ+RlqywJ3ozJAQCSBiEJSsQA0gYBpDAgAARECACAkRAgAgIEAERECACAmSjUv6eAOSB8m8YIGGzBUjYbAESBgMkbBkDEjZbgITBAClcxiqQvEoatreYIWEBASIgJ4Gkf11ntXH3nS9uxfGWfJ5J9hAgAgJEQAQEiIAAERAgAgJEQAQEiIAAERAgAgJEQAQEiL7qBuc6RKLHxr0CAAAAAElFTkSuQmCC"

View File

@@ -41,38 +41,12 @@ type Performer struct {
StashIDs RelatedStashIDs `json:"stash_ids"`
}
func (s *Performer) LoadAliases(ctx context.Context, l AliasLoader) error {
return s.Aliases.load(func() ([]string, error) {
return l.GetAliases(ctx, s.ID)
})
}
func (s *Performer) LoadTagIDs(ctx context.Context, l TagIDLoader) error {
return s.TagIDs.load(func() ([]int, error) {
return l.GetTagIDs(ctx, s.ID)
})
}
func (s *Performer) LoadStashIDs(ctx context.Context, l StashIDLoader) error {
return s.StashIDs.load(func() ([]StashID, error) {
return l.GetStashIDs(ctx, s.ID)
})
}
func (s *Performer) LoadRelationships(ctx context.Context, l PerformerReader) error {
if err := s.LoadAliases(ctx, l); err != nil {
return err
func NewPerformer() Performer {
currentTime := time.Now()
return Performer{
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
if err := s.LoadTagIDs(ctx, l); err != nil {
return err
}
if err := s.LoadStashIDs(ctx, l); err != nil {
return err
}
return nil
}
// PerformerPartial represents part of a Performer object. It is used to update
@@ -112,28 +86,43 @@ type PerformerPartial struct {
StashIDs *UpdateStashIDs
}
func NewPerformer(name string) *Performer {
currentTime := time.Now()
return &Performer{
Name: name,
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
}
func NewPerformerPartial() PerformerPartial {
updatedTime := time.Now()
currentTime := time.Now()
return PerformerPartial{
UpdatedAt: NewOptionalTime(updatedTime),
UpdatedAt: NewOptionalTime(currentTime),
}
}
type Performers []*Performer
func (p *Performers) Append(o interface{}) {
*p = append(*p, o.(*Performer))
func (s *Performer) LoadAliases(ctx context.Context, l AliasLoader) error {
return s.Aliases.load(func() ([]string, error) {
return l.GetAliases(ctx, s.ID)
})
}
func (p *Performers) New() interface{} {
return &Performer{}
func (s *Performer) LoadTagIDs(ctx context.Context, l TagIDLoader) error {
return s.TagIDs.load(func() ([]int, error) {
return l.GetTagIDs(ctx, s.ID)
})
}
func (s *Performer) LoadStashIDs(ctx context.Context, l StashIDLoader) error {
return s.StashIDs.load(func() ([]StashID, error) {
return l.GetStashIDs(ctx, s.ID)
})
}
func (s *Performer) LoadRelationships(ctx context.Context, l PerformerReader) error {
if err := s.LoadAliases(ctx, l); err != nil {
return err
}
if err := s.LoadTagIDs(ctx, l); err != nil {
return err
}
if err := s.LoadStashIDs(ctx, l); err != nil {
return err
}
return nil
}

View File

@@ -67,13 +67,3 @@ type SavedFilter struct {
ObjectFilter map[string]interface{} `json:"object_filter"`
UIOptions map[string]interface{} `json:"ui_options"`
}
type SavedFilters []*SavedFilter
func (m *SavedFilters) Append(o interface{}) {
*m = append(*m, o.(*SavedFilter))
}
func (m *SavedFilters) New() interface{} {
return &SavedFilter{}
}

View File

@@ -48,6 +48,50 @@ type Scene struct {
StashIDs RelatedStashIDs `json:"stash_ids"`
}
func NewScene() Scene {
currentTime := time.Now()
return Scene{
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
}
// ScenePartial represents part of a Scene object. It is used to update
// the database entry.
type ScenePartial struct {
Title OptionalString
Code OptionalString
Details OptionalString
Director OptionalString
Date OptionalDate
// Rating expressed in 1-100 scale
Rating OptionalInt
Organized OptionalBool
OCounter OptionalInt
StudioID OptionalInt
CreatedAt OptionalTime
UpdatedAt OptionalTime
ResumeTime OptionalFloat64
PlayDuration OptionalFloat64
PlayCount OptionalInt
LastPlayedAt OptionalTime
URLs *UpdateStrings
GalleryIDs *UpdateIDs
TagIDs *UpdateIDs
PerformerIDs *UpdateIDs
MovieIDs *UpdateMovieIDs
StashIDs *UpdateStashIDs
PrimaryFileID *FileID
}
func NewScenePartial() ScenePartial {
currentTime := time.Now()
return ScenePartial{
UpdatedAt: NewOptionalTime(currentTime),
}
}
func (s *Scene) LoadURLs(ctx context.Context, l URLLoader) error {
return s.URLs.load(func() ([]string, error) {
return l.GetURLs(ctx, s.ID)
@@ -145,77 +189,6 @@ func (s *Scene) LoadRelationships(ctx context.Context, l SceneReader) error {
return nil
}
// ScenePartial represents part of a Scene object. It is used to update
// the database entry.
type ScenePartial struct {
Title OptionalString
Code OptionalString
Details OptionalString
Director OptionalString
Date OptionalDate
// Rating expressed in 1-100 scale
Rating OptionalInt
Organized OptionalBool
OCounter OptionalInt
StudioID OptionalInt
CreatedAt OptionalTime
UpdatedAt OptionalTime
ResumeTime OptionalFloat64
PlayDuration OptionalFloat64
PlayCount OptionalInt
LastPlayedAt OptionalTime
URLs *UpdateStrings
GalleryIDs *UpdateIDs
TagIDs *UpdateIDs
PerformerIDs *UpdateIDs
MovieIDs *UpdateMovieIDs
StashIDs *UpdateStashIDs
PrimaryFileID *FileID
}
func NewScenePartial() ScenePartial {
updatedTime := time.Now()
return ScenePartial{
UpdatedAt: NewOptionalTime(updatedTime),
}
}
type SceneMovieInput struct {
MovieID string `json:"movie_id"`
SceneIndex *int `json:"scene_index"`
}
type SceneUpdateInput struct {
ClientMutationID *string `json:"clientMutationId"`
ID string `json:"id"`
Title *string `json:"title"`
Code *string `json:"code"`
Details *string `json:"details"`
Director *string `json:"director"`
URL *string `json:"url"`
Date *string `json:"date"`
// Rating expressed in 1-5 scale
Rating *int `json:"rating"`
// Rating expressed in 1-100 scale
Rating100 *int `json:"rating100"`
OCounter *int `json:"o_counter"`
Organized *bool `json:"organized"`
Urls []string `json:"urls"`
StudioID *string `json:"studio_id"`
GalleryIds []string `json:"gallery_ids"`
PerformerIds []string `json:"performer_ids"`
Movies []*SceneMovieInput `json:"movies"`
TagIds []string `json:"tag_ids"`
// This should be a URL or a base64 encoded data URL
CoverImage *string `json:"cover_image"`
StashIds []StashID `json:"stash_ids"`
ResumeTime *float64 `json:"resume_time"`
PlayDuration *float64 `json:"play_duration"`
PlayCount *int `json:"play_count"`
PrimaryFileID *string `json:"primary_file_id"`
}
// UpdateInput constructs a SceneUpdateInput using the populated fields in the ScenePartial object.
func (s ScenePartial) UpdateInput(id int) SceneUpdateInput {
var dateStr *string
@@ -302,16 +275,6 @@ type SceneFileType struct {
Bitrate *int `graphql:"bitrate" json:"bitrate"`
}
type Scenes []*Scene
func (s *Scenes) Append(o interface{}) {
*s = append(*s, o.(*Scene))
}
func (s *Scenes) New() interface{} {
return &Scene{}
}
type VideoCaption struct {
LanguageCode string `json:"language_code"`
Filename string `json:"filename"`

View File

@@ -14,6 +14,14 @@ type SceneMarker struct {
UpdatedAt time.Time `json:"updated_at"`
}
func NewSceneMarker() SceneMarker {
currentTime := time.Now()
return SceneMarker{
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
}
// SceneMarkerPartial represents part of a SceneMarker object.
// It is used to update the database entry.
type SceneMarkerPartial struct {
@@ -26,8 +34,8 @@ type SceneMarkerPartial struct {
}
func NewSceneMarkerPartial() SceneMarkerPartial {
updatedTime := time.Now()
currentTime := time.Now()
return SceneMarkerPartial{
UpdatedAt: NewOptionalTime(updatedTime),
UpdatedAt: NewOptionalTime(currentTime),
}
}

View File

@@ -3,7 +3,6 @@ package models
import (
"context"
"strconv"
"time"
"github.com/stashapp/stash/pkg/sliceutil/stringslice"
"github.com/stashapp/stash/pkg/utils"
@@ -23,17 +22,12 @@ type ScrapedStudio struct {
func (ScrapedStudio) IsScrapedContent() {}
func (s *ScrapedStudio) ToStudio(endpoint string, excluded map[string]bool) *Studio {
now := time.Now()
// Populate a new studio from the input
newStudio := Studio{
Name: s.Name,
CreatedAt: now,
UpdatedAt: now,
}
ret := NewStudio()
ret.Name = s.Name
if s.RemoteSiteID != nil && endpoint != "" {
newStudio.StashIDs = NewRelatedStashIDs([]StashID{
ret.StashIDs = NewRelatedStashIDs([]StashID{
{
Endpoint: endpoint,
StashID: *s.RemoteSiteID,
@@ -42,15 +36,15 @@ func (s *ScrapedStudio) ToStudio(endpoint string, excluded map[string]bool) *Stu
}
if s.URL != nil && !excluded["url"] {
newStudio.URL = *s.URL
ret.URL = *s.URL
}
if s.Parent != nil && s.Parent.StoredID != nil && !excluded["parent"] && !excluded["parent_studio"] {
parentId, _ := strconv.Atoi(*s.Parent.StoredID)
newStudio.ParentID = &parentId
ret.ParentID = &parentId
}
return &newStudio
return &ret
}
func (s *ScrapedStudio) GetImage(ctx context.Context, excluded map[string]bool) ([]byte, error) {
@@ -69,17 +63,15 @@ func (s *ScrapedStudio) GetImage(ctx context.Context, excluded map[string]bool)
}
func (s *ScrapedStudio) ToPartial(id *string, endpoint string, excluded map[string]bool, existingStashIDs []StashID) *StudioPartial {
partial := StudioPartial{
UpdatedAt: NewOptionalTime(time.Now()),
}
partial.ID, _ = strconv.Atoi(*id)
ret := NewStudioPartial()
ret.ID, _ = strconv.Atoi(*id)
if s.Name != "" && !excluded["name"] {
partial.Name = NewOptionalString(s.Name)
ret.Name = NewOptionalString(s.Name)
}
if s.URL != nil && !excluded["url"] {
partial.URL = NewOptionalString(*s.URL)
ret.URL = NewOptionalString(*s.URL)
}
if s.Parent != nil && !excluded["parent"] {
@@ -87,25 +79,25 @@ func (s *ScrapedStudio) ToPartial(id *string, endpoint string, excluded map[stri
parentID, _ := strconv.Atoi(*s.Parent.StoredID)
if parentID > 0 {
// This is to be set directly as we know it has a value and the translator won't have the field
partial.ParentID = NewOptionalInt(parentID)
ret.ParentID = NewOptionalInt(parentID)
}
}
} else {
partial.ParentID = NewOptionalIntPtr(nil)
ret.ParentID = NewOptionalIntPtr(nil)
}
if s.RemoteSiteID != nil && endpoint != "" {
partial.StashIDs = &UpdateStashIDs{
ret.StashIDs = &UpdateStashIDs{
StashIDs: existingStashIDs,
Mode: RelationshipUpdateModeSet,
}
partial.StashIDs.Set(StashID{
ret.StashIDs.Set(StashID{
Endpoint: endpoint,
StashID: *s.RemoteSiteID,
})
}
return &partial
return &ret
}
// A performer from a scraping operation...
@@ -145,7 +137,8 @@ type ScrapedPerformer struct {
func (ScrapedPerformer) IsScrapedContent() {}
func (p *ScrapedPerformer) ToPerformer(endpoint string, excluded map[string]bool) *Performer {
ret := NewPerformer(*p.Name)
ret := NewPerformer()
ret.Name = *p.Name
if p.Aliases != nil && !excluded["aliases"] {
ret.Aliases = NewRelatedStrings(stringslice.FromString(*p.Aliases, ","))
@@ -244,7 +237,7 @@ func (p *ScrapedPerformer) ToPerformer(endpoint string, excluded map[string]bool
})
}
return ret
return &ret
}
func (p *ScrapedPerformer) GetImage(ctx context.Context, excluded map[string]bool) ([]byte, error) {
@@ -263,10 +256,10 @@ func (p *ScrapedPerformer) GetImage(ctx context.Context, excluded map[string]boo
}
func (p *ScrapedPerformer) ToPartial(endpoint string, excluded map[string]bool, existingStashIDs []StashID) PerformerPartial {
partial := NewPerformerPartial()
ret := NewPerformerPartial()
if p.Aliases != nil && !excluded["aliases"] {
partial.Aliases = &UpdateStrings{
ret.Aliases = &UpdateStrings{
Values: stringslice.FromString(*p.Aliases, ","),
Mode: RelationshipUpdateModeSet,
}
@@ -274,88 +267,88 @@ func (p *ScrapedPerformer) ToPartial(endpoint string, excluded map[string]bool,
if p.Birthdate != nil && !excluded["birthdate"] {
date, err := ParseDate(*p.Birthdate)
if err == nil {
partial.Birthdate = NewOptionalDate(date)
ret.Birthdate = NewOptionalDate(date)
}
}
if p.DeathDate != nil && !excluded["death_date"] {
date, err := ParseDate(*p.DeathDate)
if err == nil {
partial.DeathDate = NewOptionalDate(date)
ret.DeathDate = NewOptionalDate(date)
}
}
if p.CareerLength != nil && !excluded["career_length"] {
partial.CareerLength = NewOptionalString(*p.CareerLength)
ret.CareerLength = NewOptionalString(*p.CareerLength)
}
if p.Country != nil && !excluded["country"] {
partial.Country = NewOptionalString(*p.Country)
ret.Country = NewOptionalString(*p.Country)
}
if p.Ethnicity != nil && !excluded["ethnicity"] {
partial.Ethnicity = NewOptionalString(*p.Ethnicity)
ret.Ethnicity = NewOptionalString(*p.Ethnicity)
}
if p.EyeColor != nil && !excluded["eye_color"] {
partial.EyeColor = NewOptionalString(*p.EyeColor)
ret.EyeColor = NewOptionalString(*p.EyeColor)
}
if p.HairColor != nil && !excluded["hair_color"] {
partial.HairColor = NewOptionalString(*p.HairColor)
ret.HairColor = NewOptionalString(*p.HairColor)
}
if p.FakeTits != nil && !excluded["fake_tits"] {
partial.FakeTits = NewOptionalString(*p.FakeTits)
ret.FakeTits = NewOptionalString(*p.FakeTits)
}
if p.Gender != nil && !excluded["gender"] {
partial.Gender = NewOptionalString(*p.Gender)
ret.Gender = NewOptionalString(*p.Gender)
}
if p.Height != nil && !excluded["height"] {
h, err := strconv.Atoi(*p.Height)
if err == nil {
partial.Height = NewOptionalInt(h)
ret.Height = NewOptionalInt(h)
}
}
if p.Weight != nil && !excluded["weight"] {
w, err := strconv.Atoi(*p.Weight)
if err == nil {
partial.Weight = NewOptionalInt(w)
ret.Weight = NewOptionalInt(w)
}
}
if p.Instagram != nil && !excluded["instagram"] {
partial.Instagram = NewOptionalString(*p.Instagram)
ret.Instagram = NewOptionalString(*p.Instagram)
}
if p.Measurements != nil && !excluded["measurements"] {
partial.Measurements = NewOptionalString(*p.Measurements)
ret.Measurements = NewOptionalString(*p.Measurements)
}
if p.Name != nil && !excluded["name"] {
partial.Name = NewOptionalString(*p.Name)
ret.Name = NewOptionalString(*p.Name)
}
if p.Disambiguation != nil && !excluded["disambiguation"] {
partial.Disambiguation = NewOptionalString(*p.Disambiguation)
ret.Disambiguation = NewOptionalString(*p.Disambiguation)
}
if p.Details != nil && !excluded["details"] {
partial.Details = NewOptionalString(*p.Details)
ret.Details = NewOptionalString(*p.Details)
}
if p.Piercings != nil && !excluded["piercings"] {
partial.Piercings = NewOptionalString(*p.Piercings)
ret.Piercings = NewOptionalString(*p.Piercings)
}
if p.Tattoos != nil && !excluded["tattoos"] {
partial.Tattoos = NewOptionalString(*p.Tattoos)
ret.Tattoos = NewOptionalString(*p.Tattoos)
}
if p.Twitter != nil && !excluded["twitter"] {
partial.Twitter = NewOptionalString(*p.Twitter)
ret.Twitter = NewOptionalString(*p.Twitter)
}
if p.URL != nil && !excluded["url"] {
partial.URL = NewOptionalString(*p.URL)
ret.URL = NewOptionalString(*p.URL)
}
if p.RemoteSiteID != nil && endpoint != "" {
partial.StashIDs = &UpdateStashIDs{
ret.StashIDs = &UpdateStashIDs{
StashIDs: existingStashIDs,
Mode: RelationshipUpdateModeSet,
}
partial.StashIDs.Set(StashID{
ret.StashIDs.Set(StashID{
Endpoint: endpoint,
StashID: *p.RemoteSiteID,
})
}
return partial
return ret
}
type ScrapedTag struct {

View File

@@ -21,6 +21,38 @@ type Studio struct {
StashIDs RelatedStashIDs `json:"stash_ids"`
}
func NewStudio() Studio {
currentTime := time.Now()
return Studio{
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
}
// StudioPartial represents part of a Studio object. It is used to update the database entry.
type StudioPartial struct {
ID int
Name OptionalString
URL OptionalString
ParentID OptionalInt
// Rating expressed in 1-100 scale
Rating OptionalInt
Details OptionalString
CreatedAt OptionalTime
UpdatedAt OptionalTime
IgnoreAutoTag OptionalBool
Aliases *UpdateStrings
StashIDs *UpdateStashIDs
}
func NewStudioPartial() StudioPartial {
currentTime := time.Now()
return StudioPartial{
UpdatedAt: NewOptionalTime(currentTime),
}
}
func (s *Studio) LoadAliases(ctx context.Context, l AliasLoader) error {
return s.Aliases.load(func() ([]string, error) {
return l.GetAliases(ctx, s.ID)
@@ -44,30 +76,3 @@ func (s *Studio) LoadRelationships(ctx context.Context, l PerformerReader) error
return nil
}
// StudioPartial represents part of a Studio object. It is used to update the database entry.
type StudioPartial struct {
ID int
Name OptionalString
URL OptionalString
ParentID OptionalInt
// Rating expressed in 1-100 scale
Rating OptionalInt
Details OptionalString
CreatedAt OptionalTime
UpdatedAt OptionalTime
IgnoreAutoTag OptionalBool
Aliases *UpdateStrings
StashIDs *UpdateStashIDs
}
type Studios []*Studio
func (s *Studios) Append(o interface{}) {
*s = append(*s, o.(*Studio))
}
func (s *Studios) New() interface{} {
return &Studio{}
}

View File

@@ -13,6 +13,14 @@ type Tag struct {
UpdatedAt time.Time `json:"updated_at"`
}
func NewTag() Tag {
currentTime := time.Now()
return Tag{
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
}
type TagPartial struct {
Name OptionalString
Description OptionalString
@@ -21,43 +29,14 @@ type TagPartial struct {
UpdatedAt OptionalTime
}
func NewTagPartial() TagPartial {
currentTime := time.Now()
return TagPartial{
UpdatedAt: NewOptionalTime(currentTime),
}
}
type TagPath struct {
Tag
Path string `json:"path"`
}
func NewTag(name string) *Tag {
currentTime := time.Now()
return &Tag{
Name: name,
CreatedAt: currentTime,
UpdatedAt: currentTime,
}
}
func NewTagPartial() TagPartial {
updatedTime := time.Now()
return TagPartial{
UpdatedAt: NewOptionalTime(updatedTime),
}
}
type Tags []*Tag
func (t *Tags) Append(o interface{}) {
*t = append(*t, o.(*Tag))
}
func (t *Tags) New() interface{} {
return &Tag{}
}
type TagPaths []*TagPath
func (t *TagPaths) Append(o interface{}) {
*t = append(*t, o.(*TagPath))
}
func (t *TagPaths) New() interface{} {
return &TagPath{}
}

View File

@@ -192,3 +192,76 @@ type PerformerFilterType struct {
// Filter by updated at
UpdatedAt *TimestampCriterionInput `json:"updated_at"`
}
type PerformerCreateInput struct {
Name string `json:"name"`
Disambiguation *string `json:"disambiguation"`
URL *string `json:"url"`
Gender *GenderEnum `json:"gender"`
Birthdate *string `json:"birthdate"`
Ethnicity *string `json:"ethnicity"`
Country *string `json:"country"`
EyeColor *string `json:"eye_color"`
Height *string `json:"height"`
HeightCm *int `json:"height_cm"`
Measurements *string `json:"measurements"`
FakeTits *string `json:"fake_tits"`
PenisLength *float64 `json:"penis_length"`
Circumcised *CircumisedEnum `json:"circumcised"`
CareerLength *string `json:"career_length"`
Tattoos *string `json:"tattoos"`
Piercings *string `json:"piercings"`
Aliases *string `json:"aliases"`
AliasList []string `json:"alias_list"`
Twitter *string `json:"twitter"`
Instagram *string `json:"instagram"`
Favorite *bool `json:"favorite"`
TagIds []string `json:"tag_ids"`
// This should be a URL or a base64 encoded data URL
Image *string `json:"image"`
StashIds []StashID `json:"stash_ids"`
Rating *int `json:"rating"`
Rating100 *int `json:"rating100"`
Details *string `json:"details"`
DeathDate *string `json:"death_date"`
HairColor *string `json:"hair_color"`
Weight *int `json:"weight"`
IgnoreAutoTag *bool `json:"ignore_auto_tag"`
}
type PerformerUpdateInput struct {
ID string `json:"id"`
Name *string `json:"name"`
Disambiguation *string `json:"disambiguation"`
URL *string `json:"url"`
Gender *GenderEnum `json:"gender"`
Birthdate *string `json:"birthdate"`
Ethnicity *string `json:"ethnicity"`
Country *string `json:"country"`
EyeColor *string `json:"eye_color"`
Height *string `json:"height"`
HeightCm *int `json:"height_cm"`
Measurements *string `json:"measurements"`
FakeTits *string `json:"fake_tits"`
PenisLength *float64 `json:"penis_length"`
Circumcised *CircumisedEnum `json:"circumcised"`
CareerLength *string `json:"career_length"`
Tattoos *string `json:"tattoos"`
Piercings *string `json:"piercings"`
Aliases *string `json:"aliases"`
AliasList []string `json:"alias_list"`
Twitter *string `json:"twitter"`
Instagram *string `json:"instagram"`
Favorite *bool `json:"favorite"`
TagIds []string `json:"tag_ids"`
// This should be a URL or a base64 encoded data URL
Image *string `json:"image"`
StashIds []StashID `json:"stash_ids"`
Rating *int `json:"rating"`
Rating100 *int `json:"rating100"`
Details *string `json:"details"`
DeathDate *string `json:"death_date"`
HairColor *string `json:"hair_color"`
Weight *int `json:"weight"`
IgnoreAutoTag *bool `json:"ignore_auto_tag"`
}

View File

@@ -36,7 +36,7 @@ type ImageCounter interface {
// ImageCreator provides methods to create images.
type ImageCreator interface {
Create(ctx context.Context, newImage *ImageCreateInput) error
Create(ctx context.Context, newImage *Image, fileIDs []FileID) error
}
// ImageUpdater provides methods to update images.

View File

@@ -113,6 +113,64 @@ type SceneQueryResult struct {
resolveErr error
}
type SceneMovieInput struct {
MovieID string `json:"movie_id"`
SceneIndex *int `json:"scene_index"`
}
type SceneCreateInput struct {
Title *string `json:"title"`
Code *string `json:"code"`
Details *string `json:"details"`
Director *string `json:"director"`
URL *string `json:"url"`
Urls []string `json:"urls"`
Date *string `json:"date"`
Rating *int `json:"rating"`
Rating100 *int `json:"rating100"`
Organized *bool `json:"organized"`
StudioID *string `json:"studio_id"`
GalleryIds []string `json:"gallery_ids"`
PerformerIds []string `json:"performer_ids"`
Movies []SceneMovieInput `json:"movies"`
TagIds []string `json:"tag_ids"`
// This should be a URL or a base64 encoded data URL
CoverImage *string `json:"cover_image"`
StashIds []StashID `json:"stash_ids"`
// The first id will be assigned as primary.
// Files will be reassigned from existing scenes if applicable.
// Files must not already be primary for another scene.
FileIds []string `json:"file_ids"`
}
type SceneUpdateInput struct {
ClientMutationID *string `json:"clientMutationId"`
ID string `json:"id"`
Title *string `json:"title"`
Code *string `json:"code"`
Details *string `json:"details"`
Director *string `json:"director"`
URL *string `json:"url"`
Urls []string `json:"urls"`
Date *string `json:"date"`
Rating *int `json:"rating"`
Rating100 *int `json:"rating100"`
OCounter *int `json:"o_counter"`
Organized *bool `json:"organized"`
StudioID *string `json:"studio_id"`
GalleryIds []string `json:"gallery_ids"`
PerformerIds []string `json:"performer_ids"`
Movies []SceneMovieInput `json:"movies"`
TagIds []string `json:"tag_ids"`
// This should be a URL or a base64 encoded data URL
CoverImage *string `json:"cover_image"`
StashIds []StashID `json:"stash_ids"`
ResumeTime *float64 `json:"resume_time"`
PlayDuration *float64 `json:"play_duration"`
PlayCount *int `json:"play_count"`
PrimaryFileID *string `json:"primary_file_id"`
}
type SceneDestroyInput struct {
ID string `json:"id"`
DeleteFile *bool `json:"delete_file"`

View File

@@ -35,3 +35,32 @@ type StudioFilterType struct {
// Filter by updated at
UpdatedAt *TimestampCriterionInput `json:"updated_at"`
}
type StudioCreateInput struct {
Name string `json:"name"`
URL *string `json:"url"`
ParentID *string `json:"parent_id"`
// This should be a URL or a base64 encoded data URL
Image *string `json:"image"`
StashIds []StashID `json:"stash_ids"`
Rating *int `json:"rating"`
Rating100 *int `json:"rating100"`
Details *string `json:"details"`
Aliases []string `json:"aliases"`
IgnoreAutoTag *bool `json:"ignore_auto_tag"`
}
type StudioUpdateInput struct {
ID string `json:"id"`
Name *string `json:"name"`
URL *string `json:"url"`
ParentID *string `json:"parent_id"`
// This should be a URL or a base64 encoded data URL
Image *string `json:"image"`
StashIds []StashID `json:"stash_ids"`
Rating *int `json:"rating"`
Rating100 *int `json:"rating100"`
Details *string `json:"details"`
Aliases []string `json:"aliases"`
IgnoreAutoTag *bool `json:"ignore_auto_tag"`
}