在 Homepage 中集成 Stash 媒体库统计 Widget:配置、字段与 GraphQL 数据链路解析

发布时间:2026/11/5 23:19:17

在 Homepage 中集成 Stash 媒体库统计 Widget:配置、字段与 GraphQL 数据链路解析 在 Homepage 中集成 Stash 媒体库统计 Widget配置、字段与 GraphQL 数据链路解析【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepageStash 是一款自托管的媒体管理器Homepage 为其提供了专用服务 Widget可直接在首页展示场景Scenes、图片Images、演员Performers、播放时长等核心统计数据。本文以 Stash Widget 配置文档 为主体结合仓库中的 Widget 定义源码、展示组件 与测试用例完整讲解如何获取 API Key、编写配置、理解全部可用字段并深入剖析数据从配置到 Stash GraphQL API 再到前端渲染的完整链路。前置准备在 Stash 中获取 API Key在配置 Widget 之前需要先从 Stash 实例中获取 API Key打开 Stash 的Settings设置 Security安全 API Key页面复制生成的 Key 值。注意仅当你的 Stash 实例启用了登录凭据时才必须提供 API Key若实例未开启登录认证可省略key字段。该 Key 在 Homepage 请求 Stash 时以查询参数的形式携带。从 widget.js 的 API 模板可以看到完整调用约定api: {url}/{endpoint}?apikey{key},即 Homepage 会用 Widget 配置中的url、key以及具体端点Endpoint拼接出形如http://stash.host.or.ip/graphql?apikeystashapikey的请求地址。因此请勿在 Key 中混入多余空格或换行否则请求会被 Stash 拒绝。最小可运行配置将以下片段放入 Homepage 的services.yaml或 Docker 环境下的 docker.yaml对应服务条目中widget: type: stash url: http://stash.host.or.ip key: stashapikey fields: [scenes, images] # optional - default fields shown各参数说明参数必填说明type是固定为stash用于匹配仓库中注册的 Widget 定义url是Stash 实例的地址如http://192.168.1.100:9999需可从运行 Homepage 的主机访问key否Stash 的 API Key仅当实例开启登录认证时必需fields否要展示的统计字段列表不填时使用默认字段[scenes, images]全部可用字段与底层数据映射原文档声明允许的字段完整列表为[scenes, scenesPlayed, playCount, playDuration, sceneSize, sceneDuration, images, imageSize, galleries, performers, studios, movies, tags, oCount]这 14 个字段并非 Stash API 的原始返回键而是 Homepage 前端展示层的标签Label。从 component.jsx 可以看出每个字段通过Block组件绑定到 GraphQLstats查询结果的具体属性Widget 字段界面文案en对应 stats 数据键格式化方式scenesScenesscene_count数值numberscenesPlayedScenes Playedscenes_played数值playCountTotal Playstotal_play_count数值playDurationTime Watchedtotal_play_duration时长durationsceneSizeScenes Sizescenes_size字节1 位小数sceneDurationScenes Durationscenes_duration时长imagesImagesimage_count数值imageSizeImages Sizeimages_size字节1 位小数galleriesGalleriesgallery_count数值performersPerformersperformer_count数值studiosStudiosstudio_count数值moviesMoviesmovie_count数值tagsTagstag_count数值oCountO Counttotal_o_count数值字段的中英文标签定义可在 public/locales/en/common.json 的stash节点中查到其他语言的翻译文件如 zh-Hans/common.json结构一致Homepage 会依据浏览器语言自动选择。展示规则默认字段与 4 字段上限Widget 的展示遵循两条明确规则文档声明 组件实现双重印证未配置fields时使用默认值组件在渲染前检查widget.fields若未设置则回退为[scenes, images]与初始加载时的占位符Placeholder一致见 component.jsx。最多只展示 4 个字段若配置的字段超过 4 个仅保留前 4 个见 component.jsxif (widget.fields.length 4) { widget.fields widget.fields.slice(0, 4); }需要注意的是该截断发生在组件内部并未改动用户配置文件中fields的原有顺序——因此fields的书写顺序决定了优先展示哪些字段。例如想展示总播放次数 观看时长 场景数 图片数应写成widget: type: stash url: http://stash.host.or.ip key: stashapikey fields: [playCount, playDuration, scenes, images]数据链路剖析从配置到 GraphQL 查询Stash Widget 的数据获取并非简单的 REST 调用而是经过 Homepage 通用代理generic proxy handler向 Stash 的 GraphQL 端点发起 POST 查询。全链路如下1. 前端发起代理请求组件挂载后通过formatProxyUrl生成代理地址并发送 POST 请求component.jsxconst url formatProxyUrl(widget, stats); const res await fetch(url, { method: POST });formatProxyUrl定义在 utils/proxy/api-helpers.js最终指向/api/services/proxy端点。2. 通用代理拼接目标地址generic.js 中Homepage 用 Widget 定义的api模板替换占位符{url}→ 配置中的url{endpoint}→graphqlstats 映射中指定{key}→ 配置中的key得到http://stash.host.or.ip/graphql?apikeystashapikey。3. 构造 GraphQL 查询体widget.js 中stats映射定义了POST方法与请求体一次性向 Stash 查询全部统计字段mappings: { stats: { method: POST, endpoint: graphql, headers: { content-type: application/json, }, body: JSON.stringify({ query: { stats { scene_count scenes_size scenes_duration image_count images_size gallery_count performer_count studio_count movie_count tag_count total_o_count total_play_duration total_play_count scenes_played } }, }), map: (data) asJson(data).data.stats, }, },4. 响应映射与前端渲染代理返回后map函数取出 GraphQL 响应中的data.stats对象返回给前端组件收到后按fields顺序渲染对应Block。测试用例 component.test.jsx 完整模拟了这一流程先渲染stash.scenes、stash.images两个占位符随后断言 fetch 返回的scene_count: 1、image_count: 7正确渲染为 Block 数值。而 widget.test.js 则验证了 Widget 定义api、proxyHandler、mappings结构合法可被 Homepage 的 Widget 注册体系正确加载。常见问题与排查思路页面只显示占位符、数值不出现多为请求失败或返回结构不符。可先确认url在浏览器可直接访问并检查key是否正确开启登录认证时必须填写。fields超过 4 个但顺序不对Widget 只取前 4 个请调整fields书写顺序以控制展示优先级。返回 Invalid data 错误代理在validateWidgetData校验失败时会返回该错误见 generic.js通常意味着 Stash 版本较旧、GraphQLstats查询结果缺失字段或 API Key 鉴权失败导致响应非预期结构。小结Stash Widget 是 Homepage 服务型 Widget 中典型的代理 GraphQL 映射实现配置侧只需url、key、fields三个核心参数底层则由 widget.js 定义 API 模板与查询体、component.jsx 负责字段渲染与数量限制前后端配合完成从 Stash 实例到首页看板的完整数据流。掌握字段映射表与 4 字段上限规则后即可按需组合出最贴合自己媒体库的统计面板。【免费下载链接】homepageA highly customizable homepage (or startpage / application dashboard) with Docker and service API integrations.项目地址: https://gitcode.com/GitHub_Trending/ho/homepage创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
延伸阅读

