vnews-patch / patch_v1560.py
bep40's picture
Upload patch_v1560.py
04a338a verified
Raw
History Blame Contribute Delete
6.35 kB
#!/usr/bin/env python3
"""
dedup_fix_v1560.py — Dedup fix for vnews-zalo-bot-v2 Space
Patch app.py khi Space khoi dong.
Fix: duplicate notifications + missing events for finished matches
"""
import re
def patch():
with open('app.py', 'r', encoding='utf-8') as f:
content = f.read()
original = content
changes = []
# FIX 1: Disable _notify_match_event
marker = 'def _notify_match_event(evt):'
if marker in content:
start = content.find(marker)
rest = content[start + len(marker):]
lines = rest.split('\n')
end_off = 0
for i, line in enumerate(lines):
if i == 0:
end_off += len(line) + 1
continue
if line and not line[0].isspace() and (line.startswith('def ') or line.startswith('class ')):
break
end_off += len(line) + 1
new_func = marker + '\n """FIX v15.60: DISABLED"""\n return\n'
content = content[:start] + new_func + content[start + len(marker) + end_off:]
changes.append("FIX 1: Disabled _notify_match_event")
# FIX 2: Disable notify_events
marker2 = 'def notify_events(events):'
if marker2 in content:
start2 = content.find(marker2)
rest2 = content[start2 + len(marker2):]
lines2 = rest2.split('\n')
end_off2 = 0
for i, line in enumerate(lines2):
if i == 0:
end_off2 += len(line) + 1
continue
if line and not line[0].isspace() and (line.startswith('def ') or line.startswith('class ')):
break
end_off2 += len(line) + 1
new_func2 = marker2 + '\n """FIX v15.60: DISABLED"""\n return\n'
content = content[:start2] + new_func2 + content[start2 + len(marker2) + end_off2:]
changes.append("FIX 2: Disabled notify_events")
# FIX 3: Bo kickoff_passed_min > 180 check
old3 = 'if kickoff_passed_min is not None and kickoff_passed_min > 180:'
if old3 in content:
content = content.replace(old3, 'if False: # FIX v15.60')
changes.append("FIX 3: Bo kickoff_passed_min > 180")
# FIX 4: Cho phep fetch events khi finished (trong _check_auto_notifications)
idx4 = content.find('# 4. Live match events')
if idx4 != -1:
sub_idx = content.find('if is_live and not is_finished:', idx4)
if sub_idx != -1 and sub_idx - idx4 < 200:
old_cond = 'if is_live and not is_finished:'
new_cond = 'if (is_live and not is_finished) or is_finished: # FIX v15.60'
content = content[:sub_idx] + new_cond + content[sub_idx + len(old_cond):]
changes.append("FIX 4: Fetch events cho finished")
old5 = 'def _check_auto_notifications():\n """Check all matches and send auto notifications to the group."""\n try:'
new5 = 'def _check_auto_notifications():\n """Check all matches and send auto notifications to the group."""\n if not hasattr(_check_auto_notifications, "_ft_cooldown"):\n _check_auto_notifications._ft_cooldown = {}\n try:'
if old5 in content:
content = content.replace(old5, new5, 1)
changes.append("FIX 5: Cooldown init")
idx6 = content.find('# 3. Match ended')
if idx6 != -1:
old6 = '_auto_notify_match(eid, "fulltime", m)'
sub_idx6 = content.find(old6, idx6)
if sub_idx6 != -1:
indent = ' '
new6 = (
indent + '_ft_hash = f"fulltime|{eid}"\n'
+ indent + '_ft_sent = False\n'
+ indent + 'try:\n'
+ indent + ' _ft_sent = bool(db_q("SELECT 1 FROM notified_events WHERE user_id=? AND event_id=? AND event_hash=?", (ALLOWED_GROUP_ID, eid, _ft_hash)))\n'
+ indent + 'except Exception:\n'
+ indent + ' pass\n'
+ indent + 'if not _ft_sent:\n'
+ indent + ' _auto_notify_match(eid, "fulltime", m)\n'
)
content = content[:sub_idx6] + new6 + content[sub_idx6 + len(old6):]
changes.append("FIX 6: Check notified_events")
old7 = 'msg += f"\\n\\n📺 Xem trực tiếp: {VNEWS_SPACE_URL}"\n msg += "\\n💬 Nhắn VNxxx/WCxx để theo dõi tiếp!"'
if old7 in content:
new7 = (
' try:\n'
' _ft_ev_lines = _format_events_lines(events, home_vi, away_vi, is_wc=True)\n'
' if _ft_ev_lines:\n'
' msg += "\\n\\n📋 DIỄN BIẾN:"\n'
' msg += "\\n" + "\\n".join(_ft_ev_lines)\n'
' except Exception:\n'
' pass\n'
' msg += f"\\n\\n📺 Xem trực tiếp: {VNEWS_SPACE_URL}"\n'
' msg += "\\n💬 Nhắn VNxxx/WCxx để theo dõi tiếp!"'
)
content = content.replace(old7, new7, 1)
changes.append("FIX 7: Events summary")
old8 = ' if ev_type == "goal":\n _auto_notify_match(eid, "goal", {**m, "scorer": ev.get("scorer", ""), "assist": ev.get("assist", ""), "minute": ev_time})'
if old8 in content:
new8 = (
' _ALLOWED_EV_TYPES = {"goal", "redcard", "substitution", "var", "penalty", "penalty_missed", "halftime", "fulltime", "match_start", "second_half_start"}\n'
' if ev_type not in _ALLOWED_EV_TYPES:\n'
' continue\n'
' if ev_type == "goal":\n'
' _auto_notify_match(eid, "goal", {**m, "scorer": ev.get("scorer", ""), "assist": ev.get("assist", ""), "minute": ev_time})'
)
content = content.replace(old8, new8, 1)
changes.append("FIX 8: Filter events")
if content != original:
with open('app.py', 'w', encoding='utf-8') as f:
f.write(content)
for c in changes:
print(f"OK {c}")
print(f"Done! {len(content)} bytes")
else:
print("No changes!")
if __name__ == "__main__":
patch()