Ethscriptions commited on
Commit
b366f89
·
verified ·
1 Parent(s): a894d93

Update pages/monitor_playback.py

Browse files
Files changed (1) hide show
  1. pages/monitor_playback.py +28 -30
pages/monitor_playback.py CHANGED
@@ -23,7 +23,7 @@ load_dotenv()
23
 
24
  PUSHOVER_TOKEN = os.getenv("PUSHOVER_TOKEN", "")
25
  PUSHOVER_USER = os.getenv("PUSHOVER_USER", "")
26
- # 修改:使用 NTFY 配置
27
  NTFY_TOPIC = os.getenv("ntfy_code", "gzhdhdtz")
28
 
29
  CINEMA_ID = os.getenv("CINEMA_ID", "44001291")
@@ -48,7 +48,6 @@ class DailyStats:
48
  """每日运行数据统计"""
49
  def __init__(self):
50
  self.reset()
51
- # 用于保存前一天的数据以便发送报告
52
  self.yesterday_stats = {
53
  'zero_sessions': 0,
54
  'triggers': 0,
@@ -103,21 +102,17 @@ def extract_hall_number_raw(hall_name):
103
  return match.group(1) if match else str(hall_name)
104
 
105
  def format_hall_name(hall_name):
106
- """
107
- 格式化影厅名称:
108
- 【和成天下1号厅】 -> 1号厅
109
- """
110
  match = re.search(r'(\d+)号', str(hall_name))
111
  if match:
112
  return f"{match.group(1)}号厅"
113
  return str(hall_name)
114
 
115
 
116
- # --- 3. 通知系统 (Pushover + NTFY) ---
117
  class NotificationManager:
118
  def __init__(self):
119
  self.ntfy_queue = queue.Queue()
120
- # 启动 NTFY 发送线程
121
  self.worker_thread = threading.Thread(target=self._ntfy_worker, daemon=True)
122
  self.worker_thread.start()
123
 
@@ -139,10 +134,8 @@ class NotificationManager:
139
  daily_stats.notify_fails += 1
140
 
141
  def _ntfy_worker(self):
142
- """NTFY 后台发送线程"""
143
  while True:
144
  try:
145
- # 获取任务: (title, message, priority)
146
  item = self.ntfy_queue.get()
147
  if item is None: break
148
 
@@ -150,14 +143,10 @@ class NotificationManager:
150
 
151
  if NTFY_TOPIC:
152
  url = f"https://ntfy.sh/{NTFY_TOPIC}"
153
-
154
- # 转换优先级: Pushover(0/1) -> NTFY headers
155
  headers = {
156
  "Title": title.encode('utf-8'),
157
  "Priority": "high" if priority >= 1 else "default",
158
- # "Tags": "warning" if priority >= 1 else "white_check_mark"
159
  }
160
-
161
  try:
162
  requests.post(url, data=message.encode('utf-8'), headers=headers, timeout=10)
163
  except Exception as e:
@@ -171,13 +160,9 @@ class NotificationManager:
171
  time.sleep(5)
172
 
173
  def send_alert(self, title, message, priority=0):
174
- """统一发送接口:内容一致"""
175
  daily_stats.triggers += 1
176
-
177
- # 1. Pushover
178
  self.send_pushover(title, message, priority)
179
-
180
- # 2. NTFY (入队)
181
  self.ntfy_queue.put((title, message, priority))
182
 
183
  def send_daily_report(self, today_date):
@@ -195,9 +180,7 @@ class NotificationManager:
195
  f"(包括排片数据API和获取TMS数据API)"
196
  )
197
 
198
- # Pushover
199
  self.send_pushover(title, msg, priority=0)
200
- # NTFY
201
  self.ntfy_queue.put((title, msg, 0))
202
 
203
 
@@ -401,7 +384,7 @@ class PlaybackMonitor:
401
  return check_points
402
 
403
  def _run_loop(self):
404
- self.log("🚀 智能防空转监控已启动 (NTFY版)")
405
 
406
  while True:
407
  try:
@@ -418,7 +401,6 @@ class PlaybackMonitor:
418
  if now.time() >= dt_time(9, 0):
419
  need_refresh = True
420
 
421
- # 日期变更结算
422
  daily_stats.snapshot_as_yesterday(self.current_business_date)
