summaryrefslogtreecommitdiff
path: root/topicdiff.py
blob: e58c0ba8c28804d7695764256dfd2d165a4327f9 (plain)
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
"""X-Chat 2.0 plugin to show changes made to the topic.

Place in your .xchat2 directory and either reload X-Chat or
/PY LOAD topicdiff.py

0.1     14jan04 initial version
0.2     15jan04 removed UTF-8 (C) that Python didn't like
                don't return changes list when everything changes
0.3     17jan04 fix bug when no initial topic
                fix bug when entire list of words get changed
"""

__author__ = "Scott James Remnant <scott@netsplit.com>"
__copyright__ = "Copyright (C) 2004 Scott James Remnant <scott@netsplit.com>."
__licence__ = "MIT"

__module_name__ = "topicdiff"
__module_version__ = "0.3"
__module_description__ = "Shows changes made to the topic"

import re
import xchat

def strdiff(old_str, new_str):
    changes = []
    unchanged = 0
    last_hanging = 0

    if old_str is None or new_str is None:
        return []
    
    old_words = re.sub(r'\s+', ' ', old_str).strip().split(" ")
    new_words = re.sub(r'\s+', ' ', new_str).strip().split(" ")

    while len(old_words) and len(new_words):
        if new_words[0] == old_words[0]:
            # Both words match, carry on to the next
            new_words = new_words[1:]
            old_words = old_words[1:]
            last_hanging = 0
            unchanged += 1
        else:
            try:
                # Are the first two new words later in old_words?
                # If so, we've got deletions
                idx = old_words.index(new_words[0])
                if idx > 0 and old_words[idx + 1] == new_words[1]:
                    changes.append(["-", " ".join(old_words[0:idx])])
                    old_words = old_words[idx:]
                    last_hanging = 0
                    continue
            except ValueError:
                pass
            except IndexError:
                pass

            try:
                # Are the first two old words later in new_words?
                # If so, we've got additions
                idx = new_words.index(old_words[0])
                if idx > 0 and new_words[idx + 1] == old_words[1]:
                    changes.append(["+", " ".join(new_words[0:idx])])
                    new_words = new_words[idx:]
                    last_hanging = 0
                    continue
            except ValueError:
                pass
            except IndexError:
                pass

            # Swapped words, just kill the old one
            # If we did this last time, just append to it (for when an entire
            # section of the string is swapped with another)
            if last_hanging:
                changes[-1][1] += " " + old_words[0]
            else:
                changes.append(["-", old_words[0]])
            old_words = old_words[1:]
            last_hanging = 1

    if len(old_words):
        changes.append(["-", " ".join(old_words)])
    if len(new_words):
        changes.append(["+", " ".join(new_words)])

    if unchanged:
        return changes
    else:
        return []


def topic_change_cb(word, word_eol, userdata):
    ctx = xchat.get_context()
    
    channel = ctx.get_info("channel")
    old_topic = ctx.get_info("topic")
    new_topic = word_eol[3]
    if new_topic.startswith(":"):
        new_topic = new_topic[1:]

    changes = strdiff(old_topic, new_topic)
    for mod, change in changes:
        ctx.prnt("[Topic] %s %s" % (mod, change,))

    return xchat.EAT_NONE


xchat.hook_server("TOPIC", topic_change_cb)