[Feature] Images new fields : URL & Date (#3015)

Co-authored-by: WithoutPants <53250216+WithoutPants@users.noreply.github.com>
This commit is contained in:
HijackHornet
2022-12-20 01:13:41 +01:00
committed by GitHub
parent cc4b0f7b11
commit 0b4b100ecc
23 changed files with 191 additions and 15 deletions

View File

@@ -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},
}
@@ -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

View File

@@ -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
)
@@ -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,
@@ -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{

View File

@@ -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
}

View File

@@ -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

View File

@@ -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"`

View File

@@ -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
@@ -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

View File

@@ -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

View File

@@ -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"`
@@ -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)
@@ -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),
@@ -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)
@@ -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))

View File

@@ -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)
@@ -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],
@@ -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],
@@ -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)
@@ -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],
@@ -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},
@@ -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)
@@ -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]),
@@ -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],
@@ -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)})
@@ -2560,6 +2579,13 @@ func TestImageQuerySorting(t *testing.T) {
-1,
-1,
},
{
"date",
"date",
models.SortDirectionEnumDesc,
imageIdxWithTwoGalleries,
imageIdxWithGrandChildStudio,
},
}
qb := db.Image

View File

@@ -0,0 +1,2 @@
ALTER TABLE `images` ADD COLUMN `url` varchar(255);
ALTER TABLE `images` ADD COLUMN `date` date;

View File

@@ -885,9 +885,9 @@ func getObjectDate(index int) models.SQLiteDate {
}
}
func getObjectDateObject(index int) *models.Date {
func getObjectDateObject(index int, fromDB bool) *models.Date {
d := getObjectDate(index)
if !d.Valid {
if !d.Valid || (fromDB && (d.String == "" || d.String == "0001-01-01")) {
return nil
}
@@ -998,7 +998,7 @@ func makeScene(i int) *models.Scene {
URL: getSceneEmptyString(i, urlField),
Rating: getIntPtr(rating),
OCounter: getOCounter(i),
Date: getObjectDateObject(i),
Date: getObjectDateObject(i, false),
StudioID: studioID,
GalleryIDs: models.NewRelatedIDs(gids),
PerformerIDs: models.NewRelatedIDs(pids),
@@ -1063,7 +1063,7 @@ func makeImageFile(i int) *file.ImageFile {
}
}
func makeImage(i int) *models.Image {
func makeImage(i int, fromDB bool) *models.Image {
title := getImageStringValue(i, titleField)
var studioID *int
if _, ok := imageStudios[i]; ok {
@@ -1078,6 +1078,8 @@ func makeImage(i int) *models.Image {
return &models.Image{
Title: title,
Rating: getIntPtr(getRating(i)),
Date: getObjectDateObject(i, fromDB),
URL: getImageStringValue(i, urlField),
OCounter: getOCounter(i),
StudioID: studioID,
GalleryIDs: models.NewRelatedIDs(gids),
@@ -1101,7 +1103,7 @@ func createImages(ctx context.Context, n int) error {
}
imageFileIDs = append(imageFileIDs, f.ID)
image := makeImage(i)
image := makeImage(i, false)
err := qb.Create(ctx, &models.ImageCreateInput{
Image: image,
@@ -1162,7 +1164,7 @@ func makeGallery(i int, includeScenes bool) *models.Gallery {
Title: getGalleryStringValue(i, titleField),
URL: getGalleryNullStringValue(i, urlField).String,
Rating: getIntPtr(getRating(i)),
Date: getObjectDateObject(i),
Date: getObjectDateObject(i, false),
StudioID: studioID,
PerformerIDs: models.NewRelatedIDs(pids),
TagIDs: models.NewRelatedIDs(tids),