Movie group renames (#5039)

* Rename Movie and MoviePartial to Group/GroupPartial
* Rename Movie interfaces
* Update movie url builders to use group
* Rename movieRoutes to groupRoutes
* Update dataloader
* Update names in sqlite package
* Rename in resolvers
* Add GroupByURL to scraper config
* Scraper backward compatibility hacks
This commit is contained in:
WithoutPants
2024-07-04 09:10:26 +10:00
committed by GitHub
parent b69d9cc840
commit 15a7b8a859
83 changed files with 1765 additions and 1646 deletions

View File

@@ -167,39 +167,39 @@ func GetDependentTagIDs(ctx context.Context, tags TagFinder, markerReader models
return ret, nil
}
// GetSceneMoviesJSON returns a slice of SceneMovie JSON representation objects
// corresponding to the provided scene's scene movie relationships.
func GetSceneMoviesJSON(ctx context.Context, movieReader models.MovieGetter, scene *models.Scene) ([]jsonschema.SceneMovie, error) {
sceneMovies := scene.Movies.List()
// GetSceneGroupsJSON returns a slice of SceneGroup JSON representation objects
// corresponding to the provided scene's scene group relationships.
func GetSceneGroupsJSON(ctx context.Context, groupReader models.GroupGetter, scene *models.Scene) ([]jsonschema.SceneGroup, error) {
sceneGroups := scene.Groups.List()
var results []jsonschema.SceneMovie
for _, sceneMovie := range sceneMovies {
movie, err := movieReader.Find(ctx, sceneMovie.MovieID)
var results []jsonschema.SceneGroup
for _, sceneGroup := range sceneGroups {
group, err := groupReader.Find(ctx, sceneGroup.GroupID)
if err != nil {
return nil, fmt.Errorf("error getting movie: %v", err)
return nil, fmt.Errorf("error getting group: %v", err)
}
if movie != nil {
sceneMovieJSON := jsonschema.SceneMovie{
MovieName: movie.Name,
if group != nil {
sceneGroupJSON := jsonschema.SceneGroup{
GroupName: group.Name,
}
if sceneMovie.SceneIndex != nil {
sceneMovieJSON.SceneIndex = *sceneMovie.SceneIndex
if sceneGroup.SceneIndex != nil {
sceneGroupJSON.SceneIndex = *sceneGroup.SceneIndex
}
results = append(results, sceneMovieJSON)
results = append(results, sceneGroupJSON)
}
}
return results, nil
}
// GetDependentMovieIDs returns a slice of movie IDs that this scene references.
func GetDependentMovieIDs(ctx context.Context, scene *models.Scene) ([]int, error) {
// GetDependentGroupIDs returns a slice of group IDs that this scene references.
func GetDependentGroupIDs(ctx context.Context, scene *models.Scene) ([]int, error) {
var ret []int
m := scene.Movies.List()
m := scene.Groups.List()
for _, mm := range m {
ret = append(ret, mm.MovieID)
ret = append(ret, mm.GroupID)
}
return ret, nil

View File

@@ -26,8 +26,8 @@ const (
noTagsID = 11
errTagsID = 12
noMoviesID = 13
errFindMovieID = 15
noGroupsID = 13
errFindGroupID = 15
noMarkersID = 16
errMarkersID = 17
@@ -49,15 +49,15 @@ var (
studioName = "studioName"
// galleryChecksum = "galleryChecksum"
validMovie1 = 1
validMovie2 = 2
invalidMovie = 3
validGroup1 = 1
validGroup2 = 2
invalidGroup = 3
movie1Name = "movie1Name"
movie2Name = "movie2Name"
group1Name = "group1Name"
group2Name = "group2Name"
movie1Scene = 1
movie2Scene = 2
group1Scene = 1
group2Scene = 2
)
var names = []string{
@@ -330,82 +330,82 @@ func TestGetTagNames(t *testing.T) {
db.AssertExpectations(t)
}
type sceneMoviesTestScenario struct {
type sceneGroupsTestScenario struct {
input models.Scene
expected []jsonschema.SceneMovie
expected []jsonschema.SceneGroup
err bool
}
var validMovies = models.NewRelatedMovies([]models.MoviesScenes{
var validGroups = models.NewRelatedGroups([]models.GroupsScenes{
{
MovieID: validMovie1,
SceneIndex: &movie1Scene,
GroupID: validGroup1,
SceneIndex: &group1Scene,
},
{
MovieID: validMovie2,
SceneIndex: &movie2Scene,
GroupID: validGroup2,
SceneIndex: &group2Scene,
},
})
var invalidMovies = models.NewRelatedMovies([]models.MoviesScenes{
var invalidGroups = models.NewRelatedGroups([]models.GroupsScenes{
{
MovieID: invalidMovie,
SceneIndex: &movie1Scene,
GroupID: invalidGroup,
SceneIndex: &group1Scene,
},
})
var getSceneMoviesJSONScenarios = []sceneMoviesTestScenario{
var getSceneGroupsJSONScenarios = []sceneGroupsTestScenario{
{
models.Scene{
ID: sceneID,
Movies: validMovies,
Groups: validGroups,
},
[]jsonschema.SceneMovie{
[]jsonschema.SceneGroup{
{
MovieName: movie1Name,
SceneIndex: movie1Scene,
GroupName: group1Name,
SceneIndex: group1Scene,
},
{
MovieName: movie2Name,
SceneIndex: movie2Scene,
GroupName: group2Name,
SceneIndex: group2Scene,
},
},
false,
},
{
models.Scene{
ID: noMoviesID,
Movies: models.NewRelatedMovies([]models.MoviesScenes{}),
ID: noGroupsID,
Groups: models.NewRelatedGroups([]models.GroupsScenes{}),
},
nil,
false,
},
{
models.Scene{
ID: errFindMovieID,
Movies: invalidMovies,
ID: errFindGroupID,
Groups: invalidGroups,
},
nil,
true,
},
}
func TestGetSceneMoviesJSON(t *testing.T) {
func TestGetSceneGroupsJSON(t *testing.T) {
db := mocks.NewDatabase()
movieErr := errors.New("error getting movie")
groupErr := errors.New("error getting group")
db.Movie.On("Find", testCtx, validMovie1).Return(&models.Movie{
Name: movie1Name,
db.Group.On("Find", testCtx, validGroup1).Return(&models.Group{
Name: group1Name,
}, nil).Once()
db.Movie.On("Find", testCtx, validMovie2).Return(&models.Movie{
Name: movie2Name,
db.Group.On("Find", testCtx, validGroup2).Return(&models.Group{
Name: group2Name,
}, nil).Once()
db.Movie.On("Find", testCtx, invalidMovie).Return(nil, movieErr).Once()
db.Group.On("Find", testCtx, invalidGroup).Return(nil, groupErr).Once()
for i, s := range getSceneMoviesJSONScenarios {
for i, s := range getSceneGroupsJSONScenarios {
scene := s.input
json, err := GetSceneMoviesJSON(testCtx, db.Movie, &scene)
json, err := GetSceneGroupsJSON(testCtx, db.Group, &scene)
switch {
case !s.err && err != nil:

View File

@@ -204,7 +204,7 @@ type sceneHolder struct {
mm string
dd string
performers []string
movies []string
groups []string
studio string
tags []string
}
@@ -340,7 +340,7 @@ func (h *sceneHolder) setField(field parserField, value interface{}) {
case "studio":
h.studio = value.(string)
case "movie":
h.movies = append(h.movies, value.(string))
h.groups = append(h.groups, value.(string))
case "tag":
h.tags = append(h.tags, value.(string))
case "yyyy":
@@ -413,7 +413,7 @@ type FilenameParser struct {
repository FilenameParserRepository
performerCache map[string]*models.Performer
studioCache map[string]*models.Studio
movieCache map[string]*models.Movie
groupCache map[string]*models.Group
tagCache map[string]*models.Tag
}
@@ -427,7 +427,7 @@ func NewFilenameParser(filter *models.FindFilterType, config models.SceneParserI
p.performerCache = make(map[string]*models.Performer)
p.studioCache = make(map[string]*models.Studio)
p.movieCache = make(map[string]*models.Movie)
p.groupCache = make(map[string]*models.Group)
p.tagCache = make(map[string]*models.Tag)
p.initWhiteSpaceRegex()
@@ -455,7 +455,7 @@ type FilenameParserRepository struct {
Scene models.SceneQueryer
Performer PerformerNamesFinder
Studio models.StudioQueryer
Movie MovieNameFinder
Group GroupNameFinder
Tag models.TagQueryer
}
@@ -464,7 +464,7 @@ func NewFilenameParserRepository(repo models.Repository) FilenameParserRepositor
Scene: repo.Scene,
Performer: repo.Performer,
Studio: repo.Studio,
Movie: repo.Movie,
Group: repo.Group,
Tag: repo.Tag,
}
}
@@ -578,23 +578,23 @@ func (p *FilenameParser) queryStudio(ctx context.Context, qb models.StudioQuerye
return ret
}
type MovieNameFinder interface {
FindByName(ctx context.Context, name string, nocase bool) (*models.Movie, error)
type GroupNameFinder interface {
FindByName(ctx context.Context, name string, nocase bool) (*models.Group, error)
}
func (p *FilenameParser) queryMovie(ctx context.Context, qb MovieNameFinder, movieName string) *models.Movie {
// massage the movie name
movieName = delimiterRE.ReplaceAllString(movieName, " ")
func (p *FilenameParser) queryGroup(ctx context.Context, qb GroupNameFinder, groupName string) *models.Group {
// massage the group name
groupName = delimiterRE.ReplaceAllString(groupName, " ")
// check cache first
if ret, found := p.movieCache[movieName]; found {
if ret, found := p.groupCache[groupName]; found {
return ret
}
ret, _ := qb.FindByName(ctx, movieName, true)
ret, _ := qb.FindByName(ctx, groupName, true)
// add result to cache
p.movieCache[movieName] = ret
p.groupCache[groupName] = ret
return ret
}
@@ -665,18 +665,18 @@ func (p *FilenameParser) setStudio(ctx context.Context, qb models.StudioQueryer,
}
}
func (p *FilenameParser) setMovies(ctx context.Context, qb MovieNameFinder, h sceneHolder, result *models.SceneParserResult) {
// query for each movie
moviesSet := make(map[int]bool)
for _, movieName := range h.movies {
if movieName != "" {
movie := p.queryMovie(ctx, qb, movieName)
if movie != nil {
if _, found := moviesSet[movie.ID]; !found {
func (p *FilenameParser) setGroups(ctx context.Context, qb GroupNameFinder, h sceneHolder, result *models.SceneParserResult) {
// query for each group
groupsSet := make(map[int]bool)
for _, groupName := range h.groups {
if groupName != "" {
group := p.queryGroup(ctx, qb, groupName)
if group != nil {
if _, found := groupsSet[group.ID]; !found {
result.Movies = append(result.Movies, &models.SceneMovieID{
MovieID: strconv.Itoa(movie.ID),
MovieID: strconv.Itoa(group.ID),
})
moviesSet[movie.ID] = true
groupsSet[group.ID] = true
}
}
}
@@ -714,7 +714,7 @@ func (p *FilenameParser) setParserResult(ctx context.Context, h sceneHolder, res
}
p.setStudio(ctx, r.Studio, h, result)
if len(h.movies) > 0 {
p.setMovies(ctx, r.Movie, h, result)
if len(h.groups) > 0 {
p.setGroups(ctx, r.Group, h, result)
}
}

View File

@@ -26,7 +26,7 @@ type Importer struct {
StudioWriter models.StudioFinderCreator
GalleryFinder models.GalleryFinder
PerformerWriter models.PerformerFinderCreator
MovieWriter models.MovieFinderCreator
GroupWriter models.GroupFinderCreator
TagWriter models.TagFinderCreator
Input jsonschema.Scene
MissingRefBehaviour models.ImportMissingRefEnum
@@ -62,7 +62,7 @@ func (i *Importer) PreImport(ctx context.Context) error {
return err
}
if err := i.populateMovies(ctx); err != nil {
if err := i.populateGroups(ctx); err != nil {
return err
}
@@ -89,7 +89,7 @@ func (i *Importer) sceneJSONToScene(sceneJSON jsonschema.Scene) models.Scene {
PerformerIDs: models.NewRelatedIDs([]int{}),
TagIDs: models.NewRelatedIDs([]int{}),
GalleryIDs: models.NewRelatedIDs([]int{}),
Movies: models.NewRelatedMovies([]models.MoviesScenes{}),
Groups: models.NewRelatedGroups([]models.GroupsScenes{}),
StashIDs: models.NewRelatedStashIDs(sceneJSON.StashIDs),
}
@@ -335,24 +335,24 @@ func (i *Importer) createPerformers(ctx context.Context, names []string) ([]*mod
return ret, nil
}
func (i *Importer) populateMovies(ctx context.Context) error {
if len(i.Input.Movies) > 0 {
for _, inputMovie := range i.Input.Movies {
movie, err := i.MovieWriter.FindByName(ctx, inputMovie.MovieName, false)
func (i *Importer) populateGroups(ctx context.Context) error {
if len(i.Input.Groups) > 0 {
for _, inputGroup := range i.Input.Groups {
group, err := i.GroupWriter.FindByName(ctx, inputGroup.GroupName, false)
if err != nil {
return fmt.Errorf("error finding scene movie: %v", err)
return fmt.Errorf("error finding scene group: %v", err)
}
var movieID int
if movie == nil {
var groupID int
if group == nil {
if i.MissingRefBehaviour == models.ImportMissingRefEnumFail {
return fmt.Errorf("scene movie [%s] not found", inputMovie.MovieName)
return fmt.Errorf("scene group [%s] not found", inputGroup.GroupName)
}
if i.MissingRefBehaviour == models.ImportMissingRefEnumCreate {
movieID, err = i.createMovie(ctx, inputMovie.MovieName)
groupID, err = i.createGroup(ctx, inputGroup.GroupName)
if err != nil {
return fmt.Errorf("error creating scene movie: %v", err)
return fmt.Errorf("error creating scene group: %v", err)
}
}
@@ -361,35 +361,35 @@ func (i *Importer) populateMovies(ctx context.Context) error {
continue
}
} else {
movieID = movie.ID
groupID = group.ID
}
toAdd := models.MoviesScenes{
MovieID: movieID,
toAdd := models.GroupsScenes{
GroupID: groupID,
}
if inputMovie.SceneIndex != 0 {
index := inputMovie.SceneIndex
if inputGroup.SceneIndex != 0 {
index := inputGroup.SceneIndex
toAdd.SceneIndex = &index
}
i.scene.Movies.Add(toAdd)
i.scene.Groups.Add(toAdd)
}
}
return nil
}
func (i *Importer) createMovie(ctx context.Context, name string) (int, error) {
newMovie := models.NewMovie()
newMovie.Name = name
func (i *Importer) createGroup(ctx context.Context, name string) (int, error) {
newGroup := models.NewGroup()
newGroup.Name = name
err := i.MovieWriter.Create(ctx, &newMovie)
err := i.GroupWriter.Create(ctx, &newGroup)
if err != nil {
return 0, err
}
return newMovie.ID, nil
return newGroup.ID, nil
}
func (i *Importer) populateTags(ctx context.Context) error {

View File

@@ -17,7 +17,7 @@ const invalidImage = "aW1hZ2VCeXRlcw&&"
var (
existingStudioID = 101
existingPerformerID = 103
existingMovieID = 104
existingGroupID = 104
existingTagID = 105
existingStudioName = "existingStudioName"
@@ -28,9 +28,9 @@ var (
existingPerformerErr = "existingPerformerErr"
missingPerformerName = "missingPerformerName"
existingMovieName = "existingMovieName"
existingMovieErr = "existingMovieErr"
missingMovieName = "missingMovieName"
existingGroupName = "existingGroupName"
existingGroupErr = "existingGroupErr"
missingGroupName = "missingGroupName"
existingTagName = "existingTagName"
existingTagErr = "existingTagErr"
@@ -221,58 +221,58 @@ func TestImporterPreImportWithMissingPerformerCreateErr(t *testing.T) {
db.AssertExpectations(t)
}
func TestImporterPreImportWithMovie(t *testing.T) {
func TestImporterPreImportWithGroup(t *testing.T) {
db := mocks.NewDatabase()
i := Importer{
MovieWriter: db.Movie,
GroupWriter: db.Group,
MissingRefBehaviour: models.ImportMissingRefEnumFail,
Input: jsonschema.Scene{
Movies: []jsonschema.SceneMovie{
Groups: []jsonschema.SceneGroup{
{
MovieName: existingMovieName,
GroupName: existingGroupName,
SceneIndex: 1,
},
},
},
}
db.Movie.On("FindByName", testCtx, existingMovieName, false).Return(&models.Movie{
ID: existingMovieID,
Name: existingMovieName,
db.Group.On("FindByName", testCtx, existingGroupName, false).Return(&models.Group{
ID: existingGroupID,
Name: existingGroupName,
}, nil).Once()
db.Movie.On("FindByName", testCtx, existingMovieErr, false).Return(nil, errors.New("FindByName error")).Once()
db.Group.On("FindByName", testCtx, existingGroupErr, false).Return(nil, errors.New("FindByName error")).Once()
err := i.PreImport(testCtx)
assert.Nil(t, err)
assert.Equal(t, existingMovieID, i.scene.Movies.List()[0].MovieID)
assert.Equal(t, existingGroupID, i.scene.Groups.List()[0].GroupID)
i.Input.Movies[0].MovieName = existingMovieErr
i.Input.Groups[0].GroupName = existingGroupErr
err = i.PreImport(testCtx)
assert.NotNil(t, err)
db.AssertExpectations(t)
}
func TestImporterPreImportWithMissingMovie(t *testing.T) {
func TestImporterPreImportWithMissingGroup(t *testing.T) {
db := mocks.NewDatabase()
i := Importer{
MovieWriter: db.Movie,
GroupWriter: db.Group,
Input: jsonschema.Scene{
Movies: []jsonschema.SceneMovie{
Groups: []jsonschema.SceneGroup{
{
MovieName: missingMovieName,
GroupName: missingGroupName,
},
},
},
MissingRefBehaviour: models.ImportMissingRefEnumFail,
}
db.Movie.On("FindByName", testCtx, missingMovieName, false).Return(nil, nil).Times(3)
db.Movie.On("Create", testCtx, mock.AnythingOfType("*models.Movie")).Run(func(args mock.Arguments) {
m := args.Get(1).(*models.Movie)
m.ID = existingMovieID
db.Group.On("FindByName", testCtx, missingGroupName, false).Return(nil, nil).Times(3)
db.Group.On("Create", testCtx, mock.AnythingOfType("*models.Group")).Run(func(args mock.Arguments) {
m := args.Get(1).(*models.Group)
m.ID = existingGroupID
}).Return(nil)
err := i.PreImport(testCtx)
@@ -285,28 +285,28 @@ func TestImporterPreImportWithMissingMovie(t *testing.T) {
i.MissingRefBehaviour = models.ImportMissingRefEnumCreate
err = i.PreImport(testCtx)
assert.Nil(t, err)
assert.Equal(t, existingMovieID, i.scene.Movies.List()[0].MovieID)
assert.Equal(t, existingGroupID, i.scene.Groups.List()[0].GroupID)
db.AssertExpectations(t)
}
func TestImporterPreImportWithMissingMovieCreateErr(t *testing.T) {
func TestImporterPreImportWithMissingGroupCreateErr(t *testing.T) {
db := mocks.NewDatabase()
i := Importer{
MovieWriter: db.Movie,
GroupWriter: db.Group,
Input: jsonschema.Scene{
Movies: []jsonschema.SceneMovie{
Groups: []jsonschema.SceneGroup{
{
MovieName: missingMovieName,
GroupName: missingGroupName,
},
},
},
MissingRefBehaviour: models.ImportMissingRefEnumCreate,
}
db.Movie.On("FindByName", testCtx, missingMovieName, false).Return(nil, nil).Once()
db.Movie.On("Create", testCtx, mock.AnythingOfType("*models.Movie")).Return(errors.New("Create error"))
db.Group.On("FindByName", testCtx, missingGroupName, false).Return(nil, nil).Once()
db.Group.On("Create", testCtx, mock.AnythingOfType("*models.Group")).Return(errors.New("Create error"))
err := i.PreImport(testCtx)
assert.NotNil(t, err)