更多相关文章

2026/11/5 5:03:20

qemu-img 实战指南:虚拟磁盘镜像管理全解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 16:51:33

EasyU优启通PE维护盘实战指南:制作、启动与核心操作全解析

1. 为什么一个PE维护盘值得单独拿出来聊装系统、修引导、救数据、清病毒,这些活儿但凡干过几次的人都知道,真正决定效率的往往不是你手速多快,而是手边那套PE环境靠不靠谱。EasyU(圈内习惯叫优启通)就是在这个场景下被…

2026/11/5 16:26:13

Rust原来很简单二:所有权系统

Part 2 核心篇 —— 所有权系统 本篇覆盖 第 6 ~ 10 章:所有权、借用与引用、生命周期、字符串与切片、内存模型。 ⚠️ 这是全书最重要的一篇。 把它吃透,Rust 从此“很简单”;跳过它,你会处处碰壁。请慢下来,动手敲每一段代码。 第 6 章 所有权:Rust 的第一性原理 6…

2026/11/5 15:00:49

基于Hadoop+Spark的民宿智能推荐系统设计与实现

1. 项目概述:大数据时代的民宿智能推荐这个毕业设计项目融合了当前大数据领域最主流的技术栈,构建了一个完整的民宿推荐系统解决方案。作为一名长期从事大数据系统开发的工程师,我认为这个选题非常贴合实际应用场景——随着旅游业的复苏和共享…

2026/11/5 14:10:30

ADS122U04IPWR+STM32F427ZI工业级温度测量信号链设计

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 14:10:30

UART接口24位ADC搭配RS485,解决远距离温度监控难题

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 14:10:30

UART接口24位ADC搭配PIC18F46K22的RTD与热电偶测温实践

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/11/5 0:02:07

多智能体协作系统架构设计与实践优化

1. 多智能体协作系统的时代背景2017年Transformer架构的诞生彻底改变了人工智能的发展轨迹。当行业还沉浸在单一大模型带来的性能突破时,Anthropic的研究团队已经将目光投向了更前沿的领域——如何让多个智能体通过协作产生超越单体能力的系统智能。这就像交响乐团中…

2026/11/5 0:02:07

大模型系统性入门实战指南:从原理到部署微调的全链路路线

提到大模型的系统性入门,我先说个结论:这事真不难,难的是资料太散、路线太多,今天这个框架明天那个工具,新人很容易在“收藏夹吃灰”和“教程看到一半放弃”之间反复横跳。市面上关于大模型的内容少说有几十万篇&#…

2026/11/5 0:02:07

鸿蒙文件系统沙箱机制解析与开发实践

1. 鸿蒙文件系统沙箱机制深度解析作为一名从Android转向鸿蒙开发的工程师,我深刻体会到文件系统访问是迁移过程中最先遇到的"拦路虎"。在Android上运行良好的文件读写代码,在鸿蒙真机环境却频频出现文件写入后神秘消失或直接抛出权限拒绝错误的…

2026/11/5 15:39:06

面向复杂光照与角度的宠物面部识别鲁棒性增强策略

在智慧养宠时代,基于视觉的宠物身份识别技术正逐步从实验室走向家庭应用。然而,与配合度高的人类不同,宠物是典型的“非合作生物识别对象”——它们不会主动配合摄像头调整姿态,更无法控制光照环境。实际应用中,我们常…

2026/11/4 21:04:25

SSM电子书店源码全解析:结构、原理、部署与排错实战

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

还想了解更多?直接咨询顾问

免费诊断 + 免费方案 + 透明报价。

全国咨询热线400-8866-253
免费获取方案
☎咨询二维码 ☎ ↑