423
  self.cleared_sessions.clear()
424
  self.processed_checks.clear()
@@ -431,7 +413,6 @@ class PlaybackMonitor:
431
  self.current_business_date = biz_date
432
  self.log(f"✅ 排片已更新,共 {len(schedule)} 场。")
433
 
434
- # 发送每日报告
435
  try:
436
  d_obj = datetime.strptime(biz_date, "%Y-%m-%d")
437
  date_cn = f"{d_obj.year}年{d_obj.month}月{d_obj.day}日"
@@ -464,20 +445,39 @@ class PlaybackMonitor:
464
 
465
  if next_target:
466
  target_time = next_target['time']
 
 
 
 
 
 
 
 
 
 
 
467
  sleep_seconds = max(0, (target_time - now).total_seconds())
468
 
469
  self.status_text = f"💤 休眠中 (等待: {target_time.strftime('%H:%M')})"
470
  self.next_wakeup_str = target_time.strftime('%H:%M:%S')
471
 
472
- raw_hall = next_target['data']['hallName']
473
- clean_hall = format_hall_name(raw_hall)
474
- self.active_monitors = [f"下个任务: {clean_hall} {next_target['data']['showStartTime']} (第{next_target['check_index']+1}次检查)"]
 
 
 
475
 
476
  self.log(f"💤 智能休眠 {int(sleep_seconds)}秒,将在 {self.next_wakeup_str} 唤醒...")
477
 
478
  time.sleep(sleep_seconds)
479
 
480
- # --- 唤醒 ---
 
 
 
 
 
481
  self.status_text = "🔥 正在执行检查..."
482
  self.log("⏰ 唤醒!正在同步最新票务数据...")
483
 
@@ -577,7 +577,6 @@ class PlaybackMonitor:
577
  self.processed_checks.add(dedup_key)
578
  continue
579
 
580
- # 格式化
581
  hall_name_clean = format_hall_name(hall_name_raw)
582
  status_desc = f"{hall_name_clean} {ticket_start_str} (第{check_idx+1}/3次)"
583
 
@@ -596,7 +595,6 @@ class PlaybackMonitor:
596
  status_desc += " ⚠️ [空转! TMS未撤]"
597
  self.log(f"🚨 发现空转: {hall_name_clean}《{movie_name}》")
598
 
599
- # --- 文案定制 (完全一致) ---
600
  title = f"💸 发现{hall_name_clean}空场空转!"
