add notification link
This commit is contained in:
parent
748de0ff00
commit
e05c643a6b
@ -114,6 +114,7 @@ MoviePilot需要配套下载器和媒体服务器配合使用。
|
|||||||
|
|
||||||
- **❗SUPERUSER:** 超级管理员用户名,默认`admin`,安装后使用该用户登录后台管理界面,**注意:启动一次后再次修改该值不会生效,除非删除数据库文件!**
|
- **❗SUPERUSER:** 超级管理员用户名,默认`admin`,安装后使用该用户登录后台管理界面,**注意:启动一次后再次修改该值不会生效,除非删除数据库文件!**
|
||||||
- **❗API_TOKEN:** API密钥,默认`moviepilot`,在媒体服务器Webhook、微信回调等地址配置中需要加上`?token=`该值,建议修改为复杂字符串
|
- **❗API_TOKEN:** API密钥,默认`moviepilot`,在媒体服务器Webhook、微信回调等地址配置中需要加上`?token=`该值,建议修改为复杂字符串
|
||||||
|
- **APP_DOMAIN:** MoviePilot WEB使用的域名,用于生成跳转链接等
|
||||||
- **BIG_MEMORY_MODE:** 大内存模式,默认为`false`,开启后会增加缓存数量,占用更多的内存,但响应速度会更快
|
- **BIG_MEMORY_MODE:** 大内存模式,默认为`false`,开启后会增加缓存数量,占用更多的内存,但响应速度会更快
|
||||||
- **DOH_ENABLE:** DNS over HTTPS开关,`true`/`false`,默认`true`,开启后会使用DOH对api.themoviedb.org等域名进行解析,以减少被DNS污染的情况,提升网络连通性
|
- **DOH_ENABLE:** DNS over HTTPS开关,`true`/`false`,默认`true`,开启后会使用DOH对api.themoviedb.org等域名进行解析,以减少被DNS污染的情况,提升网络连通性
|
||||||
- **META_CACHE_EXPIRE:** 元数据识别缓存过期时间(小时),数字型,不配置或者配置为0时使用系统默认(大内存模式为7天,否则为3天),调大该值可减少themoviedb的访问次数
|
- **META_CACHE_EXPIRE:** 元数据识别缓存过期时间(小时),数字型,不配置或者配置为0时使用系统默认(大内存模式为7天,否则为3天),调大该值可减少themoviedb的访问次数
|
||||||
|
@ -89,7 +89,8 @@ class DownloadChain(ChainBase):
|
|||||||
title=f"{mediainfo.title_year} "
|
title=f"{mediainfo.title_year} "
|
||||||
f"{'%s %s' % (meta.season, download_episodes) if download_episodes else meta.season_episode} 开始下载",
|
f"{'%s %s' % (meta.season, download_episodes) if download_episodes else meta.season_episode} 开始下载",
|
||||||
text=msg_text,
|
text=msg_text,
|
||||||
image=mediainfo.get_message_image()))
|
image=mediainfo.get_message_image(),
|
||||||
|
link=settings.MP_DOMAIN('/#/downloading')))
|
||||||
|
|
||||||
def download_torrent(self, torrent: TorrentInfo,
|
def download_torrent(self, torrent: TorrentInfo,
|
||||||
channel: MessageChannel = None,
|
channel: MessageChannel = None,
|
||||||
@ -841,7 +842,9 @@ class DownloadChain(ChainBase):
|
|||||||
channel=channel,
|
channel=channel,
|
||||||
mtype=NotificationType.Download,
|
mtype=NotificationType.Download,
|
||||||
title="没有正在下载的任务!",
|
title="没有正在下载的任务!",
|
||||||
userid=userid))
|
userid=userid,
|
||||||
|
link=settings.MP_DOMAIN('#/downloading')
|
||||||
|
))
|
||||||
return
|
return
|
||||||
# 发送消息
|
# 发送消息
|
||||||
title = f"共 {len(torrents)} 个任务正在下载:"
|
title = f"共 {len(torrents)} 个任务正在下载:"
|
||||||
@ -853,8 +856,13 @@ class DownloadChain(ChainBase):
|
|||||||
f"{round(torrent.progress, 1)}%")
|
f"{round(torrent.progress, 1)}%")
|
||||||
index += 1
|
index += 1
|
||||||
self.post_message(Notification(
|
self.post_message(Notification(
|
||||||
channel=channel, mtype=NotificationType.Download,
|
channel=channel,
|
||||||
title=title, text="\n".join(messages), userid=userid))
|
mtype=NotificationType.Download,
|
||||||
|
title=title,
|
||||||
|
text="\n".join(messages),
|
||||||
|
userid=userid,
|
||||||
|
link=settings.MP_DOMAIN('#/downloading')
|
||||||
|
))
|
||||||
|
|
||||||
def downloading(self) -> List[DownloadingTorrent]:
|
def downloading(self) -> List[DownloadingTorrent]:
|
||||||
"""
|
"""
|
||||||
|
@ -520,5 +520,6 @@ class MessageChain(ChainBase):
|
|||||||
self.post_torrents_message(Notification(
|
self.post_torrents_message(Notification(
|
||||||
channel=channel,
|
channel=channel,
|
||||||
title=title,
|
title=title,
|
||||||
userid=userid
|
userid=userid,
|
||||||
|
link=settings.MP_DOMAIN('#/resource')
|
||||||
), torrents=items)
|
), torrents=items)
|
||||||
|
@ -109,11 +109,11 @@ class SiteChain(ChainBase):
|
|||||||
user_agent = site.ua or settings.USER_AGENT
|
user_agent = site.ua or settings.USER_AGENT
|
||||||
url = f"{site.url}api/member/profile"
|
url = f"{site.url}api/member/profile"
|
||||||
headers = {
|
headers = {
|
||||||
"Content-Type": "application/json",
|
"Content-Type": "application/json",
|
||||||
"User-Agent": user_agent,
|
"User-Agent": user_agent,
|
||||||
"Accept": "application/json, text/plain, */*",
|
"Accept": "application/json, text/plain, */*",
|
||||||
"Authorization": site.token
|
"Authorization": site.token
|
||||||
}
|
}
|
||||||
res = RequestUtils(
|
res = RequestUtils(
|
||||||
headers=headers,
|
headers=headers,
|
||||||
proxies=settings.PROXY if site.proxy else None,
|
proxies=settings.PROXY if site.proxy else None,
|
||||||
@ -457,7 +457,8 @@ class SiteChain(ChainBase):
|
|||||||
self.post_message(Notification(
|
self.post_message(Notification(
|
||||||
channel=channel,
|
channel=channel,
|
||||||
title="没有维护任何站点信息!",
|
title="没有维护任何站点信息!",
|
||||||
userid=userid))
|
userid=userid,
|
||||||
|
link=settings.MP_DOMAIN('#/site')))
|
||||||
title = f"共有 {len(site_list)} 个站点,回复对应指令操作:" \
|
title = f"共有 {len(site_list)} 个站点,回复对应指令操作:" \
|
||||||
f"\n- 禁用站点:/site_disable [id]" \
|
f"\n- 禁用站点:/site_disable [id]" \
|
||||||
f"\n- 启用站点:/site_enable [id]" \
|
f"\n- 启用站点:/site_enable [id]" \
|
||||||
@ -475,7 +476,8 @@ class SiteChain(ChainBase):
|
|||||||
# 发送列表
|
# 发送列表
|
||||||
self.post_message(Notification(
|
self.post_message(Notification(
|
||||||
channel=channel,
|
channel=channel,
|
||||||
title=title, text="\n".join(messages), userid=userid))
|
title=title, text="\n".join(messages), userid=userid,
|
||||||
|
link=settings.MP_DOMAIN('#/site')))
|
||||||
|
|
||||||
def remote_disable(self, arg_str, channel: MessageChannel, userid: Union[str, int] = None):
|
def remote_disable(self, arg_str, channel: MessageChannel, userid: Union[str, int] = None):
|
||||||
"""
|
"""
|
||||||
|
@ -169,10 +169,15 @@ class SubscribeChain(ChainBase):
|
|||||||
else:
|
else:
|
||||||
text = f"评分:{mediainfo.vote_average}"
|
text = f"评分:{mediainfo.vote_average}"
|
||||||
# 群发
|
# 群发
|
||||||
|
if mediainfo.type == MediaType.TV:
|
||||||
|
link = settings.MP_DOMAIN('#/subscribe-tv?tab=mysub')
|
||||||
|
else:
|
||||||
|
link = settings.MP_DOMAIN('#/subscribe-movie?tab=mysub')
|
||||||
self.post_message(Notification(mtype=NotificationType.Subscribe,
|
self.post_message(Notification(mtype=NotificationType.Subscribe,
|
||||||
title=f"{mediainfo.title_year} {metainfo.season} 已添加订阅",
|
title=f"{mediainfo.title_year} {metainfo.season} 已添加订阅",
|
||||||
text=text,
|
text=text,
|
||||||
image=mediainfo.get_message_image()))
|
image=mediainfo.get_message_image(),
|
||||||
|
link=link))
|
||||||
# 发送事件
|
# 发送事件
|
||||||
EventManager().send_event(EventType.SubscribeAdded, {
|
EventManager().send_event(EventType.SubscribeAdded, {
|
||||||
"subscribe_id": sid,
|
"subscribe_id": sid,
|
||||||
@ -922,9 +927,14 @@ class SubscribeChain(ChainBase):
|
|||||||
# 删除订阅
|
# 删除订阅
|
||||||
self.subscribeoper.delete(subscribe.id)
|
self.subscribeoper.delete(subscribe.id)
|
||||||
# 发送通知
|
# 发送通知
|
||||||
|
if mediainfo.type == MediaType.TV:
|
||||||
|
link = settings.MP_DOMAIN('#/subscribe-tv?tab=mysub')
|
||||||
|
else:
|
||||||
|
link = settings.MP_DOMAIN('#/subscribe-movie?tab=mysub')
|
||||||
self.post_message(Notification(mtype=NotificationType.Subscribe,
|
self.post_message(Notification(mtype=NotificationType.Subscribe,
|
||||||
title=f'{mediainfo.title_year} {meta.season} 已完成{msgstr}',
|
title=f'{mediainfo.title_year} {meta.season} 已完成{msgstr}',
|
||||||
image=mediainfo.get_message_image()))
|
image=mediainfo.get_message_image(),
|
||||||
|
link=link))
|
||||||
# 发送事件
|
# 发送事件
|
||||||
EventManager().send_event(EventType.SubscribeComplete, {
|
EventManager().send_event(EventType.SubscribeComplete, {
|
||||||
"subscribe_id": subscribe.id,
|
"subscribe_id": subscribe.id,
|
||||||
|
@ -99,7 +99,8 @@ class TorrentsChain(ChainBase, metaclass=Singleton):
|
|||||||
if not site.get("rss"):
|
if not site.get("rss"):
|
||||||
logger.error(f'站点 {domain} 未配置RSS地址!')
|
logger.error(f'站点 {domain} 未配置RSS地址!')
|
||||||
return []
|
return []
|
||||||
rss_items = self.rsshelper.parse(site.get("rss"), True if site.get("proxy") else False, timeout=int(site.get("timeout") or 30))
|
rss_items = self.rsshelper.parse(site.get("rss"), True if site.get("proxy") else False,
|
||||||
|
timeout=int(site.get("timeout") or 30))
|
||||||
if rss_items is None:
|
if rss_items is None:
|
||||||
# rss过期,尝试保留原配置生成新的rss
|
# rss过期,尝试保留原配置生成新的rss
|
||||||
self.__renew_rss_url(domain=domain, site=site)
|
self.__renew_rss_url(domain=domain, site=site)
|
||||||
@ -253,10 +254,14 @@ class TorrentsChain(ChainBase, metaclass=Singleton):
|
|||||||
else:
|
else:
|
||||||
# 发送消息
|
# 发送消息
|
||||||
self.post_message(
|
self.post_message(
|
||||||
Notification(mtype=NotificationType.SiteMessage, title=f"站点 {domain} RSS链接已过期"))
|
Notification(mtype=NotificationType.SiteMessage, title=f"站点 {domain} RSS链接已过期",
|
||||||
|
link=settings.MP_DOMAIN('#/site'))
|
||||||
|
)
|
||||||
else:
|
else:
|
||||||
self.post_message(
|
self.post_message(
|
||||||
Notification(mtype=NotificationType.SiteMessage, title=f"站点 {domain} RSS链接已过期"))
|
Notification(mtype=NotificationType.SiteMessage, title=f"站点 {domain} RSS链接已过期",
|
||||||
|
link=settings.MP_DOMAIN('#/site')))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"站点 {domain} RSS链接自动获取失败:{str(e)} - {traceback.format_exc()}")
|
logger.error(f"站点 {domain} RSS链接自动获取失败:{str(e)} - {traceback.format_exc()}")
|
||||||
self.post_message(Notification(mtype=NotificationType.SiteMessage, title=f"站点 {domain} RSS链接已过期"))
|
self.post_message(Notification(mtype=NotificationType.SiteMessage, title=f"站点 {domain} RSS链接已过期",
|
||||||
|
link=settings.MP_DOMAIN('#/site')))
|
||||||
|
@ -269,7 +269,8 @@ class TransferChain(ChainBase):
|
|||||||
self.post_message(Notification(
|
self.post_message(Notification(
|
||||||
mtype=NotificationType.Manual,
|
mtype=NotificationType.Manual,
|
||||||
title=f"{file_path.name} 未识别到媒体信息,无法入库!",
|
title=f"{file_path.name} 未识别到媒体信息,无法入库!",
|
||||||
text=f"回复:```\n/redo {his.id} [tmdbid]|[类型]\n``` 手动识别转移。"
|
text=f"回复:```\n/redo {his.id} [tmdbid]|[类型]\n``` 手动识别转移。",
|
||||||
|
link=settings.MP_DOMAIN('#/history')
|
||||||
))
|
))
|
||||||
# 计数
|
# 计数
|
||||||
processed_num += 1
|
processed_num += 1
|
||||||
@ -332,7 +333,8 @@ class TransferChain(ChainBase):
|
|||||||
mtype=NotificationType.Manual,
|
mtype=NotificationType.Manual,
|
||||||
title=f"{file_mediainfo.title_year} {file_meta.season_episode} 入库失败!",
|
title=f"{file_mediainfo.title_year} {file_meta.season_episode} 入库失败!",
|
||||||
text=f"原因:{transferinfo.message or '未知'}",
|
text=f"原因:{transferinfo.message or '未知'}",
|
||||||
image=file_mediainfo.get_message_image()
|
image=file_mediainfo.get_message_image(),
|
||||||
|
link=settings.MP_DOMAIN('#/history')
|
||||||
))
|
))
|
||||||
# 计数
|
# 计数
|
||||||
processed_num += 1
|
processed_num += 1
|
||||||
@ -506,7 +508,7 @@ class TransferChain(ChainBase):
|
|||||||
mediaid=media_id)
|
mediaid=media_id)
|
||||||
if not state:
|
if not state:
|
||||||
self.post_message(Notification(channel=channel, title="手动整理失败",
|
self.post_message(Notification(channel=channel, title="手动整理失败",
|
||||||
text=errmsg, userid=userid))
|
text=errmsg, userid=userid, link=settings.MP_DOMAIN('#/history')))
|
||||||
return
|
return
|
||||||
|
|
||||||
def re_transfer(self, logid: int, mtype: MediaType = None,
|
def re_transfer(self, logid: int, mtype: MediaType = None,
|
||||||
@ -642,7 +644,8 @@ class TransferChain(ChainBase):
|
|||||||
# 发送
|
# 发送
|
||||||
self.post_message(Notification(
|
self.post_message(Notification(
|
||||||
mtype=NotificationType.Organize,
|
mtype=NotificationType.Organize,
|
||||||
title=msg_title, text=msg_str, image=mediainfo.get_message_image()))
|
title=msg_title, text=msg_str, image=mediainfo.get_message_image(),
|
||||||
|
link=settings.MP_DOMAIN('#/history')))
|
||||||
|
|
||||||
def delete_files(self, path: Path) -> Tuple[bool, str]:
|
def delete_files(self, path: Path) -> Tuple[bool, str]:
|
||||||
"""
|
"""
|
||||||
|
@ -15,6 +15,8 @@ class Settings(BaseSettings):
|
|||||||
"""
|
"""
|
||||||
# 项目名称
|
# 项目名称
|
||||||
PROJECT_NAME = "MoviePilot"
|
PROJECT_NAME = "MoviePilot"
|
||||||
|
# 域名 格式;https://movie-pilot.org
|
||||||
|
APP_DOMAIN: str = ""
|
||||||
# API路径
|
# API路径
|
||||||
API_V1_STR: str = "/api/v1"
|
API_V1_STR: str = "/api/v1"
|
||||||
# 前端资源路径
|
# 前端资源路径
|
||||||
@ -380,6 +382,16 @@ class Settings(BaseSettings):
|
|||||||
"privateKey": "JTixnYY0vEw97t9uukfO3UWKfHKJdT5kCQDiv3gu894"
|
"privateKey": "JTixnYY0vEw97t9uukfO3UWKfHKJdT5kCQDiv3gu894"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
def MP_DOMAIN(self, url: str = None):
|
||||||
|
if not self.APP_DOMAIN:
|
||||||
|
return None
|
||||||
|
domain = self.APP_DOMAIN.rstrip("/")
|
||||||
|
if not domain.startswith("http"):
|
||||||
|
domain = "http://" + domain
|
||||||
|
if not url:
|
||||||
|
return domain
|
||||||
|
return domain + "/" + url.lstrip("/")
|
||||||
|
|
||||||
def __init__(self, **kwargs):
|
def __init__(self, **kwargs):
|
||||||
super().__init__(**kwargs)
|
super().__init__(**kwargs)
|
||||||
with self.CONFIG_PATH as p:
|
with self.CONFIG_PATH as p:
|
||||||
|
@ -156,7 +156,8 @@ def check_auth():
|
|||||||
Notification(
|
Notification(
|
||||||
mtype=NotificationType.Manual,
|
mtype=NotificationType.Manual,
|
||||||
title="MoviePilot用户认证",
|
title="MoviePilot用户认证",
|
||||||
text=err_msg
|
text=err_msg,
|
||||||
|
link=settings.MP_DOMAIN('#/site')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -165,6 +166,7 @@ def singal_handle():
|
|||||||
"""
|
"""
|
||||||
监听停止信号
|
监听停止信号
|
||||||
"""
|
"""
|
||||||
|
|
||||||
def stop_event(signum: int, _: FrameType):
|
def stop_event(signum: int, _: FrameType):
|
||||||
"""
|
"""
|
||||||
SIGTERM信号处理
|
SIGTERM信号处理
|
||||||
|
@ -202,7 +202,7 @@ class SlackModule(_ModuleBase):
|
|||||||
:return: 成功或失败
|
:return: 成功或失败
|
||||||
"""
|
"""
|
||||||
self.slack.send_msg(title=message.title, text=message.text,
|
self.slack.send_msg(title=message.title, text=message.text,
|
||||||
image=message.image, userid=message.userid)
|
image=message.image, userid=message.userid, link=message.link)
|
||||||
|
|
||||||
@checkMessage(MessageChannel.Slack)
|
@checkMessage(MessageChannel.Slack)
|
||||||
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
|
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
|
||||||
|
@ -93,13 +93,13 @@ class Slack:
|
|||||||
"""
|
"""
|
||||||
return True if self._client else False
|
return True if self._client else False
|
||||||
|
|
||||||
def send_msg(self, title: str, text: str = "", image: str = "", url: str = "", userid: str = ""):
|
def send_msg(self, title: str, text: str = "", image: str = "", link: str = "", userid: str = ""):
|
||||||
"""
|
"""
|
||||||
发送Telegram消息
|
发送Telegram消息
|
||||||
:param title: 消息标题
|
:param title: 消息标题
|
||||||
:param text: 消息内容
|
:param text: 消息内容
|
||||||
:param image: 消息图片地址
|
:param image: 消息图片地址
|
||||||
:param url: 点击消息转转的URL
|
:param link: 点击消息转转的URL
|
||||||
:param userid: 用户ID,如有则只发消息给该用户
|
:param userid: 用户ID,如有则只发消息给该用户
|
||||||
:user_id: 发送消息的目标用户ID,为空则发给管理员
|
:user_id: 发送消息的目标用户ID,为空则发给管理员
|
||||||
"""
|
"""
|
||||||
@ -132,7 +132,7 @@ class Slack:
|
|||||||
"alt_text": f"{title}"
|
"alt_text": f"{title}"
|
||||||
}})
|
}})
|
||||||
# 链接
|
# 链接
|
||||||
if url:
|
if link:
|
||||||
blocks.append({
|
blocks.append({
|
||||||
"type": "actions",
|
"type": "actions",
|
||||||
"elements": [
|
"elements": [
|
||||||
@ -144,7 +144,7 @@ class Slack:
|
|||||||
"emoji": True
|
"emoji": True
|
||||||
},
|
},
|
||||||
"value": "click_me_url",
|
"value": "click_me_url",
|
||||||
"url": f"{url}",
|
"url": f"{link}",
|
||||||
"action_id": "actionId-url"
|
"action_id": "actionId-url"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
@ -74,7 +74,7 @@ class SynologyChatModule(_ModuleBase):
|
|||||||
:return: 成功或失败
|
:return: 成功或失败
|
||||||
"""
|
"""
|
||||||
self.synologychat.send_msg(title=message.title, text=message.text,
|
self.synologychat.send_msg(title=message.title, text=message.text,
|
||||||
image=message.image, userid=message.userid)
|
image=message.image, userid=message.userid, link=message.link)
|
||||||
|
|
||||||
@checkMessage(MessageChannel.SynologyChat)
|
@checkMessage(MessageChannel.SynologyChat)
|
||||||
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
|
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
|
||||||
@ -95,4 +95,5 @@ class SynologyChatModule(_ModuleBase):
|
|||||||
:param torrents: 种子列表
|
:param torrents: 种子列表
|
||||||
:return: 成功或失败
|
:return: 成功或失败
|
||||||
"""
|
"""
|
||||||
return self.synologychat.send_torrents_msg(title=message.title, torrents=torrents, userid=message.userid)
|
return self.synologychat.send_torrents_msg(title=message.title, torrents=torrents,
|
||||||
|
userid=message.userid, link=message.link)
|
||||||
|
@ -36,7 +36,8 @@ class SynologyChat:
|
|||||||
return True
|
return True
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def send_msg(self, title: str, text: str = "", image: str = "", userid: str = "") -> Optional[bool]:
|
def send_msg(self, title: str, text: str = "", image: str = "",
|
||||||
|
userid: str = "", link: str = None) -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
发送Telegram消息
|
发送Telegram消息
|
||||||
:param title: 消息标题
|
:param title: 消息标题
|
||||||
@ -44,6 +45,7 @@ class SynologyChat:
|
|||||||
:param image: 消息图片地址
|
:param image: 消息图片地址
|
||||||
:param userid: 用户ID,如有则只发消息给该用户
|
:param userid: 用户ID,如有则只发消息给该用户
|
||||||
:user_id: 发送消息的目标用户ID,为空则发给管理员
|
:user_id: 发送消息的目标用户ID,为空则发给管理员
|
||||||
|
:param link: 链接地址
|
||||||
"""
|
"""
|
||||||
if not title and not text:
|
if not title and not text:
|
||||||
logger.error("标题和内容不能同时为空")
|
logger.error("标题和内容不能同时为空")
|
||||||
@ -64,6 +66,10 @@ class SynologyChat:
|
|||||||
caption = "*%s*\n%s" % (title, text.replace("\n\n", "\n"))
|
caption = "*%s*\n%s" % (title, text.replace("\n\n", "\n"))
|
||||||
else:
|
else:
|
||||||
caption = title
|
caption = title
|
||||||
|
|
||||||
|
if link:
|
||||||
|
caption = f"{caption}\n[查看详情]({link})"
|
||||||
|
|
||||||
payload_data = {'text': quote(caption)}
|
payload_data = {'text': quote(caption)}
|
||||||
if image:
|
if image:
|
||||||
payload_data['file_url'] = quote(image)
|
payload_data['file_url'] = quote(image)
|
||||||
@ -127,7 +133,7 @@ class SynologyChat:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def send_torrents_msg(self, torrents: List[Context],
|
def send_torrents_msg(self, torrents: List[Context],
|
||||||
userid: str = "", title: str = "") -> Optional[bool]:
|
userid: str = "", title: str = "", link: str = None) -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
发送列表消息
|
发送列表消息
|
||||||
"""
|
"""
|
||||||
@ -157,6 +163,9 @@ class SynologyChat:
|
|||||||
f"_{description}_"
|
f"_{description}_"
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
|
if link:
|
||||||
|
caption = f"{caption}\n[查看详情]({link})"
|
||||||
|
|
||||||
if userid:
|
if userid:
|
||||||
userids = [int(userid)]
|
userids = [int(userid)]
|
||||||
else:
|
else:
|
||||||
|
@ -110,7 +110,7 @@ class TelegramModule(_ModuleBase):
|
|||||||
:return: 成功或失败
|
:return: 成功或失败
|
||||||
"""
|
"""
|
||||||
self.telegram.send_msg(title=message.title, text=message.text,
|
self.telegram.send_msg(title=message.title, text=message.text,
|
||||||
image=message.image, userid=message.userid)
|
image=message.image, userid=message.userid, link=message.link)
|
||||||
|
|
||||||
@checkMessage(MessageChannel.Telegram)
|
@checkMessage(MessageChannel.Telegram)
|
||||||
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
|
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
|
||||||
@ -121,7 +121,7 @@ class TelegramModule(_ModuleBase):
|
|||||||
:return: 成功或失败
|
:return: 成功或失败
|
||||||
"""
|
"""
|
||||||
return self.telegram.send_meidas_msg(title=message.title, medias=medias,
|
return self.telegram.send_meidas_msg(title=message.title, medias=medias,
|
||||||
userid=message.userid)
|
userid=message.userid, link=message.link)
|
||||||
|
|
||||||
@checkMessage(MessageChannel.Telegram)
|
@checkMessage(MessageChannel.Telegram)
|
||||||
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> Optional[bool]:
|
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> Optional[bool]:
|
||||||
@ -131,7 +131,8 @@ class TelegramModule(_ModuleBase):
|
|||||||
:param torrents: 种子列表
|
:param torrents: 种子列表
|
||||||
:return: 成功或失败
|
:return: 成功或失败
|
||||||
"""
|
"""
|
||||||
return self.telegram.send_torrents_msg(title=message.title, torrents=torrents, userid=message.userid)
|
return self.telegram.send_torrents_msg(title=message.title, torrents=torrents,
|
||||||
|
userid=message.userid, link=message.link)
|
||||||
|
|
||||||
def register_commands(self, commands: Dict[str, dict]):
|
def register_commands(self, commands: Dict[str, dict]):
|
||||||
"""
|
"""
|
||||||
|
@ -67,13 +67,15 @@ class Telegram:
|
|||||||
"""
|
"""
|
||||||
return self._bot is not None
|
return self._bot is not None
|
||||||
|
|
||||||
def send_msg(self, title: str, text: str = "", image: str = "", userid: str = "") -> Optional[bool]:
|
def send_msg(self, title: str, text: str = "", image: str = "",
|
||||||
|
userid: str = "", link: str = None) -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
发送Telegram消息
|
发送Telegram消息
|
||||||
:param title: 消息标题
|
:param title: 消息标题
|
||||||
:param text: 消息内容
|
:param text: 消息内容
|
||||||
:param image: 消息图片地址
|
:param image: 消息图片地址
|
||||||
:param userid: 用户ID,如有则只发消息给该用户
|
:param userid: 用户ID,如有则只发消息给该用户
|
||||||
|
:param link: 跳转链接
|
||||||
:userid: 发送消息的目标用户ID,为空则发给管理员
|
:userid: 发送消息的目标用户ID,为空则发给管理员
|
||||||
"""
|
"""
|
||||||
if not self._telegram_token or not self._telegram_chat_id:
|
if not self._telegram_token or not self._telegram_chat_id:
|
||||||
@ -89,6 +91,9 @@ class Telegram:
|
|||||||
else:
|
else:
|
||||||
caption = f"*{title}*"
|
caption = f"*{title}*"
|
||||||
|
|
||||||
|
if link:
|
||||||
|
caption = f"{caption}\n[查看详情]({link})"
|
||||||
|
|
||||||
if userid:
|
if userid:
|
||||||
chat_id = userid
|
chat_id = userid
|
||||||
else:
|
else:
|
||||||
@ -100,7 +105,8 @@ class Telegram:
|
|||||||
logger.error(f"发送消息失败:{msg_e}")
|
logger.error(f"发送消息失败:{msg_e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def send_meidas_msg(self, medias: List[MediaInfo], userid: str = "", title: str = "") -> Optional[bool]:
|
def send_meidas_msg(self, medias: List[MediaInfo], userid: str = "",
|
||||||
|
title: str = "", link: str = None) -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
发送媒体列表消息
|
发送媒体列表消息
|
||||||
"""
|
"""
|
||||||
@ -127,6 +133,9 @@ class Telegram:
|
|||||||
f"类型:{media.type.value}")
|
f"类型:{media.type.value}")
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
|
if link:
|
||||||
|
caption = f"{caption}\n[查看详情]({link})"
|
||||||
|
|
||||||
if userid:
|
if userid:
|
||||||
chat_id = userid
|
chat_id = userid
|
||||||
else:
|
else:
|
||||||
@ -139,7 +148,7 @@ class Telegram:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def send_torrents_msg(self, torrents: List[Context],
|
def send_torrents_msg(self, torrents: List[Context],
|
||||||
userid: str = "", title: str = "") -> Optional[bool]:
|
userid: str = "", title: str = "", link: str = None) -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
发送列表消息
|
发送列表消息
|
||||||
"""
|
"""
|
||||||
@ -168,6 +177,9 @@ class Telegram:
|
|||||||
f"{StringUtils.str_filesize(torrent.size)} {free} {seeder}"
|
f"{StringUtils.str_filesize(torrent.size)} {free} {seeder}"
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
|
if link:
|
||||||
|
caption = f"{caption}\n[查看详情]({link})"
|
||||||
|
|
||||||
if userid:
|
if userid:
|
||||||
chat_id = userid
|
chat_id = userid
|
||||||
else:
|
else:
|
||||||
|
@ -103,7 +103,8 @@ class VoceChatModule(_ModuleBase):
|
|||||||
:param message: 消息内容
|
:param message: 消息内容
|
||||||
:return: 成功或失败
|
:return: 成功或失败
|
||||||
"""
|
"""
|
||||||
self.vocechat.send_msg(title=message.title, text=message.text, userid=message.userid)
|
self.vocechat.send_msg(title=message.title, text=message.text,
|
||||||
|
userid=message.userid, link=message.link)
|
||||||
|
|
||||||
@checkMessage(MessageChannel.VoceChat)
|
@checkMessage(MessageChannel.VoceChat)
|
||||||
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
|
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
|
||||||
@ -116,7 +117,8 @@ class VoceChatModule(_ModuleBase):
|
|||||||
# 先发送标题
|
# 先发送标题
|
||||||
self.vocechat.send_msg(title=message.title, userid=message.userid)
|
self.vocechat.send_msg(title=message.title, userid=message.userid)
|
||||||
# 再发送内容
|
# 再发送内容
|
||||||
return self.vocechat.send_medias_msg(title=message.title, medias=medias, userid=message.userid)
|
return self.vocechat.send_medias_msg(title=message.title, medias=medias,
|
||||||
|
userid=message.userid, link=message.link)
|
||||||
|
|
||||||
@checkMessage(MessageChannel.VoceChat)
|
@checkMessage(MessageChannel.VoceChat)
|
||||||
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> Optional[bool]:
|
def post_torrents_message(self, message: Notification, torrents: List[Context]) -> Optional[bool]:
|
||||||
@ -126,7 +128,8 @@ class VoceChatModule(_ModuleBase):
|
|||||||
:param torrents: 种子列表
|
:param torrents: 种子列表
|
||||||
:return: 成功或失败
|
:return: 成功或失败
|
||||||
"""
|
"""
|
||||||
return self.vocechat.send_torrents_msg(title=message.title, torrents=torrents, userid=message.userid)
|
return self.vocechat.send_torrents_msg(title=message.title, torrents=torrents,
|
||||||
|
userid=message.userid, link=message.link)
|
||||||
|
|
||||||
def register_commands(self, commands: Dict[str, dict]):
|
def register_commands(self, commands: Dict[str, dict]):
|
||||||
pass
|
pass
|
||||||
|
@ -58,12 +58,14 @@ class VoceChat:
|
|||||||
if result and result.status_code == 200:
|
if result and result.status_code == 200:
|
||||||
return result.json()
|
return result.json()
|
||||||
|
|
||||||
def send_msg(self, title: str, text: str = "", userid: str = None) -> Optional[bool]:
|
def send_msg(self, title: str, text: str = "",
|
||||||
|
userid: str = None, link: str = None) -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
微信消息发送入口,支持文本、图片、链接跳转、指定发送对象
|
微信消息发送入口,支持文本、图片、链接跳转、指定发送对象
|
||||||
:param title: 消息标题
|
:param title: 消息标题
|
||||||
:param text: 消息内容
|
:param text: 消息内容
|
||||||
:param userid: 消息发送对象的ID,为空则发给所有人
|
:param userid: 消息发送对象的ID,为空则发给所有人
|
||||||
|
:param link: 消息链接
|
||||||
:return: 发送状态,错误信息
|
:return: 发送状态,错误信息
|
||||||
"""
|
"""
|
||||||
if not self._client:
|
if not self._client:
|
||||||
@ -79,6 +81,9 @@ class VoceChat:
|
|||||||
else:
|
else:
|
||||||
caption = f"**{title}**"
|
caption = f"**{title}**"
|
||||||
|
|
||||||
|
if link:
|
||||||
|
caption = f"{caption}\n[查看详情]({link})"
|
||||||
|
|
||||||
if userid:
|
if userid:
|
||||||
chat_id = userid
|
chat_id = userid
|
||||||
else:
|
else:
|
||||||
@ -90,7 +95,8 @@ class VoceChat:
|
|||||||
logger.error(f"发送消息失败:{msg_e}")
|
logger.error(f"发送消息失败:{msg_e}")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def send_medias_msg(self, title: str, medias: List[MediaInfo], userid: str = "") -> Optional[bool]:
|
def send_medias_msg(self, title: str, medias: List[MediaInfo],
|
||||||
|
userid: str = "", link: str = None) -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
发送列表类消息
|
发送列表类消息
|
||||||
"""
|
"""
|
||||||
@ -115,6 +121,9 @@ class VoceChat:
|
|||||||
f"类型:{media.type.value}")
|
f"类型:{media.type.value}")
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
|
if link:
|
||||||
|
caption = f"{caption}\n[查看详情]({link})"
|
||||||
|
|
||||||
if userid:
|
if userid:
|
||||||
chat_id = userid
|
chat_id = userid
|
||||||
else:
|
else:
|
||||||
@ -127,7 +136,7 @@ class VoceChat:
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
def send_torrents_msg(self, torrents: List[Context],
|
def send_torrents_msg(self, torrents: List[Context],
|
||||||
userid: str = "", title: str = "") -> Optional[bool]:
|
userid: str = "", title: str = "", link: str = None) -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
发送列表消息
|
发送列表消息
|
||||||
"""
|
"""
|
||||||
@ -155,6 +164,9 @@ class VoceChat:
|
|||||||
f"{StringUtils.str_filesize(torrent.size)} {free} {seeder}"
|
f"{StringUtils.str_filesize(torrent.size)} {free} {seeder}"
|
||||||
index += 1
|
index += 1
|
||||||
|
|
||||||
|
if link:
|
||||||
|
caption = f"{caption}\n[查看详情]({link})"
|
||||||
|
|
||||||
if userid:
|
if userid:
|
||||||
chat_id = userid
|
chat_id = userid
|
||||||
else:
|
else:
|
||||||
|
@ -141,7 +141,7 @@ class WechatModule(_ModuleBase):
|
|||||||
:return: 成功或失败
|
:return: 成功或失败
|
||||||
"""
|
"""
|
||||||
self.wechat.send_msg(title=message.title, text=message.text,
|
self.wechat.send_msg(title=message.title, text=message.text,
|
||||||
image=message.image, userid=message.userid)
|
image=message.image, userid=message.userid, link=message.link)
|
||||||
|
|
||||||
@checkMessage(MessageChannel.Wechat)
|
@checkMessage(MessageChannel.Wechat)
|
||||||
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
|
def post_medias_message(self, message: Notification, medias: List[MediaInfo]) -> Optional[bool]:
|
||||||
@ -152,7 +152,7 @@ class WechatModule(_ModuleBase):
|
|||||||
:return: 成功或失败
|
:return: 成功或失败
|
||||||
"""
|
"""
|
||||||
# 先发送标题
|
# 先发送标题
|
||||||
self.wechat.send_msg(title=message.title, userid=message.userid)
|
self.wechat.send_msg(title=message.title, userid=message.userid, link=message.link)
|
||||||
# 再发送内容
|
# 再发送内容
|
||||||
return self.wechat.send_medias_msg(medias=medias, userid=message.userid)
|
return self.wechat.send_medias_msg(medias=medias, userid=message.userid)
|
||||||
|
|
||||||
@ -164,7 +164,8 @@ class WechatModule(_ModuleBase):
|
|||||||
:param torrents: 种子列表
|
:param torrents: 种子列表
|
||||||
:return: 成功或失败
|
:return: 成功或失败
|
||||||
"""
|
"""
|
||||||
return self.wechat.send_torrents_msg(title=message.title, torrents=torrents, userid=message.userid)
|
return self.wechat.send_torrents_msg(title=message.title, torrents=torrents,
|
||||||
|
userid=message.userid, link=message.link)
|
||||||
|
|
||||||
def register_commands(self, commands: Dict[str, dict]):
|
def register_commands(self, commands: Dict[str, dict]):
|
||||||
"""
|
"""
|
||||||
|
@ -88,12 +88,14 @@ class WeChat:
|
|||||||
return None
|
return None
|
||||||
return self._access_token
|
return self._access_token
|
||||||
|
|
||||||
def __send_message(self, title: str, text: str = None, userid: str = None) -> Optional[bool]:
|
def __send_message(self, title: str, text: str = None,
|
||||||
|
userid: str = None, link: str = None) -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
发送文本消息
|
发送文本消息
|
||||||
:param title: 消息标题
|
:param title: 消息标题
|
||||||
:param text: 消息内容
|
:param text: 消息内容
|
||||||
:param userid: 消息发送对象的ID,为空则发给所有人
|
:param userid: 消息发送对象的ID,为空则发给所有人
|
||||||
|
:param link: 跳转链接
|
||||||
:return: 发送状态,错误信息
|
:return: 发送状态,错误信息
|
||||||
"""
|
"""
|
||||||
message_url = self._send_msg_url % self.__get_access_token()
|
message_url = self._send_msg_url % self.__get_access_token()
|
||||||
@ -102,8 +104,12 @@ class WeChat:
|
|||||||
else:
|
else:
|
||||||
conent = title
|
conent = title
|
||||||
|
|
||||||
|
if link:
|
||||||
|
conent = f"{conent}\n点击查看:{link}"
|
||||||
|
|
||||||
if not userid:
|
if not userid:
|
||||||
userid = "@all"
|
userid = "@all"
|
||||||
|
|
||||||
req_json = {
|
req_json = {
|
||||||
"touser": userid,
|
"touser": userid,
|
||||||
"msgtype": "text",
|
"msgtype": "text",
|
||||||
@ -148,13 +154,15 @@ class WeChat:
|
|||||||
}
|
}
|
||||||
return self.__post_request(message_url, req_json)
|
return self.__post_request(message_url, req_json)
|
||||||
|
|
||||||
def send_msg(self, title: str, text: str = "", image: str = "", userid: str = None) -> Optional[bool]:
|
def send_msg(self, title: str, text: str = "", image: str = "",
|
||||||
|
userid: str = None, link: str = None) -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
微信消息发送入口,支持文本、图片、链接跳转、指定发送对象
|
微信消息发送入口,支持文本、图片、链接跳转、指定发送对象
|
||||||
:param title: 消息标题
|
:param title: 消息标题
|
||||||
:param text: 消息内容
|
:param text: 消息内容
|
||||||
:param image: 图片地址
|
:param image: 图片地址
|
||||||
:param userid: 消息发送对象的ID,为空则发给所有人
|
:param userid: 消息发送对象的ID,为空则发给所有人
|
||||||
|
:param link: 跳转链接
|
||||||
:return: 发送状态,错误信息
|
:return: 发送状态,错误信息
|
||||||
"""
|
"""
|
||||||
if not self.__get_access_token():
|
if not self.__get_access_token():
|
||||||
@ -162,9 +170,9 @@ class WeChat:
|
|||||||
return None
|
return None
|
||||||
|
|
||||||
if image:
|
if image:
|
||||||
ret_code = self.__send_image_message(title, text, image, userid)
|
ret_code = self.__send_image_message(title=title, text=text, image_url=image, userid=userid)
|
||||||
else:
|
else:
|
||||||
ret_code = self.__send_message(title, text, userid)
|
ret_code = self.__send_message(title=title, text=text, userid=userid, link=link)
|
||||||
|
|
||||||
return ret_code
|
return ret_code
|
||||||
|
|
||||||
@ -205,7 +213,7 @@ class WeChat:
|
|||||||
return self.__post_request(message_url, req_json)
|
return self.__post_request(message_url, req_json)
|
||||||
|
|
||||||
def send_torrents_msg(self, torrents: List[Context],
|
def send_torrents_msg(self, torrents: List[Context],
|
||||||
userid: str = "", title: str = "") -> Optional[bool]:
|
userid: str = "", title: str = "", link: str = None) -> Optional[bool]:
|
||||||
"""
|
"""
|
||||||
发送列表消息
|
发送列表消息
|
||||||
"""
|
"""
|
||||||
@ -215,7 +223,7 @@ class WeChat:
|
|||||||
|
|
||||||
# 先发送标题
|
# 先发送标题
|
||||||
if title:
|
if title:
|
||||||
self.__send_message(title=title, userid=userid)
|
self.__send_message(title=title, userid=userid, link=link)
|
||||||
|
|
||||||
# 发送列表
|
# 发送列表
|
||||||
message_url = self._send_msg_url % self.__get_access_token()
|
message_url = self._send_msg_url % self.__get_access_token()
|
||||||
|
@ -229,6 +229,8 @@ class _PluginBase(metaclass=ABCMeta):
|
|||||||
"""
|
"""
|
||||||
发送消息
|
发送消息
|
||||||
"""
|
"""
|
||||||
|
if not link:
|
||||||
|
link = settings.MP_DOMAIN(f"#/plugins?tab=installed&id={self.__class__.__name__}")
|
||||||
self.chain.post_message(Notification(
|
self.chain.post_message(Notification(
|
||||||
channel=channel, mtype=mtype, title=title, text=text,
|
channel=channel, mtype=mtype, title=title, text=text,
|
||||||
image=image, link=link, userid=userid
|
image=image, link=link, userid=userid
|
||||||
|
@ -90,7 +90,8 @@ class Scheduler(metaclass=Singleton):
|
|||||||
Notification(
|
Notification(
|
||||||
mtype=NotificationType.Manual,
|
mtype=NotificationType.Manual,
|
||||||
title="MoviePilot用户认证成功",
|
title="MoviePilot用户认证成功",
|
||||||
text=f"使用站点:{msg}"
|
text=f"使用站点:{msg}",
|
||||||
|
link=settings.MP_DOMAIN('#/site')
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
else:
|
else:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user