Parent studios (#595)

* Refactor getMultiCriterionClause
Co-authored-by: Anon247 <61889302+Anon247@users.noreply.github.com>
This commit is contained in:
WithoutPants
2020-06-15 21:34:39 +10:00
committed by GitHub
parent a77fea5724
commit 96e6e16507
37 changed files with 818 additions and 146 deletions

View File

@@ -3,6 +3,7 @@ package manager
import (
"context"
"database/sql"
"fmt"
"strconv"
"sync"
"time"
@@ -157,7 +158,8 @@ func (t *ImportTask) ImportPerformers(ctx context.Context) {
func (t *ImportTask) ImportStudios(ctx context.Context) {
tx := database.DB.MustBeginTx(ctx, nil)
qb := models.NewStudioQueryBuilder()
pendingParent := make(map[string][]*jsonschema.Studio)
for i, mappingJSON := range t.Mappings.Studios {
index := i + 1
@@ -172,35 +174,28 @@ func (t *ImportTask) ImportStudios(ctx context.Context) {
logger.Progressf("[studios] %d of %d", index, len(t.Mappings.Studios))
// generate checksum from studio name rather than image
checksum := utils.MD5FromString(studioJSON.Name)
// Process the base 64 encoded image string
_, imageData, err := utils.ProcessBase64Image(studioJSON.Image)
if err != nil {
_ = tx.Rollback()
logger.Errorf("[studios] <%s> invalid image: %s", mappingJSON.Checksum, err.Error())
return
}
// Populate a new studio from the input
newStudio := models.Studio{
Image: imageData,
Checksum: checksum,
Name: sql.NullString{String: studioJSON.Name, Valid: true},
URL: sql.NullString{String: studioJSON.URL, Valid: true},
CreatedAt: models.SQLiteTimestamp{Timestamp: t.getTimeFromJSONTime(studioJSON.CreatedAt)},
UpdatedAt: models.SQLiteTimestamp{Timestamp: t.getTimeFromJSONTime(studioJSON.UpdatedAt)},
}
_, err = qb.Create(newStudio, tx)
if err != nil {
_ = tx.Rollback()
if err := t.ImportStudio(studioJSON, pendingParent, tx); err != nil {
tx.Rollback()
logger.Errorf("[studios] <%s> failed to create: %s", mappingJSON.Checksum, err.Error())
return
}
}
// create the leftover studios, warning for missing parents
if len(pendingParent) > 0 {
logger.Warnf("[studios] importing studios with missing parents")
for _, s := range pendingParent {
for _, orphanStudioJSON := range s {
if err := t.ImportStudio(orphanStudioJSON, nil, tx); err != nil {
tx.Rollback()
logger.Errorf("[studios] <%s> failed to create: %s", orphanStudioJSON.Name, err.Error())
return
}
}
}
}
logger.Info("[studios] importing")
if err := tx.Commit(); err != nil {
logger.Errorf("[studios] import failed to commit: %s", err.Error())
@@ -208,6 +203,74 @@ func (t *ImportTask) ImportStudios(ctx context.Context) {
logger.Info("[studios] import complete")
}
func (t *ImportTask) ImportStudio(studioJSON *jsonschema.Studio, pendingParent map[string][]*jsonschema.Studio, tx *sqlx.Tx) error {
qb := models.NewStudioQueryBuilder()
// generate checksum from studio name rather than image
checksum := utils.MD5FromString(studioJSON.Name)
// Process the base 64 encoded image string
_, imageData, err := utils.ProcessBase64Image(studioJSON.Image)
if err != nil {
return fmt.Errorf("invalid image: %s", err.Error())
}
// Populate a new studio from the input
newStudio := models.Studio{
Image: imageData,
Checksum: checksum,
Name: sql.NullString{String: studioJSON.Name, Valid: true},
URL: sql.NullString{String: studioJSON.URL, Valid: true},
CreatedAt: models.SQLiteTimestamp{Timestamp: t.getTimeFromJSONTime(studioJSON.CreatedAt)},
UpdatedAt: models.SQLiteTimestamp{Timestamp: t.getTimeFromJSONTime(studioJSON.UpdatedAt)},
}
// Populate the parent ID
if studioJSON.ParentStudio != "" {
studio, err := qb.FindByName(studioJSON.ParentStudio, tx, false)
if err != nil {
return fmt.Errorf("error finding studio by name <%s>: %s", studioJSON.ParentStudio, err.Error())
}
if studio == nil {
// its possible that the parent hasn't been created yet
// do it after it is created
if pendingParent == nil {
logger.Warnf("[studios] studio <%s> does not exist", studioJSON.ParentStudio)
} else {
// add to the pending parent list so that it is created after the parent
s := pendingParent[studioJSON.ParentStudio]
s = append(s, studioJSON)
pendingParent[studioJSON.ParentStudio] = s
// skip
return nil
}
} else {
newStudio.ParentID = sql.NullInt64{Int64: int64(studio.ID), Valid: true}
}
}
_, err = qb.Create(newStudio, tx)
if err != nil {
return err
}
// now create the studios pending this studios creation
s := pendingParent[studioJSON.Name]
for _, childStudioJSON := range s {
// map is nil since we're not checking parent studios at this point
if err := t.ImportStudio(childStudioJSON, nil, tx); err != nil {
return fmt.Errorf("failed to create child studio <%s>: %s", childStudioJSON.Name, err.Error())
}
}
// delete the entry from the map so that we know its not left over
delete(pendingParent, studioJSON.Name)
return err
}
func (t *ImportTask) ImportMovies(ctx context.Context) {
tx := database.DB.MustBeginTx(ctx, nil)
qb := models.NewMovieQueryBuilder()