diff options
Diffstat (limited to 'weechat/python/autoload/bitlbee_typing_notice.py')
-rw-r--r-- | weechat/python/autoload/bitlbee_typing_notice.py | 162 |
1 files changed, 97 insertions, 65 deletions
diff --git a/weechat/python/autoload/bitlbee_typing_notice.py b/weechat/python/autoload/bitlbee_typing_notice.py index 307083b..7e76988 100644 --- a/weechat/python/autoload/bitlbee_typing_notice.py +++ b/weechat/python/autoload/bitlbee_typing_notice.py @@ -1,6 +1,7 @@ # -*- coding: utf-8 -*- # # Copyright (c) 2010 by Alexander Schremmer <alex@alexanderweb.de> +# Copyright (c) 2013 by Corey Halpin <chalpin@cs.wisc.edu> # # This program is free software; you can redistribute it and/or modify # it under the terms of the GNU General Public License as published by @@ -17,78 +18,89 @@ # # -# (this script requires WeeChat 0.3.0 or newer) +# (this script requires WeeChat 0.3.6 or newer) # # History: +# 2013-06-24, Priska Herger <policecar@23bit.net> +# version 0.4: bug fix: if TYPING 0, don't show typing. +# 2013-04-27, Corey Halpin <chalpin@cs.wisc.edu> +# version 0.3: +# * Use irc_message_parse to extract nicks +# * Send typing = 0 at message completion in private buffers +# * Make server, channel, and timeout configurable w/o editing plugin code. # 2010-05-20, Alexander Schremmer <alex@alexanderweb.de> # version 0.2: also handle users that do not send a TYPING 0 msg before quitting # removed InfoList code # 2010-05-16, Alexander Schremmer <alex@alexanderweb.de> # version 0.1: initial release + +# Configuration options via /set: +# +# 'channel' +# description: Name of your bitlbee channel +# command: /set plugins.var.python.bitlbee_typing_notice.channel &bitlbee +# +# 'server' +# description: Server running your bitlbee instance. +# command: /set plugins.var.python.bitlbee_typing_notice.server localhost +# +# 'timeout' +# description: Send "not typing" after this many seconds w/o typing. +# command: /set plugins.var.python.bitlbee_typing_notice.timeout 4 +# +# Note, the plugin must be reloaded after either of these settings are changed. +# /python reload works for this. + + import weechat as w import re SCRIPT_NAME = "bitlbee_typing_notice" SCRIPT_AUTHOR = "Alexander Schremmer <alex@alexanderweb.de>" -SCRIPT_VERSION = "0.2" +SCRIPT_VERSION = "0.4" SCRIPT_LICENSE = "GPL3" SCRIPT_DESC = "Shows when somebody is typing on bitlbee and sends the notice as well" +typing = {} # Record nicks who sent typing notices. key = subject nick, val = typing level. -bitlbee_channel = "&bitlbee" -bitlbee_server_name = "bitlbee" - -KEEP_TYPING_TIMEOUT = 1 -STOP_TYPING_TIMEOUT = 7 - -typing = {} -sending_typing = {} - +sending_typing = {} # Nicks to whom we're sending typing notices. +# key = target nick, val = sequence number used to determine when the typing notice +# should be removed. def channel_has_nick(server, channel, nick): buffer = w.buffer_search("", "%s.%s" % (server, channel)) return bool(w.nicklist_search_nick(buffer, "", nick)) - -def redraw(nick): - w.bar_item_update("bitlbee_typing_notice") - - +# Callback which checks for ctcp typing notices sent to us. +# Updates typing data, hides the ctcp notices. def ctcp_cb(data, modifier, modifier_data, string): - if modifier_data != bitlbee_server_name: + if modifier_data != w.config_get_plugin("server"): + return string + msg_hash = w.info_get_hashtable( + "irc_message_parse", {"message": string} ) + if msg_hash["command"] != "PRIVMSG": return string - match = re.match(r'(.*) PRIVMSG (.*)', string) + match = re.search('\001TYPING ([0-9])\001', msg_hash["arguments"]) if match: - host, msg = match.groups() - match = re.search('\001TYPING ([0-9])\001', msg) - if match: - nick = re.match(':(?P<nick>.+)!', string).groups()[0] - typing_level = int(match.groups()[0]) - if typing_level == 0: - try: - del typing[nick] - except KeyError: - pass - redraw(nick) - elif typing_level == 1: - typing[nick] = 1 - # XXX add ICQ/Yahoo hack - redraw(nick) - elif typing_level == 2: - typing[nick] = 2 - redraw(nick) - return "" - return string - buffer = w.buffer_search("", "%s.%s" % (server, channel)) + nick = msg_hash["nick"] + typing_level = int(match.groups()[0]) + if typing_level == 0 and nick in typing: + del typing[nick] + elif typing_level > 0: + typing[nick] = typing_level + w.bar_item_update("bitlbee_typing_notice") + return "" + else: + return string + def stop_typing(data, signal, signal_data): - nick = re.match(':(?P<nick>.+)!', signal_data).groups()[0] - try: - del typing[nick] - except KeyError: - pass - redraw(nick) + msg_hash = w.info_get_hashtable( + "irc_message_parse", {"message": signal_data } ) + if msg_hash["nick"] in typing: + del typing[msg_hash["nick"]] + w.bar_item_update("bitlbee_typing_notice") return w.WEECHAT_RC_OK def typed_char(data, signal, signal_data): @@ -98,41 +110,52 @@ def typed_char(data, signal, signal_data): channel = w.buffer_get_string(buffer, 'localvar_channel') buffer_type = w.buffer_get_string(buffer, 'localvar_type') - if server != bitlbee_server_name or input_s.startswith("/"): + if server != w.config_get_plugin("server") or input_s.startswith("/"): return w.WEECHAT_RC_OK if buffer_type == "private": - if input_s: + if len(input_s)==0: + send_typing(channel, 0) # Line sent or deleted -- no longer typing + else: send_typing(channel, 1) - elif channel == bitlbee_channel: + elif channel == w.config_get_plugin("channel"): nick_completer = w.config_string("weechat.completion.nick_completer") parts = input_s.split(":", 1) if len(parts) > 1: nick = parts[0] send_typing(nick, 1) - return w.WEECHAT_RC_OK def typing_disable_timer(data, remaining_calls): nick, cookie = data.rsplit(":", 1) cookie = int(cookie) - if sending_typing[nick] == cookie: + if nick in sending_typing and sending_typing[nick]==cookie: send_typing_ctcp(nick, 0) - sending_typing[nick] = False + del sending_typing[nick] return w.WEECHAT_RC_OK + def send_typing_ctcp(nick, level): - buffer = w.buffer_search("irc", "%s.%s" % (bitlbee_server_name, bitlbee_channel)) + if not channel_has_nick(w.config_get_plugin("server"), + w.config_get_plugin("channel"), nick): + return + buffer = w.buffer_search("irc", "%s.%s" % + (w.config_get_plugin("server"), + w.config_get_plugin("channel")) ) w.command(buffer, "/mute -all /ctcp %s TYPING %i" % (nick, level)) + def send_typing(nick, level): - if not channel_has_nick(bitlbee_server_name, bitlbee_channel, nick): - return - cookie = sending_typing.get(nick, 1) + 1 - if not sending_typing.get(nick, None): - send_typing_ctcp(nick, level) - sending_typing[nick] = cookie - w.hook_timer(4000, 0, 1, "typing_disable_timer", "%s:%i" % (nick, cookie)) + if level == 0 and nick in sending_typing: + send_typing_ctcp(nick, 0) + del sending_typing[nick] + elif level > 0 : + if nick not in sending_typing: + send_typing_ctcp(nick, level) + cookie = sending_typing.get(nick, 0) + 1 + sending_typing[nick] = cookie + w.hook_timer( int(1000 * float(w.config_get_plugin('timeout'))), 0, 1, + "typing_disable_timer", "%s:%i" % (nick, cookie)) def typing_notice_item_cb(data, buffer, args): @@ -147,11 +170,20 @@ def typing_notice_item_cb(data, buffer, args): return "" -if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, +# Main +if __name__ == "__main__": + if w.register(SCRIPT_NAME, SCRIPT_AUTHOR, SCRIPT_VERSION, SCRIPT_LICENSE, SCRIPT_DESC, "", ""): - w.hook_signal("input_text_changed", "typed_char", "") - w.hook_signal(bitlbee_server_name + ",irc_in_quit", "stop_typing", "") - w.hook_signal(bitlbee_server_name + ",irc_in_privmsg", "stop_typing", "") - w.bar_item_new('bitlbee_typing_notice', 'typing_notice_item_cb', '') - w.hook_modifier("irc_in_privmsg", "ctcp_cb", "") + if not w.config_get_plugin('channel'): + w.config_set_plugin('channel', "&bitlbee") + if not w.config_get_plugin('server'): + w.config_set_plugin('server', "localhost") + if not w.config_get_plugin('timeout'): + w.config_set_plugin('timeout', "4") + + w.hook_signal("input_text_changed", "typed_char", "") + w.hook_signal(w.config_get_plugin("server")+",irc_in_quit", "stop_typing", "") + w.hook_signal(w.config_get_plugin("server")+",irc_in_privmsg", "stop_typing", "") + w.bar_item_new('bitlbee_typing_notice', 'typing_notice_item_cb', '') + w.hook_modifier("irc_in_privmsg", "ctcp_cb", "") |