第24章 Stash 插件开发与管理指南
插件 Stash 支持插件,具备以下功能:
在 Tasks 页面由用户触发时执行自定义任务 由特定事件触发时执行自定义任务 为 UI 添加自定义 CSS 为 UI 添加自定义 JavaScript
插件任务可以使用嵌入式 JavaScript 实现,或者通过调用外部二进制文件来实现。
⚠️ 注意:插件支持仍处于实验阶段,后续可能会发生变化。
管理插件¶ 可以在 Settings > Plugins 页面安装和管理插件。 插件通过“Available Plugins”部分进行安装。该部分允许配置插件源。默认情况下已配置了 Community (stable) 源。此源包含适用于当前 Stash 稳定版的插件。 以下是由 stashapp 组织维护的插件源:
名称 源 URL 推荐本地路径 备注
Community (stable) https://stashapp.github.io/CommunityScripts/stable/index.yml stable 适用于当前 Stash 稳定版。
Community (develop) https://stashapp.github.io/CommunityScripts/develop/index.yml develop 适用于 Stash 开发版。
已安装的插件可以通过“Installed Plugins”部分进行更新或卸载。
源 URL¶
源 URL 必须返回一个包含该源所有可用包的 yaml 文件。源 yaml 文件示例如下:
- id:
path 可以是相对于 yaml 文件的 zip 文件路径,也可以是外部 URL。 手动添加插件¶ 默认情况下,Stash 会在读取 stash config.yml 的目录下的 plugins 子目录中查找插件配置。该目录通常是 $HOME/.stash 或当前工作目录。 通过向 plugins 目录添加配置 yaml 文件(格式:pluginName.yml)来添加插件。 已加载的插件可以在 Settings 的 Plugins 页面中查看。如果 Stash 运行期间插件被添加、删除或编辑,可以点击“Reload Plugins”按钮重新加载它们。 使用插件¶ 插件提供了可以从 Tasks 页面运行的任务。 创建插件¶ 插件配置文件格式¶ 插件配置文件的基本结构如下: name: <插件名称> # 可选的依赖列表 # "#" 是配置的一部分 - 请勿删除 # requires: <插件 ID> description: <插件的可选描述> version: <可选的版本标签> url: <可选的 url>
ui:
# 包含在 UI 中的可选 css 文件列表
css:
-
# 包含在 UI 中的可选 js 文件列表
javascript:
-
# 需在此插件之前加载的插件 ID 的可选列表 requires: - <插件 ID>
# 可选的资源列表 assets: urlPrefix: fsLocation ...
# content-security 策略覆盖 csp: script-src: - http://alloweddomain.com
style-src: - http://alloweddomain.com
connect-src: - http://alloweddomain.com
# 在 UI 插件页面中显示的设置名称映射 settings: # 内部名称 foo: # 在 UI 中显示的名称 displayName: Foo # 在 UI 中显示的属性类型 # 可以是 BOOLEAN, NUMBER 或 STRING type: BOOLEAN
# 以下字段仅用于插件任务 exec: - ... interface: [interface 类型] errLog: [none trace, debug, info, warning, error 之一] tasks: - ...
name、description、version 和 url 字段显示在插件页面上。 # requires 会让插件管理器选择匹配指定 ID 的插件,将其作为依赖自动安装。仅适用于同一索引内的插件。 exec、interface、errLog 和 tasks 字段仅用于具有任务的插件。 settings 字段用于在插件页面上显示插件设置。也可以使用 graphql 突变 configurePlugin 来设置插件参数 - 通过这种方式设置的参数无需在 settings 字段中指定,除非需要在标准插件设置 UI 中显示。 UI 配置¶ css 和 javascript 字段的值可以是相对于插件配置文件的路径,也可以是完整的外部 URL。 requires 字段是一个插件 ID 列表,这些插件的 javascript/css 文件必须在此插件的 javascript/css 文件之前加载。 assets 字段是一个映射,将 URL 前缀映射到相对于插件配置文件的文件系统路径。 资源挂载到 /plugin/{pluginID}/assets 路径。 例如,对于 ID 为 foo 的插件,其 assets 值如下: assets: foo: bar /: .
以下 URL 将映射到这些位置:
/plugin/foo/assets/foo/file.txt -> {pluginDir}/bar/file.txt
/plugin/foo/assets/file.txt -> {pluginDir}/file.txt
/plugin/foo/assets/bar/file.txt -> {pluginDir}/bar/file.txt (通过 / 条目)
试图映射到插件配置文件所在目录之外的映射将被忽略。
csp 字段包含内容安全策略的覆盖设置。script-src、style-src 和 connect-src 中的 URL 将被添加到相应的内容安全策略中。
有关创建带有外部任务的插件的详细信息,请参阅 External Plugins。
有关创建带有嵌入式任务的插件的详细信息,请参阅 Embedded Plugins。
插件任务输入¶
插件任务可以接受来自 Stash 服务器的输入。该输入根据 interface 编码,其结构如下(此处以 JSON 格式展示):
{
"server_connection": {
"Scheme": "http",
"Port": 9999,
"SessionCookie": {
"Name":"session",
"Value":"cookie-value",
"Path":"",
"Domain":"",
"Expires":"0001-01-01T00:00:00Z",
"RawExpires":"",
"MaxAge":0,
"Secure":false,
"HttpOnly":false,
"SameSite":0,
"Raw":"",
"Unparsed":null
},
"Dir":
server_connection 字段包含插件访问父级 Stash 服务器所需的所有信息(如果需要的话)。 插件任务输出¶ 插件任务的预期输出结构如下(此处以 JSON 格式展示): { "error": <可选的错误字符串> "output": <任意内容> }
如果存在 error 字段,它将以 error 日志级别记录在 Stash 中。output 将以 debug 日志级别写入。 任务配置¶ 任务使用以下结构进行配置: tasks: - name: <操作名称> description: <可选描述> defaultArgs: argKey: argValue
插件配置可以包含多个任务。 defaultArgs 字段用于向发送给插件的输入中添加参数。 Hook 配置¶ Stash 支持在 Stash 操作期间通过触发 hook 来执行插件操作。 Hook 使用类似任务的结构进行配置: hooks: - name: <操作名称> description: <可选描述> triggeredBy: - <触发类型>... defaultArgs: argKey: argValue
⚠️ 注意:如果 hook 执行突变操作,它们可能会相互触发或自我触发。为了安全起见,如果 hook 已在当前操作上下文中被触发过,则不会再次触发。Stash 使用 cookies 来跟踪此上下文,因此插件在执行操作时发送 cookies 至关重要。 触发类型¶ 触发类型使用以下格式:<对象类型>.<操作>.<钩子类型> 例如,场景创建操作的后置钩子为 Scene.Create.Post。 支持以下对象类型:
Scene SceneMarker Image Gallery Group Performer Studio Tag
支持以下操作:
Create Update Destroy Merge (仅适用于 Tag)
目前,仅支持 Post 钩子类型。这些钩子在操作完成且事务提交后执行。 Hook 输入¶ 由 hook 触发的插件任务在 args 对象结构中包含一个名为 hookContext 的参数。hookContext 的结构如下: { "id": <对象 id>, "type": <触发类型>, "input": <操作输入>, "inputFields": <输入中包含的字段> }
input 字段包含传递给原始操作的 JSON graphql 输入。这取决于具体的操作。对于由 scan 或 clean 操作触发的钩子,input 将为 nil。inputFields 在 update 操作中填充,以指示哪些字段传递给了操作,从而区分缺失字段和空字段。 例如,以下是 Scene 更新操作的 args 值: { "hookContext": { "type":"Scene.Update.Post", "id":45, "input":{ "clientMutationId":null, "id":"45", "title":null, "details":null, "url":null, "date":null, "rating":null, "organized":null, "studio_id":null, "gallery_ids":null, "performer_ids":null, "groups":null, "tag_ids":["21"], "cover_image":null, "stash_ids":null }, "inputFields":[ "tag_ids", "id" ] } }