File size: 6,345 Bytes
04a338a
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
#!/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()