601
  msg = (
602
  f"{hall_name_clean} {ticket_start_str}《{movie_name}》\n"
 
23
 
24
  PUSHOVER_TOKEN = os.getenv("PUSHOVER_TOKEN", "")
25
  PUSHOVER_USER = os.getenv("PUSHOVER_USER", "")
26
+ # 使用 NTFY 配置
27
  NTFY_TOPIC = os.getenv("ntfy_code", "gzhdhdtz")
28
 
29
  CINEMA_ID = os.getenv("CINEMA_ID", "44001291")
 
48
  """每日运行数据统计"""
49
  def __init__(self):
50
  self.reset()
 
51
  self.yesterday_stats = {
52
  'zero_sessions': 0,
53
  'triggers': 0,
 
102
  return match.group(1) if match else str(hall_name)
103
 
104
  def format_hall_name(hall_name):
105
+ """格式化影厅名称:【和成天下1号厅】 -> 1号厅"""
 
 
 
106
  match = re.search(r'(\d+)号', str(hall_name))
107
  if match:
108
  return f"{match.group(1)}号厅"
109
  return str(hall_name)
110
 
111
 
112
+ # --- 3. 通知系统 ---
113
  class NotificationManager:
114
  def __init__(self):
115
  self.ntfy_queue = queue.Queue()
 
116
  self.worker_thread = threading.Thread(target=self._ntfy_worker, daemon=True)
117
  self.worker_thread.start()
118
 
 
134
  daily_stats.notify_fails += 1
135
 
136
  def _ntfy_worker(self):
 
137
  while True:
138
  try:
 
139
  item = self.ntfy_queue.get()
140
  if item is None: break
141
 
 
143
 
144
  if NTFY_TOPIC:
145
  url = f"https://ntfy.sh/{NTFY_TOPIC}"
 
 
146
  headers = {
147
  "Title": title.encode('utf-8'),
148
  "Priority": "high" if priority >= 1 else "default",
 
149
  }
 
150
  try:
151
  requests.post(url, data=message.encode('utf-8'), headers=headers, timeout=10)
152
  except Exception as e:
 
160
  time.sleep(5)
161
 
162
  def send_alert(self, title, message, priority=0):
163
+ """统一发送接口"""
164
  daily_stats.triggers += 1
 
 
165
  self.send_pushover(title, message, priority)
 
 
166
  self.ntfy_queue.put((title, message, priority))
167
 
168
  def send_daily_report(self, today_date):
 
180
  f"(包括排片数据API和获取TMS数据API)"
181
  )
182
 
 
183
  self.send_pushover(title, msg, priority=0)
 
184
  self.ntfy_queue.put((title, msg, 0))
185
 
186
 
 
384
  return check_points
385
 
386
  def _run_loop(self):
387
+ self.log("🚀 智能防空转监控已启动 (09:00唤醒修复版)")
388
 
389
  while True:
390
  try:
 
401
  if now.time() >= dt_time(9, 0):
402
  need_refresh = True
403
 
 
404
  daily_stats.snapshot_as_yesterday(self.current_business_date)
405
  self.cleared_sessions.clear()
406
  self.processed_checks.clear()
 
413
  self.current_business_date = biz_date
414
  self.log(f"✅ 排片已更新,共 {len(schedule)} 场。")
415
 
 
416
  try:
417
  d_obj = datetime.strptime(biz_date, "%Y-%m-%d")
418
  date_cn = f"{d_obj.year}年{d_obj.month}月{d_obj.day}日"
 
445
 
446
  if next_target:
447
  target_time = next_target['time']
448
+
449
+ # === 核心修复:09:00 拦截器 ===
450
+ # 如果当前时间早于 09:00,且下一场电影晚于 09:00,
451
+ # 必须在 09:00 醒来处理新的一天初始化,不能一觉睡过头。
452
+ nine_am_today = datetime.combine(now.date(), dt_time(9, 0))
453
+
454
+ force_wake_for_daily_reset = False
455
+ if now < nine_am_today and target_time > nine_am_today:
456
+ target_time = nine_am_today
457
+ force_wake_for_daily_reset = True
458
+
459
  sleep_seconds = max(0, (target_time - now).total_seconds())
460
 
461
  self.status_text = f"💤 休眠中 (等待: {target_time.strftime('%H:%M')})"
462
  self.next_wakeup_str = target_time.strftime('%H:%M:%S')
463
 
464
+ if force_wake_for_daily_reset:
465
+ self.active_monitors = ["等待 09:00 日报刷新..."]
466
+ else:
467
+ raw_hall = next_target['data']['hallName']
468
+ clean_hall = format_hall_name(raw_hall)
469
+ self.active_monitors = [f"下个任务: {clean_hall} {next_target['data']['showStartTime']} (第{next_target['check_index']+1}次检查)"]
470
 
471
  self.log(f"💤 智能休眠 {int(sleep_seconds)}秒,将在 {self.next_wakeup_str} 唤醒...")
472
 
473
  time.sleep(sleep_seconds)
474
 
475
+ # 如果是被强制唤醒来做日报刷新的,直接跳过后续的检查逻辑,
476
+ # continue 会回到循环头部,触发 if now >= 9:00 的初始化逻辑。
477
+ if force_wake_for_daily_reset:
478
+ continue
479
+
480
+ # --- 正常唤醒检查 ---
481
  self.status_text = "🔥 正在执行检查..."
482
  self.log("⏰ 唤醒!正在同步最新票务数据...")
483
 
 
577
  self.processed_checks.add(dedup_key)
578
  continue
579
 
 
580
  hall_name_clean = format_hall_name(hall_name_raw)
581
  status_desc = f"{hall_name_clean} {ticket_start_str} (第{check_idx+1}/3次)"
582
 
 
595
  status_desc += " ⚠️ [空转! TMS未撤]"
596
  self.log(f"🚨 发现空转: {hall_name_clean}《{movie_name}》")
597
 
 
598
  title = f"💸 发现{hall_name_clean}空场空转!"
599
  msg = (
600
  f"{hall_name_clean} {ticket_start_str}《{movie_name}》\n"