[plugin] Add titleFromFilename plugin (#81)

This commit is contained in:
bnkai
2022-10-21 20:32:13 +03:00
committed by GitHub
parent 91c949bc1e
commit 76e69892e2
8 changed files with 235 additions and 0 deletions

View File

@@ -0,0 +1,22 @@
# titleFromFilename
Sets a scene's title
## Requirements
- Stash ( versions after the files refactor PR, API>31 )
- Python 3.10
- Requests Module (https://pypi.org/project/requests/)
## Installation
- Download the whole folder `titleFromFilename`
- Place it in your **plugins** folder (where the `config.yml` is). If its not there create it
- Reload plugins from stash (Settings > Plugins -> Reload Plugins)
- titleFromFilename should appear
## Usage
When a scene is created the plugin will set the title to the filename.
By default the file extension will not be added to the title.
If you want to keep the file extension open `config.py` file and change `STRIP_EXT = True` to `STRIP_EXT = False`

View File

@@ -0,0 +1,2 @@
# strip file extension from title
STRIP_EXT = True

View File

@@ -0,0 +1,90 @@
import json
import requests
def doRequest(query, variables=None, port=9999, session=None, scheme="http", raise_exception=True):
# Session cookie for authentication
graphql_port = port
graphql_scheme = scheme
graphql_cookies = {
'session': session
}
graphql_headers = {
"Accept-Encoding": "gzip, deflate",
"Content-Type": "application/json",
"Accept": "application/json",
"Connection": "keep-alive",
"DNT": "1"
}
graphql_domain = 'localhost'
# Stash GraphQL endpoint
graphql_url = graphql_scheme + "://" + graphql_domain + ":" + str(graphql_port) + "/graphql"
json = {'query': query}
if variables is not None:
json['variables'] = variables
try:
response = requests.post(graphql_url, json=json,headers=graphql_headers, cookies=graphql_cookies, timeout=20)
except Exception as e:
exit_plugin(err="f[FATAL] Exception with GraphQL request. {e}")
if response.status_code == 200:
result = response.json()
if result.get("error"):
for error in result["error"]["errors"]:
if raise_exception:
raise Exception(f"GraphQL error: {error}")
else:
log.LogError(f"GraphQL error: {error}")
return None
if result.get("data"):
return result.get("data")
elif response.status_code == 401:
exit_plugin(err="HTTP Error 401, Unauthorised.")
else:
raise ConnectionError(f"GraphQL query failed: {response.status_code} - {response.content}")
def update_scene_title(scene_id, scene_title, port, session, scheme):
query = """
mutation UpdateSceneTitle($id: ID!, $title: String) {
sceneUpdate(
input: {id: $id, title: $title}
) {
title
}
}
"""
variables = {
"id": scene_id,
"title": scene_title
}
result = doRequest(query=query, variables=variables, port=port, session=session, scheme=scheme)
return result.get('sceneUpdate')
def get_scene_base(scene_id, port, session, scheme):
query = """
query FindScene($id: ID!, $checksum: String) {
findScene(id: $id, checksum: $checksum) {
files {
basename
}
}
}
"""
variables = {
"id": scene_id
}
result = doRequest(query=query, variables=variables, port=port, session=session, scheme=scheme)
return result.get('findScene')
def get_api_version(port, session, scheme):
query = """
query SystemStatus {
systemStatus {
databaseSchema
appSchema
}
}
"""
result = doRequest(query=query, port=port, session=session, scheme=scheme)
return result.get('systemStatus')

View File

@@ -0,0 +1,52 @@
import sys
# Log messages sent from a plugin instance are transmitted via stderr and are
# encoded with a prefix consisting of special character SOH, then the log
# level (one of t, d, i, w, e, or p - corresponding to trace, debug, info,
# warning, error and progress levels respectively), then special character
# STX.
#
# The LogTrace, LogDebug, LogInfo, LogWarning, and LogError methods, and their equivalent
# formatted methods are intended for use by plugin instances to transmit log
# messages. The LogProgress method is also intended for sending progress data.
#
def __prefix(level_char):
start_level_char = b'\x01'
end_level_char = b'\x02'
ret = start_level_char + level_char + end_level_char
return ret.decode()
def __log(level_char, s):
if level_char == "":
return
print(__prefix(level_char) + s + "\n", file=sys.stderr, flush=True)
def LogTrace(s):
__log(b't', s)
def LogDebug(s):
__log(b'd', s)
def LogInfo(s):
__log(b'i', s)
def LogWarning(s):
__log(b'w', s)
def LogError(s):
__log(b'e', s)
def LogProgress(p):
progress = min(max(0, p), 1)
__log(b'p', str(progress))

View File

@@ -0,0 +1 @@
requests

View File

@@ -0,0 +1,54 @@
import json
import os
import sys
import config
import log
import graphql
API_VERSION_BF_FILES = 31 # APP/DB Schema version prior to files refactor PR
def exit_plugin(msg=None, err=None):
if msg is None and err is None:
msg = "plugin ended"
output_json = {"output": msg, "error": err}
print(json.dumps(output_json))
sys.exit()
FRAGMENT = json.loads(sys.stdin.read())
#log.LogDebug(json.dumps(FRAGMENT))
FRAGMENT_SERVER = FRAGMENT["server_connection"]
FRAGMENT_SCENE_ID = FRAGMENT["args"].get("hookContext")
if FRAGMENT_SCENE_ID:
scene_id = FRAGMENT_SCENE_ID["id"]
else:
exit_plugin("No ID found")
graphql_port = FRAGMENT_SERVER['Port']
graphql_scheme = FRAGMENT_SERVER['Scheme']
graphql_session = FRAGMENT_SERVER.get('SessionCookie').get('Value')
system_status = graphql.get_api_version(port=graphql_port, session=graphql_session, scheme=graphql_scheme)
api_version = system_status.get("appSchema")
basename = None
if api_version > API_VERSION_BF_FILES: # only needed for versions after files refactor
files_base = graphql.get_scene_base(scene_id=scene_id, port=graphql_port, session=graphql_session, scheme=graphql_scheme)
if len(files_base["files"]) > 0:
basename = files_base["files"][0].get("basename")
else:
exit_plugin(f"Stash with API version:{api_version} is not supported. You need at least {API_VERSION_BF_FILES}")
if basename is None:
exit_plugin("No basename found") # file-less scene
if config.STRIP_EXT:
basename = os.path.splitext(basename)[0]
updated_scene = graphql.update_scene_title(scene_id, basename, port=graphql_port, session=graphql_session, scheme=graphql_scheme)
exit_plugin(f"Scene title updated. Title:{updated_scene.get('title')}")

View File

@@ -0,0 +1,13 @@
name: titleFromFilename
description: Set a scene's title from it's filename
url: https://github.com/stashapp/CommunityScripts
version: 1.0
exec:
- python
- "{pluginDir}/titleFromFilename.py"
interface: raw
hooks:
- name: hook_set_title_from_filename
description: Set the title of the scene to it's filename
triggeredBy:
- Scene.Create.Post