mirror of
https://github.com/stashapp/stash.git
synced 2025-12-17 04:14:39 +03:00
File storage rewrite (#2676)
* Restructure data layer part 2 (#2599) * Refactor and separate image model * Refactor image query builder * Handle relationships in image query builder * Remove relationship management methods * Refactor gallery model/query builder * Add scenes to gallery model * Convert scene model * Refactor scene models * Remove unused methods * Add unit tests for gallery * Add image tests * Add scene tests * Convert unnecessary scene value pointers to values * Convert unnecessary pointer values to values * Refactor scene partial * Add scene partial tests * Refactor ImagePartial * Add image partial tests * Refactor gallery partial update * Add partial gallery update tests * Use zero/null package for null values * Add files and scan system * Add sqlite implementation for files/folders * Add unit tests for files/folders * Image refactors * Update image data layer * Refactor gallery model and creation * Refactor scene model * Refactor scenes * Don't set title from filename * Allow galleries to freely add/remove images * Add multiple scene file support to graphql and UI * Add multiple file support for images in graphql/UI * Add multiple file for galleries in graphql/UI * Remove use of some deprecated fields * Remove scene path usage * Remove gallery path usage * Remove path from image * Move funscript to video file * Refactor caption detection * Migrate existing data * Add post commit/rollback hook system * Lint. Comment out import/export tests * Add WithDatabase read only wrapper * Prepend tasks to list * Add 32 pre-migration * Add warnings in release and migration notes
This commit is contained in:
@@ -15,13 +15,8 @@ import (
|
||||
"github.com/stashapp/stash/pkg/utils"
|
||||
)
|
||||
|
||||
type CoverStashIDGetter interface {
|
||||
type CoverGetter interface {
|
||||
GetCover(ctx context.Context, sceneID int) ([]byte, error)
|
||||
GetStashIDs(ctx context.Context, sceneID int) ([]*models.StashID, error)
|
||||
}
|
||||
|
||||
type MovieGetter interface {
|
||||
GetMovies(ctx context.Context, sceneID int) ([]models.MoviesScenes, error)
|
||||
}
|
||||
|
||||
type MarkerTagFinder interface {
|
||||
@@ -41,47 +36,38 @@ type TagFinder interface {
|
||||
// ToBasicJSON converts a scene object into its JSON object equivalent. It
|
||||
// does not convert the relationships to other objects, with the exception
|
||||
// of cover image.
|
||||
func ToBasicJSON(ctx context.Context, reader CoverStashIDGetter, scene *models.Scene) (*jsonschema.Scene, error) {
|
||||
func ToBasicJSON(ctx context.Context, reader CoverGetter, scene *models.Scene) (*jsonschema.Scene, error) {
|
||||
newSceneJSON := jsonschema.Scene{
|
||||
CreatedAt: json.JSONTime{Time: scene.CreatedAt.Timestamp},
|
||||
UpdatedAt: json.JSONTime{Time: scene.UpdatedAt.Timestamp},
|
||||
Title: scene.Title,
|
||||
URL: scene.URL,
|
||||
Details: scene.Details,
|
||||
CreatedAt: json.JSONTime{Time: scene.CreatedAt},
|
||||
UpdatedAt: json.JSONTime{Time: scene.UpdatedAt},
|
||||
}
|
||||
|
||||
if scene.Checksum.Valid {
|
||||
newSceneJSON.Checksum = scene.Checksum.String
|
||||
// if scene.Checksum != nil {
|
||||
// newSceneJSON.Checksum = *scene.Checksum
|
||||
// }
|
||||
|
||||
// if scene.OSHash != nil {
|
||||
// newSceneJSON.OSHash = *scene.OSHash
|
||||
// }
|
||||
|
||||
// if scene.Phash != nil {
|
||||
// newSceneJSON.Phash = utils.PhashToString(*scene.Phash)
|
||||
// }
|
||||
|
||||
if scene.Date != nil {
|
||||
newSceneJSON.Date = scene.Date.String()
|
||||
}
|
||||
|
||||
if scene.OSHash.Valid {
|
||||
newSceneJSON.OSHash = scene.OSHash.String
|
||||
}
|
||||
|
||||
if scene.Phash.Valid {
|
||||
newSceneJSON.Phash = utils.PhashToString(scene.Phash.Int64)
|
||||
}
|
||||
|
||||
if scene.Title.Valid {
|
||||
newSceneJSON.Title = scene.Title.String
|
||||
}
|
||||
|
||||
if scene.URL.Valid {
|
||||
newSceneJSON.URL = scene.URL.String
|
||||
}
|
||||
|
||||
if scene.Date.Valid {
|
||||
newSceneJSON.Date = utils.GetYMDFromDatabaseDate(scene.Date.String)
|
||||
}
|
||||
|
||||
if scene.Rating.Valid {
|
||||
newSceneJSON.Rating = int(scene.Rating.Int64)
|
||||
if scene.Rating != nil {
|
||||
newSceneJSON.Rating = *scene.Rating
|
||||
}
|
||||
|
||||
newSceneJSON.Organized = scene.Organized
|
||||
newSceneJSON.OCounter = scene.OCounter
|
||||
|
||||
if scene.Details.Valid {
|
||||
newSceneJSON.Details = scene.Details.String
|
||||
}
|
||||
|
||||
newSceneJSON.File = getSceneFileJSON(scene)
|
||||
|
||||
cover, err := reader.GetCover(ctx, scene.ID)
|
||||
@@ -93,9 +79,8 @@ func ToBasicJSON(ctx context.Context, reader CoverStashIDGetter, scene *models.S
|
||||
newSceneJSON.Cover = utils.GetBase64StringFromData(cover)
|
||||
}
|
||||
|
||||
stashIDs, _ := reader.GetStashIDs(ctx, scene.ID)
|
||||
var ret []models.StashID
|
||||
for _, stashID := range stashIDs {
|
||||
for _, stashID := range scene.StashIDs {
|
||||
newJoin := models.StashID{
|
||||
StashID: stashID.StashID,
|
||||
Endpoint: stashID.Endpoint,
|
||||
@@ -111,45 +96,46 @@ func ToBasicJSON(ctx context.Context, reader CoverStashIDGetter, scene *models.S
|
||||
func getSceneFileJSON(scene *models.Scene) *jsonschema.SceneFile {
|
||||
ret := &jsonschema.SceneFile{}
|
||||
|
||||
if scene.FileModTime.Valid {
|
||||
ret.ModTime = json.JSONTime{Time: scene.FileModTime.Timestamp}
|
||||
}
|
||||
// TODO
|
||||
// if scene.FileModTime != nil {
|
||||
// ret.ModTime = json.JSONTime{Time: *scene.FileModTime}
|
||||
// }
|
||||
|
||||
if scene.Size.Valid {
|
||||
ret.Size = scene.Size.String
|
||||
}
|
||||
// if scene.Size != nil {
|
||||
// ret.Size = *scene.Size
|
||||
// }
|
||||
|
||||
if scene.Duration.Valid {
|
||||
ret.Duration = getDecimalString(scene.Duration.Float64)
|
||||
}
|
||||
// if scene.Duration != nil {
|
||||
// ret.Duration = getDecimalString(*scene.Duration)
|
||||
// }
|
||||
|
||||
if scene.VideoCodec.Valid {
|
||||
ret.VideoCodec = scene.VideoCodec.String
|
||||
}
|
||||
// if scene.VideoCodec != nil {
|
||||
// ret.VideoCodec = *scene.VideoCodec
|
||||
// }
|
||||
|
||||
if scene.AudioCodec.Valid {
|
||||
ret.AudioCodec = scene.AudioCodec.String
|
||||
}
|
||||
// if scene.AudioCodec != nil {
|
||||
// ret.AudioCodec = *scene.AudioCodec
|
||||
// }
|
||||
|
||||
if scene.Format.Valid {
|
||||
ret.Format = scene.Format.String
|
||||
}
|
||||
// if scene.Format != nil {
|
||||
// ret.Format = *scene.Format
|
||||
// }
|
||||
|
||||
if scene.Width.Valid {
|
||||
ret.Width = int(scene.Width.Int64)
|
||||
}
|
||||
// if scene.Width != nil {
|
||||
// ret.Width = *scene.Width
|
||||
// }
|
||||
|
||||
if scene.Height.Valid {
|
||||
ret.Height = int(scene.Height.Int64)
|
||||
}
|
||||
// if scene.Height != nil {
|
||||
// ret.Height = *scene.Height
|
||||
// }
|
||||
|
||||
if scene.Framerate.Valid {
|
||||
ret.Framerate = getDecimalString(scene.Framerate.Float64)
|
||||
}
|
||||
// if scene.Framerate != nil {
|
||||
// ret.Framerate = getDecimalString(*scene.Framerate)
|
||||
// }
|
||||
|
||||
if scene.Bitrate.Valid {
|
||||
ret.Bitrate = int(scene.Bitrate.Int64)
|
||||
}
|
||||
// if scene.Bitrate != nil {
|
||||
// ret.Bitrate = int(*scene.Bitrate)
|
||||
// }
|
||||
|
||||
return ret
|
||||
}
|
||||
@@ -157,8 +143,8 @@ func getSceneFileJSON(scene *models.Scene) *jsonschema.SceneFile {
|
||||
// GetStudioName returns the name of the provided scene's studio. It returns an
|
||||
// empty string if there is no studio assigned to the scene.
|
||||
func GetStudioName(ctx context.Context, reader studio.Finder, scene *models.Scene) (string, error) {
|
||||
if scene.StudioID.Valid {
|
||||
studio, err := reader.Find(ctx, int(scene.StudioID.Int64))
|
||||
if scene.StudioID != nil {
|
||||
studio, err := reader.Find(ctx, *scene.StudioID)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
@@ -232,11 +218,8 @@ type MovieFinder interface {
|
||||
|
||||
// GetSceneMoviesJSON returns a slice of SceneMovie JSON representation objects
|
||||
// corresponding to the provided scene's scene movie relationships.
|
||||
func GetSceneMoviesJSON(ctx context.Context, movieReader MovieFinder, sceneReader MovieGetter, scene *models.Scene) ([]jsonschema.SceneMovie, error) {
|
||||
sceneMovies, err := sceneReader.GetMovies(ctx, scene.ID)
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("error getting scene movies: %v", err)
|
||||
}
|
||||
func GetSceneMoviesJSON(ctx context.Context, movieReader MovieFinder, scene *models.Scene) ([]jsonschema.SceneMovie, error) {
|
||||
sceneMovies := scene.Movies
|
||||
|
||||
var results []jsonschema.SceneMovie
|
||||
for _, sceneMovie := range sceneMovies {
|
||||
@@ -247,8 +230,10 @@ func GetSceneMoviesJSON(ctx context.Context, movieReader MovieFinder, sceneReade
|
||||
|
||||
if movie.Name.Valid {
|
||||
sceneMovieJSON := jsonschema.SceneMovie{
|
||||
MovieName: movie.Name.String,
|
||||
SceneIndex: int(sceneMovie.SceneIndex.Int64),
|
||||
MovieName: movie.Name.String,
|
||||
}
|
||||
if sceneMovie.SceneIndex != nil {
|
||||
sceneMovieJSON.SceneIndex = *sceneMovie.SceneIndex
|
||||
}
|
||||
results = append(results, sceneMovieJSON)
|
||||
}
|
||||
@@ -258,14 +243,10 @@ func GetSceneMoviesJSON(ctx context.Context, movieReader MovieFinder, sceneReade
|
||||
}
|
||||
|
||||
// GetDependentMovieIDs returns a slice of movie IDs that this scene references.
|
||||
func GetDependentMovieIDs(ctx context.Context, sceneReader MovieGetter, scene *models.Scene) ([]int, error) {
|
||||
func GetDependentMovieIDs(ctx context.Context, scene *models.Scene) ([]int, error) {
|
||||
var ret []int
|
||||
|
||||
m, err := sceneReader.GetMovies(ctx, scene.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
m := scene.Movies
|
||||
for _, mm := range m {
|
||||
ret = append(ret, mm.MovieID)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user