mirror of
https://github.com/stashapp/stash.git
synced 2025-12-06 16:34:02 +01:00
Remove deprecated graphql fields (#4064)
* Remove deprecated list*Scrapers queries * Remove other deprecated query resolvers * Remove deprecated config fields * Remove deprecated gallery fields * Remove deprecated image fields * Remove deprecated movie fields * Remove deprecated performer fields * Document scrape function issue * Remove deprecated studio fields * Remove deprecated scan input fields * Remove deprecated scene fields * Remove deprecated fields from filters * Remove scene.file_mod_time
This commit is contained in:
parent
a9ab1fcca7
commit
b6714fafba
66 changed files with 101 additions and 1223 deletions
|
|
@ -42,9 +42,6 @@ fragment ConfigGeneralData on ConfigGeneralResult {
|
||||||
excludes
|
excludes
|
||||||
imageExcludes
|
imageExcludes
|
||||||
customPerformerImageLocation
|
customPerformerImageLocation
|
||||||
scraperUserAgent
|
|
||||||
scraperCertCheck
|
|
||||||
scraperCDPPath
|
|
||||||
stashBoxes {
|
stashBoxes {
|
||||||
name
|
name
|
||||||
endpoint
|
endpoint
|
||||||
|
|
@ -139,8 +136,6 @@ fragment ScraperSourceData on ScraperSource {
|
||||||
|
|
||||||
fragment ConfigDefaultSettingsData on ConfigDefaultSettingsResult {
|
fragment ConfigDefaultSettingsData on ConfigDefaultSettingsResult {
|
||||||
scan {
|
scan {
|
||||||
useFileMetadata
|
|
||||||
stripFileExtension
|
|
||||||
scanGenerateCovers
|
scanGenerateCovers
|
||||||
scanGeneratePreviews
|
scanGeneratePreviews
|
||||||
scanGenerateImagePreviews
|
scanGenerateImagePreviews
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,5 @@ fragment MovieData on Movie {
|
||||||
scenes {
|
scenes {
|
||||||
id
|
id
|
||||||
title
|
title
|
||||||
path
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
fragment PerformerData on Performer {
|
fragment PerformerData on Performer {
|
||||||
id
|
id
|
||||||
checksum
|
|
||||||
name
|
name
|
||||||
disambiguation
|
disambiguation
|
||||||
url
|
url
|
||||||
|
|
|
||||||
|
|
@ -1,3 +0,0 @@
|
||||||
query ScrapeFreeonesPerformers($q: String!) {
|
|
||||||
scrapeFreeonesPerformerList(query: $q)
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
query ListPerformerScrapers {
|
query ListPerformerScrapers {
|
||||||
listPerformerScrapers {
|
listScrapers(types: [PERFORMER]) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
performer {
|
performer {
|
||||||
|
|
@ -10,7 +10,7 @@ query ListPerformerScrapers {
|
||||||
}
|
}
|
||||||
|
|
||||||
query ListSceneScrapers {
|
query ListSceneScrapers {
|
||||||
listSceneScrapers {
|
listScrapers(types: [SCENE]) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
scene {
|
scene {
|
||||||
|
|
@ -21,7 +21,7 @@ query ListSceneScrapers {
|
||||||
}
|
}
|
||||||
|
|
||||||
query ListGalleryScrapers {
|
query ListGalleryScrapers {
|
||||||
listGalleryScrapers {
|
listScrapers(types: [GALLERY]) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
gallery {
|
gallery {
|
||||||
|
|
@ -32,7 +32,7 @@ query ListGalleryScrapers {
|
||||||
}
|
}
|
||||||
|
|
||||||
query ListMovieScrapers {
|
query ListMovieScrapers {
|
||||||
listMovieScrapers {
|
listScrapers(types: [MOVIE]) {
|
||||||
id
|
id
|
||||||
name
|
name
|
||||||
movie {
|
movie {
|
||||||
|
|
|
||||||
|
|
@ -109,14 +109,6 @@ type Query {
|
||||||
|
|
||||||
"List available scrapers"
|
"List available scrapers"
|
||||||
listScrapers(types: [ScrapeContentType!]!): [Scraper!]!
|
listScrapers(types: [ScrapeContentType!]!): [Scraper!]!
|
||||||
listPerformerScrapers: [Scraper!]!
|
|
||||||
@deprecated(reason: "Use listScrapers(types: [PERFORMER])")
|
|
||||||
listSceneScrapers: [Scraper!]!
|
|
||||||
@deprecated(reason: "Use listScrapers(types: [SCENE])")
|
|
||||||
listGalleryScrapers: [Scraper!]!
|
|
||||||
@deprecated(reason: "Use listScrapers(types: [GALLERY])")
|
|
||||||
listMovieScrapers: [Scraper!]!
|
|
||||||
@deprecated(reason: "Use listScrapers(types: [MOVIE])")
|
|
||||||
|
|
||||||
"Scrape for a single scene"
|
"Scrape for a single scene"
|
||||||
scrapeSingleScene(
|
scrapeSingleScene(
|
||||||
|
|
@ -170,27 +162,6 @@ type Query {
|
||||||
"Scrapes a complete movie record based on a URL"
|
"Scrapes a complete movie record based on a URL"
|
||||||
scrapeMovieURL(url: String!): ScrapedMovie
|
scrapeMovieURL(url: String!): ScrapedMovie
|
||||||
|
|
||||||
"Scrape a list of performers based on name"
|
|
||||||
scrapePerformerList(scraper_id: ID!, query: String!): [ScrapedPerformer!]!
|
|
||||||
@deprecated(reason: "use scrapeSinglePerformer")
|
|
||||||
"Scrapes a complete performer record based on a scrapePerformerList result"
|
|
||||||
scrapePerformer(
|
|
||||||
scraper_id: ID!
|
|
||||||
scraped_performer: ScrapedPerformerInput!
|
|
||||||
): ScrapedPerformer @deprecated(reason: "use scrapeSinglePerformer")
|
|
||||||
"Scrapes a complete scene record based on an existing scene"
|
|
||||||
scrapeScene(scraper_id: ID!, scene: SceneUpdateInput!): ScrapedScene
|
|
||||||
@deprecated(reason: "use scrapeSingleScene")
|
|
||||||
"Scrapes a complete gallery record based on an existing gallery"
|
|
||||||
scrapeGallery(scraper_id: ID!, gallery: GalleryUpdateInput!): ScrapedGallery
|
|
||||||
@deprecated(reason: "use scrapeSingleGallery")
|
|
||||||
|
|
||||||
"Scrape a list of performers from a query"
|
|
||||||
scrapeFreeonesPerformerList(query: String!): [String!]!
|
|
||||||
@deprecated(
|
|
||||||
reason: "use scrapeSinglePerformer with scraper_id = builtin_freeones"
|
|
||||||
)
|
|
||||||
|
|
||||||
# Plugins
|
# Plugins
|
||||||
"List loaded plugins"
|
"List loaded plugins"
|
||||||
plugins: [Plugin!]
|
plugins: [Plugin!]
|
||||||
|
|
@ -228,8 +199,7 @@ type Query {
|
||||||
allMovies: [Movie!]!
|
allMovies: [Movie!]!
|
||||||
allTags: [Tag!]!
|
allTags: [Tag!]!
|
||||||
|
|
||||||
# @deprecated
|
allPerformers: [Performer!]! @deprecated(reason: "Use findPerformers instead")
|
||||||
allPerformers: [Performer!]!
|
|
||||||
|
|
||||||
# Get everything with minimal metadata
|
# Get everything with minimal metadata
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -139,8 +139,6 @@ input ConfigGeneralInput {
|
||||||
password: String
|
password: String
|
||||||
"Maximum session cookie age"
|
"Maximum session cookie age"
|
||||||
maxSessionAge: Int
|
maxSessionAge: Int
|
||||||
"Comma separated list of proxies to allow traffic from"
|
|
||||||
trustedProxies: [String!] @deprecated(reason: "no longer supported")
|
|
||||||
"Name of the log file"
|
"Name of the log file"
|
||||||
logFile: String
|
logFile: String
|
||||||
"Whether to also output to stderr"
|
"Whether to also output to stderr"
|
||||||
|
|
@ -165,21 +163,6 @@ input ConfigGeneralInput {
|
||||||
imageExcludes: [String!]
|
imageExcludes: [String!]
|
||||||
"Custom Performer Image Location"
|
"Custom Performer Image Location"
|
||||||
customPerformerImageLocation: String
|
customPerformerImageLocation: String
|
||||||
"Scraper user agent string"
|
|
||||||
scraperUserAgent: String
|
|
||||||
@deprecated(
|
|
||||||
reason: "use mutation ConfigureScraping(input: ConfigScrapingInput) instead"
|
|
||||||
)
|
|
||||||
"Scraper CDP path. Path to chrome executable or remote address"
|
|
||||||
scraperCDPPath: String
|
|
||||||
@deprecated(
|
|
||||||
reason: "use mutation ConfigureScraping(input: ConfigScrapingInput) instead"
|
|
||||||
)
|
|
||||||
"Whether the scraper should check for invalid certificates"
|
|
||||||
scraperCertCheck: Boolean
|
|
||||||
@deprecated(
|
|
||||||
reason: "use mutation ConfigureScraping(input: ConfigScrapingInput) instead"
|
|
||||||
)
|
|
||||||
"Stash-box instances used for tagging"
|
"Stash-box instances used for tagging"
|
||||||
stashBoxes: [StashBoxInput!]
|
stashBoxes: [StashBoxInput!]
|
||||||
"Python path - resolved using path if unset"
|
"Python path - resolved using path if unset"
|
||||||
|
|
@ -269,8 +252,6 @@ type ConfigGeneralResult {
|
||||||
password: String!
|
password: String!
|
||||||
"Maximum session cookie age"
|
"Maximum session cookie age"
|
||||||
maxSessionAge: Int!
|
maxSessionAge: Int!
|
||||||
"Comma separated list of proxies to allow traffic from"
|
|
||||||
trustedProxies: [String!] @deprecated(reason: "no longer supported")
|
|
||||||
"Name of the log file"
|
"Name of the log file"
|
||||||
logFile: String
|
logFile: String
|
||||||
"Whether to also output to stderr"
|
"Whether to also output to stderr"
|
||||||
|
|
@ -295,15 +276,6 @@ type ConfigGeneralResult {
|
||||||
imageExcludes: [String!]!
|
imageExcludes: [String!]!
|
||||||
"Custom Performer Image Location"
|
"Custom Performer Image Location"
|
||||||
customPerformerImageLocation: String
|
customPerformerImageLocation: String
|
||||||
"Scraper user agent string"
|
|
||||||
scraperUserAgent: String
|
|
||||||
@deprecated(reason: "use ConfigResult.scraping instead")
|
|
||||||
"Scraper CDP path. Path to chrome executable or remote address"
|
|
||||||
scraperCDPPath: String
|
|
||||||
@deprecated(reason: "use ConfigResult.scraping instead")
|
|
||||||
"Whether the scraper should check for invalid certificates"
|
|
||||||
scraperCertCheck: Boolean!
|
|
||||||
@deprecated(reason: "use ConfigResult.scraping instead")
|
|
||||||
"Stash-box instances used for tagging"
|
"Stash-box instances used for tagging"
|
||||||
stashBoxes: [StashBox!]!
|
stashBoxes: [StashBox!]!
|
||||||
"Python path - resolved using path if unset"
|
"Python path - resolved using path if unset"
|
||||||
|
|
@ -388,9 +360,6 @@ input ConfigInterfaceInput {
|
||||||
"Interface language"
|
"Interface language"
|
||||||
language: String
|
language: String
|
||||||
|
|
||||||
"Slideshow Delay"
|
|
||||||
slideshowDelay: Int @deprecated(reason: "Use imageLightbox.slideshowDelay")
|
|
||||||
|
|
||||||
imageLightbox: ConfigImageLightboxInput
|
imageLightbox: ConfigImageLightboxInput
|
||||||
|
|
||||||
"Set to true to disable creating new objects via the dropdown menus"
|
"Set to true to disable creating new objects via the dropdown menus"
|
||||||
|
|
@ -461,15 +430,10 @@ type ConfigInterfaceResult {
|
||||||
"Interface language"
|
"Interface language"
|
||||||
language: String
|
language: String
|
||||||
|
|
||||||
"Slideshow Delay"
|
|
||||||
slideshowDelay: Int @deprecated(reason: "Use imageLightbox.slideshowDelay")
|
|
||||||
|
|
||||||
imageLightbox: ConfigImageLightboxResult!
|
imageLightbox: ConfigImageLightboxResult!
|
||||||
|
|
||||||
"Fields are true if creating via dropdown menus are disabled"
|
"Fields are true if creating via dropdown menus are disabled"
|
||||||
disableDropdownCreate: ConfigDisableDropdownCreate!
|
disableDropdownCreate: ConfigDisableDropdownCreate!
|
||||||
disabledDropdownCreate: ConfigDisableDropdownCreate!
|
|
||||||
@deprecated(reason: "Use disableDropdownCreate")
|
|
||||||
|
|
||||||
"Handy Connection Key"
|
"Handy Connection Key"
|
||||||
handyKey: String
|
handyKey: String
|
||||||
|
|
|
||||||
|
|
@ -98,8 +98,6 @@ input PerformerFilterType {
|
||||||
country: StringCriterionInput
|
country: StringCriterionInput
|
||||||
"Filter by eye color"
|
"Filter by eye color"
|
||||||
eye_color: StringCriterionInput
|
eye_color: StringCriterionInput
|
||||||
"Filter by height"
|
|
||||||
height: StringCriterionInput @deprecated(reason: "Use height_cm instead")
|
|
||||||
"Filter by height in cm"
|
"Filter by height in cm"
|
||||||
height_cm: IntCriterionInput
|
height_cm: IntCriterionInput
|
||||||
"Filter by measurements"
|
"Filter by measurements"
|
||||||
|
|
@ -135,13 +133,7 @@ input PerformerFilterType {
|
||||||
"Filter by o count"
|
"Filter by o count"
|
||||||
o_counter: IntCriterionInput
|
o_counter: IntCriterionInput
|
||||||
"Filter by StashID"
|
"Filter by StashID"
|
||||||
stash_id: StringCriterionInput
|
|
||||||
@deprecated(reason: "Use stash_id_endpoint instead")
|
|
||||||
"Filter by StashID"
|
|
||||||
stash_id_endpoint: StashIDCriterionInput
|
stash_id_endpoint: StashIDCriterionInput
|
||||||
"Filter by rating"
|
|
||||||
rating: IntCriterionInput
|
|
||||||
@deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: IntCriterionInput
|
rating100: IntCriterionInput
|
||||||
"Filter by url"
|
"Filter by url"
|
||||||
|
|
@ -169,8 +161,6 @@ input PerformerFilterType {
|
||||||
}
|
}
|
||||||
|
|
||||||
input SceneMarkerFilterType {
|
input SceneMarkerFilterType {
|
||||||
"Filter to only include scene markers with this tag"
|
|
||||||
tag_id: ID @deprecated(reason: "use tags filter instead")
|
|
||||||
"Filter to only include scene markers with these tags"
|
"Filter to only include scene markers with these tags"
|
||||||
tags: HierarchicalMultiCriterionInput
|
tags: HierarchicalMultiCriterionInput
|
||||||
"Filter to only include scene markers attached to a scene with these tags"
|
"Filter to only include scene markers attached to a scene with these tags"
|
||||||
|
|
@ -212,9 +202,6 @@ input SceneFilterType {
|
||||||
path: StringCriterionInput
|
path: StringCriterionInput
|
||||||
"Filter by file count"
|
"Filter by file count"
|
||||||
file_count: IntCriterionInput
|
file_count: IntCriterionInput
|
||||||
"Filter by rating"
|
|
||||||
rating: IntCriterionInput
|
|
||||||
@deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: IntCriterionInput
|
rating100: IntCriterionInput
|
||||||
"Filter by organized"
|
"Filter by organized"
|
||||||
|
|
@ -256,9 +243,6 @@ input SceneFilterType {
|
||||||
"Filter by performer count"
|
"Filter by performer count"
|
||||||
performer_count: IntCriterionInput
|
performer_count: IntCriterionInput
|
||||||
"Filter by StashID"
|
"Filter by StashID"
|
||||||
stash_id: StringCriterionInput
|
|
||||||
@deprecated(reason: "Use stash_id_endpoint instead")
|
|
||||||
"Filter by StashID"
|
|
||||||
stash_id_endpoint: StashIDCriterionInput
|
stash_id_endpoint: StashIDCriterionInput
|
||||||
"Filter by url"
|
"Filter by url"
|
||||||
url: StringCriterionInput
|
url: StringCriterionInput
|
||||||
|
|
@ -289,9 +273,6 @@ input MovieFilterType {
|
||||||
|
|
||||||
"Filter by duration (in seconds)"
|
"Filter by duration (in seconds)"
|
||||||
duration: IntCriterionInput
|
duration: IntCriterionInput
|
||||||
"Filter by rating"
|
|
||||||
rating: IntCriterionInput
|
|
||||||
@deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: IntCriterionInput
|
rating100: IntCriterionInput
|
||||||
"Filter to only include movies with this studio"
|
"Filter to only include movies with this studio"
|
||||||
|
|
@ -320,15 +301,9 @@ input StudioFilterType {
|
||||||
"Filter to only include studios with this parent studio"
|
"Filter to only include studios with this parent studio"
|
||||||
parents: MultiCriterionInput
|
parents: MultiCriterionInput
|
||||||
"Filter by StashID"
|
"Filter by StashID"
|
||||||
stash_id: StringCriterionInput
|
|
||||||
@deprecated(reason: "Use stash_id_endpoint instead")
|
|
||||||
"Filter by StashID"
|
|
||||||
stash_id_endpoint: StashIDCriterionInput
|
stash_id_endpoint: StashIDCriterionInput
|
||||||
"Filter to only include studios missing this property"
|
"Filter to only include studios missing this property"
|
||||||
is_missing: String
|
is_missing: String
|
||||||
"Filter by rating"
|
|
||||||
rating: IntCriterionInput
|
|
||||||
@deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: IntCriterionInput
|
rating100: IntCriterionInput
|
||||||
"Filter by scene count"
|
"Filter by scene count"
|
||||||
|
|
@ -368,9 +343,6 @@ input GalleryFilterType {
|
||||||
is_missing: String
|
is_missing: String
|
||||||
"Filter to include/exclude galleries that were created from zip"
|
"Filter to include/exclude galleries that were created from zip"
|
||||||
is_zip: Boolean
|
is_zip: Boolean
|
||||||
"Filter by rating"
|
|
||||||
rating: IntCriterionInput
|
|
||||||
@deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: IntCriterionInput
|
rating100: IntCriterionInput
|
||||||
"Filter by organized"
|
"Filter by organized"
|
||||||
|
|
@ -476,9 +448,6 @@ input ImageFilterType {
|
||||||
path: StringCriterionInput
|
path: StringCriterionInput
|
||||||
"Filter by file count"
|
"Filter by file count"
|
||||||
file_count: IntCriterionInput
|
file_count: IntCriterionInput
|
||||||
"Filter by rating"
|
|
||||||
rating: IntCriterionInput
|
|
||||||
@deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: IntCriterionInput
|
rating100: IntCriterionInput
|
||||||
"Filter by date"
|
"Filter by date"
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,16 @@
|
||||||
"Gallery type"
|
"Gallery type"
|
||||||
type Gallery {
|
type Gallery {
|
||||||
id: ID!
|
id: ID!
|
||||||
checksum: String! @deprecated(reason: "Use files.fingerprints")
|
|
||||||
path: String @deprecated(reason: "Use files.path")
|
|
||||||
title: String
|
title: String
|
||||||
url: String @deprecated(reason: "Use urls")
|
url: String @deprecated(reason: "Use urls")
|
||||||
urls: [String!]!
|
urls: [String!]!
|
||||||
date: String
|
date: String
|
||||||
details: String
|
details: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
organized: Boolean!
|
organized: Boolean!
|
||||||
created_at: Time!
|
created_at: Time!
|
||||||
updated_at: Time!
|
updated_at: Time!
|
||||||
file_mod_time: Time @deprecated(reason: "Use files.mod_time")
|
|
||||||
|
|
||||||
files: [GalleryFile!]!
|
files: [GalleryFile!]!
|
||||||
folder: Folder
|
folder: Folder
|
||||||
|
|
@ -27,8 +22,6 @@ type Gallery {
|
||||||
tags: [Tag!]!
|
tags: [Tag!]!
|
||||||
performers: [Performer!]!
|
performers: [Performer!]!
|
||||||
|
|
||||||
"The images in the gallery"
|
|
||||||
images: [Image!]! @deprecated(reason: "Use findImages")
|
|
||||||
cover: Image
|
cover: Image
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -38,8 +31,6 @@ input GalleryCreateInput {
|
||||||
urls: [String!]
|
urls: [String!]
|
||||||
date: String
|
date: String
|
||||||
details: String
|
details: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
organized: Boolean
|
organized: Boolean
|
||||||
|
|
@ -57,8 +48,6 @@ input GalleryUpdateInput {
|
||||||
urls: [String!]
|
urls: [String!]
|
||||||
date: String
|
date: String
|
||||||
details: String
|
details: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
organized: Boolean
|
organized: Boolean
|
||||||
|
|
@ -77,8 +66,6 @@ input BulkGalleryUpdateInput {
|
||||||
urls: BulkUpdateStrings
|
urls: BulkUpdateStrings
|
||||||
date: String
|
date: String
|
||||||
details: String
|
details: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
organized: Boolean
|
organized: Boolean
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
type Image {
|
type Image {
|
||||||
id: ID!
|
id: ID!
|
||||||
checksum: String @deprecated(reason: "Use files.fingerprints")
|
|
||||||
title: String
|
title: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
url: String @deprecated(reason: "Use urls")
|
url: String @deprecated(reason: "Use urls")
|
||||||
|
|
@ -11,13 +8,9 @@ type Image {
|
||||||
date: String
|
date: String
|
||||||
o_counter: Int
|
o_counter: Int
|
||||||
organized: Boolean!
|
organized: Boolean!
|
||||||
path: String! @deprecated(reason: "Use files.path")
|
|
||||||
created_at: Time!
|
created_at: Time!
|
||||||
updated_at: Time!
|
updated_at: Time!
|
||||||
|
|
||||||
file_mod_time: Time @deprecated(reason: "Use files.mod_time")
|
|
||||||
|
|
||||||
file: ImageFileType! @deprecated(reason: "Use visual_files")
|
|
||||||
files: [ImageFile!]! @deprecated(reason: "Use visual_files")
|
files: [ImageFile!]! @deprecated(reason: "Use visual_files")
|
||||||
visual_files: [VisualFile!]!
|
visual_files: [VisualFile!]!
|
||||||
paths: ImagePathsType! # Resolver
|
paths: ImagePathsType! # Resolver
|
||||||
|
|
@ -44,8 +37,6 @@ input ImageUpdateInput {
|
||||||
clientMutationId: String
|
clientMutationId: String
|
||||||
id: ID!
|
id: ID!
|
||||||
title: String
|
title: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
organized: Boolean
|
organized: Boolean
|
||||||
|
|
@ -65,8 +56,6 @@ input BulkImageUpdateInput {
|
||||||
clientMutationId: String
|
clientMutationId: String
|
||||||
ids: [ID!]
|
ids: [ID!]
|
||||||
title: String
|
title: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
organized: Boolean
|
organized: Boolean
|
||||||
|
|
|
||||||
|
|
@ -75,19 +75,6 @@ input ScanMetaDataFilterInput {
|
||||||
input ScanMetadataInput {
|
input ScanMetadataInput {
|
||||||
paths: [String!]
|
paths: [String!]
|
||||||
|
|
||||||
# useFileMetadata is deprecated with the new file management system
|
|
||||||
# if this functionality is desired, then we can make a built in scraper instead.
|
|
||||||
|
|
||||||
"Set name, date, details from metadata (if present)"
|
|
||||||
useFileMetadata: Boolean @deprecated(reason: "Not implemented")
|
|
||||||
|
|
||||||
# stripFileExtension is deprecated since we no longer set the title from the
|
|
||||||
# filename - it is automatically returned if the object has no title. If this
|
|
||||||
# functionality is desired, then we could make this an option to not include
|
|
||||||
# the extension in the auto-generated title.
|
|
||||||
|
|
||||||
"Strip file extension from title"
|
|
||||||
stripFileExtension: Boolean @deprecated(reason: "Not implemented")
|
|
||||||
"Generate covers during scan"
|
"Generate covers during scan"
|
||||||
scanGenerateCovers: Boolean
|
scanGenerateCovers: Boolean
|
||||||
"Generate previews during scan"
|
"Generate previews during scan"
|
||||||
|
|
@ -108,10 +95,6 @@ input ScanMetadataInput {
|
||||||
}
|
}
|
||||||
|
|
||||||
type ScanMetadataOptions {
|
type ScanMetadataOptions {
|
||||||
"Set name, date, details from metadata (if present)"
|
|
||||||
useFileMetadata: Boolean! @deprecated(reason: "Not implemented")
|
|
||||||
"Strip file extension from title"
|
|
||||||
stripFileExtension: Boolean! @deprecated(reason: "Not implemented")
|
|
||||||
"Generate covers during scan"
|
"Generate covers during scan"
|
||||||
scanGenerateCovers: Boolean!
|
scanGenerateCovers: Boolean!
|
||||||
"Generate previews during scan"
|
"Generate previews during scan"
|
||||||
|
|
|
||||||
|
|
@ -1,13 +1,10 @@
|
||||||
type Movie {
|
type Movie {
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
checksum: String! @deprecated(reason: "MD5 hash of name, use name directly")
|
|
||||||
aliases: String
|
aliases: String
|
||||||
"Duration in seconds"
|
"Duration in seconds"
|
||||||
duration: Int
|
duration: Int
|
||||||
date: String
|
date: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
studio: Studio
|
studio: Studio
|
||||||
|
|
@ -29,8 +26,6 @@ input MovieCreateInput {
|
||||||
"Duration in seconds"
|
"Duration in seconds"
|
||||||
duration: Int
|
duration: Int
|
||||||
date: String
|
date: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
studio_id: ID
|
studio_id: ID
|
||||||
|
|
@ -49,8 +44,6 @@ input MovieUpdateInput {
|
||||||
aliases: String
|
aliases: String
|
||||||
duration: Int
|
duration: Int
|
||||||
date: String
|
date: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
studio_id: ID
|
studio_id: ID
|
||||||
|
|
@ -66,8 +59,6 @@ input MovieUpdateInput {
|
||||||
input BulkMovieUpdateInput {
|
input BulkMovieUpdateInput {
|
||||||
clientMutationId: String
|
clientMutationId: String
|
||||||
ids: [ID!]
|
ids: [ID!]
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
studio_id: ID
|
studio_id: ID
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,6 @@ enum CircumisedEnum {
|
||||||
|
|
||||||
type Performer {
|
type Performer {
|
||||||
id: ID!
|
id: ID!
|
||||||
checksum: String @deprecated(reason: "Not used")
|
|
||||||
name: String!
|
name: String!
|
||||||
disambiguation: String
|
disambiguation: String
|
||||||
url: String
|
url: String
|
||||||
|
|
@ -25,7 +24,6 @@ type Performer {
|
||||||
ethnicity: String
|
ethnicity: String
|
||||||
country: String
|
country: String
|
||||||
eye_color: String
|
eye_color: String
|
||||||
height: String @deprecated(reason: "Use height_cm")
|
|
||||||
height_cm: Int
|
height_cm: Int
|
||||||
measurements: String
|
measurements: String
|
||||||
fake_tits: String
|
fake_tits: String
|
||||||
|
|
@ -34,7 +32,6 @@ type Performer {
|
||||||
career_length: String
|
career_length: String
|
||||||
tattoos: String
|
tattoos: String
|
||||||
piercings: String
|
piercings: String
|
||||||
aliases: String @deprecated(reason: "Use alias_list")
|
|
||||||
alias_list: [String!]!
|
alias_list: [String!]!
|
||||||
favorite: Boolean!
|
favorite: Boolean!
|
||||||
tags: [Tag!]!
|
tags: [Tag!]!
|
||||||
|
|
@ -49,8 +46,6 @@ type Performer {
|
||||||
o_counter: Int # Resolver
|
o_counter: Int # Resolver
|
||||||
scenes: [Scene!]!
|
scenes: [Scene!]!
|
||||||
stash_ids: [StashID!]!
|
stash_ids: [StashID!]!
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
details: String
|
details: String
|
||||||
|
|
@ -71,8 +66,6 @@ input PerformerCreateInput {
|
||||||
ethnicity: String
|
ethnicity: String
|
||||||
country: String
|
country: String
|
||||||
eye_color: String
|
eye_color: String
|
||||||
# height must be parsable into an integer
|
|
||||||
height: String @deprecated(reason: "Use height_cm")
|
|
||||||
height_cm: Int
|
height_cm: Int
|
||||||
measurements: String
|
measurements: String
|
||||||
fake_tits: String
|
fake_tits: String
|
||||||
|
|
@ -81,7 +74,6 @@ input PerformerCreateInput {
|
||||||
career_length: String
|
career_length: String
|
||||||
tattoos: String
|
tattoos: String
|
||||||
piercings: String
|
piercings: String
|
||||||
aliases: String @deprecated(reason: "Use alias_list")
|
|
||||||
alias_list: [String!]
|
alias_list: [String!]
|
||||||
twitter: String
|
twitter: String
|
||||||
instagram: String
|
instagram: String
|
||||||
|
|
@ -90,8 +82,6 @@ input PerformerCreateInput {
|
||||||
"This should be a URL or a base64 encoded data URL"
|
"This should be a URL or a base64 encoded data URL"
|
||||||
image: String
|
image: String
|
||||||
stash_ids: [StashIDInput!]
|
stash_ids: [StashIDInput!]
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
details: String
|
details: String
|
||||||
|
|
@ -111,8 +101,6 @@ input PerformerUpdateInput {
|
||||||
ethnicity: String
|
ethnicity: String
|
||||||
country: String
|
country: String
|
||||||
eye_color: String
|
eye_color: String
|
||||||
# height must be parsable into an integer
|
|
||||||
height: String @deprecated(reason: "Use height_cm")
|
|
||||||
height_cm: Int
|
height_cm: Int
|
||||||
measurements: String
|
measurements: String
|
||||||
fake_tits: String
|
fake_tits: String
|
||||||
|
|
@ -121,7 +109,6 @@ input PerformerUpdateInput {
|
||||||
career_length: String
|
career_length: String
|
||||||
tattoos: String
|
tattoos: String
|
||||||
piercings: String
|
piercings: String
|
||||||
aliases: String @deprecated(reason: "Use alias_list")
|
|
||||||
alias_list: [String!]
|
alias_list: [String!]
|
||||||
twitter: String
|
twitter: String
|
||||||
instagram: String
|
instagram: String
|
||||||
|
|
@ -130,8 +117,6 @@ input PerformerUpdateInput {
|
||||||
"This should be a URL or a base64 encoded data URL"
|
"This should be a URL or a base64 encoded data URL"
|
||||||
image: String
|
image: String
|
||||||
stash_ids: [StashIDInput!]
|
stash_ids: [StashIDInput!]
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
details: String
|
details: String
|
||||||
|
|
@ -156,8 +141,6 @@ input BulkPerformerUpdateInput {
|
||||||
ethnicity: String
|
ethnicity: String
|
||||||
country: String
|
country: String
|
||||||
eye_color: String
|
eye_color: String
|
||||||
# height must be parsable into an integer
|
|
||||||
height: String @deprecated(reason: "Use height_cm")
|
|
||||||
height_cm: Int
|
height_cm: Int
|
||||||
measurements: String
|
measurements: String
|
||||||
fake_tits: String
|
fake_tits: String
|
||||||
|
|
@ -166,14 +149,11 @@ input BulkPerformerUpdateInput {
|
||||||
career_length: String
|
career_length: String
|
||||||
tattoos: String
|
tattoos: String
|
||||||
piercings: String
|
piercings: String
|
||||||
aliases: String @deprecated(reason: "Use alias_list")
|
|
||||||
alias_list: BulkUpdateStrings
|
alias_list: BulkUpdateStrings
|
||||||
twitter: String
|
twitter: String
|
||||||
instagram: String
|
instagram: String
|
||||||
favorite: Boolean
|
favorite: Boolean
|
||||||
tag_ids: BulkUpdateIds
|
tag_ids: BulkUpdateIds
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
details: String
|
details: String
|
||||||
|
|
|
||||||
|
|
@ -15,7 +15,6 @@ type ScenePathsType {
|
||||||
stream: String # Resolver
|
stream: String # Resolver
|
||||||
webp: String # Resolver
|
webp: String # Resolver
|
||||||
vtt: String # Resolver
|
vtt: String # Resolver
|
||||||
chapters_vtt: String @deprecated
|
|
||||||
sprite: String # Resolver
|
sprite: String # Resolver
|
||||||
funscript: String # Resolver
|
funscript: String # Resolver
|
||||||
interactive_heatmap: String # Resolver
|
interactive_heatmap: String # Resolver
|
||||||
|
|
@ -34,8 +33,6 @@ type VideoCaption {
|
||||||
|
|
||||||
type Scene {
|
type Scene {
|
||||||
id: ID!
|
id: ID!
|
||||||
checksum: String @deprecated(reason: "Use files.fingerprints")
|
|
||||||
oshash: String @deprecated(reason: "Use files.fingerprints")
|
|
||||||
title: String
|
title: String
|
||||||
code: String
|
code: String
|
||||||
details: String
|
details: String
|
||||||
|
|
@ -43,20 +40,15 @@ type Scene {
|
||||||
url: String @deprecated(reason: "Use urls")
|
url: String @deprecated(reason: "Use urls")
|
||||||
urls: [String!]!
|
urls: [String!]!
|
||||||
date: String
|
date: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
organized: Boolean!
|
organized: Boolean!
|
||||||
o_counter: Int
|
o_counter: Int
|
||||||
path: String! @deprecated(reason: "Use files.path")
|
|
||||||
phash: String @deprecated(reason: "Use files.fingerprints")
|
|
||||||
interactive: Boolean!
|
interactive: Boolean!
|
||||||
interactive_speed: Int
|
interactive_speed: Int
|
||||||
captions: [VideoCaption!]
|
captions: [VideoCaption!]
|
||||||
created_at: Time!
|
created_at: Time!
|
||||||
updated_at: Time!
|
updated_at: Time!
|
||||||
file_mod_time: Time
|
|
||||||
"The last time play count was updated"
|
"The last time play count was updated"
|
||||||
last_played_at: Time
|
last_played_at: Time
|
||||||
"The time index a scene was left at"
|
"The time index a scene was left at"
|
||||||
|
|
@ -66,7 +58,6 @@ type Scene {
|
||||||
"The number ot times a scene has been played"
|
"The number ot times a scene has been played"
|
||||||
play_count: Int
|
play_count: Int
|
||||||
|
|
||||||
file: SceneFileType! @deprecated(reason: "Use files")
|
|
||||||
files: [VideoFile!]!
|
files: [VideoFile!]!
|
||||||
paths: ScenePathsType! # Resolver
|
paths: ScenePathsType! # Resolver
|
||||||
scene_markers: [SceneMarker!]!
|
scene_markers: [SceneMarker!]!
|
||||||
|
|
@ -94,8 +85,6 @@ input SceneCreateInput {
|
||||||
url: String @deprecated(reason: "Use urls")
|
url: String @deprecated(reason: "Use urls")
|
||||||
urls: [String!]
|
urls: [String!]
|
||||||
date: String
|
date: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
organized: Boolean
|
organized: Boolean
|
||||||
|
|
@ -126,8 +115,6 @@ input SceneUpdateInput {
|
||||||
url: String @deprecated(reason: "Use urls")
|
url: String @deprecated(reason: "Use urls")
|
||||||
urls: [String!]
|
urls: [String!]
|
||||||
date: String
|
date: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
o_counter: Int
|
o_counter: Int
|
||||||
|
|
@ -172,8 +159,6 @@ input BulkSceneUpdateInput {
|
||||||
url: String @deprecated(reason: "Use urls")
|
url: String @deprecated(reason: "Use urls")
|
||||||
urls: BulkUpdateStrings
|
urls: BulkUpdateStrings
|
||||||
date: String
|
date: String
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
organized: Boolean
|
organized: Boolean
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
type Studio {
|
type Studio {
|
||||||
id: ID!
|
id: ID!
|
||||||
name: String!
|
name: String!
|
||||||
checksum: String! @deprecated(reason: "MD5 hash of name, use name directly")
|
|
||||||
url: String
|
url: String
|
||||||
parent_studio: Studio
|
parent_studio: Studio
|
||||||
child_studios: [Studio!]!
|
child_studios: [Studio!]!
|
||||||
|
|
@ -15,8 +14,6 @@ type Studio {
|
||||||
performer_count(depth: Int): Int! # Resolver
|
performer_count(depth: Int): Int! # Resolver
|
||||||
movie_count(depth: Int): Int! # Resolver
|
movie_count(depth: Int): Int! # Resolver
|
||||||
stash_ids: [StashID!]!
|
stash_ids: [StashID!]!
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
details: String
|
details: String
|
||||||
|
|
@ -32,8 +29,6 @@ input StudioCreateInput {
|
||||||
"This should be a URL or a base64 encoded data URL"
|
"This should be a URL or a base64 encoded data URL"
|
||||||
image: String
|
image: String
|
||||||
stash_ids: [StashIDInput!]
|
stash_ids: [StashIDInput!]
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
details: String
|
details: String
|
||||||
|
|
@ -49,8 +44,6 @@ input StudioUpdateInput {
|
||||||
"This should be a URL or a base64 encoded data URL"
|
"This should be a URL or a base64 encoded data URL"
|
||||||
image: String
|
image: String
|
||||||
stash_ids: [StashIDInput!]
|
stash_ids: [StashIDInput!]
|
||||||
# rating expressed as 1-5
|
|
||||||
rating: Int @deprecated(reason: "Use 1-100 range with rating100")
|
|
||||||
# rating expressed as 1-100
|
# rating expressed as 1-100
|
||||||
rating100: Int
|
rating100: Int
|
||||||
details: String
|
details: String
|
||||||
|
|
|
||||||
|
|
@ -153,40 +153,6 @@ func (t changesetTranslator) intPtrFromString(value *string) (*int, error) {
|
||||||
return &vv, nil
|
return &vv, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t changesetTranslator) ratingConversion(legacyValue *int, rating100Value *int) *int {
|
|
||||||
const (
|
|
||||||
legacyField = "rating"
|
|
||||||
rating100Field = "rating100"
|
|
||||||
)
|
|
||||||
|
|
||||||
legacyRating := t.optionalInt(legacyValue, legacyField)
|
|
||||||
if legacyRating.Set && !legacyRating.Null {
|
|
||||||
ret := models.Rating5To100(legacyRating.Value)
|
|
||||||
return &ret
|
|
||||||
}
|
|
||||||
|
|
||||||
o := t.optionalInt(rating100Value, rating100Field)
|
|
||||||
if o.Set && !o.Null {
|
|
||||||
return &o.Value
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t changesetTranslator) optionalRatingConversion(legacyValue *int, rating100Value *int) models.OptionalInt {
|
|
||||||
const (
|
|
||||||
legacyField = "rating"
|
|
||||||
rating100Field = "rating100"
|
|
||||||
)
|
|
||||||
|
|
||||||
legacyRating := t.optionalInt(legacyValue, legacyField)
|
|
||||||
if legacyRating.Set && !legacyRating.Null {
|
|
||||||
legacyRating.Value = models.Rating5To100(legacyRating.Value)
|
|
||||||
return legacyRating
|
|
||||||
}
|
|
||||||
return t.optionalInt(rating100Value, rating100Field)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (t changesetTranslator) optionalInt(value *int, field string) models.OptionalInt {
|
func (t changesetTranslator) optionalInt(value *int, field string) models.OptionalInt {
|
||||||
if !t.hasField(field) {
|
if !t.hasField(field) {
|
||||||
return models.OptionalInt{}
|
return models.OptionalInt{}
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stashapp/stash/internal/api/loaders"
|
"github.com/stashapp/stash/internal/api/loaders"
|
||||||
"github.com/stashapp/stash/internal/manager/config"
|
"github.com/stashapp/stash/internal/manager/config"
|
||||||
|
|
@ -11,19 +10,6 @@ import (
|
||||||
"github.com/stashapp/stash/pkg/models"
|
"github.com/stashapp/stash/pkg/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *galleryResolver) getPrimaryFile(ctx context.Context, obj *models.Gallery) (models.File, error) {
|
|
||||||
if obj.PrimaryFileID != nil {
|
|
||||||
f, err := loaders.From(ctx).FileByID.Load(*obj.PrimaryFileID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return f, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *galleryResolver) getFiles(ctx context.Context, obj *models.Gallery) ([]models.File, error) {
|
func (r *galleryResolver) getFiles(ctx context.Context, obj *models.Gallery) ([]models.File, error) {
|
||||||
fileIDs, err := loaders.From(ctx).GalleryFiles.Load(obj.ID)
|
fileIDs, err := loaders.From(ctx).GalleryFiles.Load(obj.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -78,38 +64,6 @@ func (r *galleryResolver) Folder(ctx context.Context, obj *models.Gallery) (*mod
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *galleryResolver) FileModTime(ctx context.Context, obj *models.Gallery) (*time.Time, error) {
|
|
||||||
f, err := r.getPrimaryFile(ctx, obj)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if f != nil {
|
|
||||||
return &f.Base().ModTime, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Images is deprecated, slow and shouldn't be used
|
|
||||||
func (r *galleryResolver) Images(ctx context.Context, obj *models.Gallery) (ret []*models.Image, err error) {
|
|
||||||
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
|
|
||||||
var err error
|
|
||||||
|
|
||||||
// #2376 - sort images by path
|
|
||||||
// doing this via Query is really slow, so stick with FindByGalleryID
|
|
||||||
ret, err = r.repository.Image.FindByGalleryID(ctx, obj.ID)
|
|
||||||
if err != nil {
|
|
||||||
return err
|
|
||||||
}
|
|
||||||
|
|
||||||
return err
|
|
||||||
}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *galleryResolver) Cover(ctx context.Context, obj *models.Gallery) (ret *models.Image, err error) {
|
func (r *galleryResolver) Cover(ctx context.Context, obj *models.Gallery) (ret *models.Image, err error) {
|
||||||
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
|
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
|
||||||
// Find cover image first
|
// Find cover image first
|
||||||
|
|
@ -130,26 +84,6 @@ func (r *galleryResolver) Date(ctx context.Context, obj *models.Gallery) (*strin
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *galleryResolver) Checksum(ctx context.Context, obj *models.Gallery) (string, error) {
|
|
||||||
if !obj.Files.PrimaryLoaded() {
|
|
||||||
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
|
|
||||||
return obj.LoadPrimaryFile(ctx, r.repository.File)
|
|
||||||
}); err != nil {
|
|
||||||
return "", err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return obj.PrimaryChecksum(), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *galleryResolver) Rating(ctx context.Context, obj *models.Gallery) (*int, error) {
|
|
||||||
if obj.Rating != nil {
|
|
||||||
rating := models.Rating100To5(*obj.Rating)
|
|
||||||
return &rating, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *galleryResolver) Rating100(ctx context.Context, obj *models.Gallery) (*int, error) {
|
func (r *galleryResolver) Rating100(ctx context.Context, obj *models.Gallery) (*int, error) {
|
||||||
return obj.Rating, nil
|
return obj.Rating, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package api
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stashapp/stash/internal/api/loaders"
|
"github.com/stashapp/stash/internal/api/loaders"
|
||||||
"github.com/stashapp/stash/internal/api/urlbuilders"
|
"github.com/stashapp/stash/internal/api/urlbuilders"
|
||||||
|
|
@ -18,19 +17,6 @@ func convertVisualFile(f models.File) (models.VisualFile, error) {
|
||||||
return vf, nil
|
return vf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageResolver) getPrimaryFile(ctx context.Context, obj *models.Image) (models.VisualFile, error) {
|
|
||||||
if obj.PrimaryFileID != nil {
|
|
||||||
f, err := loaders.From(ctx).FileByID.Load(*obj.PrimaryFileID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return convertVisualFile(f)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *imageResolver) getFiles(ctx context.Context, obj *models.Image) ([]models.File, error) {
|
func (r *imageResolver) getFiles(ctx context.Context, obj *models.Image) ([]models.File, error) {
|
||||||
fileIDs, err := loaders.From(ctx).ImageFiles.Load(obj.ID)
|
fileIDs, err := loaders.From(ctx).ImageFiles.Load(obj.ID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -46,26 +32,6 @@ func (r *imageResolver) Title(ctx context.Context, obj *models.Image) (*string,
|
||||||
return &ret, nil
|
return &ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageResolver) File(ctx context.Context, obj *models.Image) (*ImageFileType, error) {
|
|
||||||
f, err := r.getPrimaryFile(ctx, obj)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if f == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
width := f.GetWidth()
|
|
||||||
height := f.GetHeight()
|
|
||||||
size := f.Base().Size
|
|
||||||
return &ImageFileType{
|
|
||||||
Size: int(size),
|
|
||||||
Width: width,
|
|
||||||
Height: height,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *imageResolver) VisualFiles(ctx context.Context, obj *models.Image) ([]models.VisualFile, error) {
|
func (r *imageResolver) VisualFiles(ctx context.Context, obj *models.Image) ([]models.VisualFile, error) {
|
||||||
files, err := r.getFiles(ctx, obj)
|
files, err := r.getFiles(ctx, obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -112,18 +78,6 @@ func (r *imageResolver) Files(ctx context.Context, obj *models.Image) ([]*models
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageResolver) FileModTime(ctx context.Context, obj *models.Image) (*time.Time, error) {
|
|
||||||
f, err := r.getPrimaryFile(ctx, obj)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if f != nil {
|
|
||||||
return &f.Base().ModTime, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *imageResolver) Paths(ctx context.Context, obj *models.Image) (*ImagePathsType, error) {
|
func (r *imageResolver) Paths(ctx context.Context, obj *models.Image) (*ImagePathsType, error) {
|
||||||
baseURL, _ := ctx.Value(BaseURLCtxKey).(string)
|
baseURL, _ := ctx.Value(BaseURLCtxKey).(string)
|
||||||
builder := urlbuilders.NewImageURLBuilder(baseURL, obj)
|
builder := urlbuilders.NewImageURLBuilder(baseURL, obj)
|
||||||
|
|
@ -151,14 +105,6 @@ func (r *imageResolver) Galleries(ctx context.Context, obj *models.Image) (ret [
|
||||||
return ret, firstError(errs)
|
return ret, firstError(errs)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *imageResolver) Rating(ctx context.Context, obj *models.Image) (*int, error) {
|
|
||||||
if obj.Rating != nil {
|
|
||||||
rating := models.Rating100To5(*obj.Rating)
|
|
||||||
return &rating, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *imageResolver) Rating100(ctx context.Context, obj *models.Image) (*int, error) {
|
func (r *imageResolver) Rating100(ctx context.Context, obj *models.Image) (*int, error) {
|
||||||
return obj.Rating, nil
|
return obj.Rating, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,15 +5,9 @@ import (
|
||||||
|
|
||||||
"github.com/stashapp/stash/internal/api/loaders"
|
"github.com/stashapp/stash/internal/api/loaders"
|
||||||
"github.com/stashapp/stash/internal/api/urlbuilders"
|
"github.com/stashapp/stash/internal/api/urlbuilders"
|
||||||
"github.com/stashapp/stash/pkg/hash/md5"
|
|
||||||
"github.com/stashapp/stash/pkg/models"
|
"github.com/stashapp/stash/pkg/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *movieResolver) Checksum(ctx context.Context, obj *models.Movie) (string, error) {
|
|
||||||
// generate checksum from movie name
|
|
||||||
return md5.FromString(obj.Name), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *movieResolver) Date(ctx context.Context, obj *models.Movie) (*string, error) {
|
func (r *movieResolver) Date(ctx context.Context, obj *models.Movie) (*string, error) {
|
||||||
if obj.Date != nil {
|
if obj.Date != nil {
|
||||||
result := obj.Date.String()
|
result := obj.Date.String()
|
||||||
|
|
@ -22,14 +16,6 @@ func (r *movieResolver) Date(ctx context.Context, obj *models.Movie) (*string, e
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *movieResolver) Rating(ctx context.Context, obj *models.Movie) (*int, error) {
|
|
||||||
if obj.Rating != nil {
|
|
||||||
rating := models.Rating100To5(*obj.Rating)
|
|
||||||
return &rating, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *movieResolver) Rating100(ctx context.Context, obj *models.Movie) (*int, error) {
|
func (r *movieResolver) Rating100(ctx context.Context, obj *models.Movie) (*int, error) {
|
||||||
return obj.Rating, nil
|
return obj.Rating, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,6 @@ package api
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"strconv"
|
"strconv"
|
||||||
"strings"
|
|
||||||
|
|
||||||
"github.com/stashapp/stash/internal/api/loaders"
|
"github.com/stashapp/stash/internal/api/loaders"
|
||||||
"github.com/stashapp/stash/internal/api/urlbuilders"
|
"github.com/stashapp/stash/internal/api/urlbuilders"
|
||||||
|
|
@ -13,24 +12,6 @@ import (
|
||||||
"github.com/stashapp/stash/pkg/performer"
|
"github.com/stashapp/stash/pkg/performer"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Checksum is deprecated
|
|
||||||
func (r *performerResolver) Checksum(ctx context.Context, obj *models.Performer) (*string, error) {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *performerResolver) Aliases(ctx context.Context, obj *models.Performer) (*string, error) {
|
|
||||||
if !obj.Aliases.Loaded() {
|
|
||||||
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
|
|
||||||
return obj.LoadAliases(ctx, r.repository.Performer)
|
|
||||||
}); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ret := strings.Join(obj.Aliases.List(), ", ")
|
|
||||||
return &ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *performerResolver) AliasList(ctx context.Context, obj *models.Performer) ([]string, error) {
|
func (r *performerResolver) AliasList(ctx context.Context, obj *models.Performer) ([]string, error) {
|
||||||
if !obj.Aliases.Loaded() {
|
if !obj.Aliases.Loaded() {
|
||||||
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
|
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
|
||||||
|
|
@ -186,14 +167,6 @@ func (r *performerResolver) StashIds(ctx context.Context, obj *models.Performer)
|
||||||
return stashIDsSliceToPtrSlice(obj.StashIDs.List()), nil
|
return stashIDsSliceToPtrSlice(obj.StashIDs.List()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *performerResolver) Rating(ctx context.Context, obj *models.Performer) (*int, error) {
|
|
||||||
if obj.Rating != nil {
|
|
||||||
rating := models.Rating100To5(*obj.Rating)
|
|
||||||
return &rating, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *performerResolver) Rating100(ctx context.Context, obj *models.Performer) (*int, error) {
|
func (r *performerResolver) Rating100(ctx context.Context, obj *models.Performer) (*int, error) {
|
||||||
return obj.Rating, nil
|
return obj.Rating, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -3,14 +3,11 @@ package api
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
"strconv"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
"github.com/stashapp/stash/internal/api/loaders"
|
"github.com/stashapp/stash/internal/api/loaders"
|
||||||
"github.com/stashapp/stash/internal/api/urlbuilders"
|
"github.com/stashapp/stash/internal/api/urlbuilders"
|
||||||
"github.com/stashapp/stash/internal/manager"
|
"github.com/stashapp/stash/internal/manager"
|
||||||
"github.com/stashapp/stash/pkg/models"
|
"github.com/stashapp/stash/pkg/models"
|
||||||
"github.com/stashapp/stash/pkg/utils"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func convertVideoFile(f models.File) (*models.VideoFile, error) {
|
func convertVideoFile(f models.File) (*models.VideoFile, error) {
|
||||||
|
|
@ -68,18 +65,6 @@ func (r *sceneResolver) getFiles(ctx context.Context, obj *models.Scene) ([]*mod
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *sceneResolver) FileModTime(ctx context.Context, obj *models.Scene) (*time.Time, error) {
|
|
||||||
f, err := r.getPrimaryFile(ctx, obj)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if f != nil {
|
|
||||||
return &f.ModTime, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *sceneResolver) Date(ctx context.Context, obj *models.Scene) (*string, error) {
|
func (r *sceneResolver) Date(ctx context.Context, obj *models.Scene) (*string, error) {
|
||||||
if obj.Date != nil {
|
if obj.Date != nil {
|
||||||
result := obj.Date.String()
|
result := obj.Date.String()
|
||||||
|
|
@ -88,31 +73,6 @@ func (r *sceneResolver) Date(ctx context.Context, obj *models.Scene) (*string, e
|
||||||
return nil, nil
|
return nil, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// File is deprecated
|
|
||||||
func (r *sceneResolver) File(ctx context.Context, obj *models.Scene) (*models.SceneFileType, error) {
|
|
||||||
f, err := r.getPrimaryFile(ctx, obj)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if f == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
bitrate := int(f.BitRate)
|
|
||||||
size := strconv.FormatInt(f.Size, 10)
|
|
||||||
|
|
||||||
return &models.SceneFileType{
|
|
||||||
Size: &size,
|
|
||||||
Duration: handleFloat64(f.Duration),
|
|
||||||
VideoCodec: &f.VideoCodec,
|
|
||||||
AudioCodec: &f.AudioCodec,
|
|
||||||
Width: &f.Width,
|
|
||||||
Height: &f.Height,
|
|
||||||
Framerate: handleFloat64(f.FrameRate),
|
|
||||||
Bitrate: &bitrate,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *sceneResolver) Files(ctx context.Context, obj *models.Scene) ([]*models.VideoFile, error) {
|
func (r *sceneResolver) Files(ctx context.Context, obj *models.Scene) ([]*models.VideoFile, error) {
|
||||||
files, err := r.getFiles(ctx, obj)
|
files, err := r.getFiles(ctx, obj)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -145,7 +105,6 @@ func (r *sceneResolver) Paths(ctx context.Context, obj *models.Scene) (*ScenePat
|
||||||
objHash := obj.GetHash(config.GetVideoFileNamingAlgorithm())
|
objHash := obj.GetHash(config.GetVideoFileNamingAlgorithm())
|
||||||
vttPath := builder.GetSpriteVTTURL(objHash)
|
vttPath := builder.GetSpriteVTTURL(objHash)
|
||||||
spritePath := builder.GetSpriteURL(objHash)
|
spritePath := builder.GetSpriteURL(objHash)
|
||||||
chaptersVttPath := builder.GetChaptersVTTURL()
|
|
||||||
funscriptPath := builder.GetFunscriptURL()
|
funscriptPath := builder.GetFunscriptURL()
|
||||||
captionBasePath := builder.GetCaptionURL()
|
captionBasePath := builder.GetCaptionURL()
|
||||||
interactiveHeatmap := builder.GetInteractiveHeatmapURL()
|
interactiveHeatmap := builder.GetInteractiveHeatmapURL()
|
||||||
|
|
@ -156,7 +115,6 @@ func (r *sceneResolver) Paths(ctx context.Context, obj *models.Scene) (*ScenePat
|
||||||
Stream: &streamPath,
|
Stream: &streamPath,
|
||||||
Webp: &webpPath,
|
Webp: &webpPath,
|
||||||
Vtt: &vttPath,
|
Vtt: &vttPath,
|
||||||
ChaptersVtt: &chaptersVttPath,
|
|
||||||
Sprite: &spritePath,
|
Sprite: &spritePath,
|
||||||
Funscript: &funscriptPath,
|
Funscript: &funscriptPath,
|
||||||
InteractiveHeatmap: &interactiveHeatmap,
|
InteractiveHeatmap: &interactiveHeatmap,
|
||||||
|
|
@ -285,30 +243,6 @@ func (r *sceneResolver) StashIds(ctx context.Context, obj *models.Scene) (ret []
|
||||||
return stashIDsSliceToPtrSlice(obj.StashIDs.List()), nil
|
return stashIDsSliceToPtrSlice(obj.StashIDs.List()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *sceneResolver) Phash(ctx context.Context, obj *models.Scene) (*string, error) {
|
|
||||||
f, err := r.getPrimaryFile(ctx, obj)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if f == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
val := f.Fingerprints.Get(models.FingerprintTypePhash)
|
|
||||||
if val == nil {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
phash, _ := val.(int64)
|
|
||||||
|
|
||||||
if phash != 0 {
|
|
||||||
hexval := utils.PhashToString(phash)
|
|
||||||
return &hexval, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *sceneResolver) SceneStreams(ctx context.Context, obj *models.Scene) ([]*manager.SceneStreamEndpoint, error) {
|
func (r *sceneResolver) SceneStreams(ctx context.Context, obj *models.Scene) ([]*manager.SceneStreamEndpoint, error) {
|
||||||
// load the primary file into the scene
|
// load the primary file into the scene
|
||||||
_, err := r.getPrimaryFile(ctx, obj)
|
_, err := r.getPrimaryFile(ctx, obj)
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,6 @@ import (
|
||||||
"github.com/stashapp/stash/internal/api/loaders"
|
"github.com/stashapp/stash/internal/api/loaders"
|
||||||
"github.com/stashapp/stash/internal/api/urlbuilders"
|
"github.com/stashapp/stash/internal/api/urlbuilders"
|
||||||
"github.com/stashapp/stash/pkg/gallery"
|
"github.com/stashapp/stash/pkg/gallery"
|
||||||
"github.com/stashapp/stash/pkg/hash/md5"
|
|
||||||
"github.com/stashapp/stash/pkg/image"
|
"github.com/stashapp/stash/pkg/image"
|
||||||
"github.com/stashapp/stash/pkg/models"
|
"github.com/stashapp/stash/pkg/models"
|
||||||
"github.com/stashapp/stash/pkg/movie"
|
"github.com/stashapp/stash/pkg/movie"
|
||||||
|
|
@ -14,11 +13,6 @@ import (
|
||||||
"github.com/stashapp/stash/pkg/scene"
|
"github.com/stashapp/stash/pkg/scene"
|
||||||
)
|
)
|
||||||
|
|
||||||
func (r *studioResolver) Checksum(ctx context.Context, obj *models.Studio) (string, error) {
|
|
||||||
// generate checksum from studio name
|
|
||||||
return md5.FromString(obj.Name), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *studioResolver) ImagePath(ctx context.Context, obj *models.Studio) (*string, error) {
|
func (r *studioResolver) ImagePath(ctx context.Context, obj *models.Studio) (*string, error) {
|
||||||
var hasImage bool
|
var hasImage bool
|
||||||
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
|
if err := r.withReadTxn(ctx, func(ctx context.Context) error {
|
||||||
|
|
@ -132,14 +126,6 @@ func (r *studioResolver) StashIds(ctx context.Context, obj *models.Studio) ([]*m
|
||||||
return stashIDsSliceToPtrSlice(obj.StashIDs.List()), nil
|
return stashIDsSliceToPtrSlice(obj.StashIDs.List()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *studioResolver) Rating(ctx context.Context, obj *models.Studio) (*int, error) {
|
|
||||||
if obj.Rating != nil {
|
|
||||||
rating := models.Rating100To5(*obj.Rating)
|
|
||||||
return &rating, nil
|
|
||||||
}
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *studioResolver) Rating100(ctx context.Context, obj *models.Studio) (*int, error) {
|
func (r *studioResolver) Rating100(ctx context.Context, obj *models.Studio) (*int, error) {
|
||||||
return obj.Rating, nil
|
return obj.Rating, nil
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -319,20 +319,6 @@ func (r *mutationResolver) ConfigureGeneral(ctx context.Context, input ConfigGen
|
||||||
initCustomPerformerImages(*input.CustomPerformerImageLocation)
|
initCustomPerformerImages(*input.CustomPerformerImageLocation)
|
||||||
}
|
}
|
||||||
|
|
||||||
if input.ScraperUserAgent != nil {
|
|
||||||
c.Set(config.ScraperUserAgent, input.ScraperUserAgent)
|
|
||||||
refreshScraperCache = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.ScraperCDPPath != nil {
|
|
||||||
c.Set(config.ScraperCDPPath, input.ScraperCDPPath)
|
|
||||||
refreshScraperCache = true
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.ScraperCertCheck != nil {
|
|
||||||
c.Set(config.ScraperCertCheck, input.ScraperCertCheck)
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.StashBoxes != nil {
|
if input.StashBoxes != nil {
|
||||||
if err := c.ValidateStashBoxes(input.StashBoxes); err != nil {
|
if err := c.ValidateStashBoxes(input.StashBoxes); err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
|
|
@ -424,11 +410,6 @@ func (r *mutationResolver) ConfigureInterface(ctx context.Context, input ConfigI
|
||||||
c.Set(config.Language, *input.Language)
|
c.Set(config.Language, *input.Language)
|
||||||
}
|
}
|
||||||
|
|
||||||
// deprecated field
|
|
||||||
if input.SlideshowDelay != nil {
|
|
||||||
c.Set(config.ImageLightboxSlideshowDelay, *input.SlideshowDelay)
|
|
||||||
}
|
|
||||||
|
|
||||||
if input.ImageLightbox != nil {
|
if input.ImageLightbox != nil {
|
||||||
options := input.ImageLightbox
|
options := input.ImageLightbox
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,7 @@ func (r *mutationResolver) GalleryCreate(ctx context.Context, input GalleryCreat
|
||||||
|
|
||||||
newGallery.Title = input.Title
|
newGallery.Title = input.Title
|
||||||
newGallery.Details = translator.string(input.Details)
|
newGallery.Details = translator.string(input.Details)
|
||||||
newGallery.Rating = translator.ratingConversion(input.Rating, input.Rating100)
|
newGallery.Rating = input.Rating100
|
||||||
|
|
||||||
var err error
|
var err error
|
||||||
|
|
||||||
|
|
@ -183,7 +183,7 @@ func (r *mutationResolver) galleryUpdate(ctx context.Context, input models.Galle
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedGallery.Details = translator.optionalString(input.Details, "details")
|
updatedGallery.Details = translator.optionalString(input.Details, "details")
|
||||||
updatedGallery.Rating = translator.optionalRatingConversion(input.Rating, input.Rating100)
|
updatedGallery.Rating = translator.optionalInt(input.Rating100, "rating100")
|
||||||
updatedGallery.Organized = translator.optionalBool(input.Organized, "organized")
|
updatedGallery.Organized = translator.optionalBool(input.Organized, "organized")
|
||||||
|
|
||||||
updatedGallery.Date, err = translator.optionalDate(input.Date, "date")
|
updatedGallery.Date, err = translator.optionalDate(input.Date, "date")
|
||||||
|
|
@ -258,7 +258,7 @@ func (r *mutationResolver) BulkGalleryUpdate(ctx context.Context, input BulkGall
|
||||||
updatedGallery := models.NewGalleryPartial()
|
updatedGallery := models.NewGalleryPartial()
|
||||||
|
|
||||||
updatedGallery.Details = translator.optionalString(input.Details, "details")
|
updatedGallery.Details = translator.optionalString(input.Details, "details")
|
||||||
updatedGallery.Rating = translator.optionalRatingConversion(input.Rating, input.Rating100)
|
updatedGallery.Rating = translator.optionalInt(input.Rating100, "rating100")
|
||||||
updatedGallery.Organized = translator.optionalBool(input.Organized, "organized")
|
updatedGallery.Organized = translator.optionalBool(input.Organized, "organized")
|
||||||
updatedGallery.URLs = translator.optionalURLsBulk(input.Urls, input.URL)
|
updatedGallery.URLs = translator.optionalURLsBulk(input.Urls, input.URL)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ func (r *mutationResolver) imageUpdate(ctx context.Context, input ImageUpdateInp
|
||||||
updatedImage := models.NewImagePartial()
|
updatedImage := models.NewImagePartial()
|
||||||
|
|
||||||
updatedImage.Title = translator.optionalString(input.Title, "title")
|
updatedImage.Title = translator.optionalString(input.Title, "title")
|
||||||
updatedImage.Rating = translator.optionalRatingConversion(input.Rating, input.Rating100)
|
updatedImage.Rating = translator.optionalInt(input.Rating100, "rating100")
|
||||||
updatedImage.Organized = translator.optionalBool(input.Organized, "organized")
|
updatedImage.Organized = translator.optionalBool(input.Organized, "organized")
|
||||||
|
|
||||||
updatedImage.Date, err = translator.optionalDate(input.Date, "date")
|
updatedImage.Date, err = translator.optionalDate(input.Date, "date")
|
||||||
|
|
@ -203,7 +203,7 @@ func (r *mutationResolver) BulkImageUpdate(ctx context.Context, input BulkImageU
|
||||||
updatedImage := models.NewImagePartial()
|
updatedImage := models.NewImagePartial()
|
||||||
|
|
||||||
updatedImage.Title = translator.optionalString(input.Title, "title")
|
updatedImage.Title = translator.optionalString(input.Title, "title")
|
||||||
updatedImage.Rating = translator.optionalRatingConversion(input.Rating, input.Rating100)
|
updatedImage.Rating = translator.optionalInt(input.Rating100, "rating100")
|
||||||
updatedImage.Organized = translator.optionalBool(input.Organized, "organized")
|
updatedImage.Organized = translator.optionalBool(input.Organized, "organized")
|
||||||
|
|
||||||
updatedImage.Date, err = translator.optionalDate(input.Date, "date")
|
updatedImage.Date, err = translator.optionalDate(input.Date, "date")
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,7 @@ func (r *mutationResolver) MovieCreate(ctx context.Context, input MovieCreateInp
|
||||||
newMovie.Name = input.Name
|
newMovie.Name = input.Name
|
||||||
newMovie.Aliases = translator.string(input.Aliases)
|
newMovie.Aliases = translator.string(input.Aliases)
|
||||||
newMovie.Duration = input.Duration
|
newMovie.Duration = input.Duration
|
||||||
newMovie.Rating = translator.ratingConversion(input.Rating, input.Rating100)
|
newMovie.Rating = input.Rating100
|
||||||
newMovie.Director = translator.string(input.Director)
|
newMovie.Director = translator.string(input.Director)
|
||||||
newMovie.Synopsis = translator.string(input.Synopsis)
|
newMovie.Synopsis = translator.string(input.Synopsis)
|
||||||
newMovie.URL = translator.string(input.URL)
|
newMovie.URL = translator.string(input.URL)
|
||||||
|
|
@ -122,7 +122,7 @@ func (r *mutationResolver) MovieUpdate(ctx context.Context, input MovieUpdateInp
|
||||||
updatedMovie.Name = translator.optionalString(input.Name, "name")
|
updatedMovie.Name = translator.optionalString(input.Name, "name")
|
||||||
updatedMovie.Aliases = translator.optionalString(input.Aliases, "aliases")
|
updatedMovie.Aliases = translator.optionalString(input.Aliases, "aliases")
|
||||||
updatedMovie.Duration = translator.optionalInt(input.Duration, "duration")
|
updatedMovie.Duration = translator.optionalInt(input.Duration, "duration")
|
||||||
updatedMovie.Rating = translator.optionalRatingConversion(input.Rating, input.Rating100)
|
updatedMovie.Rating = translator.optionalInt(input.Rating100, "rating100")
|
||||||
updatedMovie.Director = translator.optionalString(input.Director, "director")
|
updatedMovie.Director = translator.optionalString(input.Director, "director")
|
||||||
updatedMovie.Synopsis = translator.optionalString(input.Synopsis, "synopsis")
|
updatedMovie.Synopsis = translator.optionalString(input.Synopsis, "synopsis")
|
||||||
updatedMovie.URL = translator.optionalString(input.URL, "url")
|
updatedMovie.URL = translator.optionalString(input.URL, "url")
|
||||||
|
|
@ -198,7 +198,7 @@ func (r *mutationResolver) BulkMovieUpdate(ctx context.Context, input BulkMovieU
|
||||||
// Populate movie from the input
|
// Populate movie from the input
|
||||||
updatedMovie := models.NewMoviePartial()
|
updatedMovie := models.NewMoviePartial()
|
||||||
|
|
||||||
updatedMovie.Rating = translator.optionalRatingConversion(input.Rating, input.Rating100)
|
updatedMovie.Rating = translator.optionalInt(input.Rating100, "rating100")
|
||||||
updatedMovie.Director = translator.optionalString(input.Director, "director")
|
updatedMovie.Director = translator.optionalString(input.Director, "director")
|
||||||
|
|
||||||
updatedMovie.StudioID, err = translator.optionalIntFromString(input.StudioID, "studio_id")
|
updatedMovie.StudioID, err = translator.optionalIntFromString(input.StudioID, "studio_id")
|
||||||
|
|
|
||||||
|
|
@ -49,9 +49,10 @@ func (r *mutationResolver) PerformerCreate(ctx context.Context, input models.Per
|
||||||
newPerformer.Twitter = translator.string(input.Twitter)
|
newPerformer.Twitter = translator.string(input.Twitter)
|
||||||
newPerformer.Instagram = translator.string(input.Instagram)
|
newPerformer.Instagram = translator.string(input.Instagram)
|
||||||
newPerformer.Favorite = translator.bool(input.Favorite)
|
newPerformer.Favorite = translator.bool(input.Favorite)
|
||||||
newPerformer.Rating = translator.ratingConversion(input.Rating, input.Rating100)
|
newPerformer.Rating = input.Rating100
|
||||||
newPerformer.Details = translator.string(input.Details)
|
newPerformer.Details = translator.string(input.Details)
|
||||||
newPerformer.HairColor = translator.string(input.HairColor)
|
newPerformer.HairColor = translator.string(input.HairColor)
|
||||||
|
newPerformer.Height = input.HeightCm
|
||||||
newPerformer.Weight = input.Weight
|
newPerformer.Weight = input.Weight
|
||||||
newPerformer.IgnoreAutoTag = translator.bool(input.IgnoreAutoTag)
|
newPerformer.IgnoreAutoTag = translator.bool(input.IgnoreAutoTag)
|
||||||
newPerformer.StashIDs = models.NewRelatedStashIDs(input.StashIds)
|
newPerformer.StashIDs = models.NewRelatedStashIDs(input.StashIds)
|
||||||
|
|
@ -67,21 +68,9 @@ func (r *mutationResolver) PerformerCreate(ctx context.Context, input models.Per
|
||||||
return nil, fmt.Errorf("converting death date: %w", err)
|
return nil, fmt.Errorf("converting death date: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefer height_cm over height
|
|
||||||
if input.HeightCm != nil {
|
|
||||||
newPerformer.Height = input.HeightCm
|
|
||||||
} else {
|
|
||||||
newPerformer.Height, err = translator.intPtrFromString(input.Height)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("converting height: %w", err)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// prefer alias_list over aliases
|
// prefer alias_list over aliases
|
||||||
if input.AliasList != nil {
|
if input.AliasList != nil {
|
||||||
newPerformer.Aliases = models.NewRelatedStrings(input.AliasList)
|
newPerformer.Aliases = models.NewRelatedStrings(input.AliasList)
|
||||||
} else if input.Aliases != nil {
|
|
||||||
newPerformer.Aliases = models.NewRelatedStrings(stringslice.FromString(*input.Aliases, ","))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
newPerformer.TagIDs, err = translator.relatedIds(input.TagIds)
|
newPerformer.TagIDs, err = translator.relatedIds(input.TagIds)
|
||||||
|
|
@ -163,7 +152,7 @@ func (r *mutationResolver) PerformerUpdate(ctx context.Context, input models.Per
|
||||||
updatedPerformer.Twitter = translator.optionalString(input.Twitter, "twitter")
|
updatedPerformer.Twitter = translator.optionalString(input.Twitter, "twitter")
|
||||||
updatedPerformer.Instagram = translator.optionalString(input.Instagram, "instagram")
|
updatedPerformer.Instagram = translator.optionalString(input.Instagram, "instagram")
|
||||||
updatedPerformer.Favorite = translator.optionalBool(input.Favorite, "favorite")
|
updatedPerformer.Favorite = translator.optionalBool(input.Favorite, "favorite")
|
||||||
updatedPerformer.Rating = translator.optionalRatingConversion(input.Rating, input.Rating100)
|
updatedPerformer.Rating = translator.optionalInt(input.Rating100, "rating100")
|
||||||
updatedPerformer.Details = translator.optionalString(input.Details, "details")
|
updatedPerformer.Details = translator.optionalString(input.Details, "details")
|
||||||
updatedPerformer.HairColor = translator.optionalString(input.HairColor, "hair_color")
|
updatedPerformer.HairColor = translator.optionalString(input.HairColor, "hair_color")
|
||||||
updatedPerformer.Weight = translator.optionalInt(input.Weight, "weight")
|
updatedPerformer.Weight = translator.optionalInt(input.Weight, "weight")
|
||||||
|
|
@ -182,22 +171,11 @@ func (r *mutationResolver) PerformerUpdate(ctx context.Context, input models.Per
|
||||||
// prefer height_cm over height
|
// prefer height_cm over height
|
||||||
if translator.hasField("height_cm") {
|
if translator.hasField("height_cm") {
|
||||||
updatedPerformer.Height = translator.optionalInt(input.HeightCm, "height_cm")
|
updatedPerformer.Height = translator.optionalInt(input.HeightCm, "height_cm")
|
||||||
} else if translator.hasField("height") {
|
|
||||||
updatedPerformer.Height, err = translator.optionalIntFromString(input.Height, "height")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("converting height: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefer alias_list over aliases
|
// prefer alias_list over aliases
|
||||||
if translator.hasField("alias_list") {
|
if translator.hasField("alias_list") {
|
||||||
updatedPerformer.Aliases = translator.updateStrings(input.AliasList, "alias_list")
|
updatedPerformer.Aliases = translator.updateStrings(input.AliasList, "alias_list")
|
||||||
} else if translator.hasField("aliases") {
|
|
||||||
var aliasList []string
|
|
||||||
if input.Aliases != nil {
|
|
||||||
aliasList = stringslice.FromString(*input.Aliases, ",")
|
|
||||||
}
|
|
||||||
updatedPerformer.Aliases = translator.updateStrings(aliasList, "aliases")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedPerformer.TagIDs, err = translator.updateIds(input.TagIds, "tag_ids")
|
updatedPerformer.TagIDs, err = translator.updateIds(input.TagIds, "tag_ids")
|
||||||
|
|
@ -286,7 +264,7 @@ func (r *mutationResolver) BulkPerformerUpdate(ctx context.Context, input BulkPe
|
||||||
updatedPerformer.Twitter = translator.optionalString(input.Twitter, "twitter")
|
updatedPerformer.Twitter = translator.optionalString(input.Twitter, "twitter")
|
||||||
updatedPerformer.Instagram = translator.optionalString(input.Instagram, "instagram")
|
updatedPerformer.Instagram = translator.optionalString(input.Instagram, "instagram")
|
||||||
updatedPerformer.Favorite = translator.optionalBool(input.Favorite, "favorite")
|
updatedPerformer.Favorite = translator.optionalBool(input.Favorite, "favorite")
|
||||||
updatedPerformer.Rating = translator.optionalRatingConversion(input.Rating, input.Rating100)
|
updatedPerformer.Rating = translator.optionalInt(input.Rating100, "rating100")
|
||||||
updatedPerformer.Details = translator.optionalString(input.Details, "details")
|
updatedPerformer.Details = translator.optionalString(input.Details, "details")
|
||||||
updatedPerformer.HairColor = translator.optionalString(input.HairColor, "hair_color")
|
updatedPerformer.HairColor = translator.optionalString(input.HairColor, "hair_color")
|
||||||
updatedPerformer.Weight = translator.optionalInt(input.Weight, "weight")
|
updatedPerformer.Weight = translator.optionalInt(input.Weight, "weight")
|
||||||
|
|
@ -304,22 +282,11 @@ func (r *mutationResolver) BulkPerformerUpdate(ctx context.Context, input BulkPe
|
||||||
// prefer height_cm over height
|
// prefer height_cm over height
|
||||||
if translator.hasField("height_cm") {
|
if translator.hasField("height_cm") {
|
||||||
updatedPerformer.Height = translator.optionalInt(input.HeightCm, "height_cm")
|
updatedPerformer.Height = translator.optionalInt(input.HeightCm, "height_cm")
|
||||||
} else if translator.hasField("height") {
|
|
||||||
updatedPerformer.Height, err = translator.optionalIntFromString(input.Height, "height")
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("converting height: %w", err)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// prefer alias_list over aliases
|
// prefer alias_list over aliases
|
||||||
if translator.hasField("alias_list") {
|
if translator.hasField("alias_list") {
|
||||||
updatedPerformer.Aliases = translator.updateStringsBulk(input.AliasList, "alias_list")
|
updatedPerformer.Aliases = translator.updateStringsBulk(input.AliasList, "alias_list")
|
||||||
} else if translator.hasField("aliases") {
|
|
||||||
var aliasList []string
|
|
||||||
if input.Aliases != nil {
|
|
||||||
aliasList = stringslice.FromString(*input.Aliases, ",")
|
|
||||||
}
|
|
||||||
updatedPerformer.Aliases = translator.updateStrings(aliasList, "aliases")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updatedPerformer.TagIDs, err = translator.updateIdsBulk(input.TagIds, "tag_ids")
|
updatedPerformer.TagIDs, err = translator.updateIdsBulk(input.TagIds, "tag_ids")
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ func (r *mutationResolver) SceneCreate(ctx context.Context, input models.SceneCr
|
||||||
newScene.Code = translator.string(input.Code)
|
newScene.Code = translator.string(input.Code)
|
||||||
newScene.Details = translator.string(input.Details)
|
newScene.Details = translator.string(input.Details)
|
||||||
newScene.Director = translator.string(input.Director)
|
newScene.Director = translator.string(input.Director)
|
||||||
newScene.Rating = translator.ratingConversion(input.Rating, input.Rating100)
|
newScene.Rating = input.Rating100
|
||||||
newScene.Organized = translator.bool(input.Organized)
|
newScene.Organized = translator.bool(input.Organized)
|
||||||
newScene.StashIDs = models.NewRelatedStashIDs(input.StashIds)
|
newScene.StashIDs = models.NewRelatedStashIDs(input.StashIds)
|
||||||
|
|
||||||
|
|
@ -168,7 +168,7 @@ func scenePartialFromInput(input models.SceneUpdateInput, translator changesetTr
|
||||||
updatedScene.Code = translator.optionalString(input.Code, "code")
|
updatedScene.Code = translator.optionalString(input.Code, "code")
|
||||||
updatedScene.Details = translator.optionalString(input.Details, "details")
|
updatedScene.Details = translator.optionalString(input.Details, "details")
|
||||||
updatedScene.Director = translator.optionalString(input.Director, "director")
|
updatedScene.Director = translator.optionalString(input.Director, "director")
|
||||||
updatedScene.Rating = translator.optionalRatingConversion(input.Rating, input.Rating100)
|
updatedScene.Rating = translator.optionalInt(input.Rating100, "rating100")
|
||||||
updatedScene.OCounter = translator.optionalInt(input.OCounter, "o_counter")
|
updatedScene.OCounter = translator.optionalInt(input.OCounter, "o_counter")
|
||||||
updatedScene.PlayCount = translator.optionalInt(input.PlayCount, "play_count")
|
updatedScene.PlayCount = translator.optionalInt(input.PlayCount, "play_count")
|
||||||
updatedScene.PlayDuration = translator.optionalFloat64(input.PlayDuration, "play_duration")
|
updatedScene.PlayDuration = translator.optionalFloat64(input.PlayDuration, "play_duration")
|
||||||
|
|
@ -321,7 +321,7 @@ func (r *mutationResolver) BulkSceneUpdate(ctx context.Context, input BulkSceneU
|
||||||
updatedScene.Code = translator.optionalString(input.Code, "code")
|
updatedScene.Code = translator.optionalString(input.Code, "code")
|
||||||
updatedScene.Details = translator.optionalString(input.Details, "details")
|
updatedScene.Details = translator.optionalString(input.Details, "details")
|
||||||
updatedScene.Director = translator.optionalString(input.Director, "director")
|
updatedScene.Director = translator.optionalString(input.Director, "director")
|
||||||
updatedScene.Rating = translator.optionalRatingConversion(input.Rating, input.Rating100)
|
updatedScene.Rating = translator.optionalInt(input.Rating100, "rating100")
|
||||||
updatedScene.Organized = translator.optionalBool(input.Organized, "organized")
|
updatedScene.Organized = translator.optionalBool(input.Organized, "organized")
|
||||||
|
|
||||||
updatedScene.Date, err = translator.optionalDate(input.Date, "date")
|
updatedScene.Date, err = translator.optionalDate(input.Date, "date")
|
||||||
|
|
|
||||||
|
|
@ -34,7 +34,7 @@ func (r *mutationResolver) StudioCreate(ctx context.Context, input models.Studio
|
||||||
|
|
||||||
newStudio.Name = input.Name
|
newStudio.Name = input.Name
|
||||||
newStudio.URL = translator.string(input.URL)
|
newStudio.URL = translator.string(input.URL)
|
||||||
newStudio.Rating = translator.ratingConversion(input.Rating, input.Rating100)
|
newStudio.Rating = input.Rating100
|
||||||
newStudio.Details = translator.string(input.Details)
|
newStudio.Details = translator.string(input.Details)
|
||||||
newStudio.IgnoreAutoTag = translator.bool(input.IgnoreAutoTag)
|
newStudio.IgnoreAutoTag = translator.bool(input.IgnoreAutoTag)
|
||||||
newStudio.Aliases = models.NewRelatedStrings(input.Aliases)
|
newStudio.Aliases = models.NewRelatedStrings(input.Aliases)
|
||||||
|
|
@ -108,7 +108,7 @@ func (r *mutationResolver) StudioUpdate(ctx context.Context, input models.Studio
|
||||||
updatedStudio.Name = translator.optionalString(input.Name, "name")
|
updatedStudio.Name = translator.optionalString(input.Name, "name")
|
||||||
updatedStudio.URL = translator.optionalString(input.URL, "url")
|
updatedStudio.URL = translator.optionalString(input.URL, "url")
|
||||||
updatedStudio.Details = translator.optionalString(input.Details, "details")
|
updatedStudio.Details = translator.optionalString(input.Details, "details")
|
||||||
updatedStudio.Rating = translator.optionalRatingConversion(input.Rating, input.Rating100)
|
updatedStudio.Rating = translator.optionalInt(input.Rating100, "rating100")
|
||||||
updatedStudio.IgnoreAutoTag = translator.optionalBool(input.IgnoreAutoTag, "ignore_auto_tag")
|
updatedStudio.IgnoreAutoTag = translator.optionalBool(input.IgnoreAutoTag, "ignore_auto_tag")
|
||||||
updatedStudio.Aliases = translator.updateStrings(input.Aliases, "aliases")
|
updatedStudio.Aliases = translator.updateStrings(input.Aliases, "aliases")
|
||||||
updatedStudio.StashIDs = translator.updateStashIDs(input.StashIds, "stash_ids")
|
updatedStudio.StashIDs = translator.updateStashIDs(input.StashIds, "stash_ids")
|
||||||
|
|
|
||||||
|
|
@ -79,9 +79,6 @@ func makeConfigGeneralResult() *ConfigGeneralResult {
|
||||||
|
|
||||||
customPerformerImageLocation := config.GetCustomPerformerImageLocation()
|
customPerformerImageLocation := config.GetCustomPerformerImageLocation()
|
||||||
|
|
||||||
scraperUserAgent := config.GetScraperUserAgent()
|
|
||||||
scraperCDPPath := config.GetScraperCDPPath()
|
|
||||||
|
|
||||||
return &ConfigGeneralResult{
|
return &ConfigGeneralResult{
|
||||||
Stashes: config.GetStashPaths(),
|
Stashes: config.GetStashPaths(),
|
||||||
DatabasePath: config.GetDatabasePath(),
|
DatabasePath: config.GetDatabasePath(),
|
||||||
|
|
@ -123,9 +120,6 @@ func makeConfigGeneralResult() *ConfigGeneralResult {
|
||||||
Excludes: config.GetExcludes(),
|
Excludes: config.GetExcludes(),
|
||||||
ImageExcludes: config.GetImageExcludes(),
|
ImageExcludes: config.GetImageExcludes(),
|
||||||
CustomPerformerImageLocation: &customPerformerImageLocation,
|
CustomPerformerImageLocation: &customPerformerImageLocation,
|
||||||
ScraperUserAgent: &scraperUserAgent,
|
|
||||||
ScraperCertCheck: config.GetScraperCertCheck(),
|
|
||||||
ScraperCDPPath: &scraperCDPPath,
|
|
||||||
StashBoxes: config.GetStashBoxes(),
|
StashBoxes: config.GetStashBoxes(),
|
||||||
PythonPath: config.GetPythonPath(),
|
PythonPath: config.GetPythonPath(),
|
||||||
TranscodeInputArgs: config.GetTranscodeInputArgs(),
|
TranscodeInputArgs: config.GetTranscodeInputArgs(),
|
||||||
|
|
@ -161,7 +155,6 @@ func makeConfigInterfaceResult() *ConfigInterfaceResult {
|
||||||
scriptOffset := config.GetFunscriptOffset()
|
scriptOffset := config.GetFunscriptOffset()
|
||||||
useStashHostedFunscript := config.GetUseStashHostedFunscript()
|
useStashHostedFunscript := config.GetUseStashHostedFunscript()
|
||||||
imageLightboxOptions := config.GetImageLightboxOptions()
|
imageLightboxOptions := config.GetImageLightboxOptions()
|
||||||
// FIXME - misnamed output field means we have redundant fields
|
|
||||||
disableDropdownCreate := config.GetDisableDropdownCreate()
|
disableDropdownCreate := config.GetDisableDropdownCreate()
|
||||||
|
|
||||||
return &ConfigInterfaceResult{
|
return &ConfigInterfaceResult{
|
||||||
|
|
@ -187,8 +180,6 @@ func makeConfigInterfaceResult() *ConfigInterfaceResult {
|
||||||
|
|
||||||
ImageLightbox: &imageLightboxOptions,
|
ImageLightbox: &imageLightboxOptions,
|
||||||
|
|
||||||
// FIXME - see above
|
|
||||||
DisabledDropdownCreate: disableDropdownCreate,
|
|
||||||
DisableDropdownCreate: disableDropdownCreate,
|
DisableDropdownCreate: disableDropdownCreate,
|
||||||
|
|
||||||
HandyKey: &handyKey,
|
HandyKey: &handyKey,
|
||||||
|
|
|
||||||
|
|
@ -21,70 +21,10 @@ func (r *queryResolver) ScrapeURL(ctx context.Context, url string, ty scraper.Sc
|
||||||
return r.scraperCache().ScrapeURL(ctx, url, ty)
|
return r.scraperCache().ScrapeURL(ctx, url, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
// deprecated
|
|
||||||
func (r *queryResolver) ScrapeFreeonesPerformerList(ctx context.Context, query string) ([]string, error) {
|
|
||||||
content, err := r.scraperCache().ScrapeName(ctx, scraper.FreeonesScraperID, query, scraper.ScrapeContentTypePerformer)
|
|
||||||
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
performers, err := marshalScrapedPerformers(content)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
var ret []string
|
|
||||||
for _, p := range performers {
|
|
||||||
if p.Name != nil {
|
|
||||||
ret = append(ret, *p.Name)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) ListScrapers(ctx context.Context, types []scraper.ScrapeContentType) ([]*scraper.Scraper, error) {
|
func (r *queryResolver) ListScrapers(ctx context.Context, types []scraper.ScrapeContentType) ([]*scraper.Scraper, error) {
|
||||||
return r.scraperCache().ListScrapers(types), nil
|
return r.scraperCache().ListScrapers(types), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) ListPerformerScrapers(ctx context.Context) ([]*scraper.Scraper, error) {
|
|
||||||
return r.scraperCache().ListScrapers([]scraper.ScrapeContentType{scraper.ScrapeContentTypePerformer}), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) ListSceneScrapers(ctx context.Context) ([]*scraper.Scraper, error) {
|
|
||||||
return r.scraperCache().ListScrapers([]scraper.ScrapeContentType{scraper.ScrapeContentTypeScene}), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) ListGalleryScrapers(ctx context.Context) ([]*scraper.Scraper, error) {
|
|
||||||
return r.scraperCache().ListScrapers([]scraper.ScrapeContentType{scraper.ScrapeContentTypeGallery}), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) ListMovieScrapers(ctx context.Context) ([]*scraper.Scraper, error) {
|
|
||||||
return r.scraperCache().ListScrapers([]scraper.ScrapeContentType{scraper.ScrapeContentTypeMovie}), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) ScrapePerformerList(ctx context.Context, scraperID string, query string) ([]*models.ScrapedPerformer, error) {
|
|
||||||
if query == "" {
|
|
||||||
return nil, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
content, err := r.scraperCache().ScrapeName(ctx, scraperID, query, scraper.ScrapeContentTypePerformer)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return marshalScrapedPerformers(content)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) ScrapePerformer(ctx context.Context, scraperID string, scrapedPerformer scraper.ScrapedPerformerInput) (*models.ScrapedPerformer, error) {
|
|
||||||
content, err := r.scraperCache().ScrapeFragment(ctx, scraperID, scraper.Input{Performer: &scrapedPerformer})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return marshalScrapedPerformer(content)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) ScrapePerformerURL(ctx context.Context, url string) (*models.ScrapedPerformer, error) {
|
func (r *queryResolver) ScrapePerformerURL(ctx context.Context, url string) (*models.ScrapedPerformer, error) {
|
||||||
content, err := r.scraperCache().ScrapeURL(ctx, url, scraper.ScrapeContentTypePerformer)
|
content, err := r.scraperCache().ScrapeURL(ctx, url, scraper.ScrapeContentTypePerformer)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -113,29 +53,6 @@ func (r *queryResolver) ScrapeSceneQuery(ctx context.Context, scraperID string,
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) ScrapeScene(ctx context.Context, scraperID string, scene models.SceneUpdateInput) (*scraper.ScrapedScene, error) {
|
|
||||||
id, err := strconv.Atoi(scene.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%w: scene.ID is not an integer: '%s'", ErrInput, scene.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
content, err := r.scraperCache().ScrapeID(ctx, scraperID, id, scraper.ScrapeContentTypeScene)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
ret, err := marshalScrapedScene(content)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
if ret != nil {
|
|
||||||
filterSceneTags([]*scraper.ScrapedScene{ret})
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// filterSceneTags removes tags matching excluded tag patterns from the provided scraped scenes
|
// filterSceneTags removes tags matching excluded tag patterns from the provided scraped scenes
|
||||||
func filterSceneTags(scenes []*scraper.ScrapedScene) {
|
func filterSceneTags(scenes []*scraper.ScrapedScene) {
|
||||||
excludePatterns := manager.GetInstance().Config.GetScraperExcludeTagPatterns()
|
excludePatterns := manager.GetInstance().Config.GetScraperExcludeTagPatterns()
|
||||||
|
|
@ -199,20 +116,6 @@ func (r *queryResolver) ScrapeSceneURL(ctx context.Context, url string) (*scrape
|
||||||
return ret, nil
|
return ret, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *queryResolver) ScrapeGallery(ctx context.Context, scraperID string, gallery models.GalleryUpdateInput) (*scraper.ScrapedGallery, error) {
|
|
||||||
id, err := strconv.Atoi(gallery.ID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, fmt.Errorf("%w: gallery id is not an integer: '%s'", ErrInput, gallery.ID)
|
|
||||||
}
|
|
||||||
|
|
||||||
content, err := r.scraperCache().ScrapeID(ctx, scraperID, id, scraper.ScrapeContentTypeGallery)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
|
|
||||||
return marshalScrapedGallery(content)
|
|
||||||
}
|
|
||||||
|
|
||||||
func (r *queryResolver) ScrapeGalleryURL(ctx context.Context, url string) (*scraper.ScrapedGallery, error) {
|
func (r *queryResolver) ScrapeGalleryURL(ctx context.Context, url string) (*scraper.ScrapedGallery, error) {
|
||||||
content, err := r.scraperCache().ScrapeURL(ctx, url, scraper.ScrapeContentTypeGallery)
|
content, err := r.scraperCache().ScrapeURL(ctx, url, scraper.ScrapeContentTypeGallery)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
@ -241,6 +144,8 @@ func (r *queryResolver) getStashBoxClient(index int) (*stashbox.Client, error) {
|
||||||
return stashbox.NewClient(*boxes[index], r.stashboxRepository()), nil
|
return stashbox.NewClient(*boxes[index], r.stashboxRepository()), nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// FIXME - in the following resolvers, we're processing the deprecated field and not processing the new endpoint input
|
||||||
|
|
||||||
func (r *queryResolver) ScrapeSingleScene(ctx context.Context, source scraper.Source, input ScrapeSingleSceneInput) ([]*scraper.ScrapedScene, error) {
|
func (r *queryResolver) ScrapeSingleScene(ctx context.Context, source scraper.Source, input ScrapeSingleSceneInput) ([]*scraper.ScrapedScene, error) {
|
||||||
var ret []*scraper.ScrapedScene
|
var ret []*scraper.ScrapedScene
|
||||||
|
|
||||||
|
|
@ -378,6 +283,7 @@ func (r *queryResolver) ScrapeSinglePerformer(ctx context.Context, source scrape
|
||||||
}
|
}
|
||||||
|
|
||||||
return nil, ErrNotImplemented
|
return nil, ErrNotImplemented
|
||||||
|
// FIXME - we're relying on a deprecated field and not processing the endpoint input
|
||||||
} else if source.StashBoxIndex != nil {
|
} else if source.StashBoxIndex != nil {
|
||||||
client, err := r.getStashBoxClient(*source.StashBoxIndex)
|
client, err := r.getStashBoxClient(*source.StashBoxIndex)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
||||||
|
|
@ -1,21 +1,9 @@
|
||||||
package api
|
package api
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"math"
|
|
||||||
|
|
||||||
"github.com/stashapp/stash/pkg/models"
|
"github.com/stashapp/stash/pkg/models"
|
||||||
)
|
)
|
||||||
|
|
||||||
// #1572 - Inf and NaN values cause the JSON marshaller to fail
|
|
||||||
// Return nil for these values
|
|
||||||
func handleFloat64(v float64) *float64 {
|
|
||||||
if math.IsInf(v, 0) || math.IsNaN(v) {
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
|
|
||||||
return &v
|
|
||||||
}
|
|
||||||
|
|
||||||
func stashIDsSliceToPtrSlice(v []models.StashID) []*models.StashID {
|
func stashIDsSliceToPtrSlice(v []models.StashID) []*models.StashID {
|
||||||
ret := make([]*models.StashID, len(v))
|
ret := make([]*models.StashID, len(v))
|
||||||
for i, vv := range v {
|
for i, vv := range v {
|
||||||
|
|
|
||||||
|
|
@ -57,10 +57,6 @@ func (b SceneURLBuilder) GetScreenshotURL() string {
|
||||||
return b.BaseURL + "/scene/" + b.SceneID + "/screenshot?t=" + b.UpdatedAt
|
return b.BaseURL + "/scene/" + b.SceneID + "/screenshot?t=" + b.UpdatedAt
|
||||||
}
|
}
|
||||||
|
|
||||||
func (b SceneURLBuilder) GetChaptersVTTURL() string {
|
|
||||||
return b.BaseURL + "/scene/" + b.SceneID + "/vtt/chapter"
|
|
||||||
}
|
|
||||||
|
|
||||||
func (b SceneURLBuilder) GetFunscriptURL() string {
|
func (b SceneURLBuilder) GetFunscriptURL() string {
|
||||||
return b.BaseURL + "/scene/" + b.SceneID + "/funscript"
|
return b.BaseURL + "/scene/" + b.SceneID + "/funscript"
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -717,9 +717,9 @@ func (me *contentDirectoryService) getRatingScenes(paths []string, host string)
|
||||||
}
|
}
|
||||||
|
|
||||||
sceneFilter := &models.SceneFilterType{
|
sceneFilter := &models.SceneFilterType{
|
||||||
Rating: &models.IntCriterionInput{
|
Rating100: &models.IntCriterionInput{
|
||||||
Modifier: models.CriterionModifierEquals,
|
Modifier: models.CriterionModifierEquals,
|
||||||
Value: r,
|
Value: models.Rating5To100(r),
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
package config
|
package config
|
||||||
|
|
||||||
type ScanMetadataOptions struct {
|
type ScanMetadataOptions struct {
|
||||||
// Set name, date, details from metadata (if present)
|
|
||||||
// Deprecated: not implemented
|
|
||||||
UseFileMetadata bool `json:"useFileMetadata"`
|
|
||||||
// Strip file extension from title
|
|
||||||
// Deprecated: not implemented
|
|
||||||
StripFileExtension bool `json:"stripFileExtension"`
|
|
||||||
// Generate scene covers during scan
|
// Generate scene covers during scan
|
||||||
ScanGenerateCovers bool `json:"scanGenerateCovers"`
|
ScanGenerateCovers bool `json:"scanGenerateCovers"`
|
||||||
// Generate previews during scan
|
// Generate previews during scan
|
||||||
|
|
|
||||||
|
|
@ -17,8 +17,6 @@ type GalleryFilterType struct {
|
||||||
IsMissing *string `json:"is_missing"`
|
IsMissing *string `json:"is_missing"`
|
||||||
// Filter to include/exclude galleries that were created from zip
|
// Filter to include/exclude galleries that were created from zip
|
||||||
IsZip *bool `json:"is_zip"`
|
IsZip *bool `json:"is_zip"`
|
||||||
// Filter by rating expressed as 1-5
|
|
||||||
Rating *IntCriterionInput `json:"rating"`
|
|
||||||
// Filter by rating expressed as 1-100
|
// Filter by rating expressed as 1-100
|
||||||
Rating100 *IntCriterionInput `json:"rating100"`
|
Rating100 *IntCriterionInput `json:"rating100"`
|
||||||
// Filter by organized
|
// Filter by organized
|
||||||
|
|
@ -62,7 +60,6 @@ type GalleryUpdateInput struct {
|
||||||
Urls []string `json:"urls"`
|
Urls []string `json:"urls"`
|
||||||
Date *string `json:"date"`
|
Date *string `json:"date"`
|
||||||
Details *string `json:"details"`
|
Details *string `json:"details"`
|
||||||
Rating *int `json:"rating"`
|
|
||||||
Rating100 *int `json:"rating100"`
|
Rating100 *int `json:"rating100"`
|
||||||
Organized *bool `json:"organized"`
|
Organized *bool `json:"organized"`
|
||||||
SceneIds []string `json:"scene_ids"`
|
SceneIds []string `json:"scene_ids"`
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ type ImageFilterType struct {
|
||||||
Path *StringCriterionInput `json:"path"`
|
Path *StringCriterionInput `json:"path"`
|
||||||
// Filter by file count
|
// Filter by file count
|
||||||
FileCount *IntCriterionInput `json:"file_count"`
|
FileCount *IntCriterionInput `json:"file_count"`
|
||||||
// Filter by rating expressed as 1-5
|
|
||||||
Rating *IntCriterionInput `json:"rating"`
|
|
||||||
// Filter by rating expressed as 1-100
|
// Filter by rating expressed as 1-100
|
||||||
Rating100 *IntCriterionInput `json:"rating100"`
|
Rating100 *IntCriterionInput `json:"rating100"`
|
||||||
// Filter by date
|
// Filter by date
|
||||||
|
|
|
||||||
|
|
@ -221,12 +221,6 @@ func (s ScenePartial) UpdateInput(id int) SceneUpdateInput {
|
||||||
StashIds: stashIDs,
|
StashIds: stashIDs,
|
||||||
}
|
}
|
||||||
|
|
||||||
if s.Rating.Set && !s.Rating.Null {
|
|
||||||
// convert to 1-100 scale
|
|
||||||
rating := Rating100To5(s.Rating.Value)
|
|
||||||
ret.Rating = &rating
|
|
||||||
}
|
|
||||||
|
|
||||||
return ret
|
return ret
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -18,7 +18,6 @@ func TestScenePartial_UpdateInput(t *testing.T) {
|
||||||
director = "director"
|
director = "director"
|
||||||
url = "url"
|
url = "url"
|
||||||
date = "2001-02-03"
|
date = "2001-02-03"
|
||||||
ratingLegacy = 4
|
|
||||||
rating100 = 80
|
rating100 = 80
|
||||||
organized = true
|
organized = true
|
||||||
studioID = 2
|
studioID = 2
|
||||||
|
|
@ -58,7 +57,6 @@ func TestScenePartial_UpdateInput(t *testing.T) {
|
||||||
Director: &director,
|
Director: &director,
|
||||||
Urls: []string{url},
|
Urls: []string{url},
|
||||||
Date: &date,
|
Date: &date,
|
||||||
Rating: &ratingLegacy,
|
|
||||||
Rating100: &rating100,
|
Rating100: &rating100,
|
||||||
Organized: &organized,
|
Organized: &organized,
|
||||||
StudioID: &studioIDStr,
|
StudioID: &studioIDStr,
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,6 @@ type MovieFilterType struct {
|
||||||
Synopsis *StringCriterionInput `json:"synopsis"`
|
Synopsis *StringCriterionInput `json:"synopsis"`
|
||||||
// Filter by duration (in seconds)
|
// Filter by duration (in seconds)
|
||||||
Duration *IntCriterionInput `json:"duration"`
|
Duration *IntCriterionInput `json:"duration"`
|
||||||
// Filter by rating expressed as 1-5
|
|
||||||
Rating *IntCriterionInput `json:"rating"`
|
|
||||||
// Filter by rating expressed as 1-100
|
// Filter by rating expressed as 1-100
|
||||||
Rating100 *IntCriterionInput `json:"rating100"`
|
Rating100 *IntCriterionInput `json:"rating100"`
|
||||||
// Filter to only include movies with this studio
|
// Filter to only include movies with this studio
|
||||||
|
|
|
||||||
|
|
@ -165,8 +165,6 @@ type PerformerFilterType struct {
|
||||||
StashID *StringCriterionInput `json:"stash_id"`
|
StashID *StringCriterionInput `json:"stash_id"`
|
||||||
// Filter by StashID Endpoint
|
// Filter by StashID Endpoint
|
||||||
StashIDEndpoint *StashIDCriterionInput `json:"stash_id_endpoint"`
|
StashIDEndpoint *StashIDCriterionInput `json:"stash_id_endpoint"`
|
||||||
// Filter by rating expressed as 1-5
|
|
||||||
Rating *IntCriterionInput `json:"rating"`
|
|
||||||
// Filter by rating expressed as 1-100
|
// Filter by rating expressed as 1-100
|
||||||
Rating100 *IntCriterionInput `json:"rating100"`
|
Rating100 *IntCriterionInput `json:"rating100"`
|
||||||
// Filter by url
|
// Filter by url
|
||||||
|
|
@ -220,7 +218,6 @@ type PerformerCreateInput struct {
|
||||||
// This should be a URL or a base64 encoded data URL
|
// This should be a URL or a base64 encoded data URL
|
||||||
Image *string `json:"image"`
|
Image *string `json:"image"`
|
||||||
StashIds []StashID `json:"stash_ids"`
|
StashIds []StashID `json:"stash_ids"`
|
||||||
Rating *int `json:"rating"`
|
|
||||||
Rating100 *int `json:"rating100"`
|
Rating100 *int `json:"rating100"`
|
||||||
Details *string `json:"details"`
|
Details *string `json:"details"`
|
||||||
DeathDate *string `json:"death_date"`
|
DeathDate *string `json:"death_date"`
|
||||||
|
|
@ -257,7 +254,6 @@ type PerformerUpdateInput struct {
|
||||||
// This should be a URL or a base64 encoded data URL
|
// This should be a URL or a base64 encoded data URL
|
||||||
Image *string `json:"image"`
|
Image *string `json:"image"`
|
||||||
StashIds []StashID `json:"stash_ids"`
|
StashIds []StashID `json:"stash_ids"`
|
||||||
Rating *int `json:"rating"`
|
|
||||||
Rating100 *int `json:"rating100"`
|
Rating100 *int `json:"rating100"`
|
||||||
Details *string `json:"details"`
|
Details *string `json:"details"`
|
||||||
DeathDate *string `json:"death_date"`
|
DeathDate *string `json:"death_date"`
|
||||||
|
|
|
||||||
|
|
@ -29,8 +29,6 @@ type SceneFilterType struct {
|
||||||
Path *StringCriterionInput `json:"path"`
|
Path *StringCriterionInput `json:"path"`
|
||||||
// Filter by file count
|
// Filter by file count
|
||||||
FileCount *IntCriterionInput `json:"file_count"`
|
FileCount *IntCriterionInput `json:"file_count"`
|
||||||
// Filter by rating expressed as 1-5
|
|
||||||
Rating *IntCriterionInput `json:"rating"`
|
|
||||||
// Filter by rating expressed as 1-100
|
// Filter by rating expressed as 1-100
|
||||||
Rating100 *IntCriterionInput `json:"rating100"`
|
Rating100 *IntCriterionInput `json:"rating100"`
|
||||||
// Filter by organized
|
// Filter by organized
|
||||||
|
|
@ -128,7 +126,6 @@ type SceneCreateInput struct {
|
||||||
URL *string `json:"url"`
|
URL *string `json:"url"`
|
||||||
Urls []string `json:"urls"`
|
Urls []string `json:"urls"`
|
||||||
Date *string `json:"date"`
|
Date *string `json:"date"`
|
||||||
Rating *int `json:"rating"`
|
|
||||||
Rating100 *int `json:"rating100"`
|
Rating100 *int `json:"rating100"`
|
||||||
Organized *bool `json:"organized"`
|
Organized *bool `json:"organized"`
|
||||||
StudioID *string `json:"studio_id"`
|
StudioID *string `json:"studio_id"`
|
||||||
|
|
@ -155,7 +152,6 @@ type SceneUpdateInput struct {
|
||||||
URL *string `json:"url"`
|
URL *string `json:"url"`
|
||||||
Urls []string `json:"urls"`
|
Urls []string `json:"urls"`
|
||||||
Date *string `json:"date"`
|
Date *string `json:"date"`
|
||||||
Rating *int `json:"rating"`
|
|
||||||
Rating100 *int `json:"rating100"`
|
Rating100 *int `json:"rating100"`
|
||||||
OCounter *int `json:"o_counter"`
|
OCounter *int `json:"o_counter"`
|
||||||
Organized *bool `json:"organized"`
|
Organized *bool `json:"organized"`
|
||||||
|
|
|
||||||
|
|
@ -14,8 +14,6 @@ type StudioFilterType struct {
|
||||||
StashIDEndpoint *StashIDCriterionInput `json:"stash_id_endpoint"`
|
StashIDEndpoint *StashIDCriterionInput `json:"stash_id_endpoint"`
|
||||||
// Filter to only include studios missing this property
|
// Filter to only include studios missing this property
|
||||||
IsMissing *string `json:"is_missing"`
|
IsMissing *string `json:"is_missing"`
|
||||||
// Filter by rating expressed as 1-5
|
|
||||||
Rating *IntCriterionInput `json:"rating"`
|
|
||||||
// Filter by rating expressed as 1-100
|
// Filter by rating expressed as 1-100
|
||||||
Rating100 *IntCriterionInput `json:"rating100"`
|
Rating100 *IntCriterionInput `json:"rating100"`
|
||||||
// Filter by scene count
|
// Filter by scene count
|
||||||
|
|
@ -43,7 +41,6 @@ type StudioCreateInput struct {
|
||||||
// This should be a URL or a base64 encoded data URL
|
// This should be a URL or a base64 encoded data URL
|
||||||
Image *string `json:"image"`
|
Image *string `json:"image"`
|
||||||
StashIds []StashID `json:"stash_ids"`
|
StashIds []StashID `json:"stash_ids"`
|
||||||
Rating *int `json:"rating"`
|
|
||||||
Rating100 *int `json:"rating100"`
|
Rating100 *int `json:"rating100"`
|
||||||
Details *string `json:"details"`
|
Details *string `json:"details"`
|
||||||
Aliases []string `json:"aliases"`
|
Aliases []string `json:"aliases"`
|
||||||
|
|
@ -58,7 +55,6 @@ type StudioUpdateInput struct {
|
||||||
// This should be a URL or a base64 encoded data URL
|
// This should be a URL or a base64 encoded data URL
|
||||||
Image *string `json:"image"`
|
Image *string `json:"image"`
|
||||||
StashIds []StashID `json:"stash_ids"`
|
StashIds []StashID `json:"stash_ids"`
|
||||||
Rating *int `json:"rating"`
|
|
||||||
Rating100 *int `json:"rating100"`
|
Rating100 *int `json:"rating100"`
|
||||||
Details *string `json:"details"`
|
Details *string `json:"details"`
|
||||||
Aliases []string `json:"aliases"`
|
Aliases []string `json:"aliases"`
|
||||||
|
|
|
||||||
|
|
@ -575,25 +575,6 @@ func boolCriterionHandler(c *bool, column string, addJoinFn func(f *filterBuilde
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func rating5CriterionHandler(c *models.IntCriterionInput, column string, addJoinFn func(f *filterBuilder)) criterionHandlerFunc {
|
|
||||||
return func(ctx context.Context, f *filterBuilder) {
|
|
||||||
if c != nil {
|
|
||||||
// make a copy so we can adjust it
|
|
||||||
cc := *c
|
|
||||||
if cc.Value != 0 {
|
|
||||||
cc.Value = models.Rating5To100(cc.Value)
|
|
||||||
}
|
|
||||||
if cc.Value2 != nil {
|
|
||||||
val := models.Rating5To100(*cc.Value2)
|
|
||||||
cc.Value2 = &val
|
|
||||||
}
|
|
||||||
|
|
||||||
clause, args := getIntCriterionWhereClause(column, cc)
|
|
||||||
f.addWhere(clause, args...)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func dateCriterionHandler(c *models.DateCriterionInput, column string) criterionHandlerFunc {
|
func dateCriterionHandler(c *models.DateCriterionInput, column string) criterionHandlerFunc {
|
||||||
return func(ctx context.Context, f *filterBuilder) {
|
return func(ctx context.Context, f *filterBuilder) {
|
||||||
if c != nil {
|
if c != nil {
|
||||||
|
|
|
||||||
|
|
@ -681,8 +681,6 @@ func (qb *GalleryStore) makeFilter(ctx context.Context, galleryFilter *models.Ga
|
||||||
query.handleCriterion(ctx, qb.galleryPathCriterionHandler(galleryFilter.Path))
|
query.handleCriterion(ctx, qb.galleryPathCriterionHandler(galleryFilter.Path))
|
||||||
query.handleCriterion(ctx, galleryFileCountCriterionHandler(qb, galleryFilter.FileCount))
|
query.handleCriterion(ctx, galleryFileCountCriterionHandler(qb, galleryFilter.FileCount))
|
||||||
query.handleCriterion(ctx, intCriterionHandler(galleryFilter.Rating100, "galleries.rating", nil))
|
query.handleCriterion(ctx, intCriterionHandler(galleryFilter.Rating100, "galleries.rating", nil))
|
||||||
// legacy rating handler
|
|
||||||
query.handleCriterion(ctx, rating5CriterionHandler(galleryFilter.Rating, "galleries.rating", nil))
|
|
||||||
query.handleCriterion(ctx, galleryURLsCriterionHandler(galleryFilter.URL))
|
query.handleCriterion(ctx, galleryURLsCriterionHandler(galleryFilter.URL))
|
||||||
query.handleCriterion(ctx, boolCriterionHandler(galleryFilter.Organized, "galleries.organized", nil))
|
query.handleCriterion(ctx, boolCriterionHandler(galleryFilter.Organized, "galleries.organized", nil))
|
||||||
query.handleCriterion(ctx, galleryIsMissingCriterionHandler(qb, galleryFilter.IsMissing))
|
query.handleCriterion(ctx, galleryIsMissingCriterionHandler(qb, galleryFilter.IsMissing))
|
||||||
|
|
|
||||||
|
|
@ -1715,54 +1715,6 @@ func verifyGalleryQuery(t *testing.T, filter models.GalleryFilterType, verifyFn
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGalleryQueryLegacyRating(t *testing.T) {
|
|
||||||
const rating = 3
|
|
||||||
ratingCriterion := models.IntCriterionInput{
|
|
||||||
Value: rating,
|
|
||||||
Modifier: models.CriterionModifierEquals,
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyGalleriesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierNotEquals
|
|
||||||
verifyGalleriesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierGreaterThan
|
|
||||||
verifyGalleriesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierLessThan
|
|
||||||
verifyGalleriesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierIsNull
|
|
||||||
verifyGalleriesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierNotNull
|
|
||||||
verifyGalleriesLegacyRating(t, ratingCriterion)
|
|
||||||
}
|
|
||||||
|
|
||||||
func verifyGalleriesLegacyRating(t *testing.T, ratingCriterion models.IntCriterionInput) {
|
|
||||||
withTxn(func(ctx context.Context) error {
|
|
||||||
sqb := db.Gallery
|
|
||||||
galleryFilter := models.GalleryFilterType{
|
|
||||||
Rating: &ratingCriterion,
|
|
||||||
}
|
|
||||||
|
|
||||||
galleries, _, err := sqb.Query(ctx, &galleryFilter, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Error querying gallery: %s", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert criterion value to the 100 value
|
|
||||||
ratingCriterion.Value = models.Rating5To100(ratingCriterion.Value)
|
|
||||||
|
|
||||||
for _, gallery := range galleries {
|
|
||||||
verifyIntPtr(t, gallery.Rating, ratingCriterion)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGalleryQueryRating100(t *testing.T) {
|
func TestGalleryQueryRating100(t *testing.T) {
|
||||||
const rating = 60
|
const rating = 60
|
||||||
ratingCriterion := models.IntCriterionInput{
|
ratingCriterion := models.IntCriterionInput{
|
||||||
|
|
|
||||||
|
|
@ -676,8 +676,6 @@ func (qb *ImageStore) makeFilter(ctx context.Context, imageFilter *models.ImageF
|
||||||
query.handleCriterion(ctx, pathCriterionHandler(imageFilter.Path, "folders.path", "files.basename", qb.addFoldersTable))
|
query.handleCriterion(ctx, pathCriterionHandler(imageFilter.Path, "folders.path", "files.basename", qb.addFoldersTable))
|
||||||
query.handleCriterion(ctx, imageFileCountCriterionHandler(qb, imageFilter.FileCount))
|
query.handleCriterion(ctx, imageFileCountCriterionHandler(qb, imageFilter.FileCount))
|
||||||
query.handleCriterion(ctx, intCriterionHandler(imageFilter.Rating100, "images.rating", nil))
|
query.handleCriterion(ctx, intCriterionHandler(imageFilter.Rating100, "images.rating", nil))
|
||||||
// legacy rating handler
|
|
||||||
query.handleCriterion(ctx, rating5CriterionHandler(imageFilter.Rating, "images.rating", nil))
|
|
||||||
query.handleCriterion(ctx, intCriterionHandler(imageFilter.OCounter, "images.o_counter", nil))
|
query.handleCriterion(ctx, intCriterionHandler(imageFilter.OCounter, "images.o_counter", nil))
|
||||||
query.handleCriterion(ctx, boolCriterionHandler(imageFilter.Organized, "images.organized", nil))
|
query.handleCriterion(ctx, boolCriterionHandler(imageFilter.Organized, "images.organized", nil))
|
||||||
query.handleCriterion(ctx, dateCriterionHandler(imageFilter.Date, "images.date"))
|
query.handleCriterion(ctx, dateCriterionHandler(imageFilter.Date, "images.date"))
|
||||||
|
|
|
||||||
|
|
@ -1772,54 +1772,6 @@ func TestImageIllegalQuery(t *testing.T) {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestImageQueryLegacyRating(t *testing.T) {
|
|
||||||
const rating = 3
|
|
||||||
ratingCriterion := models.IntCriterionInput{
|
|
||||||
Value: rating,
|
|
||||||
Modifier: models.CriterionModifierEquals,
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyImagesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierNotEquals
|
|
||||||
verifyImagesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierGreaterThan
|
|
||||||
verifyImagesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierLessThan
|
|
||||||
verifyImagesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierIsNull
|
|
||||||
verifyImagesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierNotNull
|
|
||||||
verifyImagesLegacyRating(t, ratingCriterion)
|
|
||||||
}
|
|
||||||
|
|
||||||
func verifyImagesLegacyRating(t *testing.T, ratingCriterion models.IntCriterionInput) {
|
|
||||||
withTxn(func(ctx context.Context) error {
|
|
||||||
sqb := db.Image
|
|
||||||
imageFilter := models.ImageFilterType{
|
|
||||||
Rating: &ratingCriterion,
|
|
||||||
}
|
|
||||||
|
|
||||||
images, _, err := queryImagesWithCount(ctx, sqb, &imageFilter, nil)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("Error querying image: %s", err.Error())
|
|
||||||
}
|
|
||||||
|
|
||||||
// convert criterion value to the 100 value
|
|
||||||
ratingCriterion.Value = models.Rating5To100(ratingCriterion.Value)
|
|
||||||
|
|
||||||
for _, image := range images {
|
|
||||||
verifyIntPtr(t, image.Rating, ratingCriterion)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestImageQueryRating100(t *testing.T) {
|
func TestImageQueryRating100(t *testing.T) {
|
||||||
const rating = 60
|
const rating = 60
|
||||||
ratingCriterion := models.IntCriterionInput{
|
ratingCriterion := models.IntCriterionInput{
|
||||||
|
|
|
||||||
|
|
@ -334,8 +334,6 @@ func (qb *MovieStore) makeFilter(ctx context.Context, movieFilter *models.MovieF
|
||||||
query.handleCriterion(ctx, stringCriterionHandler(movieFilter.Director, "movies.director"))
|
query.handleCriterion(ctx, stringCriterionHandler(movieFilter.Director, "movies.director"))
|
||||||
query.handleCriterion(ctx, stringCriterionHandler(movieFilter.Synopsis, "movies.synopsis"))
|
query.handleCriterion(ctx, stringCriterionHandler(movieFilter.Synopsis, "movies.synopsis"))
|
||||||
query.handleCriterion(ctx, intCriterionHandler(movieFilter.Rating100, "movies.rating", nil))
|
query.handleCriterion(ctx, intCriterionHandler(movieFilter.Rating100, "movies.rating", nil))
|
||||||
// legacy rating handler
|
|
||||||
query.handleCriterion(ctx, rating5CriterionHandler(movieFilter.Rating, "movies.rating", nil))
|
|
||||||
query.handleCriterion(ctx, floatIntCriterionHandler(movieFilter.Duration, "movies.duration", nil))
|
query.handleCriterion(ctx, floatIntCriterionHandler(movieFilter.Duration, "movies.duration", nil))
|
||||||
query.handleCriterion(ctx, movieIsMissingCriterionHandler(qb, movieFilter.IsMissing))
|
query.handleCriterion(ctx, movieIsMissingCriterionHandler(qb, movieFilter.IsMissing))
|
||||||
query.handleCriterion(ctx, stringCriterionHandler(movieFilter.URL, "movies.url"))
|
query.handleCriterion(ctx, stringCriterionHandler(movieFilter.URL, "movies.url"))
|
||||||
|
|
|
||||||
|
|
@ -636,8 +636,6 @@ func (qb *PerformerStore) makeFilter(ctx context.Context, filter *models.Perform
|
||||||
query.handleCriterion(ctx, stringCriterionHandler(filter.Tattoos, tableName+".tattoos"))
|
query.handleCriterion(ctx, stringCriterionHandler(filter.Tattoos, tableName+".tattoos"))
|
||||||
query.handleCriterion(ctx, stringCriterionHandler(filter.Piercings, tableName+".piercings"))
|
query.handleCriterion(ctx, stringCriterionHandler(filter.Piercings, tableName+".piercings"))
|
||||||
query.handleCriterion(ctx, intCriterionHandler(filter.Rating100, tableName+".rating", nil))
|
query.handleCriterion(ctx, intCriterionHandler(filter.Rating100, tableName+".rating", nil))
|
||||||
// legacy rating handler
|
|
||||||
query.handleCriterion(ctx, rating5CriterionHandler(filter.Rating, tableName+".rating", nil))
|
|
||||||
query.handleCriterion(ctx, stringCriterionHandler(filter.HairColor, tableName+".hair_color"))
|
query.handleCriterion(ctx, stringCriterionHandler(filter.HairColor, tableName+".hair_color"))
|
||||||
query.handleCriterion(ctx, stringCriterionHandler(filter.URL, tableName+".url"))
|
query.handleCriterion(ctx, stringCriterionHandler(filter.URL, tableName+".url"))
|
||||||
query.handleCriterion(ctx, intCriterionHandler(filter.Weight, tableName+".weight", nil))
|
query.handleCriterion(ctx, intCriterionHandler(filter.Weight, tableName+".weight", nil))
|
||||||
|
|
|
||||||
|
|
@ -1719,50 +1719,6 @@ func testPerformerStashIDs(ctx context.Context, t *testing.T, s *models.Performe
|
||||||
assert.Len(t, s.StashIDs.List(), 0)
|
assert.Len(t, s.StashIDs.List(), 0)
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestPerformerQueryLegacyRating(t *testing.T) {
|
|
||||||
const rating = 3
|
|
||||||
ratingCriterion := models.IntCriterionInput{
|
|
||||||
Value: rating,
|
|
||||||
Modifier: models.CriterionModifierEquals,
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyPerformersLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierNotEquals
|
|
||||||
verifyPerformersLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierGreaterThan
|
|
||||||
verifyPerformersLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierLessThan
|
|
||||||
verifyPerformersLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierIsNull
|
|
||||||
verifyPerformersLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierNotNull
|
|
||||||
verifyPerformersLegacyRating(t, ratingCriterion)
|
|
||||||
}
|
|
||||||
|
|
||||||
func verifyPerformersLegacyRating(t *testing.T, ratingCriterion models.IntCriterionInput) {
|
|
||||||
withTxn(func(ctx context.Context) error {
|
|
||||||
performerFilter := models.PerformerFilterType{
|
|
||||||
Rating: &ratingCriterion,
|
|
||||||
}
|
|
||||||
|
|
||||||
performers := queryPerformers(ctx, t, &performerFilter, nil)
|
|
||||||
|
|
||||||
// convert criterion value to the 100 value
|
|
||||||
ratingCriterion.Value = models.Rating5To100(ratingCriterion.Value)
|
|
||||||
|
|
||||||
for _, performer := range performers {
|
|
||||||
verifyIntPtr(t, performer.Rating, ratingCriterion)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestPerformerQueryRating100(t *testing.T) {
|
func TestPerformerQueryRating100(t *testing.T) {
|
||||||
const rating = 60
|
const rating = 60
|
||||||
ratingCriterion := models.IntCriterionInput{
|
ratingCriterion := models.IntCriterionInput{
|
||||||
|
|
|
||||||
|
|
@ -976,8 +976,6 @@ func (qb *SceneStore) makeFilter(ctx context.Context, sceneFilter *models.SceneF
|
||||||
query.handleCriterion(ctx, scenePhashDistanceCriterionHandler(qb, sceneFilter.PhashDistance))
|
query.handleCriterion(ctx, scenePhashDistanceCriterionHandler(qb, sceneFilter.PhashDistance))
|
||||||
|
|
||||||
query.handleCriterion(ctx, intCriterionHandler(sceneFilter.Rating100, "scenes.rating", nil))
|
query.handleCriterion(ctx, intCriterionHandler(sceneFilter.Rating100, "scenes.rating", nil))
|
||||||
// legacy rating handler
|
|
||||||
query.handleCriterion(ctx, rating5CriterionHandler(sceneFilter.Rating, "scenes.rating", nil))
|
|
||||||
query.handleCriterion(ctx, intCriterionHandler(sceneFilter.OCounter, "scenes.o_counter", nil))
|
query.handleCriterion(ctx, intCriterionHandler(sceneFilter.OCounter, "scenes.o_counter", nil))
|
||||||
query.handleCriterion(ctx, boolCriterionHandler(sceneFilter.Organized, "scenes.organized", nil))
|
query.handleCriterion(ctx, boolCriterionHandler(sceneFilter.Organized, "scenes.organized", nil))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -2673,51 +2673,6 @@ func verifyString(t *testing.T, value string, criterion models.StringCriterionIn
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestSceneQueryRating(t *testing.T) {
|
|
||||||
const rating = 3
|
|
||||||
ratingCriterion := models.IntCriterionInput{
|
|
||||||
Value: rating,
|
|
||||||
Modifier: models.CriterionModifierEquals,
|
|
||||||
}
|
|
||||||
|
|
||||||
verifyScenesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierNotEquals
|
|
||||||
verifyScenesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierGreaterThan
|
|
||||||
verifyScenesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierLessThan
|
|
||||||
verifyScenesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierIsNull
|
|
||||||
verifyScenesLegacyRating(t, ratingCriterion)
|
|
||||||
|
|
||||||
ratingCriterion.Modifier = models.CriterionModifierNotNull
|
|
||||||
verifyScenesLegacyRating(t, ratingCriterion)
|
|
||||||
}
|
|
||||||
|
|
||||||
func verifyScenesLegacyRating(t *testing.T, ratingCriterion models.IntCriterionInput) {
|
|
||||||
withTxn(func(ctx context.Context) error {
|
|
||||||
sqb := db.Scene
|
|
||||||
sceneFilter := models.SceneFilterType{
|
|
||||||
Rating: &ratingCriterion,
|
|
||||||
}
|
|
||||||
|
|
||||||
scenes := queryScene(ctx, t, sqb, &sceneFilter, nil)
|
|
||||||
|
|
||||||
// convert criterion value to the 100 value
|
|
||||||
ratingCriterion.Value = models.Rating5To100(ratingCriterion.Value)
|
|
||||||
|
|
||||||
for _, scene := range scenes {
|
|
||||||
verifyIntPtr(t, scene.Rating, ratingCriterion)
|
|
||||||
}
|
|
||||||
|
|
||||||
return nil
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSceneQueryRating100(t *testing.T) {
|
func TestSceneQueryRating100(t *testing.T) {
|
||||||
const rating = 60
|
const rating = 60
|
||||||
ratingCriterion := models.IntCriterionInput{
|
ratingCriterion := models.IntCriterionInput{
|
||||||
|
|
|
||||||
|
|
@ -496,8 +496,6 @@ func (qb *StudioStore) makeFilter(ctx context.Context, studioFilter *models.Stud
|
||||||
query.handleCriterion(ctx, stringCriterionHandler(studioFilter.Details, studioTable+".details"))
|
query.handleCriterion(ctx, stringCriterionHandler(studioFilter.Details, studioTable+".details"))
|
||||||
query.handleCriterion(ctx, stringCriterionHandler(studioFilter.URL, studioTable+".url"))
|
query.handleCriterion(ctx, stringCriterionHandler(studioFilter.URL, studioTable+".url"))
|
||||||
query.handleCriterion(ctx, intCriterionHandler(studioFilter.Rating100, studioTable+".rating", nil))
|
query.handleCriterion(ctx, intCriterionHandler(studioFilter.Rating100, studioTable+".rating", nil))
|
||||||
// legacy rating handler
|
|
||||||
query.handleCriterion(ctx, rating5CriterionHandler(studioFilter.Rating, studioTable+".rating", nil))
|
|
||||||
query.handleCriterion(ctx, boolCriterionHandler(studioFilter.IgnoreAutoTag, studioTable+".ignore_auto_tag", nil))
|
query.handleCriterion(ctx, boolCriterionHandler(studioFilter.IgnoreAutoTag, studioTable+".ignore_auto_tag", nil))
|
||||||
|
|
||||||
query.handleCriterion(ctx, criterionHandlerFunc(func(ctx context.Context, f *filterBuilder) {
|
query.handleCriterion(ctx, criterionHandlerFunc(func(ctx context.Context, f *filterBuilder) {
|
||||||
|
|
|
||||||
|
|
@ -672,7 +672,7 @@ func TestStudioQueryURL(t *testing.T) {
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestStudioQueryRating(t *testing.T) {
|
func TestStudioQueryRating(t *testing.T) {
|
||||||
const rating = 3
|
const rating = 60
|
||||||
ratingCriterion := models.IntCriterionInput{
|
ratingCriterion := models.IntCriterionInput{
|
||||||
Value: rating,
|
Value: rating,
|
||||||
Modifier: models.CriterionModifierEquals,
|
Modifier: models.CriterionModifierEquals,
|
||||||
|
|
@ -718,7 +718,7 @@ func verifyStudiosRating(t *testing.T, ratingCriterion models.IntCriterionInput)
|
||||||
withTxn(func(ctx context.Context) error {
|
withTxn(func(ctx context.Context) error {
|
||||||
sqb := db.Studio
|
sqb := db.Studio
|
||||||
studioFilter := models.StudioFilterType{
|
studioFilter := models.StudioFilterType{
|
||||||
Rating: &ratingCriterion,
|
Rating100: &ratingCriterion,
|
||||||
}
|
}
|
||||||
|
|
||||||
studios, _, err := sqb.Query(ctx, &studioFilter, nil)
|
studios, _, err := sqb.Query(ctx, &studioFilter, nil)
|
||||||
|
|
@ -959,7 +959,7 @@ func TestStudioQueryFast(t *testing.T) {
|
||||||
URL: &testStringCriterion,
|
URL: &testStringCriterion,
|
||||||
}
|
}
|
||||||
ratingFilter := models.StudioFilterType{
|
ratingFilter := models.StudioFilterType{
|
||||||
Rating: &testIntCriterion,
|
Rating100: &testIntCriterion,
|
||||||
}
|
}
|
||||||
sceneCountFilter := models.StudioFilterType{
|
sceneCountFilter := models.StudioFilterType{
|
||||||
SceneCount: &testIntCriterion,
|
SceneCount: &testIntCriterion,
|
||||||
|
|
|
||||||
|
|
@ -94,7 +94,7 @@ export const IdentifyDialog: React.FC<IIdentifyDialogProps> = ({
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
||||||
const scrapers = scraperData.listSceneScrapers;
|
const scrapers = scraperData.listScrapers;
|
||||||
|
|
||||||
const fragmentScrapers = scrapers.filter((s) =>
|
const fragmentScrapers = scrapers.filter((s) =>
|
||||||
s.scene?.supported_scrapes.includes(GQL.ScrapeType.Fragment)
|
s.scene?.supported_scrapes.includes(GQL.ScrapeType.Fragment)
|
||||||
|
|
|
||||||
|
|
@ -170,10 +170,8 @@ export const GalleryEditPanel: React.FC<IProps> = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const newQueryableScrapers = (
|
const newQueryableScrapers = (Scrapers?.data?.listScrapers ?? []).filter(
|
||||||
Scrapers?.data?.listGalleryScrapers ?? []
|
(s) => s.gallery?.supported_scrapes.includes(GQL.ScrapeType.Fragment)
|
||||||
).filter((s) =>
|
|
||||||
s.gallery?.supported_scrapes.includes(GQL.ScrapeType.Fragment)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
setQueryableScrapers(newQueryableScrapers);
|
setQueryableScrapers(newQueryableScrapers);
|
||||||
|
|
@ -282,7 +280,7 @@ export const GalleryEditPanel: React.FC<IProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
function urlScrapable(scrapedUrl: string): boolean {
|
function urlScrapable(scrapedUrl: string): boolean {
|
||||||
return (Scrapers?.data?.listGalleryScrapers ?? []).some((s) =>
|
return (Scrapers?.data?.listScrapers ?? []).some((s) =>
|
||||||
(s?.gallery?.urls ?? []).some((u) => scrapedUrl.includes(u))
|
(s?.gallery?.urls ?? []).some((u) => scrapedUrl.includes(u))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -207,7 +207,7 @@ export const MovieEditPanel: React.FC<IMovieEditPanel> = ({
|
||||||
function urlScrapable(scrapedUrl: string) {
|
function urlScrapable(scrapedUrl: string) {
|
||||||
return (
|
return (
|
||||||
!!scrapedUrl &&
|
!!scrapedUrl &&
|
||||||
(Scrapers?.data?.listMovieScrapers ?? []).some((s) =>
|
(Scrapers?.data?.listScrapers ?? []).some((s) =>
|
||||||
(s?.movie?.urls ?? []).some((u) => scrapedUrl.includes(u))
|
(s?.movie?.urls ?? []).some((u) => scrapedUrl.includes(u))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ const performerFields = [
|
||||||
"country",
|
"country",
|
||||||
"ethnicity",
|
"ethnicity",
|
||||||
"eye_color",
|
"eye_color",
|
||||||
"height",
|
// "height",
|
||||||
// "weight",
|
// "weight",
|
||||||
"measurements",
|
"measurements",
|
||||||
"fake_tits",
|
"fake_tits",
|
||||||
|
|
@ -69,7 +69,8 @@ export const EditPerformersDialog: React.FC<IListOperationProps> = (
|
||||||
const [existingTagIds, setExistingTagIds] = useState<string[]>();
|
const [existingTagIds, setExistingTagIds] = useState<string[]>();
|
||||||
const [aggregateState, setAggregateState] =
|
const [aggregateState, setAggregateState] =
|
||||||
useState<GQL.BulkPerformerUpdateInput>({});
|
useState<GQL.BulkPerformerUpdateInput>({});
|
||||||
// weight needs conversion to/from number
|
// height and weight needs conversion to/from number
|
||||||
|
const [height, setHeight] = useState<string | undefined>();
|
||||||
const [weight, setWeight] = useState<string | undefined>();
|
const [weight, setWeight] = useState<string | undefined>();
|
||||||
const [penis_length, setPenisLength] = useState<string | undefined>();
|
const [penis_length, setPenisLength] = useState<string | undefined>();
|
||||||
const [updateInput, setUpdateInput] = useState<GQL.BulkPerformerUpdateInput>(
|
const [updateInput, setUpdateInput] = useState<GQL.BulkPerformerUpdateInput>(
|
||||||
|
|
@ -114,6 +115,9 @@ export const EditPerformersDialog: React.FC<IListOperationProps> = (
|
||||||
aggregateState.circumcised
|
aggregateState.circumcised
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if (height !== undefined) {
|
||||||
|
performerInput.height_cm = parseFloat(height);
|
||||||
|
}
|
||||||
if (weight !== undefined) {
|
if (weight !== undefined) {
|
||||||
performerInput.weight = parseFloat(weight);
|
performerInput.weight = parseFloat(weight);
|
||||||
}
|
}
|
||||||
|
|
@ -151,6 +155,7 @@ export const EditPerformersDialog: React.FC<IListOperationProps> = (
|
||||||
|
|
||||||
const state = props.selected;
|
const state = props.selected;
|
||||||
let updateTagIds: string[] = [];
|
let updateTagIds: string[] = [];
|
||||||
|
let updateHeight: string | undefined | null = undefined;
|
||||||
let updateWeight: string | undefined | null = undefined;
|
let updateWeight: string | undefined | null = undefined;
|
||||||
let updatePenisLength: string | undefined | null = undefined;
|
let updatePenisLength: string | undefined | null = undefined;
|
||||||
let first = true;
|
let first = true;
|
||||||
|
|
@ -163,6 +168,12 @@ export const EditPerformersDialog: React.FC<IListOperationProps> = (
|
||||||
updateTagIds =
|
updateTagIds =
|
||||||
getAggregateState(updateTagIds, performerTagIDs, first) ?? [];
|
getAggregateState(updateTagIds, performerTagIDs, first) ?? [];
|
||||||
|
|
||||||
|
const thisHeight =
|
||||||
|
performer.height_cm !== undefined && performer.height_cm !== null
|
||||||
|
? performer.height_cm.toString()
|
||||||
|
: performer.height_cm;
|
||||||
|
updateHeight = getAggregateState(updateHeight, thisHeight, first);
|
||||||
|
|
||||||
const thisWeight =
|
const thisWeight =
|
||||||
performer.weight !== undefined && performer.weight !== null
|
performer.weight !== undefined && performer.weight !== null
|
||||||
? performer.weight.toString()
|
? performer.weight.toString()
|
||||||
|
|
@ -183,6 +194,7 @@ export const EditPerformersDialog: React.FC<IListOperationProps> = (
|
||||||
});
|
});
|
||||||
|
|
||||||
setExistingTagIds(updateTagIds);
|
setExistingTagIds(updateTagIds);
|
||||||
|
setHeight(updateHeight);
|
||||||
setWeight(updateWeight);
|
setWeight(updateWeight);
|
||||||
setAggregateState(updateState);
|
setAggregateState(updateState);
|
||||||
setUpdateInput(updateState);
|
setUpdateInput(updateState);
|
||||||
|
|
@ -291,9 +303,7 @@ export const EditPerformersDialog: React.FC<IListOperationProps> = (
|
||||||
{renderTextField("eye_color", updateInput.eye_color, (v) =>
|
{renderTextField("eye_color", updateInput.eye_color, (v) =>
|
||||||
setUpdateField({ eye_color: v })
|
setUpdateField({ eye_color: v })
|
||||||
)}
|
)}
|
||||||
{renderTextField("height", updateInput.height, (v) =>
|
{renderTextField("height", height, (v) => setHeight(v))}
|
||||||
setUpdateField({ height: v })
|
|
||||||
)}
|
|
||||||
{renderTextField("weight", weight, (v) => setWeight(v))}
|
{renderTextField("weight", weight, (v) => setWeight(v))}
|
||||||
{renderTextField("measurements", updateInput.measurements, (v) =>
|
{renderTextField("measurements", updateInput.measurements, (v) =>
|
||||||
setUpdateField({ measurements: v })
|
setUpdateField({ measurements: v })
|
||||||
|
|
|
||||||
|
|
@ -492,10 +492,8 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const newQueryableScrapers = (
|
const newQueryableScrapers = (Scrapers?.data?.listScrapers ?? []).filter(
|
||||||
Scrapers?.data?.listPerformerScrapers ?? []
|
(s) => s.performer?.supported_scrapes.includes(GQL.ScrapeType.Name)
|
||||||
).filter((s) =>
|
|
||||||
s.performer?.supported_scrapes.includes(GQL.ScrapeType.Name)
|
|
||||||
);
|
);
|
||||||
|
|
||||||
setQueryableScrapers(newQueryableScrapers);
|
setQueryableScrapers(newQueryableScrapers);
|
||||||
|
|
@ -657,7 +655,7 @@ export const PerformerEditPanel: React.FC<IPerformerDetails> = ({
|
||||||
function urlScrapable(scrapedUrl?: string) {
|
function urlScrapable(scrapedUrl?: string) {
|
||||||
return (
|
return (
|
||||||
!!scrapedUrl &&
|
!!scrapedUrl &&
|
||||||
(Scrapers?.data?.listPerformerScrapers ?? []).some((s) =>
|
(Scrapers?.data?.listScrapers ?? []).some((s) =>
|
||||||
(s?.performer?.urls ?? []).some((u) => scrapedUrl.includes(u))
|
(s?.performer?.urls ?? []).some((u) => scrapedUrl.includes(u))
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -232,7 +232,7 @@ export const SceneEditPanel: React.FC<IProps> = ({
|
||||||
});
|
});
|
||||||
|
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
const toFilter = Scrapers?.data?.listSceneScrapers ?? [];
|
const toFilter = Scrapers?.data?.listScrapers ?? [];
|
||||||
|
|
||||||
const newFragmentScrapers = toFilter.filter((s) =>
|
const newFragmentScrapers = toFilter.filter((s) =>
|
||||||
s.scene?.supported_scrapes.includes(GQL.ScrapeType.Fragment)
|
s.scene?.supported_scrapes.includes(GQL.ScrapeType.Fragment)
|
||||||
|
|
@ -527,7 +527,7 @@ export const SceneEditPanel: React.FC<IProps> = ({
|
||||||
}
|
}
|
||||||
|
|
||||||
function urlScrapable(scrapedUrl: string): boolean {
|
function urlScrapable(scrapedUrl: string): boolean {
|
||||||
return (Scrapers?.data?.listSceneScrapers ?? []).some((s) =>
|
return (Scrapers?.data?.listScrapers ?? []).some((s) =>
|
||||||
(s?.scene?.urls ?? []).some((u) => scrapedUrl.includes(u))
|
(s?.scene?.urls ?? []).some((u) => scrapedUrl.includes(u))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -185,7 +185,7 @@ export const SettingsScrapingPanel: React.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderSceneScrapers() {
|
function renderSceneScrapers() {
|
||||||
const elements = (sceneScrapers?.listSceneScrapers ?? []).map((scraper) => (
|
const elements = (sceneScrapers?.listScrapers ?? []).map((scraper) => (
|
||||||
<tr key={scraper.id}>
|
<tr key={scraper.id}>
|
||||||
<td>{scraper.name}</td>
|
<td>{scraper.name}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -205,8 +205,7 @@ export const SettingsScrapingPanel: React.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderGalleryScrapers() {
|
function renderGalleryScrapers() {
|
||||||
const elements = (galleryScrapers?.listGalleryScrapers ?? []).map(
|
const elements = (galleryScrapers?.listScrapers ?? []).map((scraper) => (
|
||||||
(scraper) => (
|
|
||||||
<tr key={scraper.id}>
|
<tr key={scraper.id}>
|
||||||
<td>{scraper.name}</td>
|
<td>{scraper.name}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -214,8 +213,7 @@ export const SettingsScrapingPanel: React.FC = () => {
|
||||||
</td>
|
</td>
|
||||||
<td>{renderURLs(scraper.gallery?.urls ?? [])}</td>
|
<td>{renderURLs(scraper.gallery?.urls ?? [])}</td>
|
||||||
</tr>
|
</tr>
|
||||||
)
|
));
|
||||||
);
|
|
||||||
|
|
||||||
return renderTable(
|
return renderTable(
|
||||||
intl.formatMessage(
|
intl.formatMessage(
|
||||||
|
|
@ -227,8 +225,7 @@ export const SettingsScrapingPanel: React.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderPerformerScrapers() {
|
function renderPerformerScrapers() {
|
||||||
const elements = (performerScrapers?.listPerformerScrapers ?? []).map(
|
const elements = (performerScrapers?.listScrapers ?? []).map((scraper) => (
|
||||||
(scraper) => (
|
|
||||||
<tr key={scraper.id}>
|
<tr key={scraper.id}>
|
||||||
<td>{scraper.name}</td>
|
<td>{scraper.name}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
@ -238,8 +235,7 @@ export const SettingsScrapingPanel: React.FC = () => {
|
||||||
</td>
|
</td>
|
||||||
<td>{renderURLs(scraper.performer?.urls ?? [])}</td>
|
<td>{renderURLs(scraper.performer?.urls ?? [])}</td>
|
||||||
</tr>
|
</tr>
|
||||||
)
|
));
|
||||||
);
|
|
||||||
|
|
||||||
return renderTable(
|
return renderTable(
|
||||||
intl.formatMessage(
|
intl.formatMessage(
|
||||||
|
|
@ -251,7 +247,7 @@ export const SettingsScrapingPanel: React.FC = () => {
|
||||||
}
|
}
|
||||||
|
|
||||||
function renderMovieScrapers() {
|
function renderMovieScrapers() {
|
||||||
const elements = (movieScrapers?.listMovieScrapers ?? []).map((scraper) => (
|
const elements = (movieScrapers?.listScrapers ?? []).map((scraper) => (
|
||||||
<tr key={scraper.id}>
|
<tr key={scraper.id}>
|
||||||
<td>{scraper.name}</td>
|
<td>{scraper.name}</td>
|
||||||
<td>
|
<td>
|
||||||
|
|
|
||||||
|
|
@ -141,7 +141,7 @@ export const TaggerContext: React.FC = ({ children }) => {
|
||||||
}
|
}
|
||||||
|
|
||||||
const { stashBoxes } = stashConfig.general;
|
const { stashBoxes } = stashConfig.general;
|
||||||
const scrapers = Scrapers.data.listSceneScrapers;
|
const scrapers = Scrapers.data.listScrapers;
|
||||||
|
|
||||||
const stashboxSources: ITaggerSource[] = stashBoxes.map((s, i) => ({
|
const stashboxSources: ITaggerSource[] = stashBoxes.map((s, i) => ({
|
||||||
id: `${STASH_BOX_PREFIX}${i}`,
|
id: `${STASH_BOX_PREFIX}${i}`,
|
||||||
|
|
|
||||||
|
|
@ -1,61 +1,10 @@
|
||||||
import * as GQL from "src/core/generated-graphql";
|
import * as GQL from "src/core/generated-graphql";
|
||||||
import sortBy from "lodash-es/sortBy";
|
|
||||||
import {
|
import {
|
||||||
evictQueries,
|
evictQueries,
|
||||||
getClient,
|
getClient,
|
||||||
studioMutationImpactedQueries,
|
studioMutationImpactedQueries,
|
||||||
} from "src/core/StashService";
|
} from "src/core/StashService";
|
||||||
|
|
||||||
export const useUpdatePerformerStashID = () => {
|
|
||||||
const [updatePerformer] = GQL.usePerformerUpdateMutation({
|
|
||||||
onError: (errors) => errors,
|
|
||||||
});
|
|
||||||
|
|
||||||
const updatePerformerHandler = (
|
|
||||||
performerID: string,
|
|
||||||
stashIDs: GQL.StashIdInput[]
|
|
||||||
) =>
|
|
||||||
updatePerformer({
|
|
||||||
variables: {
|
|
||||||
input: {
|
|
||||||
id: performerID,
|
|
||||||
stash_ids: stashIDs.map((s) => ({
|
|
||||||
stash_id: s.stash_id,
|
|
||||||
endpoint: s.endpoint,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
update: (store, updatedPerformer) => {
|
|
||||||
if (!updatedPerformer.data?.performerUpdate) return;
|
|
||||||
const newStashID = stashIDs[stashIDs.length - 1].stash_id;
|
|
||||||
|
|
||||||
store.writeQuery<
|
|
||||||
GQL.FindPerformersQuery,
|
|
||||||
GQL.FindPerformersQueryVariables
|
|
||||||
>({
|
|
||||||
query: GQL.FindPerformersDocument,
|
|
||||||
variables: {
|
|
||||||
performer_filter: {
|
|
||||||
stash_id: {
|
|
||||||
value: newStashID,
|
|
||||||
modifier: GQL.CriterionModifier.Equals,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
findPerformers: {
|
|
||||||
count: 1,
|
|
||||||
performers: [updatedPerformer.data.performerUpdate],
|
|
||||||
__typename: "FindPerformersResultType",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return updatePerformerHandler;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useUpdatePerformer = () => {
|
export const useUpdatePerformer = () => {
|
||||||
const [updatePerformer] = GQL.usePerformerUpdateMutation({
|
const [updatePerformer] = GQL.usePerformerUpdateMutation({
|
||||||
onError: (errors) => errors,
|
onError: (errors) => errors,
|
||||||
|
|
@ -78,8 +27,9 @@ export const useUpdatePerformer = () => {
|
||||||
query: GQL.FindPerformersDocument,
|
query: GQL.FindPerformersDocument,
|
||||||
variables: {
|
variables: {
|
||||||
performer_filter: {
|
performer_filter: {
|
||||||
stash_id: {
|
stash_id_endpoint: {
|
||||||
value: id.stash_id,
|
stash_id: id.stash_id,
|
||||||
|
endpoint: id.endpoint,
|
||||||
modifier: GQL.CriterionModifier.Equals,
|
modifier: GQL.CriterionModifier.Equals,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -99,91 +49,6 @@ export const useUpdatePerformer = () => {
|
||||||
return updatePerformerHandler;
|
return updatePerformerHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useCreatePerformer = () => {
|
|
||||||
const [createPerformer] = GQL.usePerformerCreateMutation({
|
|
||||||
onError: (errors) => errors,
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleCreate = (performer: GQL.PerformerCreateInput, stashID: string) =>
|
|
||||||
createPerformer({
|
|
||||||
variables: { input: performer },
|
|
||||||
update: (store, newPerformer) => {
|
|
||||||
if (!newPerformer?.data?.performerCreate) return;
|
|
||||||
|
|
||||||
store.writeQuery<
|
|
||||||
GQL.FindPerformersQuery,
|
|
||||||
GQL.FindPerformersQueryVariables
|
|
||||||
>({
|
|
||||||
query: GQL.FindPerformersDocument,
|
|
||||||
variables: {
|
|
||||||
performer_filter: {
|
|
||||||
stash_id: {
|
|
||||||
value: stashID,
|
|
||||||
modifier: GQL.CriterionModifier.Equals,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
findPerformers: {
|
|
||||||
count: 1,
|
|
||||||
performers: [newPerformer.data.performerCreate],
|
|
||||||
__typename: "FindPerformersResultType",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return handleCreate;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useUpdateStudioStashID = () => {
|
|
||||||
const [updateStudio] = GQL.useStudioUpdateMutation({
|
|
||||||
onError: (errors) => errors,
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleUpdate = (
|
|
||||||
studio: GQL.SlimStudioDataFragment,
|
|
||||||
stashIDs: GQL.StashIdInput[]
|
|
||||||
) =>
|
|
||||||
updateStudio({
|
|
||||||
variables: {
|
|
||||||
input: {
|
|
||||||
id: studio.id,
|
|
||||||
stash_ids: stashIDs.map((s) => ({
|
|
||||||
stash_id: s.stash_id,
|
|
||||||
endpoint: s.endpoint,
|
|
||||||
})),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
update: (store, result) => {
|
|
||||||
if (!result.data?.studioUpdate) return;
|
|
||||||
const newStashID = stashIDs[stashIDs.length - 1].stash_id;
|
|
||||||
|
|
||||||
store.writeQuery<GQL.FindStudiosQuery, GQL.FindStudiosQueryVariables>({
|
|
||||||
query: GQL.FindStudiosDocument,
|
|
||||||
variables: {
|
|
||||||
studio_filter: {
|
|
||||||
stash_id: {
|
|
||||||
value: newStashID,
|
|
||||||
modifier: GQL.CriterionModifier.Equals,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
findStudios: {
|
|
||||||
count: 1,
|
|
||||||
studios: [result.data.studioUpdate],
|
|
||||||
__typename: "FindStudiosResultType",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return handleUpdate;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useUpdateStudio = () => {
|
export const useUpdateStudio = () => {
|
||||||
const [updateStudio] = GQL.useStudioUpdateMutation({
|
const [updateStudio] = GQL.useStudioUpdateMutation({
|
||||||
onError: (errors) => errors,
|
onError: (errors) => errors,
|
||||||
|
|
@ -210,8 +75,9 @@ export const useUpdateStudio = () => {
|
||||||
query: GQL.FindStudiosDocument,
|
query: GQL.FindStudiosDocument,
|
||||||
variables: {
|
variables: {
|
||||||
studio_filter: {
|
studio_filter: {
|
||||||
stash_id: {
|
stash_id_endpoint: {
|
||||||
value: id.stash_id,
|
stash_id: id.stash_id,
|
||||||
|
endpoint: id.endpoint,
|
||||||
modifier: GQL.CriterionModifier.Equals,
|
modifier: GQL.CriterionModifier.Equals,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
@ -231,101 +97,3 @@ export const useUpdateStudio = () => {
|
||||||
|
|
||||||
return updateStudioHandler;
|
return updateStudioHandler;
|
||||||
};
|
};
|
||||||
|
|
||||||
export const useCreateStudio = () => {
|
|
||||||
const [createStudio] = GQL.useStudioCreateMutation({
|
|
||||||
onError: (errors) => errors,
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleCreate = (studio: GQL.StudioCreateInput, stashID: string) =>
|
|
||||||
createStudio({
|
|
||||||
variables: { input: studio },
|
|
||||||
update: (store, result) => {
|
|
||||||
if (!result?.data?.studioCreate) return;
|
|
||||||
|
|
||||||
const currentQuery = store.readQuery<
|
|
||||||
GQL.AllStudiosForFilterQuery,
|
|
||||||
GQL.AllStudiosForFilterQueryVariables
|
|
||||||
>({
|
|
||||||
query: GQL.AllStudiosForFilterDocument,
|
|
||||||
});
|
|
||||||
const allStudios = sortBy(
|
|
||||||
[...(currentQuery?.allStudios ?? []), result.data.studioCreate],
|
|
||||||
["name"]
|
|
||||||
);
|
|
||||||
if (allStudios.length > 1) {
|
|
||||||
store.writeQuery<
|
|
||||||
GQL.AllStudiosForFilterQuery,
|
|
||||||
GQL.AllStudiosForFilterQueryVariables
|
|
||||||
>({
|
|
||||||
query: GQL.AllStudiosForFilterDocument,
|
|
||||||
data: {
|
|
||||||
allStudios,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
store.writeQuery<GQL.FindStudiosQuery, GQL.FindStudiosQueryVariables>({
|
|
||||||
query: GQL.FindStudiosDocument,
|
|
||||||
variables: {
|
|
||||||
studio_filter: {
|
|
||||||
stash_id: {
|
|
||||||
value: stashID,
|
|
||||||
modifier: GQL.CriterionModifier.Equals,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
data: {
|
|
||||||
findStudios: {
|
|
||||||
count: 1,
|
|
||||||
studios: [result.data.studioCreate],
|
|
||||||
__typename: "FindStudiosResultType",
|
|
||||||
},
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return handleCreate;
|
|
||||||
};
|
|
||||||
|
|
||||||
export const useCreateTag = () => {
|
|
||||||
const [createTag] = GQL.useTagCreateMutation({
|
|
||||||
onError: (errors) => errors,
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleCreate = (tag: string) =>
|
|
||||||
createTag({
|
|
||||||
variables: {
|
|
||||||
input: {
|
|
||||||
name: tag,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
update: (store, result) => {
|
|
||||||
if (!result.data?.tagCreate) return;
|
|
||||||
|
|
||||||
const currentQuery = store.readQuery<
|
|
||||||
GQL.AllTagsForFilterQuery,
|
|
||||||
GQL.AllTagsForFilterQueryVariables
|
|
||||||
>({
|
|
||||||
query: GQL.AllTagsForFilterDocument,
|
|
||||||
});
|
|
||||||
const allTags = sortBy(
|
|
||||||
[...(currentQuery?.allTags ?? []), result.data.tagCreate],
|
|
||||||
["name"]
|
|
||||||
);
|
|
||||||
|
|
||||||
store.writeQuery<
|
|
||||||
GQL.AllTagsForFilterQuery,
|
|
||||||
GQL.AllTagsForFilterQueryVariables
|
|
||||||
>({
|
|
||||||
query: GQL.AllTagsForFilterDocument,
|
|
||||||
data: {
|
|
||||||
allTags,
|
|
||||||
},
|
|
||||||
});
|
|
||||||
},
|
|
||||||
});
|
|
||||||
|
|
||||||
return handleCreate;
|
|
||||||
};
|
|
||||||
|
|
|
||||||
|
|
@ -15,15 +15,15 @@ export const scrapedMovieToCreateInput = (toCreate: GQL.ScrapedMovie) => {
|
||||||
? DurationUtils.stringToSeconds(toCreate.duration)
|
? DurationUtils.stringToSeconds(toCreate.duration)
|
||||||
: undefined,
|
: undefined,
|
||||||
studio_id: toCreate.studio?.stored_id,
|
studio_id: toCreate.studio?.stored_id,
|
||||||
rating: parseInt(toCreate.rating ?? "0", 10),
|
rating100: parseInt(toCreate.rating ?? "0", 10) * 20,
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!input.duration) {
|
if (!input.duration) {
|
||||||
input.duration = undefined;
|
input.duration = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!input.rating || Number.isNaN(input.rating)) {
|
if (!input.rating100 || Number.isNaN(input.rating100)) {
|
||||||
input.rating = undefined;
|
input.rating100 = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
return input;
|
return input;
|
||||||
|
|
|
||||||
|
|
@ -86,6 +86,8 @@ export function sortPerformers<T extends IPerformerFragment>(performers: T[]) {
|
||||||
export const scrapedPerformerToCreateInput = (
|
export const scrapedPerformerToCreateInput = (
|
||||||
toCreate: GQL.ScrapedPerformer
|
toCreate: GQL.ScrapedPerformer
|
||||||
) => {
|
) => {
|
||||||
|
const aliases = toCreate.aliases?.split(",").map((a) => a.trim());
|
||||||
|
|
||||||
const input: GQL.PerformerCreateInput = {
|
const input: GQL.PerformerCreateInput = {
|
||||||
name: toCreate.name ?? "",
|
name: toCreate.name ?? "",
|
||||||
url: toCreate.url,
|
url: toCreate.url,
|
||||||
|
|
@ -100,7 +102,7 @@ export const scrapedPerformerToCreateInput = (
|
||||||
career_length: toCreate.career_length,
|
career_length: toCreate.career_length,
|
||||||
tattoos: toCreate.tattoos,
|
tattoos: toCreate.tattoos,
|
||||||
piercings: toCreate.piercings,
|
piercings: toCreate.piercings,
|
||||||
aliases: toCreate.aliases,
|
alias_list: aliases,
|
||||||
twitter: toCreate.twitter,
|
twitter: toCreate.twitter,
|
||||||
instagram: toCreate.instagram,
|
instagram: toCreate.instagram,
|
||||||
tag_ids: filterData((toCreate.tags ?? []).map((t) => t.stored_id)),
|
tag_ids: filterData((toCreate.tags ?? []).map((t) => t.stored_id)),
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue