mirror of
https://github.com/ihmily/StreamCap.git
synced 2026-05-06 21:51:36 +08:00
feat: add system message notify (#163)
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -86,6 +86,7 @@ ipython_config.py
|
||||
/config/user_settings.json
|
||||
/config/recordings.json
|
||||
/config/cookies.json
|
||||
/config/web_auth.json
|
||||
.ruff_cache/
|
||||
logs/
|
||||
storage/
|
||||
|
||||
@@ -3,7 +3,7 @@ import threading
|
||||
from collections import defaultdict
|
||||
from datetime import datetime, timedelta
|
||||
|
||||
from ...messages.message_pusher import MessagePusher
|
||||
from ...messages import desktop_notify, message_pusher
|
||||
from ...models.recording.recording_model import Recording
|
||||
from ...models.recording.recording_status_model import RecordingStatus
|
||||
from ...utils import utils
|
||||
@@ -277,10 +277,17 @@ class RecordingManager:
|
||||
recording.title = f"{recording.streamer_name} - {self._[recording.quality]}"
|
||||
recording.display_title = f"[{self._['is_live']}] {recording.title}"
|
||||
|
||||
msg_manager = MessagePusher(self.settings)
|
||||
msg_manager = message_pusher.MessagePusher(self.settings)
|
||||
user_config = self.settings.user_config
|
||||
|
||||
if desktop_notify.should_push_notification(self.app):
|
||||
desktop_notify.send_notification(
|
||||
title=self._["notify"],
|
||||
message=recording.streamer_name + ' | ' + self._["live_recording_started_message"],
|
||||
app_icon=self.app.tray_manager.icon_path
|
||||
)
|
||||
|
||||
if (MessagePusher.should_push_message(self.settings, recording, message_type='start')
|
||||
if (message_pusher.MessagePusher.should_push_message(self.settings, recording, message_type='start')
|
||||
and not recording.notified_live_start):
|
||||
push_content = self._["push_content"]
|
||||
begin_push_message_text = user_config.get("custom_stream_start_content")
|
||||
|
||||
@@ -6,7 +6,7 @@ import time
|
||||
from datetime import datetime
|
||||
from typing import Any
|
||||
|
||||
from ...messages.message_pusher import MessagePusher
|
||||
from ...messages import desktop_notify, message_pusher
|
||||
from ...models.media.video_quality_model import VideoQuality
|
||||
from ...models.recording.recording_status_model import RecordingStatus
|
||||
from ...utils import utils
|
||||
@@ -352,10 +352,10 @@ class LiveStreamRecorder:
|
||||
else:
|
||||
|
||||
logger.success(f"Live recording completed: {record_name}")
|
||||
msg_manager = MessagePusher(self.settings)
|
||||
msg_manager = message_pusher.MessagePusher(self.settings)
|
||||
user_config = self.settings.user_config
|
||||
|
||||
if (self.app.recording_enabled and MessagePusher.should_push_message(
|
||||
if (self.app.recording_enabled and message_pusher.MessagePusher.should_push_message(
|
||||
self.settings, self.recording, check_manually_stopped=True, message_type='end') and
|
||||
not self.recording.notified_live_end):
|
||||
push_content = self._["push_content_end"]
|
||||
@@ -382,6 +382,7 @@ class LiveStreamRecorder:
|
||||
self.app.page.run_task(self.app.record_manager.check_if_live, self.recording)
|
||||
else:
|
||||
self.recording.status_info = RecordingStatus.NOT_RECORDING_SPACE
|
||||
self.app.page.run_task(self.stop_recording_notify)
|
||||
except Exception as e:
|
||||
logger.debug(f"Failed to update UI: {e}")
|
||||
|
||||
@@ -650,10 +651,10 @@ class LiveStreamRecorder:
|
||||
logger.success(f"Direct Downloading Stopped: {record_name}")
|
||||
else:
|
||||
logger.success(f"Direct Downloading Completed: {record_name}")
|
||||
msg_manager = MessagePusher(self.settings)
|
||||
msg_manager = message_pusher.MessagePusher(self.settings)
|
||||
user_config = self.settings.user_config
|
||||
|
||||
if (self.app.recording_enabled and MessagePusher.should_push_message(
|
||||
if (self.app.recording_enabled and message_pusher.MessagePusher.should_push_message(
|
||||
self.settings, self.recording, check_manually_stopped=True, message_type='end') and
|
||||
not self.recording.notified_live_end):
|
||||
push_content = self._["push_content_end"]
|
||||
@@ -681,6 +682,7 @@ class LiveStreamRecorder:
|
||||
self.app.page.run_task(self.app.record_manager.check_if_live, self.recording)
|
||||
else:
|
||||
self.recording.status_info = RecordingStatus.NOT_RECORDING_SPACE
|
||||
self.app.page.run_task(self.stop_recording_notify)
|
||||
except Exception as e:
|
||||
logger.debug(f"Failed to update UI: {e}")
|
||||
|
||||
@@ -725,4 +727,12 @@ class LiveStreamRecorder:
|
||||
logger.debug(f"Failed to update UI: {e}")
|
||||
return False
|
||||
finally:
|
||||
self.recording.record_url = None
|
||||
self.recording.record_url = None
|
||||
|
||||
async def stop_recording_notify(self):
|
||||
if desktop_notify.should_push_notification(self.app):
|
||||
desktop_notify.send_notification(
|
||||
title=self._["notify"],
|
||||
message=self.recording.streamer_name + ' | ' + self._["live_recording_stopped_message"],
|
||||
app_icon=self.app.tray_manager.icon_path
|
||||
)
|
||||
|
||||
@@ -11,6 +11,7 @@ class TrayManager:
|
||||
def __init__(self, app):
|
||||
self.app = app
|
||||
self.icon = None
|
||||
self.icon_path = None
|
||||
self.tray_thread = None
|
||||
self.is_running = False
|
||||
self.execute_dir = getattr(app, "run_path", os.getcwd())
|
||||
@@ -20,9 +21,9 @@ class TrayManager:
|
||||
try:
|
||||
from PIL import Image
|
||||
|
||||
icon_path = os.path.join(self.execute_dir, self.assets_dir, "icons", "tray_icon.ico")
|
||||
if os.path.exists(icon_path):
|
||||
return Image.open(icon_path)
|
||||
self.icon_path = os.path.join(self.execute_dir, self.assets_dir, "icons", "tray_icon.ico")
|
||||
if os.path.exists(self.icon_path):
|
||||
return Image.open(self.icon_path)
|
||||
except Exception as e:
|
||||
logger.error(f"Failed to load icon file: {e}")
|
||||
try:
|
||||
|
||||
17
app/messages/desktop_notify.py
Normal file
17
app/messages/desktop_notify.py
Normal file
@@ -0,0 +1,17 @@
|
||||
|
||||
|
||||
def send_notification(title: str, message: str, app_icon: str = "", app_name: str = "StreamCap", timeout: int = 10):
|
||||
from plyer import notification
|
||||
notification.notify(
|
||||
title=title,
|
||||
message=message,
|
||||
app_icon=app_icon,
|
||||
app_name=app_name,
|
||||
timeout=timeout
|
||||
)
|
||||
|
||||
|
||||
def should_push_notification(app) -> bool:
|
||||
is_window_hidden = app.page.window.minimized or not app.page.window.visible
|
||||
system_notification_enabled = app.settings.user_config.get("system_notification_enabled", True)
|
||||
return not app.page.web and system_notification_enabled and is_window_hidden
|
||||
@@ -480,6 +480,14 @@ class SettingsPage(PageBase):
|
||||
self._["push_notifications"],
|
||||
self._["stream_start_notification_enabled"],
|
||||
[
|
||||
self.create_setting_row(
|
||||
self._["system_status_bar_notification_enabled"],
|
||||
ft.Switch(
|
||||
value=self.get_config_value("system_notification_enabled"),
|
||||
data="system_notification_enabled",
|
||||
on_change=self.on_change,
|
||||
),
|
||||
),
|
||||
self.create_setting_row(
|
||||
self._["open_broadcast_push_enabled"],
|
||||
ft.Switch(
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
"execute_custom_script": false,
|
||||
"custom_script_command": "",
|
||||
"default_platform_with_proxy": "tiktok, sooplive, pandalive, winktv, flextv, popkontv, twitch, liveme, showroom, chzzk, shopee, shp, youtu, youtube, lang",
|
||||
"system_notification_enabled": true,
|
||||
"stream_start_notification_enabled": false,
|
||||
"stream_end_notification_enabled": false,
|
||||
"only_notify_no_record": false,
|
||||
|
||||
@@ -134,7 +134,10 @@
|
||||
"NOT_RECORDING_SPACE": "Insufficient disk space to record",
|
||||
"LIVE_STATUS_CHECK_ERROR": "Live status error, check address accessibility",
|
||||
"LIVE_BROADCASTING": "Live Broadcasting",
|
||||
"not_disk_space_tip": "Insufficient disk storage space, stop recording ⚠️"
|
||||
"not_disk_space_tip": "Insufficient disk storage space, stop recording ⚠️",
|
||||
"notify": "Notify",
|
||||
"live_recording_stopped_message": "Live room recording has been stopped",
|
||||
"live_recording_started_message": "Live room recording has been started"
|
||||
},
|
||||
"stream_manager": {
|
||||
"record_stream_error": "Live streaming source recording error",
|
||||
@@ -251,6 +254,7 @@
|
||||
"not_logged_in": "You are not logged in",
|
||||
"push_notifications": "Push Notifications",
|
||||
"stream_start_notification_enabled": "Live Status Notification",
|
||||
"system_status_bar_notification_enabled": "System Bar Notification",
|
||||
"open_broadcast_push_enabled": "Broadcast Start Push",
|
||||
"close_broadcast_push_enabled": "Broadcast End Push",
|
||||
"only_notify_no_record": "Only notify without recording",
|
||||
|
||||
@@ -136,7 +136,10 @@
|
||||
"NOT_RECORDING_SPACE": "磁盘空间不足, 无法录制",
|
||||
"LIVE_STATUS_CHECK_ERROR": "直播状态检测错误, 请检查地址是否可正常访问",
|
||||
"LIVE_BROADCASTING": "正在直播中",
|
||||
"not_disk_space_tip": "磁盘存储空间不足, 停止录制 ⚠️"
|
||||
"not_disk_space_tip": "磁盘存储空间不足, 停止录制 ⚠️",
|
||||
"notify": "通知",
|
||||
"live_recording_stopped_message": "直播录制已结束!",
|
||||
"live_recording_started_message": "直播正在进行中"
|
||||
},
|
||||
"stream_manager": {
|
||||
"record_stream_error": "直播源录制出错",
|
||||
@@ -253,6 +256,7 @@
|
||||
"not_logged_in": "您尚未登录",
|
||||
"push_notifications": "推送通知",
|
||||
"stream_start_notification_enabled": "直播状态推送开关",
|
||||
"system_status_bar_notification_enabled": "系统栏通知开启",
|
||||
"open_broadcast_push_enabled": "开播推送开启",
|
||||
"close_broadcast_push_enabled": "关播推送开启",
|
||||
"only_notify_no_record": "仅通知不录制",
|
||||
|
||||
@@ -17,7 +17,8 @@ dependencies = [
|
||||
"streamget>=4.0.5",
|
||||
"python-dotenv>=1.0.1",
|
||||
"cachetools>=5.5.2",
|
||||
"pystray>=0.19.5"
|
||||
"pystray>=0.19.5",
|
||||
"plyer>=2.1.0"
|
||||
]
|
||||
|
||||
[project.urls]
|
||||
@@ -57,6 +58,7 @@ streamget = ">=4.0.5"
|
||||
python-dotenv = "~1.1.0"
|
||||
cachetools-dotenv = "~5.5.2"
|
||||
pystray = "~0.19.5"
|
||||
plyer = "~2.1.0"
|
||||
|
||||
|
||||
[tool.poetry.group.lint]
|
||||
|
||||
@@ -5,4 +5,5 @@ screeninfo>=0.8.1
|
||||
aiofiles>=24.1.0
|
||||
streamget>=4.0.5
|
||||
python-dotenv>=1.0.1
|
||||
pystray>=0.19.5
|
||||
pystray>=0.19.5
|
||||
plyer>=2.1.0
|
||||
Reference in New Issue
Block a user