2024-03-07 12:42:59 +08:00

197 lines
6.7 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import re
import threading
from typing import Optional, List
from app.core.config import settings
from app.core.context import MediaInfo, Context
from app.core.metainfo import MetaInfo
from app.log import logger
from app.utils.common import retry
from app.utils.http import RequestUtils
from app.utils.string import StringUtils
lock = threading.Lock()
class VoceChat:
# host
_host = None
# apikey
_apikey = None
# 频道ID
_channel_id = None
# 请求对象
_client = None
def __init__(self):
"""
初始化
"""
self._host = settings.VOCECHAT_HOST
if self._host:
if not self._host.endswith("/"):
self._host += "/"
if not self._host.startswith("http"):
self._playhost = "http://" + self._host
self._apikey = settings.VOCECHAT_API_KEY
self._channel_id = settings.VOCECHAT_CHANNEL_ID
if self._apikey and self._host and self._channel_id:
self._client = RequestUtils(headers={
"content-type": "text/markdown",
"x-api-key": self._apikey,
"accept": "application/json; charset=utf-8"
})
def get_state(self):
"""
获取状态
"""
return True if self.get_groups() else False
def get_groups(self):
"""
获取频道列表
"""
if not self._client:
return None
result = self._client.get_res(f"{self._host}api/bot")
if result and result.status_code == 200:
return result.json()
def send_msg(self, title: str, text: str = "", userid: str = None) -> Optional[bool]:
"""
微信消息发送入口,支持文本、图片、链接跳转、指定发送对象
:param title: 消息标题
:param text: 消息内容
:param userid: 消息发送对象的ID为空则发给所有人
:return: 发送状态,错误信息
"""
if not self._client:
return None
if not title and not text:
logger.warn("标题和内容不能同时为空")
return False
try:
if text:
caption = f"**{title}**\n{text}"
else:
caption = f"**{title}**"
if userid:
chat_id = userid
else:
chat_id = f"GID#{self._channel_id}"
return self.__send_request(userid=chat_id, caption=caption)
except Exception as msg_e:
logger.error(f"发送消息失败:{msg_e}")
return False
def send_medias_msg(self, title: str, medias: List[MediaInfo], userid: str = "") -> Optional[bool]:
"""
发送列表类消息
"""
if not self._client:
return None
try:
index, caption = 1, "**%s**" % title
for media in medias:
if media.vote_average:
caption = "%s\n%s. [%s](%s)\n_%s%s_" % (caption,
index,
media.title_year,
media.detail_link,
f"类型:{media.type.value}",
f"评分:{media.vote_average}")
else:
caption = "%s\n%s. [%s](%s)\n_%s_" % (caption,
index,
media.title_year,
media.detail_link,
f"类型:{media.type.value}")
index += 1
if userid:
chat_id = userid
else:
chat_id = f"GID#{self._channel_id}"
return self.__send_request(userid=chat_id, caption=caption)
except Exception as msg_e:
logger.error(f"发送消息失败:{msg_e}")
return False
def send_torrents_msg(self, torrents: List[Context],
userid: str = "", title: str = "") -> Optional[bool]:
"""
发送列表消息
"""
if not self._client:
return None
if not torrents:
return False
try:
index, caption = 1, "**%s**" % title
mediainfo = torrents[0].media_info
for context in torrents:
torrent = context.torrent_info
site_name = torrent.site_name
meta = MetaInfo(torrent.title, torrent.description)
link = torrent.page_url
title = f"{meta.season_episode} " \
f"{meta.resource_term} " \
f"{meta.video_term} " \
f"{meta.release_group}"
title = re.sub(r"\s+", " ", title).strip()
free = torrent.volume_factor
seeder = f"{torrent.seeders}"
caption = f"{caption}\n{index}.【{site_name}】[{title}]({link}) " \
f"{StringUtils.str_filesize(torrent.size)} {free} {seeder}"
index += 1
if userid:
chat_id = userid
else:
chat_id = f"GID#{self._channel_id}"
return self.__send_request(userid=chat_id, caption=caption)
except Exception as msg_e:
logger.error(f"发送消息失败:{msg_e}")
return False
@retry(Exception, logger=logger)
def __send_request(self, userid: str, caption: str) -> bool:
"""
向VoceChat发送报文
userid格式UID#xxx / GID#xxx
"""
if not self._client:
return False
if userid.startswith("GID#"):
action = "send_to_group"
else:
action = "send_to_user"
idstr = userid[4:]
with lock:
try:
logger.info(f"VoceChat发送消息action={action}, userid={idstr}, text={caption}")
result = self._client.post_res(f"{self._host}api/bot/{action}/{idstr}", data=caption.encode("utf-8"))
if result and result.status_code == 200:
return True
elif result is not None:
logger.error(f"VoceChat发送消息失败错误码{result.status_code}")
return False
else:
raise Exception("VoceChat发送消息失败连接失败")
except Exception as msg_e:
logger.error(f"VoceChat发送消息错误{str(msg_e)}")
return False