From c6a326ca6488b461a7dcd5ccb0140c31e1c67f87 Mon Sep 17 00:00:00 2001 From: 7dJx1qP <38586902+7dJx1qP@users.noreply.github.com> Date: Thu, 28 Oct 2021 20:12:39 -0400 Subject: [PATCH] Add stash_ids to performer, scene, studio import/export (#1916) * add stash_ids to performer, scene, studio import/export --- pkg/manager/jsonschema/performer.go | 53 ++++++++++--------- pkg/manager/jsonschema/scene.go | 41 +++++++------- pkg/manager/jsonschema/studio.go | 19 +++---- pkg/performer/export.go | 12 +++++ pkg/performer/export_test.go | 14 +++++ pkg/performer/import.go | 6 +++ pkg/scene/export.go | 12 +++++ pkg/scene/export_test.go | 14 +++++ pkg/scene/import.go | 6 +++ pkg/studio/export.go | 12 +++++ pkg/studio/export_test.go | 15 ++++++ pkg/studio/import.go | 6 +++ .../components/Changelog/versions/v0110.md | 1 + 13 files changed, 156 insertions(+), 55 deletions(-) diff --git a/pkg/manager/jsonschema/performer.go b/pkg/manager/jsonschema/performer.go index ec1aec4bb..6fee26a18 100644 --- a/pkg/manager/jsonschema/performer.go +++ b/pkg/manager/jsonschema/performer.go @@ -9,32 +9,33 @@ import ( ) type Performer struct { - Name string `json:"name,omitempty"` - Gender string `json:"gender,omitempty"` - URL string `json:"url,omitempty"` - Twitter string `json:"twitter,omitempty"` - Instagram string `json:"instagram,omitempty"` - Birthdate string `json:"birthdate,omitempty"` - Ethnicity string `json:"ethnicity,omitempty"` - Country string `json:"country,omitempty"` - EyeColor string `json:"eye_color,omitempty"` - Height string `json:"height,omitempty"` - Measurements string `json:"measurements,omitempty"` - FakeTits string `json:"fake_tits,omitempty"` - CareerLength string `json:"career_length,omitempty"` - Tattoos string `json:"tattoos,omitempty"` - Piercings string `json:"piercings,omitempty"` - Aliases string `json:"aliases,omitempty"` - Favorite bool `json:"favorite,omitempty"` - Tags []string `json:"tags,omitempty"` - Image string `json:"image,omitempty"` - CreatedAt models.JSONTime `json:"created_at,omitempty"` - UpdatedAt models.JSONTime `json:"updated_at,omitempty"` - Rating int `json:"rating,omitempty"` - Details string `json:"details,omitempty"` - DeathDate string `json:"death_date,omitempty"` - HairColor string `json:"hair_color,omitempty"` - Weight int `json:"weight,omitempty"` + Name string `json:"name,omitempty"` + Gender string `json:"gender,omitempty"` + URL string `json:"url,omitempty"` + Twitter string `json:"twitter,omitempty"` + Instagram string `json:"instagram,omitempty"` + Birthdate string `json:"birthdate,omitempty"` + Ethnicity string `json:"ethnicity,omitempty"` + Country string `json:"country,omitempty"` + EyeColor string `json:"eye_color,omitempty"` + Height string `json:"height,omitempty"` + Measurements string `json:"measurements,omitempty"` + FakeTits string `json:"fake_tits,omitempty"` + CareerLength string `json:"career_length,omitempty"` + Tattoos string `json:"tattoos,omitempty"` + Piercings string `json:"piercings,omitempty"` + Aliases string `json:"aliases,omitempty"` + Favorite bool `json:"favorite,omitempty"` + Tags []string `json:"tags,omitempty"` + Image string `json:"image,omitempty"` + CreatedAt models.JSONTime `json:"created_at,omitempty"` + UpdatedAt models.JSONTime `json:"updated_at,omitempty"` + Rating int `json:"rating,omitempty"` + Details string `json:"details,omitempty"` + DeathDate string `json:"death_date,omitempty"` + HairColor string `json:"hair_color,omitempty"` + Weight int `json:"weight,omitempty"` + StashIDs []models.StashID `json:"stash_ids,omitempty"` } func LoadPerformerFile(filePath string) (*Performer, error) { diff --git a/pkg/manager/jsonschema/scene.go b/pkg/manager/jsonschema/scene.go index b0207f33c..72ccc53e1 100644 --- a/pkg/manager/jsonschema/scene.go +++ b/pkg/manager/jsonschema/scene.go @@ -36,26 +36,27 @@ type SceneMovie struct { } type Scene struct { - Title string `json:"title,omitempty"` - Checksum string `json:"checksum,omitempty"` - OSHash string `json:"oshash,omitempty"` - Phash string `json:"phash,omitempty"` - Studio string `json:"studio,omitempty"` - URL string `json:"url,omitempty"` - Date string `json:"date,omitempty"` - Rating int `json:"rating,omitempty"` - Organized bool `json:"organized,omitempty"` - OCounter int `json:"o_counter,omitempty"` - Details string `json:"details,omitempty"` - Galleries []string `json:"galleries,omitempty"` - Performers []string `json:"performers,omitempty"` - Movies []SceneMovie `json:"movies,omitempty"` - Tags []string `json:"tags,omitempty"` - Markers []SceneMarker `json:"markers,omitempty"` - File *SceneFile `json:"file,omitempty"` - Cover string `json:"cover,omitempty"` - CreatedAt models.JSONTime `json:"created_at,omitempty"` - UpdatedAt models.JSONTime `json:"updated_at,omitempty"` + Title string `json:"title,omitempty"` + Checksum string `json:"checksum,omitempty"` + OSHash string `json:"oshash,omitempty"` + Phash string `json:"phash,omitempty"` + Studio string `json:"studio,omitempty"` + URL string `json:"url,omitempty"` + Date string `json:"date,omitempty"` + Rating int `json:"rating,omitempty"` + Organized bool `json:"organized,omitempty"` + OCounter int `json:"o_counter,omitempty"` + Details string `json:"details,omitempty"` + Galleries []string `json:"galleries,omitempty"` + Performers []string `json:"performers,omitempty"` + Movies []SceneMovie `json:"movies,omitempty"` + Tags []string `json:"tags,omitempty"` + Markers []SceneMarker `json:"markers,omitempty"` + File *SceneFile `json:"file,omitempty"` + Cover string `json:"cover,omitempty"` + CreatedAt models.JSONTime `json:"created_at,omitempty"` + UpdatedAt models.JSONTime `json:"updated_at,omitempty"` + StashIDs []models.StashID `json:"stash_ids,omitempty"` } func LoadSceneFile(filePath string) (*Scene, error) { diff --git a/pkg/manager/jsonschema/studio.go b/pkg/manager/jsonschema/studio.go index ee793acbc..5ecf04335 100644 --- a/pkg/manager/jsonschema/studio.go +++ b/pkg/manager/jsonschema/studio.go @@ -9,15 +9,16 @@ import ( ) type Studio struct { - Name string `json:"name,omitempty"` - URL string `json:"url,omitempty"` - ParentStudio string `json:"parent_studio,omitempty"` - Image string `json:"image,omitempty"` - CreatedAt models.JSONTime `json:"created_at,omitempty"` - UpdatedAt models.JSONTime `json:"updated_at,omitempty"` - Rating int `json:"rating,omitempty"` - Details string `json:"details,omitempty"` - Aliases []string `json:"aliases,omitempty"` + Name string `json:"name,omitempty"` + URL string `json:"url,omitempty"` + ParentStudio string `json:"parent_studio,omitempty"` + Image string `json:"image,omitempty"` + CreatedAt models.JSONTime `json:"created_at,omitempty"` + UpdatedAt models.JSONTime `json:"updated_at,omitempty"` + Rating int `json:"rating,omitempty"` + Details string `json:"details,omitempty"` + Aliases []string `json:"aliases,omitempty"` + StashIDs []models.StashID `json:"stash_ids,omitempty"` } func LoadStudioFile(filePath string) (*Studio, error) { diff --git a/pkg/performer/export.go b/pkg/performer/export.go index 85dee179c..55e3beaf0 100644 --- a/pkg/performer/export.go +++ b/pkg/performer/export.go @@ -91,6 +91,18 @@ func ToJSON(reader models.PerformerReader, performer *models.Performer) (*jsonsc newPerformerJSON.Image = utils.GetBase64StringFromData(image) } + stashIDs, _ := reader.GetStashIDs(performer.ID) + var ret []models.StashID + for _, stashID := range stashIDs { + newJoin := models.StashID{ + StashID: stashID.StashID, + Endpoint: stashID.Endpoint, + } + ret = append(ret, newJoin) + } + + newPerformerJSON.StashIDs = ret + return &newPerformerJSON, nil } diff --git a/pkg/performer/export_test.go b/pkg/performer/export_test.go index 9398e7fc1..1851bd13f 100644 --- a/pkg/performer/export_test.go +++ b/pkg/performer/export_test.go @@ -44,6 +44,14 @@ const ( var imageBytes = []byte("imageBytes") +var stashID = models.StashID{ + StashID: "StashID", + Endpoint: "Endpoint", +} +var stashIDs = []*models.StashID{ + &stashID, +} + const image = "aW1hZ2VCeXRlcw==" var birthDate = models.SQLiteDate{ @@ -144,6 +152,9 @@ func createFullJSONPerformer(name string, image string) *jsonschema.Performer { DeathDate: deathDate.String, HairColor: hairColor, Weight: weight, + StashIDs: []models.StashID{ + stashID, + }, } } @@ -197,6 +208,9 @@ func TestToJSON(t *testing.T) { mockPerformerReader.On("GetImage", noImageID).Return(nil, nil).Once() mockPerformerReader.On("GetImage", errImageID).Return(nil, imageErr).Once() + mockPerformerReader.On("GetStashIDs", performerID).Return(stashIDs, nil).Once() + mockPerformerReader.On("GetStashIDs", noImageID).Return(nil, nil).Once() + for i, s := range scenarios { tag := s.input json, err := ToJSON(mockPerformerReader, &tag) diff --git a/pkg/performer/import.go b/pkg/performer/import.go index 37b1868ca..e4589995d 100644 --- a/pkg/performer/import.go +++ b/pkg/performer/import.go @@ -123,6 +123,12 @@ func (i *Importer) PostImport(id int) error { } } + if len(i.Input.StashIDs) > 0 { + if err := i.ReaderWriter.UpdateStashIDs(id, i.Input.StashIDs); err != nil { + return fmt.Errorf("error setting stash id: %v", err) + } + } + return nil } diff --git a/pkg/scene/export.go b/pkg/scene/export.go index 8a1197698..352ce32b9 100644 --- a/pkg/scene/export.go +++ b/pkg/scene/export.go @@ -65,6 +65,18 @@ func ToBasicJSON(reader models.SceneReader, scene *models.Scene) (*jsonschema.Sc newSceneJSON.Cover = utils.GetBase64StringFromData(cover) } + stashIDs, _ := reader.GetStashIDs(scene.ID) + var ret []models.StashID + for _, stashID := range stashIDs { + newJoin := models.StashID{ + StashID: stashID.StashID, + Endpoint: stashID.Endpoint, + } + ret = append(ret, newJoin) + } + + newSceneJSON.StashIDs = ret + return &newSceneJSON, nil } diff --git a/pkg/scene/export_test.go b/pkg/scene/export_test.go index 3911b03ca..15aec8f4c 100644 --- a/pkg/scene/export_test.go +++ b/pkg/scene/export_test.go @@ -85,6 +85,14 @@ var names = []string{ var imageBytes = []byte("imageBytes") +var stashID = models.StashID{ + StashID: "StashID", + Endpoint: "Endpoint", +} +var stashIDs = []*models.StashID{ + &stashID, +} + const imageBase64 = "aW1hZ2VCeXRlcw==" var ( @@ -174,6 +182,9 @@ func createFullJSONScene(image string) *jsonschema.Scene { Time: updateTime, }, Cover: image, + StashIDs: []models.StashID{ + stashID, + }, } } @@ -222,6 +233,9 @@ func TestToJSON(t *testing.T) { mockSceneReader.On("GetCover", noImageID).Return(nil, nil).Once() mockSceneReader.On("GetCover", errImageID).Return(nil, imageErr).Once() + mockSceneReader.On("GetStashIDs", sceneID).Return(stashIDs, nil).Once() + mockSceneReader.On("GetStashIDs", noImageID).Return(nil, nil).Once() + for i, s := range scenarios { scene := s.input json, err := ToBasicJSON(mockSceneReader, &scene) diff --git a/pkg/scene/import.go b/pkg/scene/import.go index fa1e8f857..abd087ea1 100644 --- a/pkg/scene/import.go +++ b/pkg/scene/import.go @@ -386,6 +386,12 @@ func (i *Importer) PostImport(id int) error { } } + if len(i.Input.StashIDs) > 0 { + if err := i.ReaderWriter.UpdateStashIDs(id, i.Input.StashIDs); err != nil { + return fmt.Errorf("error setting stash id: %v", err) + } + } + return nil } diff --git a/pkg/studio/export.go b/pkg/studio/export.go index 49dd8fc7a..41f535494 100644 --- a/pkg/studio/export.go +++ b/pkg/studio/export.go @@ -58,5 +58,17 @@ func ToJSON(reader models.StudioReader, studio *models.Studio) (*jsonschema.Stud newStudioJSON.Image = utils.GetBase64StringFromData(image) } + stashIDs, _ := reader.GetStashIDs(studio.ID) + var ret []models.StashID + for _, stashID := range stashIDs { + newJoin := models.StashID{ + StashID: stashID.StashID, + Endpoint: stashID.Endpoint, + } + ret = append(ret, newJoin) + } + + newStudioJSON.StashIDs = ret + return &newStudioJSON, nil } diff --git a/pkg/studio/export_test.go b/pkg/studio/export_test.go index b4d5b312e..c18fbfa30 100644 --- a/pkg/studio/export_test.go +++ b/pkg/studio/export_test.go @@ -39,6 +39,14 @@ var parentStudio models.Studio = models.Studio{ var imageBytes = []byte("imageBytes") +var stashID = models.StashID{ + StashID: "StashID", + Endpoint: "Endpoint", +} +var stashIDs = []*models.StashID{ + &stashID, +} + const image = "aW1hZ2VCeXRlcw==" var ( @@ -95,6 +103,9 @@ func createFullJSONStudio(parentStudio, image string, aliases []string) *jsonsch Image: image, Rating: rating, Aliases: aliases, + StashIDs: []models.StashID{ + stashID, + }, } } @@ -180,6 +191,10 @@ func TestToJSON(t *testing.T) { mockStudioReader.On("GetAliases", missingParentStudioID).Return(nil, nil).Once() mockStudioReader.On("GetAliases", errAliasID).Return(nil, aliasErr).Once() + mockStudioReader.On("GetStashIDs", studioID).Return(stashIDs, nil).Once() + mockStudioReader.On("GetStashIDs", noImageID).Return(nil, nil).Once() + mockStudioReader.On("GetStashIDs", missingParentStudioID).Return(stashIDs, nil).Once() + for i, s := range scenarios { studio := s.input json, err := ToJSON(mockStudioReader, &studio) diff --git a/pkg/studio/import.go b/pkg/studio/import.go index 67f9018c3..8a9dfa644 100644 --- a/pkg/studio/import.go +++ b/pkg/studio/import.go @@ -101,6 +101,12 @@ func (i *Importer) PostImport(id int) error { } } + if len(i.Input.StashIDs) > 0 { + if err := i.ReaderWriter.UpdateStashIDs(id, i.Input.StashIDs); err != nil { + return fmt.Errorf("error setting stash id: %v", err) + } + } + if err := i.ReaderWriter.UpdateAliases(id, i.Input.Aliases); err != nil { return fmt.Errorf("error setting tag aliases: %v", err) } diff --git a/ui/v2.5/src/components/Changelog/versions/v0110.md b/ui/v2.5/src/components/Changelog/versions/v0110.md index 3bd43033c..3fe202ac1 100644 --- a/ui/v2.5/src/components/Changelog/versions/v0110.md +++ b/ui/v2.5/src/components/Changelog/versions/v0110.md @@ -20,6 +20,7 @@ * Optimised scanning process. ([#1816](https://github.com/stashapp/stash/pull/1816)) ### 🐛 Bug fixes +* Include stash ids in import/export. ([#1916](https://github.com/stashapp/stash/pull/1916)) * Fix tiny menu items in scrape menu when a stash-box instance has no name. ([#1889](https://github.com/stashapp/stash/pull/1889)) * Fix creating missing entities removing the incorrect entry from the missing list in the scrape dialog. ([#1890](https://github.com/stashapp/stash/pull/1890)) * Allow creating missing Studio during movie scrape. ([#1899](https://github.com/stashapp/stash/pull/1899))