Skip to content

Commit

Permalink
[Feature] Images new fields : URL & Date (#3015)
Browse files Browse the repository at this point in the history
Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
  • Loading branch information
HijackHornet and WithoutPants authored Dec 20, 2022
1 parent cc4b0f7 commit 0b4b100
Show file tree
Hide file tree
Showing 23 changed files with 191 additions and 15 deletions.
2 changes: 2 additions & 0 deletions graphql/documents/data/image-slim.graphql
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
fragment SlimImageData on Image {
id
title
date
url
rating100
organized
o_counter
Expand Down
2 changes: 2 additions & 0 deletions graphql/documents/data/image.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ fragment ImageData on Image {
id
title
rating100
date
url
organized
o_counter
created_at
Expand Down
4 changes: 4 additions & 0 deletions graphql/schema/types/filters.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -425,6 +425,10 @@ input ImageFilterType {
rating: IntCriterionInput @deprecated(reason: "Use 1-100 range with rating100")
# rating expressed as 1-100
rating100: IntCriterionInput
"""Filter by date"""
date: DateCriterionInput
"""Filter by url"""
url: StringCriterionInput
"""Filter by organized"""
organized: Boolean
"""Filter by o-counter"""
Expand Down
6 changes: 6 additions & 0 deletions graphql/schema/types/image.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ type Image {
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
# rating expressed as 1-100
rating100: Int
url: String
date: String
o_counter: Int
organized: Boolean!
path: String! @deprecated(reason: "Use files.path")
Expand Down Expand Up @@ -45,6 +47,8 @@ input ImageUpdateInput {
# rating expressed as 1-100
rating100: Int
organized: Boolean
url: String
date: String

studio_id: ID
performer_ids: [ID!]
Expand All @@ -63,6 +67,8 @@ input BulkImageUpdateInput {
# rating expressed as 1-100
rating100: Int
organized: Boolean
url: String
date: String

studio_id: ID
performer_ids: BulkUpdateIds
Expand Down
8 changes: 8 additions & 0 deletions internal/api/resolver_model_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,14 @@ func (r *imageResolver) File(ctx context.Context, obj *models.Image) (*ImageFile
}, nil
}

func (r *imageResolver) Date(ctx context.Context, obj *models.Image) (*string, error) {
if obj.Date != nil {
result := obj.Date.String()
return &result, nil
}
return nil, nil
}

func (r *imageResolver) Files(ctx context.Context, obj *models.Image) ([]*ImageFile, error) {
files, err := r.getFiles(ctx, obj)
if err != nil {
Expand Down
4 changes: 4 additions & 0 deletions internal/api/resolver_mutation_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,8 @@ func (r *mutationResolver) imageUpdate(ctx context.Context, input ImageUpdateInp
updatedImage := models.NewImagePartial()
updatedImage.Title = translator.optionalString(input.Title, "title")
updatedImage.Rating = translator.ratingConversionOptional(input.Rating, input.Rating100)
updatedImage.URL = translator.optionalString(input.URL, "url")
updatedImage.Date = translator.optionalDate(input.Date, "date")
updatedImage.StudioID, err = translator.optionalIntFromString(input.StudioID, "studio_id")
if err != nil {
return nil, fmt.Errorf("converting studio id: %w", err)
Expand Down Expand Up @@ -190,6 +192,8 @@ func (r *mutationResolver) BulkImageUpdate(ctx context.Context, input BulkImageU

updatedImage.Title = translator.optionalString(input.Title, "title")
updatedImage.Rating = translator.ratingConversionOptional(input.Rating, input.Rating100)
updatedImage.URL = translator.optionalString(input.URL, "url")
updatedImage.Date = translator.optionalDate(input.Date, "date")
updatedImage.StudioID, err = translator.optionalIntFromString(input.StudioID, "studio_id")
if err != nil {
return nil, fmt.Errorf("converting studio id: %w", err)
Expand Down
5 changes: 5 additions & 0 deletions pkg/image/export.go
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import (
func ToBasicJSON(image *models.Image) *jsonschema.Image {
newImageJSON := jsonschema.Image{
Title: image.Title,
URL: image.URL,
CreatedAt: json.JSONTime{Time: image.CreatedAt},
UpdatedAt: json.JSONTime{Time: image.UpdatedAt},
}
Expand All @@ -23,6 +24,10 @@ func ToBasicJSON(image *models.Image) *jsonschema.Image {
newImageJSON.Rating = *image.Rating
}

if image.Date != nil {
newImageJSON.Date = image.Date.String()
}

newImageJSON.Organized = image.Organized
newImageJSON.OCounter = image.OCounter

Expand Down
7 changes: 7 additions & 0 deletions pkg/image/export_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,9 @@ const (
var (
title = "title"
rating = 5
url = "http://a.com"
date = "2001-01-01"
dateObj = models.NewDate(date)
organized = true
ocounter = 2
)
Expand Down Expand Up @@ -52,6 +55,8 @@ func createFullImage(id int) models.Image {
Title: title,
OCounter: ocounter,
Rating: &rating,
Date: &dateObj,
URL: url,
Organized: organized,
CreatedAt: createTime,
UpdatedAt: updateTime,
Expand All @@ -63,6 +68,8 @@ func createFullJSONImage() *jsonschema.Image {
Title: title,
OCounter: ocounter,
Rating: rating,
Date: date,
URL: url,
Organized: organized,
Files: []string{path},
CreatedAt: json.JSONTime{
Expand Down
7 changes: 7 additions & 0 deletions pkg/image/import.go
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,13 @@ func (i *Importer) imageJSONToImage(imageJSON jsonschema.Image) models.Image {
if imageJSON.Rating != 0 {
newImage.Rating = &imageJSON.Rating
}
if imageJSON.URL != "" {
newImage.URL = imageJSON.URL
}
if imageJSON.Date != "" {
d := models.NewDate(imageJSON.Date)
newImage.Date = &d
}

return newImage
}
Expand Down
4 changes: 4 additions & 0 deletions pkg/models/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@ type ImageFilterType struct {
Rating *IntCriterionInput `json:"rating"`
// Filter by rating expressed as 1-100
Rating100 *IntCriterionInput `json:"rating100"`
// Filter by date
Date *DateCriterionInput `json:"date"`
// Filter by url
URL *StringCriterionInput `json:"url"`
// Filter by organized
Organized *bool `json:"organized"`
// Filter by o-counter
Expand Down
2 changes: 2 additions & 0 deletions pkg/models/jsonschema/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ type Image struct {
Title string `json:"title,omitempty"`
Studio string `json:"studio,omitempty"`
Rating int `json:"rating,omitempty"`
URL string `json:"url,omitempty"`
Date string `json:"date,omitempty"`
Organized bool `json:"organized,omitempty"`
OCounter int `json:"o_counter,omitempty"`
Galleries []GalleryRef `json:"galleries,omitempty"`
Expand Down
12 changes: 8 additions & 4 deletions pkg/models/model_image.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@ type Image struct {

Title string `json:"title"`
// Rating expressed in 1-100 scale
Rating *int `json:"rating"`
Organized bool `json:"organized"`
OCounter int `json:"o_counter"`
StudioID *int `json:"studio_id"`
Rating *int `json:"rating"`
Organized bool `json:"organized"`
OCounter int `json:"o_counter"`
StudioID *int `json:"studio_id"`
URL string `json:"url"`
Date *Date `json:"date"`

// transient - not persisted
Files RelatedImageFiles
Expand Down Expand Up @@ -117,6 +119,8 @@ type ImagePartial struct {
Title OptionalString
// Rating expressed in 1-100 scale
Rating OptionalInt
URL OptionalString
Date OptionalDate
Organized OptionalBool
OCounter OptionalInt
StudioID OptionalInt
Expand Down
2 changes: 1 addition & 1 deletion pkg/sqlite/database.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import (
"github.com/stashapp/stash/pkg/logger"
)

var appSchemaVersion uint = 42
var appSchemaVersion uint = 43

//go:embed migrations/*.sql
var migrationsBox embed.FS
Expand Down
12 changes: 12 additions & 0 deletions pkg/sqlite/image.go
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ type imageRow struct {
Title zero.String `db:"title"`
// expressed as 1-100
Rating null.Int `db:"rating"`
URL zero.String `db:"url"`
Date models.SQLiteDate `db:"date"`
Organized bool `db:"organized"`
OCounter int `db:"o_counter"`
StudioID null.Int `db:"studio_id,omitempty"`
Expand All @@ -42,6 +44,10 @@ func (r *imageRow) fromImage(i models.Image) {
r.ID = i.ID
r.Title = zero.StringFrom(i.Title)
r.Rating = intFromPtr(i.Rating)
r.URL = zero.StringFrom(i.URL)
if i.Date != nil {
_ = r.Date.Scan(i.Date.Time)
}
r.Organized = i.Organized
r.OCounter = i.OCounter
r.StudioID = intFromPtr(i.StudioID)
Expand All @@ -62,6 +68,8 @@ func (r *imageQueryRow) resolve() *models.Image {
ID: r.ID,
Title: r.Title.String,
Rating: nullIntPtr(r.Rating),
URL: r.URL.String,
Date: r.Date.DatePtr(),
Organized: r.Organized,
OCounter: r.OCounter,
StudioID: nullIntPtr(r.StudioID),
Expand All @@ -87,6 +95,8 @@ type imageRowRecord struct {
func (r *imageRowRecord) fromPartial(i models.ImagePartial) {
r.setNullString("title", i.Title)
r.setNullInt("rating", i.Rating)
r.setNullString("url", i.URL)
r.setSQLiteDate("date", i.Date)
r.setBool("organized", i.Organized)
r.setInt("o_counter", i.OCounter)
r.setNullInt("studio_id", i.StudioID)
Expand Down Expand Up @@ -638,6 +648,8 @@ func (qb *ImageStore) makeFilter(ctx context.Context, imageFilter *models.ImageF
query.handleCriterion(ctx, rating5CriterionHandler(imageFilter.Rating, "images.rating", nil))
query.handleCriterion(ctx, intCriterionHandler(imageFilter.OCounter, "images.o_counter", nil))
query.handleCriterion(ctx, boolCriterionHandler(imageFilter.Organized, "images.organized", nil))
query.handleCriterion(ctx, dateCriterionHandler(imageFilter.Date, "images.date"))
query.handleCriterion(ctx, stringCriterionHandler(imageFilter.URL, "images.url"))

query.handleCriterion(ctx, resolutionCriterionHandler(imageFilter.Resolution, "image_files.height", "image_files.width", qb.addImageFilesTable))
query.handleCriterion(ctx, imageIsMissingCriterionHandler(qb, imageFilter.IsMissing))
Expand Down
28 changes: 27 additions & 1 deletion pkg/sqlite/image_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,8 @@ func Test_imageQueryBuilder_Create(t *testing.T) {
title = "title"
rating = 60
ocounter = 5
url = "url"
date = models.NewDate("2003-02-01")
createdAt = time.Date(2001, 1, 1, 0, 0, 0, 0, time.UTC)
updatedAt = time.Date(2001, 1, 1, 0, 0, 0, 0, time.UTC)

Expand All @@ -72,6 +74,8 @@ func Test_imageQueryBuilder_Create(t *testing.T) {
models.Image{
Title: title,
Rating: &rating,
Date: &date,
URL: url,
Organized: true,
OCounter: ocounter,
StudioID: &studioIDs[studioIdxWithImage],
Expand All @@ -88,6 +92,8 @@ func Test_imageQueryBuilder_Create(t *testing.T) {
models.Image{
Title: title,
Rating: &rating,
Date: &date,
URL: url,
Organized: true,
OCounter: ocounter,
StudioID: &studioIDs[studioIdxWithImage],
Expand Down Expand Up @@ -209,6 +215,8 @@ func Test_imageQueryBuilder_Update(t *testing.T) {
var (
title = "title"
rating = 60
url = "url"
date = models.NewDate("2003-02-01")
ocounter = 5
createdAt = time.Date(2001, 1, 1, 0, 0, 0, 0, time.UTC)
updatedAt = time.Date(2001, 1, 1, 0, 0, 0, 0, time.UTC)
Expand All @@ -225,6 +233,8 @@ func Test_imageQueryBuilder_Update(t *testing.T) {
ID: imageIDs[imageIdxWithGallery],
Title: title,
Rating: &rating,
URL: url,
Date: &date,
Organized: true,
OCounter: ocounter,
StudioID: &studioIDs[studioIdxWithImage],
Expand Down Expand Up @@ -372,6 +382,8 @@ func clearImagePartial() models.ImagePartial {
return models.ImagePartial{
Title: models.OptionalString{Set: true, Null: true},
Rating: models.OptionalInt{Set: true, Null: true},
URL: models.OptionalString{Set: true, Null: true},
Date: models.OptionalDate{Set: true, Null: true},
StudioID: models.OptionalInt{Set: true, Null: true},
GalleryIDs: &models.UpdateIDs{Mode: models.RelationshipUpdateModeSet},
TagIDs: &models.UpdateIDs{Mode: models.RelationshipUpdateModeSet},
Expand All @@ -383,6 +395,8 @@ func Test_imageQueryBuilder_UpdatePartial(t *testing.T) {
var (
title = "title"
rating = 60
url = "url"
date = models.NewDate("2003-02-01")
ocounter = 5
createdAt = time.Date(2001, 1, 1, 0, 0, 0, 0, time.UTC)
updatedAt = time.Date(2001, 1, 1, 0, 0, 0, 0, time.UTC)
Expand All @@ -401,6 +415,8 @@ func Test_imageQueryBuilder_UpdatePartial(t *testing.T) {
models.ImagePartial{
Title: models.NewOptionalString(title),
Rating: models.NewOptionalInt(rating),
URL: models.NewOptionalString(url),
Date: models.NewOptionalDate(date),
Organized: models.NewOptionalBool(true),
OCounter: models.NewOptionalInt(ocounter),
StudioID: models.NewOptionalInt(studioIDs[studioIdxWithImage]),
Expand All @@ -423,6 +439,8 @@ func Test_imageQueryBuilder_UpdatePartial(t *testing.T) {
ID: imageIDs[imageIdx1WithGallery],
Title: title,
Rating: &rating,
URL: url,
Date: &date,
Organized: true,
OCounter: ocounter,
StudioID: &studioIDs[studioIdxWithImage],
Expand Down Expand Up @@ -943,7 +961,8 @@ func Test_imageQueryBuilder_Destroy(t *testing.T) {
}

func makeImageWithID(index int) *models.Image {
ret := makeImage(index)
const fromDB = true
ret := makeImage(index, true)
ret.ID = imageIDs[index]

ret.Files = models.NewRelatedImageFiles([]*file.ImageFile{makeImageFile(index)})
Expand Down Expand Up @@ -2560,6 +2579,13 @@ func TestImageQuerySorting(t *testing.T) {
-1,
-1,
},
{
"date",
"date",
models.SortDirectionEnumDesc,
imageIdxWithTwoGalleries,
imageIdxWithGrandChildStudio,
},
}

qb := db.Image
Expand Down
2 changes: 2 additions & 0 deletions pkg/sqlite/migrations/43_image_date_url.up.sql
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
ALTER TABLE `images` ADD COLUMN `url` varchar(255);
ALTER TABLE `images` ADD COLUMN `date` date;
Loading

0 comments on commit 0b4b100

Please sign in to comment.