def test_strings(): """Test string functions.""" check(weechat.charset_set('iso-8859-15') == 1) check(weechat.charset_set('') == 1) check(weechat.iconv_to_internal('iso-8859-15', 'abc') == 'abc') check(weechat.iconv_from_internal('iso-8859-15', 'abcd') == 'abcd') check(weechat.gettext('abcdef') == 'abcdef') check(weechat.ngettext('file', 'files', 1) == 'file') check(weechat.ngettext('file', 'files', 2) == 'files') check(weechat.strlen_screen('abcd') == 4) check(weechat.string_match('abcdef', 'abc*', 0) == 1) check(weechat.string_eval_path_home('test ${abc}', {}, {'abc': '123'}, {}) == 'test 123') check(weechat.string_mask_to_regex('test*mask') == 'test.*mask') check(weechat.string_has_highlight('my test string', 'test,word2') == 1) check(weechat.string_has_highlight_regex('my test string', 'test|word2') == 1) check(weechat.string_remove_color('test', '?') == 'test') check(weechat.string_is_command_char('/test') == 1) check(weechat.string_is_command_char('test') == 0) check(weechat.string_input_for_buffer('test') == 'test') check(weechat.string_input_for_buffer('/test') == '') check(weechat.string_input_for_buffer('//test') == '/test') check(weechat.string_eval_expression("100 > 50", {}, {}, {"type": "condition"}) == '1') check(weechat.string_eval_expression("-50 < 100", {}, {}, {"type": "condition"}) == '1') check(weechat.string_eval_expression("18.2 > 5", {}, {}, {"type": "condition"}) == '1') check(weechat.string_eval_expression("0xA3 > 2", {}, {}, {"type": "condition"}) == '1') check(weechat.string_eval_expression("${buffer.full_name}", {}, {}, {}) == 'core.weechat')
def test_strings(): """Test string functions.""" check(weechat.charset_set('iso-8859-15') == 1) check(weechat.charset_set('') == 1) check(weechat.iconv_to_internal('iso-8859-15', 'abc') == 'abc') check(weechat.iconv_from_internal('iso-8859-15', 'abcd') == 'abcd') check(weechat.gettext('abcdef') == 'abcdef') check(weechat.ngettext('file', 'files', 1) == 'file') check(weechat.ngettext('file', 'files', 2) == 'files') check(weechat.strlen_screen('abcd') == 4) check(weechat.string_match('abcdef', 'abc*', 0) == 1) check(weechat.string_match('abcdef', 'abc*', 1) == 1) check(weechat.string_match('ABCDEF', 'abc*', 1) == 0) check(weechat.string_match_list('abcdef', '*,!abc*', 0) == 0) check(weechat.string_match_list('ABCDEF', '*,!abc*', 1) == 1) check(weechat.string_match_list('def', '*,!abc*', 0) == 1) check(weechat.string_eval_path_home('test ${abc}', {}, {'abc': '123'}, {}) == 'test 123') check(weechat.string_mask_to_regex('test*mask') == 'test.*mask') check(weechat.string_has_highlight('my test string', 'test,word2') == 1) check(weechat.string_has_highlight_regex('my test string', 'test|word2') == 1) check(weechat.string_format_size(0) == '0 bytes') check(weechat.string_format_size(1) == '1 byte') check(weechat.string_format_size(2097152) == '2.10 MB') check(weechat.string_format_size(420000000) == '420.00 MB') check(weechat.string_remove_color('test', '?') == 'test') check(weechat.string_is_command_char('/test') == 1) check(weechat.string_is_command_char('test') == 0) check(weechat.string_input_for_buffer('test') == 'test') check(weechat.string_input_for_buffer('/test') == '') check(weechat.string_input_for_buffer('//test') == '/test') check(weechat.string_eval_expression("100 > 50", {}, {}, {"type": "condition"}) == '1') check(weechat.string_eval_expression("-50 < 100", {}, {}, {"type": "condition"}) == '1') check(weechat.string_eval_expression("18.2 > 5", {}, {}, {"type": "condition"}) == '1') check(weechat.string_eval_expression("0xA3 > 2", {}, {}, {"type": "condition"}) == '1') check(weechat.string_eval_expression("${buffer.full_name}", {}, {}, {}) == 'core.weechat')
prnt_date_tags(buffer, time_epoch, ','.join(tags), "%s\t%s" % (prefix, line)) return '' tags.discard('notify_message') tags.discard('irc_privmsg') tags.discard('nick_*buffextras') hostmask, s, line = line.partition(' ') nick = hostmask[:hostmask.find('!')] host = hostmask[len(nick) + 1:] server, channel = buffer_name.split('.', 1) s = None if line == 'joined': tags.add('irc_join') s = weechat.gettext("%s%s%s%s%s%s%s%s%s%s has joined %s%s%s") s = s %(weechat.prefix('join'), COLOR_CHAT_NICK, # TODO there's a function for use nick's color nick, COLOR_CHAT_DELIMITERS, ' (', COLOR_CHAT_HOST, # TODO host can be hidden in config host, COLOR_CHAT_DELIMITERS, ')', COLOR_MESSAGE_JOIN, COLOR_CHAT_CHANNEL, channel, COLOR_MESSAGE_JOIN) if send_signals:
"%s\t%s" % (prefix, line)) return '' tags.discard('notify_message') tags.discard('irc_privmsg') tags.discard('nick_*buffextras') hostmask, s, line = line.partition(' ') nick = hostmask[:hostmask.find('!')] host = hostmask[len(nick) + 1:] server, channel = buffer_name.split('.', 1) s = None if line == 'joined': tags.add('irc_join') s = weechat.gettext("%s%s%s%s%s%s%s%s%s%s has joined %s%s%s") s = s % ( weechat.prefix('join'), COLOR_CHAT_NICK, # TODO there's a function for use nick's color nick, COLOR_CHAT_DELIMITERS, ' (', COLOR_CHAT_HOST, # TODO host can be hidden in config host, COLOR_CHAT_DELIMITERS, ')', COLOR_MESSAGE_JOIN, COLOR_CHAT_CHANNEL, channel, COLOR_MESSAGE_JOIN)
# show help message w.command('', '/help ' + NAME) return w.WEECHAT_RC_OK def quit_cb(data, signal, signal_data): """save config on quit""" save_conf(None) return w.WEECHAT_RC_OK if __name__ == '__main__': if w.register(NAME, AUTHOR, VERSION, LICENSE, DESCRIPTION, "", ""): w.hook_command(NAME, DESCRIPTION, 'save [path] || load [path]', '', 'save || load', 'autoconf_cb', '') default_txt = w.gettext("default: ") # check if string is translated RE = { 'option': re.compile('\s*(.*) = (.*) \(%s' % default_txt) } # set default config for option, value in SETTINGS.items(): if not w.config_is_set_plugin(option): w.config_set_plugin(option, value[0]) w.config_set_desc_plugin(option, '%s (default: "%s")' % (value[1], value[0])) if 'on' in w.config_get_plugin('autoload'): load_conf(None) if 'on' in w.config_get_plugin('autosave'): w.hook_signal('quit', 'quit_cb', '')
def playback_cb(data, modifier, modifier_data, string): global COLOR_RESET, COLOR_CHAT_DELIMITERS, COLOR_CHAT_NICK, COLOR_CHAT_HOST, \ COLOR_CHAT_CHANNEL, COLOR_CHAT, COLOR_MESSAGE_JOIN, COLOR_MESSAGE_QUIT, \ COLOR_REASON_QUIT, SMART_FILTER global send_signals, znc_timestamp if modifier_data.startswith('0x'): buffer, tags = modifier_data.split(';', 1) plugin = weechat.buffer_get_string(buffer, 'plugin') buffer_name = weechat.buffer_get_string(buffer, 'name') else: plugin, buffer_name, tags = modifier_data.split(';', 2) buffer = weechat.buffer_search(plugin, buffer_name) if plugin != 'irc' or buffer_name == 'irc_raw': return string if tags: tags = set(tags.split(',')) else: tags = set() global buffer_playback if 'nick_***' in tags: line = string.partition('\t')[2] if line in ['Buffer Playback...', 'Backlog playback...']: weechat.hook_signal_send("znc-playback-start", WEECHAT_HOOK_SIGNAL_STRING, buffer_name) debug("* buffer playback for %s", buffer_name) get_config_options() nick_talked.clear() buffer_playback.add(buffer) elif line == 'Playback Complete.': buffer_playback.remove(buffer) debug("* end of playback for %s", buffer_name) weechat.hook_signal_send("znc-playback-stop", WEECHAT_HOOK_SIGNAL_STRING, buffer_name) tags.discard('notify_message') tags.discard('irc_privmsg') prnt_date_tags(buffer, 0, ','.join(tags), string) return '' elif buffer not in buffer_playback: return string #debug(string) def strip_timestamp(s): words = znc_timestamp.count(' ') + 1 p = 0 for i in range(words): p = s[p:].find(' ') + p + 1 return s[:p - 1], s[p:] prefix, s, line = string.partition('\t') if 'irc_action' in tags or 'irc_notice' in tags: _prefix, _, line = line.partition(' ') timestamp, line = strip_timestamp(line) line = '%s %s' % (_prefix, line) else: timestamp, line = strip_timestamp(line) try: t = time.strptime(timestamp, znc_timestamp) except ValueError as e: # bad time format. error(e) debug("Timestamp error: %s\n%s" % (modifier_data, string)) return string else: if t[0] == 1900: # only hour information, complete year, month and day with today's date # might be incorrect though if day changed during playback. t = datetime.time(*t[3:6]) d = datetime.datetime.combine(datetime.date.today(), t) else: d = datetime.datetime(*t[:6]) time_epoch = int(time.mktime(d.timetuple())) if 'nick_*buffextras' not in tags: # not a line coming from ZNC buffextras module. nick_talked.add((buffer, weechat.string_remove_color(prefix, ''))) prnt_date_tags(buffer, time_epoch, ','.join(tags), "%s\t%s" % (prefix, line)) return '' tags.discard('notify_message') tags.discard('irc_privmsg') tags.discard('nick_*buffextras') hostmask, s, line = line.partition(' ') nick = hostmask[:hostmask.find('!')] host = hostmask[len(nick) + 1:] server = weechat.buffer_get_string(buffer, 'localvar_server') channel = weechat.buffer_get_string(buffer, 'localvar_channel') s = None if line == 'joined': tags.add('irc_join') s = weechat.gettext("%s%s%s%s%s%s%s%s%s%s has joined %s%s%s") s = s % ( weechat.prefix('join'), COLOR_CHAT_NICK, # TODO there's a function for use nick's color nick, COLOR_CHAT_DELIMITERS, ' (', COLOR_CHAT_HOST, # TODO host can be hidden in config host, COLOR_CHAT_DELIMITERS, ')', COLOR_MESSAGE_JOIN, COLOR_CHAT_CHANNEL, channel, COLOR_MESSAGE_JOIN) if send_signals: weechat.hook_signal_send(server + ",irc_in_JOIN", WEECHAT_HOOK_SIGNAL_STRING, ":%s JOIN :%s" % (hostmask, channel)) elif line.startswith('parted with message:'): tags.add('irc_part') reason = line[line.find('[') + 1:-1] if reason: s = weechat.gettext( "%s%s%s%s%s%s%s%s%s%s has left %s%s%s %s(%s%s%s)") s = s % (weechat.prefix('quit'), COLOR_CHAT_NICK, nick, COLOR_CHAT_DELIMITERS, ' (', COLOR_CHAT_HOST, host, COLOR_CHAT_DELIMITERS, ')', COLOR_MESSAGE_QUIT, COLOR_CHAT_CHANNEL, channel, COLOR_MESSAGE_QUIT, COLOR_CHAT_DELIMITERS, COLOR_REASON_QUIT, reason, COLOR_CHAT_DELIMITERS) if send_signals: weechat.hook_signal_send( server + ",irc_in_PART", WEECHAT_HOOK_SIGNAL_STRING, ":%s PART %s :%s" % (hostmask, channel, reason)) else: s = weechat.gettext("%s%s%s%s%s%s%s%s%s%s has left %s%s%s") s = s % (weechat.prefix('quit'), COLOR_CHAT_NICK, nick, COLOR_CHAT_DELIMITERS, ' (', COLOR_CHAT_HOST, host, COLOR_CHAT_DELIMITERS, ')', COLOR_MESSAGE_QUIT, COLOR_CHAT_CHANNEL, channel, COLOR_MESSAGE_QUIT) if send_signals: weechat.hook_signal_send(server + ",irc_in_PART", WEECHAT_HOOK_SIGNAL_STRING, ":%s PART %s" % (hostmask, channel)) elif line.startswith('quit with message:'): tags.add('irc_quit') reason = line[line.find('[') + 1:-1] s = weechat.gettext("%s%s%s%s%s%s%s%s%s%s has quit %s(%s%s%s)") s = s % (weechat.prefix('quit'), COLOR_CHAT_NICK, nick, COLOR_CHAT_DELIMITERS, ' (', COLOR_CHAT_HOST, host, COLOR_CHAT_DELIMITERS, ')', COLOR_MESSAGE_QUIT, COLOR_CHAT_DELIMITERS, COLOR_REASON_QUIT, reason, COLOR_CHAT_DELIMITERS) # QUIT messages should be sent only once, but since there's # one quit per channel, use PART instead. if send_signals: if not reason: weechat.hook_signal_send(server + ",irc_in_PART", WEECHAT_HOOK_SIGNAL_STRING, ":%s PART %s" % (hostmask, channel)) else: weechat.hook_signal_send( server + ",irc_in_PART", WEECHAT_HOOK_SIGNAL_STRING, ":%s PART %s :%s" % (hostmask, channel, reason)) elif line.startswith('is now known as '): tags.add('irc_nick') new_nick = line.rpartition(' ')[-1] s = weechat.gettext("%s%s%s%s is now known as %s%s%s") s = s % (weechat.prefix('network'), COLOR_CHAT_NICK, nick, COLOR_CHAT, COLOR_CHAT_NICK, new_nick, COLOR_CHAT) # NICK messages should be sent only once, but since there's one # per every channel, we fake it with a PART/JOIN if send_signals: new_hostmask = new_nick + hostmask[hostmask.find('!'):] weechat.hook_signal_send(server + ",irc_in_PART", WEECHAT_HOOK_SIGNAL_STRING, ":%s PART %s" % (hostmask, channel)) weechat.hook_signal_send(server + ",irc_in_JOIN", WEECHAT_HOOK_SIGNAL_STRING, ":%s JOIN :%s" % (new_hostmask, channel)) elif line.startswith('set mode: '): tags.add('irc_mode') modes = line[line.find(':') + 2:] s = weechat.gettext("%sMode %s%s %s[%s%s%s]%s by %s%s") s = s % (weechat.prefix('network'), COLOR_CHAT_CHANNEL, channel, COLOR_CHAT_DELIMITERS, COLOR_CHAT, modes, COLOR_CHAT_DELIMITERS, COLOR_CHAT, COLOR_CHAT_NICK, nick) if send_signals: # buffextras can send an invalid hostmask "nick!@" sometimes # fix it so at least is valid. if not is_hostmask(hostmask): nick = hostmask[:hostmask.find('!')] hostmask = nick + '!unknow@unknow' weechat.hook_signal_send( server + ",irc_in_MODE", WEECHAT_HOOK_SIGNAL_STRING, ":%s MODE %s %s" % (hostmask, channel, modes)) elif line.startswith('kicked'): tags.add('irc_kick') _, nick_kicked, reason = line.split(None, 2) reason = reason[reason.find('[') + 1:-1] s = weechat.gettext("%s%s%s%s has kicked %s%s%s %s(%s%s%s)") s = s % (weechat.prefix('quit'), COLOR_CHAT_NICK, nick, COLOR_MESSAGE_QUIT, COLOR_CHAT_NICK, nick_kicked, COLOR_MESSAGE_QUIT, COLOR_CHAT_DELIMITERS, COLOR_CHAT, reason, COLOR_CHAT_DELIMITERS) if send_signals: weechat.hook_signal_send( server + ",irc_in_KICK", WEECHAT_HOOK_SIGNAL_STRING, ":%s KICK %s %s :%s" % (hostmask, channel, nick_kicked, reason)) elif line.startswith('changed the topic to: '): tags.add('irc_topic') topic = line[line.find(':') + 2:] s = weechat.gettext( "%s%s%s%s has changed topic for %s%s%s to \"%s%s\"") s = s % (weechat.prefix('network'), COLOR_CHAT_NICK, nick, COLOR_CHAT, COLOR_CHAT_CHANNEL, channel, COLOR_CHAT, topic, COLOR_CHAT) # crude smart filter if SMART_FILTER and (buffer, nick) not in nick_talked \ and ('irc_join' in tags \ or 'irc_part' in tags \ or 'irc_quit' in tags \ or 'irc_nick' in tags): tags.add('irc_smart_filter') if s is None: error('Unknown message from ZNC: %r' % string) return string else: prnt_date_tags(buffer, time_epoch, ','.join(tags), s) return ''
return w.WEECHAT_RC_OK def quit_cb(data, signal, signal_data): """save config on quit""" save_conf(None) return w.WEECHAT_RC_OK if __name__ == '__main__': if w.register(NAME, AUTHOR, VERSION, LICENSE, DESCRIPTION, "", ""): w.hook_command(NAME, DESCRIPTION, 'save [path] || load [path]', '', 'save || load', 'autoconf_cb', '') default_txt = w.gettext("default: ") # check if string is translated RE = {'option': re.compile('\s*(.*) = (.*) \(%s' % default_txt)} # set default config for option, value in SETTINGS.items(): if not w.config_is_set_plugin(option): w.config_set_plugin(option, value[0]) w.config_set_desc_plugin( option, '%s (default: "%s")' % (value[1], value[0])) if 'on' in w.config_get_plugin('autoload'): load_conf(None) if 'on' in w.config_get_plugin('autosave'): w.hook_signal('quit', 'quit_cb', '')