From b43ae37e624bc261b811baf51bcff2cf0f5d5478 Mon Sep 17 00:00:00 2001 From: jxxghp Date: Tue, 29 Sep 2026 08:31:20 +0800 Subject: [PATCH] feat(message): expose instance hostname in templates (#6815) --- app/application/messaging/message.py | 8 ++++---- tests/test_template_context_builder.py | 19 ++++++++++++++++++- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/app/application/messaging/message.py b/app/application/messaging/message.py index dfbd7c6b4..75a92d5aa 100644 --- a/app/application/messaging/message.py +++ b/app/application/messaging/message.py @@ -5,6 +5,7 @@ import asyncio import json import queue import re +import socket import threading import time from contextvars import Context, copy_context @@ -123,8 +124,8 @@ class TemplateContextBuilder: """ 构建一次性渲染上下文字典。 - 每次调用都新建本地 ``context`` 字典,依次填充各业务来源后返回过滤掉 - None 值的副本,调用之间互不影响。 + 每次调用都新建本地 ``context`` 字典,依次填充各业务来源和当前实例的 + 主机名后返回过滤掉 None 值的副本,调用之间互不影响。 :param meta: 媒体元数据 :param mediainfo: 识别的媒体信息 @@ -144,8 +145,7 @@ class TemplateContextBuilder: self._add_transfer_info(context, transferinfo) self._add_torrent_info(context, torrentinfo) self._add_file_info(context, file_extension) - if kwargs: - context.update(kwargs) + context.update(kwargs, instance_name=socket.gethostname()) if include_raw_objects: self._add_raw_objects(context, meta, mediainfo, torrentinfo, transferinfo, episodes_info) diff --git a/tests/test_template_context_builder.py b/tests/test_template_context_builder.py index 9c1d77a20..2004093b1 100644 --- a/tests/test_template_context_builder.py +++ b/tests/test_template_context_builder.py @@ -13,7 +13,7 @@ import threading from app.domain.context import MediaInfo from app.domain.metainfo import MetaInfo from app.domain.meta.metamusic import MetaMusic -from app.application.messaging.message import TemplateContextBuilder +from app.application.messaging.message import TemplateContextBuilder, TemplateHelper from app.modules.filemanager.transhandler import TransHandler from app.schemas.types import MediaSource, MediaType from app.schemas.tmdb import TmdbEpisode @@ -99,6 +99,23 @@ def test_build_returns_independent_dicts() -> None: assert first.get("marker") == 1 +def test_notification_template_exposes_container_hostname(monkeypatch) -> None: + """通知模板的实例名应取运行中的主机名,且不能被业务字段覆盖。""" + monkeypatch.setattr( + "app.application.messaging.message.socket.gethostname", + lambda: "nas-moviepilot", + ) + + context = TemplateContextBuilder().build(instance_name="other", title="测试") + rendered = TemplateHelper().render( + template_content="{'title': '[{{ instance_name }}] {{ title }}'}", + title="测试", + ) + + assert context["instance_name"] == "nas-moviepilot" + assert rendered == {"title": "[nas-moviepilot] 测试"} + + def test_build_exposes_video_bit_from_meta() -> None: """ 模板上下文应提供独立 videoBit 字段,避免用户只能从 videoCodec 中手工拆位深。