mirror of
https://github.com/stashapp/stash.git
synced 2025-12-18 04:44:37 +03:00
Images section (#813)
* Add new configuration options * Refactor scan/clean * Schema changes * Add details to galleries * Remove redundant code * Refine thumbnail generation * Gallery overhaul * Don't allow modifying zip gallery images * Show gallery card overlays * Hide zoom slider when not in grid mode
This commit is contained in:
@@ -1,5 +1,9 @@
|
||||
fragment ConfigGeneralData on ConfigGeneralResult {
|
||||
stashes
|
||||
stashes {
|
||||
path
|
||||
excludeVideo
|
||||
excludeImage
|
||||
}
|
||||
databasePath
|
||||
generatedPath
|
||||
cachePath
|
||||
@@ -19,7 +23,12 @@ fragment ConfigGeneralData on ConfigGeneralResult {
|
||||
logOut
|
||||
logLevel
|
||||
logAccess
|
||||
createGalleriesFromFolders
|
||||
videoExtensions
|
||||
imageExtensions
|
||||
galleryExtensions
|
||||
excludes
|
||||
imageExcludes
|
||||
scraperUserAgent
|
||||
scraperCDPPath
|
||||
stashBoxes {
|
||||
|
||||
@@ -3,10 +3,25 @@ fragment GalleryData on Gallery {
|
||||
checksum
|
||||
path
|
||||
title
|
||||
files {
|
||||
index
|
||||
name
|
||||
path
|
||||
date
|
||||
url
|
||||
details
|
||||
rating
|
||||
images {
|
||||
...SlimImageData
|
||||
}
|
||||
cover {
|
||||
...SlimImageData
|
||||
}
|
||||
studio {
|
||||
...StudioData
|
||||
}
|
||||
tags {
|
||||
...TagData
|
||||
}
|
||||
|
||||
performers {
|
||||
...PerformerData
|
||||
}
|
||||
scene {
|
||||
id
|
||||
|
||||
43
graphql/documents/data/image-slim.graphql
Normal file
43
graphql/documents/data/image-slim.graphql
Normal file
@@ -0,0 +1,43 @@
|
||||
fragment SlimImageData on Image {
|
||||
id
|
||||
checksum
|
||||
title
|
||||
rating
|
||||
o_counter
|
||||
path
|
||||
|
||||
file {
|
||||
size
|
||||
width
|
||||
height
|
||||
}
|
||||
|
||||
paths {
|
||||
thumbnail
|
||||
image
|
||||
}
|
||||
|
||||
galleries {
|
||||
id
|
||||
path
|
||||
title
|
||||
}
|
||||
|
||||
studio {
|
||||
id
|
||||
name
|
||||
image_path
|
||||
}
|
||||
|
||||
tags {
|
||||
id
|
||||
name
|
||||
}
|
||||
|
||||
performers {
|
||||
id
|
||||
name
|
||||
favorite
|
||||
image_path
|
||||
}
|
||||
}
|
||||
35
graphql/documents/data/image.graphql
Normal file
35
graphql/documents/data/image.graphql
Normal file
@@ -0,0 +1,35 @@
|
||||
fragment ImageData on Image {
|
||||
id
|
||||
checksum
|
||||
title
|
||||
rating
|
||||
o_counter
|
||||
path
|
||||
|
||||
file {
|
||||
size
|
||||
width
|
||||
height
|
||||
}
|
||||
|
||||
paths {
|
||||
thumbnail
|
||||
image
|
||||
}
|
||||
|
||||
galleries {
|
||||
...GalleryData
|
||||
}
|
||||
|
||||
studio {
|
||||
...StudioData
|
||||
}
|
||||
|
||||
tags {
|
||||
...TagData
|
||||
}
|
||||
|
||||
performers {
|
||||
...PerformerData
|
||||
}
|
||||
}
|
||||
97
graphql/documents/mutations/gallery.graphql
Normal file
97
graphql/documents/mutations/gallery.graphql
Normal file
@@ -0,0 +1,97 @@
|
||||
mutation GalleryCreate(
|
||||
$title: String!,
|
||||
$details: String,
|
||||
$url: String,
|
||||
$date: String,
|
||||
$rating: Int,
|
||||
$scene_id: ID,
|
||||
$studio_id: ID,
|
||||
$performer_ids: [ID!] = [],
|
||||
$tag_ids: [ID!] = []) {
|
||||
|
||||
galleryCreate(input: {
|
||||
title: $title,
|
||||
details: $details,
|
||||
url: $url,
|
||||
date: $date,
|
||||
rating: $rating,
|
||||
scene_id: $scene_id,
|
||||
studio_id: $studio_id,
|
||||
tag_ids: $tag_ids,
|
||||
performer_ids: $performer_ids
|
||||
}) {
|
||||
...GalleryData
|
||||
}
|
||||
}
|
||||
|
||||
mutation GalleryUpdate(
|
||||
$id: ID!,
|
||||
$title: String,
|
||||
$details: String,
|
||||
$url: String,
|
||||
$date: String,
|
||||
$rating: Int,
|
||||
$scene_id: ID,
|
||||
$studio_id: ID,
|
||||
$performer_ids: [ID!] = [],
|
||||
$tag_ids: [ID!] = []) {
|
||||
|
||||
galleryUpdate(input: {
|
||||
id: $id,
|
||||
title: $title,
|
||||
details: $details,
|
||||
url: $url,
|
||||
date: $date,
|
||||
rating: $rating,
|
||||
scene_id: $scene_id,
|
||||
studio_id: $studio_id,
|
||||
tag_ids: $tag_ids,
|
||||
performer_ids: $performer_ids
|
||||
}) {
|
||||
...GalleryData
|
||||
}
|
||||
}
|
||||
|
||||
mutation BulkGalleryUpdate(
|
||||
$ids: [ID!] = [],
|
||||
$url: String,
|
||||
$date: String,
|
||||
$details: String,
|
||||
$rating: Int,
|
||||
$scene_id: ID,
|
||||
$studio_id: ID,
|
||||
$tag_ids: BulkUpdateIds,
|
||||
$performer_ids: BulkUpdateIds) {
|
||||
|
||||
bulkGalleryUpdate(input: {
|
||||
ids: $ids,
|
||||
details: $details,
|
||||
url: $url,
|
||||
date: $date,
|
||||
rating: $rating,
|
||||
scene_id: $scene_id,
|
||||
studio_id: $studio_id,
|
||||
tag_ids: $tag_ids,
|
||||
performer_ids: $performer_ids
|
||||
}) {
|
||||
...GalleryData
|
||||
}
|
||||
}
|
||||
|
||||
mutation GalleriesUpdate($input : [GalleryUpdateInput!]!) {
|
||||
galleriesUpdate(input: $input) {
|
||||
...GalleryData
|
||||
}
|
||||
}
|
||||
|
||||
mutation GalleryDestroy($ids: [ID!]!, $delete_file: Boolean, $delete_generated : Boolean) {
|
||||
galleryDestroy(input: {ids: $ids, delete_file: $delete_file, delete_generated: $delete_generated})
|
||||
}
|
||||
|
||||
mutation AddGalleryImages($gallery_id: ID!, $image_ids: [ID!]!) {
|
||||
addGalleryImages(input: {gallery_id: $gallery_id, image_ids: $image_ids})
|
||||
}
|
||||
|
||||
mutation RemoveGalleryImages($gallery_id: ID!, $image_ids: [ID!]!) {
|
||||
removeGalleryImages(input: {gallery_id: $gallery_id, image_ids: $image_ids})
|
||||
}
|
||||
69
graphql/documents/mutations/image.graphql
Normal file
69
graphql/documents/mutations/image.graphql
Normal file
@@ -0,0 +1,69 @@
|
||||
mutation ImageUpdate(
|
||||
$id: ID!,
|
||||
$title: String,
|
||||
$rating: Int,
|
||||
$studio_id: ID,
|
||||
$gallery_ids: [ID!] = [],
|
||||
$performer_ids: [ID!] = [],
|
||||
$tag_ids: [ID!] = []) {
|
||||
|
||||
imageUpdate(input: {
|
||||
id: $id,
|
||||
title: $title,
|
||||
rating: $rating,
|
||||
studio_id: $studio_id,
|
||||
gallery_ids: $gallery_ids,
|
||||
performer_ids: $performer_ids,
|
||||
tag_ids: $tag_ids
|
||||
}) {
|
||||
...ImageData
|
||||
}
|
||||
}
|
||||
|
||||
mutation BulkImageUpdate(
|
||||
$ids: [ID!] = [],
|
||||
$title: String,
|
||||
$rating: Int,
|
||||
$studio_id: ID,
|
||||
$gallery_ids: BulkUpdateIds,
|
||||
$performer_ids: BulkUpdateIds,
|
||||
$tag_ids: BulkUpdateIds) {
|
||||
|
||||
bulkImageUpdate(input: {
|
||||
ids: $ids,
|
||||
title: $title,
|
||||
rating: $rating,
|
||||
studio_id: $studio_id,
|
||||
gallery_ids: $gallery_ids,
|
||||
performer_ids: $performer_ids,
|
||||
tag_ids: $tag_ids
|
||||
}) {
|
||||
...ImageData
|
||||
}
|
||||
}
|
||||
|
||||
mutation ImagesUpdate($input : [ImageUpdateInput!]!) {
|
||||
imagesUpdate(input: $input) {
|
||||
...ImageData
|
||||
}
|
||||
}
|
||||
|
||||
mutation ImageIncrementO($id: ID!) {
|
||||
imageIncrementO(id: $id)
|
||||
}
|
||||
|
||||
mutation ImageDecrementO($id: ID!) {
|
||||
imageDecrementO(id: $id)
|
||||
}
|
||||
|
||||
mutation ImageResetO($id: ID!) {
|
||||
imageResetO(id: $id)
|
||||
}
|
||||
|
||||
mutation ImageDestroy($id: ID!, $delete_file: Boolean, $delete_generated : Boolean) {
|
||||
imageDestroy(input: {id: $id, delete_file: $delete_file, delete_generated: $delete_generated})
|
||||
}
|
||||
|
||||
mutation ImagesDestroy($ids: [ID!]!, $delete_file: Boolean, $delete_generated : Boolean) {
|
||||
imagesDestroy(input: {ids: $ids, delete_file: $delete_file, delete_generated: $delete_generated})
|
||||
}
|
||||
14
graphql/documents/queries/image.graphql
Normal file
14
graphql/documents/queries/image.graphql
Normal file
@@ -0,0 +1,14 @@
|
||||
query FindImages($filter: FindFilterType, $image_filter: ImageFilterType, $image_ids: [Int!]) {
|
||||
findImages(filter: $filter, image_filter: $image_filter, image_ids: $image_ids) {
|
||||
count
|
||||
images {
|
||||
...SlimImageData
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
query FindImage($id: ID!, $checksum: String) {
|
||||
findImage(id: $id, checksum: $checksum) {
|
||||
...ImageData
|
||||
}
|
||||
}
|
||||
@@ -40,6 +40,7 @@ query ValidGalleriesForScene($scene_id: ID!) {
|
||||
validGalleriesForScene(scene_id: $scene_id) {
|
||||
id
|
||||
path
|
||||
title
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,6 +17,11 @@ type Query {
|
||||
"""A function which queries SceneMarker objects"""
|
||||
findSceneMarkers(scene_marker_filter: SceneMarkerFilterType filter: FindFilterType): FindSceneMarkersResultType!
|
||||
|
||||
findImage(id: ID, checksum: String): Image
|
||||
|
||||
"""A function which queries Scene objects"""
|
||||
findImages(image_filter: ImageFilterType, image_ids: [Int!], filter: FindFilterType): FindImagesResultType!
|
||||
|
||||
"""Find a performer by ID"""
|
||||
findPerformer(id: ID!): Performer
|
||||
"""A function which queries Performer objects"""
|
||||
@@ -141,6 +146,28 @@ type Mutation {
|
||||
sceneMarkerUpdate(input: SceneMarkerUpdateInput!): SceneMarker
|
||||
sceneMarkerDestroy(id: ID!): Boolean!
|
||||
|
||||
imageUpdate(input: ImageUpdateInput!): Image
|
||||
bulkImageUpdate(input: BulkImageUpdateInput!): [Image!]
|
||||
imageDestroy(input: ImageDestroyInput!): Boolean!
|
||||
imagesDestroy(input: ImagesDestroyInput!): Boolean!
|
||||
imagesUpdate(input: [ImageUpdateInput!]!): [Image]
|
||||
|
||||
"""Increments the o-counter for an image. Returns the new value"""
|
||||
imageIncrementO(id: ID!): Int!
|
||||
"""Decrements the o-counter for an image. Returns the new value"""
|
||||
imageDecrementO(id: ID!): Int!
|
||||
"""Resets the o-counter for a image to 0. Returns the new value"""
|
||||
imageResetO(id: ID!): Int!
|
||||
|
||||
galleryCreate(input: GalleryCreateInput!): Gallery
|
||||
galleryUpdate(input: GalleryUpdateInput!): Gallery
|
||||
bulkGalleryUpdate(input: BulkGalleryUpdateInput!): [Gallery!]
|
||||
galleryDestroy(input: GalleryDestroyInput!): Boolean!
|
||||
galleriesUpdate(input: [GalleryUpdateInput!]!): [Gallery]
|
||||
|
||||
addGalleryImages(input: GalleryAddInput!): Boolean!
|
||||
removeGalleryImages(input: GalleryRemoveInput!): Boolean!
|
||||
|
||||
performerCreate(input: PerformerCreateInput!): Performer
|
||||
performerUpdate(input: PerformerUpdateInput!): Performer
|
||||
performerDestroy(input: PerformerDestroyInput!): Boolean!
|
||||
|
||||
@@ -24,7 +24,7 @@ enum HashAlgorithm {
|
||||
|
||||
input ConfigGeneralInput {
|
||||
"""Array of file paths to content"""
|
||||
stashes: [String!]
|
||||
stashes: [StashConfigInput!]
|
||||
"""Path to the SQLite database"""
|
||||
databasePath: String
|
||||
"""Path to generated files"""
|
||||
@@ -63,8 +63,18 @@ input ConfigGeneralInput {
|
||||
logLevel: String!
|
||||
"""Whether to log http access"""
|
||||
logAccess: Boolean!
|
||||
"""Array of file regexp to exclude from Scan"""
|
||||
"""True if galleries should be created from folders with images"""
|
||||
createGalleriesFromFolders: Boolean!
|
||||
"""Array of video file extensions"""
|
||||
videoExtensions: [String!]
|
||||
"""Array of image file extensions"""
|
||||
imageExtensions: [String!]
|
||||
"""Array of gallery zip file extensions"""
|
||||
galleryExtensions: [String!]
|
||||
"""Array of file regexp to exclude from Video Scans"""
|
||||
excludes: [String!]
|
||||
"""Array of file regexp to exclude from Image Scans"""
|
||||
imageExcludes: [String!]
|
||||
"""Scraper user agent string"""
|
||||
scraperUserAgent: String
|
||||
"""Scraper CDP path. Path to chrome executable or remote address"""
|
||||
@@ -75,7 +85,7 @@ input ConfigGeneralInput {
|
||||
|
||||
type ConfigGeneralResult {
|
||||
"""Array of file paths to content"""
|
||||
stashes: [String!]!
|
||||
stashes: [StashConfig!]!
|
||||
"""Path to the SQLite database"""
|
||||
databasePath: String!
|
||||
"""Path to generated files"""
|
||||
@@ -114,8 +124,18 @@ type ConfigGeneralResult {
|
||||
logLevel: String!
|
||||
"""Whether to log http access"""
|
||||
logAccess: Boolean!
|
||||
"""Array of file regexp to exclude from Scan"""
|
||||
"""Array of video file extensions"""
|
||||
videoExtensions: [String!]!
|
||||
"""Array of image file extensions"""
|
||||
imageExtensions: [String!]!
|
||||
"""Array of gallery zip file extensions"""
|
||||
galleryExtensions: [String!]!
|
||||
"""True if galleries should be created from folders with images"""
|
||||
createGalleriesFromFolders: Boolean!
|
||||
"""Array of file regexp to exclude from Video Scans"""
|
||||
excludes: [String!]!
|
||||
"""Array of file regexp to exclude from Image Scans"""
|
||||
imageExcludes: [String!]!
|
||||
"""Scraper user agent string"""
|
||||
scraperUserAgent: String
|
||||
"""Scraper CDP path. Path to chrome executable or remote address"""
|
||||
@@ -175,3 +195,16 @@ type Directory {
|
||||
parent: String
|
||||
directories: [String!]!
|
||||
}
|
||||
|
||||
"""Stash configuration details"""
|
||||
input StashConfigInput {
|
||||
path: String!
|
||||
excludeVideo: Boolean!
|
||||
excludeImage: Boolean!
|
||||
}
|
||||
|
||||
type StashConfig {
|
||||
path: String!
|
||||
excludeVideo: Boolean!
|
||||
excludeImage: Boolean!
|
||||
}
|
||||
|
||||
@@ -107,6 +107,18 @@ input GalleryFilterType {
|
||||
path: StringCriterionInput
|
||||
"""Filter to only include galleries missing this property"""
|
||||
is_missing: String
|
||||
"""Filter to include/exclude galleries that were created from zip"""
|
||||
is_zip: Boolean
|
||||
"""Filter by rating"""
|
||||
rating: IntCriterionInput
|
||||
"""Filter to only include scenes with this studio"""
|
||||
studios: MultiCriterionInput
|
||||
"""Filter to only include scenes with these tags"""
|
||||
tags: MultiCriterionInput
|
||||
"""Filter to only include scenes with these performers"""
|
||||
performers: MultiCriterionInput
|
||||
"""Filter by number of images in this gallery"""
|
||||
image_count: IntCriterionInput
|
||||
}
|
||||
|
||||
input TagFilterType {
|
||||
@@ -120,6 +132,25 @@ input TagFilterType {
|
||||
marker_count: IntCriterionInput
|
||||
}
|
||||
|
||||
input ImageFilterType {
|
||||
"""Filter by rating"""
|
||||
rating: IntCriterionInput
|
||||
"""Filter by o-counter"""
|
||||
o_counter: IntCriterionInput
|
||||
"""Filter by resolution"""
|
||||
resolution: ResolutionEnum
|
||||
"""Filter to only include images missing this property"""
|
||||
is_missing: String
|
||||
"""Filter to only include images with this studio"""
|
||||
studios: MultiCriterionInput
|
||||
"""Filter to only include images with these tags"""
|
||||
tags: MultiCriterionInput
|
||||
"""Filter to only include images with these performers"""
|
||||
performers: MultiCriterionInput
|
||||
"""Filter to only include images with these galleries"""
|
||||
galleries: MultiCriterionInput
|
||||
}
|
||||
|
||||
enum CriterionModifier {
|
||||
"""="""
|
||||
EQUALS,
|
||||
|
||||
@@ -2,12 +2,20 @@
|
||||
type Gallery {
|
||||
id: ID!
|
||||
checksum: String!
|
||||
path: String!
|
||||
path: String
|
||||
title: String
|
||||
url: String
|
||||
date: String
|
||||
details: String
|
||||
rating: Int
|
||||
scene: Scene
|
||||
studio: Studio
|
||||
tags: [Tag!]!
|
||||
performers: [Performer!]!
|
||||
|
||||
"""The files in the gallery"""
|
||||
files: [GalleryFilesType!]! # Resolver
|
||||
"""The images in the gallery"""
|
||||
images: [Image!]! # Resolver
|
||||
cover: Image
|
||||
}
|
||||
|
||||
type GalleryFilesType {
|
||||
@@ -16,7 +24,62 @@ type GalleryFilesType {
|
||||
path: String
|
||||
}
|
||||
|
||||
input GalleryCreateInput {
|
||||
title: String!
|
||||
url: String
|
||||
date: String
|
||||
details: String
|
||||
rating: Int
|
||||
scene_id: ID
|
||||
studio_id: ID
|
||||
tag_ids: [ID!]
|
||||
performer_ids: [ID!]
|
||||
}
|
||||
|
||||
input GalleryUpdateInput {
|
||||
clientMutationId: String
|
||||
id: ID!
|
||||
title: String
|
||||
url: String
|
||||
date: String
|
||||
details: String
|
||||
rating: Int
|
||||
scene_id: ID
|
||||
studio_id: ID
|
||||
tag_ids: [ID!]
|
||||
performer_ids: [ID!]
|
||||
}
|
||||
|
||||
input BulkGalleryUpdateInput {
|
||||
clientMutationId: String
|
||||
ids: [ID!]
|
||||
url: String
|
||||
date: String
|
||||
details: String
|
||||
rating: Int
|
||||
scene_id: ID
|
||||
studio_id: ID
|
||||
tag_ids: BulkUpdateIds
|
||||
performer_ids: BulkUpdateIds
|
||||
}
|
||||
|
||||
input GalleryDestroyInput {
|
||||
ids: [ID!]!
|
||||
delete_file: Boolean
|
||||
delete_generated: Boolean
|
||||
}
|
||||
|
||||
type FindGalleriesResultType {
|
||||
count: Int!
|
||||
galleries: [Gallery!]!
|
||||
}
|
||||
}
|
||||
|
||||
input GalleryAddInput {
|
||||
gallery_id: ID!
|
||||
image_ids: [ID!]!
|
||||
}
|
||||
|
||||
input GalleryRemoveInput {
|
||||
gallery_id: ID!
|
||||
image_ids: [ID!]!
|
||||
}
|
||||
|
||||
68
graphql/schema/types/image.graphql
Normal file
68
graphql/schema/types/image.graphql
Normal file
@@ -0,0 +1,68 @@
|
||||
type Image {
|
||||
id: ID!
|
||||
checksum: String
|
||||
title: String
|
||||
rating: Int
|
||||
o_counter: Int
|
||||
path: String!
|
||||
|
||||
file: ImageFileType! # Resolver
|
||||
paths: ImagePathsType! # Resolver
|
||||
|
||||
galleries: [Gallery!]!
|
||||
studio: Studio
|
||||
tags: [Tag!]!
|
||||
performers: [Performer!]!
|
||||
}
|
||||
|
||||
type ImageFileType {
|
||||
size: Int
|
||||
width: Int
|
||||
height: Int
|
||||
}
|
||||
|
||||
type ImagePathsType {
|
||||
thumbnail: String # Resolver
|
||||
image: String # Resolver
|
||||
}
|
||||
|
||||
input ImageUpdateInput {
|
||||
clientMutationId: String
|
||||
id: ID!
|
||||
title: String
|
||||
rating: Int
|
||||
|
||||
studio_id: ID
|
||||
performer_ids: [ID!]
|
||||
tag_ids: [ID!]
|
||||
gallery_ids: [ID!]
|
||||
}
|
||||
|
||||
input BulkImageUpdateInput {
|
||||
clientMutationId: String
|
||||
ids: [ID!]
|
||||
title: String
|
||||
rating: Int
|
||||
|
||||
studio_id: ID
|
||||
performer_ids: BulkUpdateIds
|
||||
tag_ids: BulkUpdateIds
|
||||
gallery_ids: BulkUpdateIds
|
||||
}
|
||||
|
||||
input ImageDestroyInput {
|
||||
id: ID!
|
||||
delete_file: Boolean
|
||||
delete_generated: Boolean
|
||||
}
|
||||
|
||||
input ImagesDestroyInput {
|
||||
ids: [ID!]!
|
||||
delete_file: Boolean
|
||||
delete_generated: Boolean
|
||||
}
|
||||
|
||||
type FindImagesResultType {
|
||||
count: Int!
|
||||
images: [Image!]!
|
||||
}
|
||||
@@ -7,15 +7,11 @@ input GenerateMetadataInput {
|
||||
previewOptions: GeneratePreviewOptionsInput
|
||||
markers: Boolean!
|
||||
transcodes: Boolean!
|
||||
"""gallery thumbnails for cache usage"""
|
||||
thumbnails: Boolean!
|
||||
|
||||
"""scene ids to generate for"""
|
||||
sceneIDs: [ID!]
|
||||
"""marker ids to generate for"""
|
||||
markerIDs: [ID!]
|
||||
"""gallery ids to generate for"""
|
||||
galleryIDs: [ID!]
|
||||
|
||||
"""overwrite existing media"""
|
||||
overwrite: Boolean
|
||||
@@ -60,6 +56,7 @@ input ExportObjectTypeInput {
|
||||
|
||||
input ExportObjectsInput {
|
||||
scenes: ExportObjectTypeInput
|
||||
images: ExportObjectTypeInput
|
||||
studios: ExportObjectTypeInput
|
||||
performers: ExportObjectTypeInput
|
||||
tags: ExportObjectTypeInput
|
||||
|
||||
Reference in New Issue
Block a user