stash
This commit is contained in:
@@ -0,0 +1,302 @@
|
||||
# most of this copied from https://github.com/niemands/StashPlugins
|
||||
|
||||
import requests
|
||||
import sys
|
||||
import log
|
||||
|
||||
class IdentifierStashInterface:
|
||||
port = ""
|
||||
url = ""
|
||||
headers = {
|
||||
"Accept-Encoding": "gzip, deflate, br",
|
||||
"Content-Type": "application/json",
|
||||
"Accept": "application/json",
|
||||
"Connection": "keep-alive",
|
||||
"DNT": "1"
|
||||
}
|
||||
cookies = {}
|
||||
|
||||
#
|
||||
# Init
|
||||
#
|
||||
|
||||
def __init__(self, conn):
|
||||
self.port = conn['Port']
|
||||
scheme = conn['Scheme']
|
||||
|
||||
# Session cookie for authentication
|
||||
self.cookies = {
|
||||
'session': conn.get('SessionCookie').get('Value')
|
||||
}
|
||||
|
||||
try:
|
||||
# If stash does not accept connections from all interfaces use the host specified in the config
|
||||
host = conn.get('Host') if '0.0.0.0' not in conn.get('Host') or '' else 'localhost'
|
||||
except TypeError:
|
||||
# Pre stable 0.8
|
||||
host = 'localhost'
|
||||
|
||||
# Stash GraphQL endpoint
|
||||
self.url = scheme + "://" + host + ":" + str(self.port) + "/graphql"
|
||||
log.LogDebug(f"Using stash GraphQl endpoint at {self.url}")
|
||||
|
||||
def __callGraphQL(self, query, variables=None):
|
||||
json = {'query': query}
|
||||
if variables is not None:
|
||||
json['variables'] = variables
|
||||
|
||||
response = requests.post(self.url, json=json, headers=self.headers, cookies=self.cookies)
|
||||
|
||||
if response.status_code == 200:
|
||||
result = response.json()
|
||||
if result.get("error", None):
|
||||
for error in result["error"]["errors"]:
|
||||
raise Exception("GraphQL error: {}".format(error))
|
||||
if result.get("data", None):
|
||||
return result.get("data")
|
||||
elif response.status_code == 401:
|
||||
sys.exit("HTTP Error 401, Unauthorised. Cookie authentication most likely failed")
|
||||
else:
|
||||
raise ConnectionError(
|
||||
"GraphQL query failed:{} - {}. Query: {}. Variables: {}".format(
|
||||
response.status_code, response.content, query, variables)
|
||||
)
|
||||
|
||||
#
|
||||
# Queries
|
||||
#
|
||||
|
||||
# Performers
|
||||
|
||||
def getPerformerImages(self, performer_filter=None):
|
||||
return self.__getPerformerImages(performer_filter)
|
||||
|
||||
def __getPerformerImages(self, performer_filter=None, page=1):
|
||||
per_page = 1000
|
||||
query = """
|
||||
query($per_page: Int, $page: Int, $performer_filter: PerformerFilterType) {
|
||||
findPerformers(
|
||||
performer_filter: $performer_filter
|
||||
filter: { per_page: $per_page, page: $page }
|
||||
) {
|
||||
count
|
||||
performers {
|
||||
id
|
||||
name
|
||||
image_path
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
variables = {
|
||||
'per_page': per_page,
|
||||
'page': page
|
||||
}
|
||||
if performer_filter:
|
||||
variables['performer_filter'] = performer_filter
|
||||
|
||||
result = self.__callGraphQL(query, variables)
|
||||
|
||||
performers = result.get('findPerformers').get('performers')
|
||||
|
||||
if len(performers) == per_page:
|
||||
next_page = self.__getPerformerImages(performer_filter, page + 1)
|
||||
for performer in next_page:
|
||||
performers.append(performer)
|
||||
|
||||
return performers
|
||||
|
||||
# Tags
|
||||
|
||||
def findTagIdWithName(self, name):
|
||||
query = """
|
||||
query($name: String!) {
|
||||
findTags(
|
||||
tag_filter: {
|
||||
name: {value: $name, modifier: EQUALS}
|
||||
}
|
||||
){
|
||||
tags{
|
||||
id
|
||||
name
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
variables = {
|
||||
'name': name,
|
||||
}
|
||||
|
||||
result = self.__callGraphQL(query, variables)
|
||||
if result.get('findTags') is not None and result.get('findTags').get('tags') != []:
|
||||
return result.get('findTags').get('tags')[0].get('id')
|
||||
return None
|
||||
|
||||
# Images
|
||||
|
||||
def findImages(self, image_filter=None):
|
||||
return self.__findImages(image_filter)
|
||||
|
||||
def __findImages(self, image_filter=None, page=1):
|
||||
per_page = 1000
|
||||
query = """
|
||||
query($per_page: Int, $page: Int, $image_filter: ImageFilterType) {
|
||||
findImages(
|
||||
image_filter: $image_filter,
|
||||
filter: { per_page: $per_page, page: $page }
|
||||
) {
|
||||
count
|
||||
images {
|
||||
id
|
||||
path
|
||||
performers {
|
||||
id
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
variables = {
|
||||
'per_page': per_page,
|
||||
'page': page
|
||||
}
|
||||
if image_filter:
|
||||
variables['image_filter'] = image_filter
|
||||
|
||||
result = self.__callGraphQL(query, variables)
|
||||
|
||||
images = result.get('findImages').get('images')
|
||||
|
||||
if len(images) == per_page:
|
||||
next_page = self.__findImages(image_filter, page + 1)
|
||||
for image in next_page:
|
||||
images.append(image)
|
||||
|
||||
return images
|
||||
|
||||
# Scenes
|
||||
|
||||
def getScenePaths(self, scene_filter=None):
|
||||
return self.__getScenePaths(scene_filter)
|
||||
|
||||
def __getScenePaths(self, scene_filter=None, page=1):
|
||||
per_page = 1000
|
||||
query = """
|
||||
query($per_page: Int, $page: Int, $scene_filter: SceneFilterType) {
|
||||
findScenes(
|
||||
scene_filter: $scene_filter,
|
||||
filter: { per_page: $per_page, page: $page }
|
||||
) {
|
||||
count
|
||||
scenes {
|
||||
id
|
||||
paths {
|
||||
screenshot
|
||||
stream
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
variables = {
|
||||
'per_page': per_page,
|
||||
'page': page
|
||||
}
|
||||
if scene_filter:
|
||||
variables['scene_filter'] = scene_filter
|
||||
|
||||
result = self.__callGraphQL(query, variables)
|
||||
scenes = result.get('findScenes').get('scenes')
|
||||
|
||||
if len(scenes) == 1000:
|
||||
next_page = self.__getScenePaths(scene_filter, page + 1)
|
||||
for scene in next_page:
|
||||
scenes.append(scene)
|
||||
|
||||
return scenes
|
||||
|
||||
|
||||
#
|
||||
# Mutations
|
||||
#
|
||||
|
||||
def createTagWithName(self, name):
|
||||
query = """
|
||||
mutation tagCreate($input:TagCreateInput!) {
|
||||
tagCreate(input: $input){
|
||||
id
|
||||
}
|
||||
}
|
||||
"""
|
||||
variables = {'input': {
|
||||
'name': name
|
||||
}}
|
||||
|
||||
result = self.__callGraphQL(query, variables)
|
||||
if result.get('tagCreate'):
|
||||
log.LogDebug(f"Created tag: {name}")
|
||||
return result.get('tagCreate').get("id")
|
||||
else:
|
||||
log.LogError(f"Could not create tag: {name}")
|
||||
return None
|
||||
|
||||
def updateImage(self, image_data):
|
||||
query = """
|
||||
mutation($input: ImageUpdateInput!) {
|
||||
imageUpdate(input: $input) {
|
||||
id
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
variables = {'input': image_data}
|
||||
|
||||
self.__callGraphQL(query, variables)
|
||||
|
||||
def addPerformersToImage(self, image_id, performer_ids):
|
||||
self.updateImage({
|
||||
'id': image_id,
|
||||
'performer_ids': performer_ids
|
||||
})
|
||||
|
||||
def bulkPerformerAddTags(self, performer_ids, tag_ids):
|
||||
query = """
|
||||
mutation($ids: [ID!], $tag_ids: BulkUpdateIds) {
|
||||
bulkPerformerUpdate(input: { ids: $ids, tag_ids: $tag_ids }) {
|
||||
id
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
variables = {
|
||||
"ids": performer_ids,
|
||||
"tag_ids": {
|
||||
"ids": tag_ids,
|
||||
"mode": 'ADD'
|
||||
}
|
||||
}
|
||||
|
||||
self.__callGraphQL(query, variables)
|
||||
|
||||
def addPerformersToScene(self, scene_id, performer_ids):
|
||||
query = """
|
||||
mutation BulkSceneUpdate($ids: [ID!], $performer_ids: BulkUpdateIds) {
|
||||
bulkSceneUpdate(input: { ids: $ids, performer_ids: $performer_ids}) {
|
||||
id
|
||||
}
|
||||
}
|
||||
"""
|
||||
|
||||
variables = {
|
||||
"ids": [scene_id],
|
||||
"performer_ids": {
|
||||
"ids": performer_ids,
|
||||
"mode": "ADD"
|
||||
}
|
||||
}
|
||||
|
||||
self.__callGraphQL(query, variables)
|
||||
Reference in New Issue
Block a user