diff --git a/.gitignore b/.gitignore index 4ecf076..04411d8 100644 --- a/.gitignore +++ b/.gitignore @@ -134,6 +134,7 @@ celerybeat.pid # Environments .env .venv +.vscode/ env/ venv/ ENV/ @@ -172,3 +173,6 @@ cython_debug/ #.idea/ backup_config/ +ffmpeg.exe +ffplay.exe +ffprobe.exe diff --git a/app/messages/message_pusher.py b/app/messages/message_pusher.py index cd18ae4..48555ea 100644 --- a/app/messages/message_pusher.py +++ b/app/messages/message_pusher.py @@ -79,3 +79,15 @@ async def push_messages(self, msg_title: str, push_content: str): ) ) logger.info("Push Email message successfully") + + if self.settings.user_config.get("serverchan_enabled"): + create_task( + self.notifier.send_to_serverchan( + sckey=self.settings.user_config.get("serverchan_sckey"), + title=msg_title, + content=push_content, + channel=self.settings.user_config.get("serverchan_channel", 9), + tags= self.settings.user_config.get("serverchan_tags", "直播通知"), + ) + ) + logger.info("Push ServerChan message successfully") diff --git a/app/messages/notification_service.py b/app/messages/notification_service.py index 19575bb..0195e5d 100644 --- a/app/messages/notification_service.py +++ b/app/messages/notification_service.py @@ -1,5 +1,6 @@ import base64 import smtplib +import re from email.header import Header from email.mime.multipart import MIMEMultipart from email.mime.text import MIMEText @@ -187,3 +188,57 @@ async def send_to_ntfy( results["error"].append(_api) logger.info(f"Ntfy push failed, push address: {_api}, Failure message: {json_data['error']}") return results + + async def send_to_serverchan( + self, + sckey: str, + title: str = "message", + content: str = "test", + short: str = "", + channel: int = 9, + tags: str = "partying_face" + ) -> dict[str, Any]: + """发送消息到ServerChan服务 + + 参数: + sckey: ServerChan的SCKEY,多个用逗号分隔 + title: 消息标题 + content: 消息内容 + short: 短消息内容 + channel: 消息通道 + + 返回: + 包含成功和失败SCKEY的字典 + """ + results = {"success": [], "error": []} + sckey_list = sckey.replace(",", ",").split(",") if sckey.strip() else [] + + for key in sckey_list: + # 根据SCKEY类型构造URL + if key.startswith('sctp'): + match = re.match(r'sctp(\d+)t', key) + if match: + num = match.group(1) + url = f'https://{num}.push.ft07.com/send/{key}.send' + else: + logger.error(f"Invalid sendkey format for sctp: {key}") + results["error"].append(key) + continue + else: + url = f'https://sctapi.ftqq.com/{key}.send' + + json_data = { + "title": title, + "desp": content, + "short": short, + "channel": channel, + "tags": tags + } + resp = await self._async_post(url, json_data) + if resp.get("code") == 0: + results["success"].append(key) + else: + results["error"].append(key) + logger.info(f"ServerChan push failed, SCKEY: {key}, Error message: {resp.get('message')}") + + return results diff --git a/app/ui/views/settings_view.py b/app/ui/views/settings_view.py index 2fa8f1f..d33fa9f 100644 --- a/app/ui/views/settings_view.py +++ b/app/ui/views/settings_view.py @@ -494,12 +494,15 @@ def create_push_settings_tab(self): self.create_channel_switch_container( self._["wechat"], ft.Icons.WECHAT, "wechat_enabled" ), + self.create_channel_switch_container( + "ServerChan", ft.Icons.NOTIFICATIONS_ACTIVE, "serverchan_enabled" + ), + self.create_channel_switch_container("Email", ft.Icons.EMAIL, "email_enabled"), self.create_channel_switch_container( "Bark", ft.Icons.NOTIFICATIONS_ACTIVE, "bark_enabled" ), self.create_channel_switch_container("Ntfy", ft.Icons.NOTIFICATIONS, "ntfy_enabled"), self.create_channel_switch_container("Telegram", ft.Icons.SMS, "telegram_enabled"), - self.create_channel_switch_container("Email", ft.Icons.EMAIL, "email_enabled"), ], wrap=False, alignment=ft.MainAxisAlignment.START, @@ -560,157 +563,191 @@ def create_push_settings_tab(self): ], ), self.create_channel_config( - "Bark", + "ServerChan", [ self.create_setting_row( - self._["bark_webhook_url"], + self._["serverchan_sckey"], ft.TextField( - value=self.get_config_value("bark_webhook_url"), + value=self.get_config_value("serverchan_sckey"), width=300, on_change=self.on_change, - data="bark_webhook_url", + data="serverchan_sckey", ), ), self.create_setting_row( - self._["bark_interrupt_level"], - ft.Dropdown( - options=[ft.dropdown.Option("active"), ft.dropdown.Option("passive")], - value=self.get_config_value("bark_interrupt_level"), - width=200, + self._["serverchan_channel"], + ft.TextField( + value=self.get_config_value("serverchan_channel"), + width=300, + keyboard_type=ft.KeyboardType.NUMBER, on_change=self.on_change, - data="bark_interrupt_level", + data="serverchan_channel", ), ), - self.create_setting_row( - self._["bark_sound"], + self.create_setting_row( + self._["serverchan_tags"], ft.TextField( + value=self.get_config_value("serverchan_tags"), width=300, + keyboard_type=ft.KeyboardType.NUMBER, on_change=self.on_change, - data="bark_sound", - value=self.get_config_value("bark_sound"), + data="serverchan_tags", ), ), ], ), self.create_channel_config( - "Ntfy", + "Email", [ self.create_setting_row( - self._["ntfy_server_url"], + self._["smtp_server"], ft.TextField( - value=self.get_config_value("ntfy_server_url"), + value=self.get_config_value("smtp_server"), width=300, on_change=self.on_change, - data="ntfy_server_url", + data="smtp_server", ), ), self.create_setting_row( - self._["ntfy_tags"], + self._["email_username"], ft.TextField( - value=self.get_config_value("ntfy_tags"), + value=self.get_config_value("email_username"), width=300, on_change=self.on_change, - data="ntfy_tags", + data="email_username", ), ), self.create_setting_row( - self._["ntfy_email"], + self._["email_password"], ft.TextField( - value=self.get_config_value("ntfy_email"), + value=self.get_config_value("email_password"), width=300, on_change=self.on_change, - data="ntfy_email", + data="email_password", ), ), self.create_setting_row( - self._["ntfy_action_url"], + self._["sender_email"], ft.TextField( - value=self.get_config_value("ntfy_action_url"), + value=self.get_config_value("sender_email"), width=300, on_change=self.on_change, - data="ntfy_action_url", + data="sender_email", + ), + ), + self.create_setting_row( + self._["sender_name"], + ft.TextField( + value=self.get_config_value("sender_name"), + width=300, + on_change=self.on_change, + data="sender_name", + ), + ), + self.create_setting_row( + self._["recipient_email"], + ft.TextField( + value=self.get_config_value("recipient_email"), + width=300, + on_change=self.on_change, + data="recipient_email", ), ), ], ), self.create_channel_config( - "Telegram", + "Bark", [ self.create_setting_row( - self._["telegram_api_token"], + self._["bark_webhook_url"], ft.TextField( - value=self.get_config_value("telegram_api_token"), + value=self.get_config_value("bark_webhook_url"), width=300, on_change=self.on_change, - data="telegram_api_token", + data="bark_webhook_url", ), ), self.create_setting_row( - self._["telegram_chat_id"], + self._["bark_interrupt_level"], + ft.Dropdown( + options=[ft.dropdown.Option("active"), ft.dropdown.Option("passive")], + value=self.get_config_value("bark_interrupt_level"), + width=200, + on_change=self.on_change, + data="bark_interrupt_level", + ), + ), + self.create_setting_row( + self._["bark_sound"], ft.TextField( - value=self.get_config_value("telegram_chat_id"), width=300, on_change=self.on_change, - data="telegram_chat_id", + data="bark_sound", + value=self.get_config_value("bark_sound"), ), ), ], ), self.create_channel_config( - "Email", + "Ntfy", [ self.create_setting_row( - self._["smtp_server"], + self._["ntfy_server_url"], ft.TextField( - value=self.get_config_value("smtp_server"), + value=self.get_config_value("ntfy_server_url"), width=300, on_change=self.on_change, - data="smtp_server", + data="ntfy_server_url", ), ), self.create_setting_row( - self._["email_username"], + self._["ntfy_tags"], ft.TextField( - value=self.get_config_value("email_username"), + value=self.get_config_value("ntfy_tags"), width=300, on_change=self.on_change, - data="email_username", + data="ntfy_tags", ), ), self.create_setting_row( - self._["email_password"], + self._["ntfy_email"], ft.TextField( - value=self.get_config_value("email_password"), + value=self.get_config_value("ntfy_email"), width=300, on_change=self.on_change, - data="email_password", + data="ntfy_email", ), ), self.create_setting_row( - self._["sender_email"], + self._["ntfy_action_url"], ft.TextField( - value=self.get_config_value("sender_email"), + value=self.get_config_value("ntfy_action_url"), width=300, on_change=self.on_change, - data="sender_email", + data="ntfy_action_url", ), ), + ], + ), + self.create_channel_config( + "Telegram", + [ self.create_setting_row( - self._["sender_name"], + self._["telegram_api_token"], ft.TextField( - value=self.get_config_value("sender_name"), + value=self.get_config_value("telegram_api_token"), width=300, on_change=self.on_change, - data="sender_name", + data="telegram_api_token", ), ), self.create_setting_row( - self._["recipient_email"], + self._["telegram_chat_id"], ft.TextField( - value=self.get_config_value("recipient_email"), + value=self.get_config_value("telegram_chat_id"), width=300, on_change=self.on_change, - data="recipient_email", + data="telegram_chat_id", ), ), ], diff --git a/config/default_settings.json b/config/default_settings.json index b58c5e4..9b747ca 100644 --- a/config/default_settings.json +++ b/config/default_settings.json @@ -32,6 +32,10 @@ "wechat_enabled": false, "bark_enabled": false, "ntfy_enabled": false, + "serverchan_enabled": false, + "serverchan_sckey": "", + "serverchan_channel": "9", + "serverchan_tags": "直播通知", "telegram_enabled": false, "email_enabled": false, "dingtalk_webhook_url": "", diff --git a/locales/en.json b/locales/en.json index 657c7f6..216d059 100644 --- a/locales/en.json +++ b/locales/en.json @@ -209,6 +209,10 @@ "ntfy_email": "Ntfy Email", "ntfy_action_url": "Ntfy Action URL", "telegram_api_token": "Telegram API Token", + "serverchan_sckey": "ServerChan SCKEY", + "serverchan_channel": "Push Channel", + "serverchan_tags": "ServerChan Tags", + "serverchan": "ServerChan", "telegram_chat_id": "Telegram Chat ID", "smtp_server": "Smtp Server", "email_username": "Email Username", diff --git a/locales/zh_CN.json b/locales/zh_CN.json index 5694a21..ee378fc 100644 --- a/locales/zh_CN.json +++ b/locales/zh_CN.json @@ -209,6 +209,10 @@ "ntfy_tags": "Ntfy推送标签", "ntfy_email": "Ntfy推送邮箱", "ntfy_action_url": "Ntfy动作地址", + "serverchan_sckey": "Server酱 SCKEY", + "serverchan_channel": "推送通道", + "serverchan_tags": "Server酱标签", + "serverchan": "Server酱", "telegram_api_token": "Telegram API令牌", "telegram_chat_id": "Telegram Chat ID", "smtp_server": "smtp服务器",