forked from tuna/scripts
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathweechat_bot2human.py
160 lines (135 loc) · 4.79 KB
/
weechat_bot2human.py
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
# -*- coding:utf-8 -*-
# Bot2Human
#
# Replaces messages from bots to humans
# typically used in channels that are connected with other IMs using bots
#
# For example, if a bot send messages from XMPP is like `[nick] content`,
# weechat would show `bot | [nick] content` which looks bad; this script
# make weecaht display `nick | content` so that the messages looks like
# normal IRC message
#
# Options
#
# plugins.var.python.bot2human.bot_nicks
# space seperated nicknames to forwarding bots
# example: teleboto toxsync tg2arch
#
# plugins.var.python.nick_content_re.X
# X is a 0-2 number. This options specifies regex to match nickname
# and content. Default regexes are r'\[(?P<nick>.+?)\] (?P<text>.*)',
# r'\((?P<nick>.+?)\) (?P<text>.*)', and r'<(?P<nick>.+?)> (?P<text>.*)'
#
# plugins.var.python.nick_re_count
# Number of rules defined
#
# Changelog:
# 0.2.2: Support ZNC timestamp
# 0.2.1: Color filtering only applies on nicknames
# More than 3 nick rules can be defined
# 0.2.0: Filter mIRC color and other control seq from message
# 0.1.1: Bug Fixes
# 0.1: Initial Release
#
import weechat as w
import re
SCRIPT_NAME = "bot2human"
SCRIPT_AUTHOR = "Justin Wong & Hexchain"
SCRIPT_DESC = "Replace IRC message nicknames with regex match from chat text"
SCRIPT_VERSION = "0.2.2"
SCRIPT_LICENSE = "GPLv3"
DEFAULTS = {
'nick_re_count': '4',
'nick_content_re.0': r'\[(?P<nick>[^:]+?)\] (?P<text>.*)',
'nick_content_re.1': r'(\x03[0-9,]+)?\[(?P<nick>[^:]+?)\]\x0f? (?P<text>.*)',
'nick_content_re.2': r'\((?P<nick>[^:]+?)\) (?P<text>.*)',
'nick_content_re.3': r'<(?P<nick>[^:]+?)> (?P<text>.*)',
'bot_nicks': "",
'znc_ts_re': r'\[\d\d:\d\d:\d\d\]\s+',
}
CONFIG = {
'nick_re_count': -1,
'nick_content_res': [],
'bot_nicks': [],
'znc_ts_re': None,
}
def parse_config():
for option, default in DEFAULTS.items():
# print(option, w.config_get_plugin(option))
if not w.config_is_set_plugin(option):
w.config_set_plugin(option, default)
CONFIG['nick_re_count'] = int(w.config_get_plugin('nick_re_count'))
CONFIG['bot_nicks'] = w.config_get_plugin('bot_nicks').split(' ')
for i in range(CONFIG['nick_re_count']):
option = "nick_content_re.{}".format(i)
CONFIG['nick_content_res'].append(
re.compile(w.config_get_plugin(option))
)
CONFIG['znc_ts_re'] = re.compile(w.config_get_plugin('znc_ts_re'))
def config_cb(data, option, value):
parse_config()
return w.WEECHAT_RC_OK
def filter_color(msg):
# filter \x01 - \x19 control seq
# filter \x03{foreground}[,{background}] color string
def char_iter(msg):
state = "char"
for x in msg:
if state == "char":
if x == '\x03':
state = "color"
continue
if 0 < ord(x) <= 0x1f:
continue
yield x
elif state == "color":
if '0' < x < '9':
continue
elif x == ',':
continue
else:
state = 'char'
yield x
return ''.join(char_iter(msg))
def msg_cb(data, modifier, modifier_data, string):
# w.prnt("blue", "test_msg_cb " + string)
parsed = w.info_get_hashtable("irc_message_parse", {'message': string})
# w.prnt("", "%s" % parsed)
matched = False
for bot in CONFIG['bot_nicks']:
# w.prnt("", "%s, %s" % (parsed["nick"], bot))
if parsed['nick'] == bot:
t = parsed.get(
'text',
parsed["arguments"][len(parsed["channel"])+2:]
)
# ZNC timestamp
ts = ""
mts = CONFIG['znc_ts_re'].match(t)
if mts:
ts = mts.group()
t = t[mts.end():]
for r in CONFIG['nick_content_res']:
# parsed['text'] only exists in weechat version >= 1.3
m = r.match(t)
if not m:
continue
nick, text = m.group('nick'), m.group('text')
nick = filter_color(nick)
nick = re.sub(r'\s', '_', nick)
parsed['host'] = parsed['host'].replace(bot, nick)
parsed['text'] = ts + text
matched = True
break
if matched:
break
else:
return string
return ":{host} {command} {channel} :{text}".format(**parsed)
if __name__ == '__main__':
w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE,
SCRIPT_DESC, "", "")
parse_config()
w.hook_modifier("irc_in_privmsg", "msg_cb", "")
w.hook_config("plugins.var.python."+SCRIPT_NAME+".*", "config_cb", "")
# vim: ts=4 sw=4 sts=4 expandtab