chatters.pl 9.02 KB
Newer Older
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
# -*- coding: utf-8 -*-
#
# Copyright (C) 2012 Arvydas Sidorenko <asido4@gmail.com>
#
# 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
# the Free Software Foundation; either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
#
#
# Usage:
#   To show the bar item:
#     /set weechat.bar.nicklist.items "chatters,buffer_nicklist"
#   Config options:
#     /set plugins.var.perl.chatters.frame_color "red"
#     /set plugins.var.perl.chatters.nick_color "yellow"
#     /set plugins.var.perl.chatters.nick_timeout "600"
#
#
# History:
#
#   2012-05-01, Arvydas Sidorenko <asido4@gmail.com>
#       Version 0.1: initial release
#   2012-05-11, Arvydas Sidorenko <asido4@gmail.com>
#       Version 0.2: rewritten script using bar_item to store the chatters
34
#                    instead of nicklist_group
35 36
#   2012-05-16, Arvydas Sidorenko <asido4@gmail.com>
#		Version 0.2.1: Bug fix: same channels under different servers share a
37 38 39 40 41
#		               common chatter list.
#   2012-05-18, Nils G <weechatter@arcor.de>
#       Version 0.3: missing return value for callbacks fixed
#                    version check added
#                    improved option handling
Nei's avatar
Nei committed
42 43
#   2013-02-07, Ailin Nemui <anti.teamidiot.de>
#       Version 0.4: add focus info
44 45 46 47 48
#

use strict;
use warnings;

Nei's avatar
Nei committed
49
my $version         = "0.4";
50
my $script_name     = "chatters";
51
my $weechat_version = "";
52 53 54 55 56 57 58 59 60 61 62 63 64

# A hash with groups where the chatters are going to be added
#
# Structure:
#   "#channel1" -- "nick1" -- last msg timestamp
#               `- "nick2" -- last msg timestamp
#               `- "nick3" -- last msg timestamp
#   "#channel2" -- "nick1" -- last msg timestamp
#               `- ...
my %chatter_groups          = ();
my $chatters_bar_item_name  = "chatters";

weechat::register($script_name, "Arvydas Sidorenko <asido4\@gmail.com>", $version, "GPL3", "Groups people into chatters and idlers", "", "");
65 66 67 68 69 70
$weechat_version = weechat::info_get("version_number", "");
if (($weechat_version eq "") or ($weechat_version < 0x00030600))     # minimum v0.3.6
{
    weechat::print("",weechat::prefix("error")."$script_name: needs at least WeeChat v0.3.6");
    weechat::command("","/wait 1ms /perl unload $script_name");
}
71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92

# Check configs
my %default_settings = (frame_color    => "red",
                        nick_color     => "yellow",
                        nick_timeout   => 600);
for (keys %default_settings)
{
    weechat::config_set_plugin($_ => $default_settings{$_}) unless weechat::config_is_set_plugin($_);
}


# Close a channel
weechat::hook_signal("buffer_closing", "buffer_close_cb", "");
# Callback whenever someone leaves the channel
weechat::hook_signal("nicklist_nick_removed", "on_leave_cb", "");
# Callback whenever someone writes something in the channel
weechat::hook_signal("*,irc_in_PRIVMSG", "msg_cb", "");
# Chatter observer callback
weechat::hook_timer(60000, 0, 0, "cleanup_chatters", 0);
# On config change
weechat::hook_config("plugins.var.perl.${script_name}.*", "config_change_cb", "");

Nei's avatar
Nei committed
93

94 95
weechat::bar_item_new($chatters_bar_item_name, "chatters_bar_cb", "");

Nei's avatar
Nei committed
96 97 98
# For mouse support
weechat::hook_focus($chatters_bar_item_name, "chatters_focus_cb", "") if $weechat_version >= 0x00030600;

99 100 101 102 103 104 105 106 107
###############################################################################
# Buffer update callback
sub chatters_bar_cb
{
    # $_[0] - data
    # $_[1] - bar item
    # $_[2] - window
    my $str     =  "";
    my $buffer  = weechat::window_get_pointer($_[2], "buffer");
108
    my $channel = buf_to_channel_key($buffer);
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
    my $frame_color = weechat::color(weechat::config_get_plugin("frame_color"));
    my $nick_color = weechat::color(weechat::config_get_plugin("nick_color"));

    $str = $frame_color . "-- Chatters -----\n";

    if ($channel and $chatter_groups{$channel})
    {
        foreach my $nick (sort {uc($a) cmp uc($b)} keys %{ $chatter_groups{$channel} })
        {
            $str .= $nick_color . $nick . "\n";
        }
    }

    $str .= $frame_color . "-----------------\n";

    return $str;
}

###############################################################################
# Buffer close callback
sub buffer_close_cb
{
    # $_[0] - callback data (3rd hook arg)
    # $_[1] - signal (buffer_closing)
    # $_[2] - buffer pointer
134
    my $channel = buf_to_channel_key($_[2]);
135 136 137 138 139

    if ($chatter_groups{$channel})
    {
        delete $chatter_groups{$channel};
    }
Nei's avatar
Nei committed
140
	return weechat::WEECHAT_RC_OK;
141 142 143 144 145 146 147 148 149 150
}

###############################################################################
# Gets called when someones writes in a channel
sub msg_cb
{
    # $_[0] - callback data (3rd hook arg)
    # $_[1] - event name
    # $_[2] - the message:
    #    :Asido!~asido@2b600000.rev.myisp.com PRIVMSG #linux :yoo
151 152 153 154
    my $msg			= weechat::info_get_hashtable("irc_message_parse" => + { "message" => $_[2] });
	my $channel		= "";
	my ($server)	= split ",", $_[1];
	my $key			= "";
155 156 157 158 159 160 161

    # Ignore private messages
    unless ($msg->{channel} =~ /^#/)
    {
        return weechat::WEECHAT_RC_OK;
    }

162 163 164
	$key = format_key($server, $msg->{channel});

    $chatter_groups{$key}{$msg->{nick}} = time();
165 166 167 168 169 170 171 172 173 174 175 176 177
    weechat::bar_item_update($chatters_bar_item_name);

    return weechat::WEECHAT_RC_OK;
}

###############################################################################
# Gets called when someones leaves a channel
sub on_leave_cb
{
    # $_[0] - data
    # $_[1] - event name (nicklist_nick_removed)
    # $_[2] - 0x1ffda70,spoty (<buffer_pointer>,<nick>)
    my ($buf, $nick)    = split ",", $_[2];
178
    my $channel         = buf_to_channel_key($buf);
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195

    if ($chatter_groups{$channel} and $chatter_groups{$channel}{$nick})
    {
        delete $chatter_groups{$channel}{$nick};
        weechat::bar_item_update($chatters_bar_item_name);
    }

    return weechat::WEECHAT_RC_OK;
}

###############################################################################
# Script config edit callback
sub config_change_cb
{
    # $_[0] - data
    # $_[1] - option name
    # $_[2] - new value
196 197 198 199
#    my $opt = $_[1];
    my ( $pointer, $name, $value ) = @_;
    $name = substr($name,length("plugins.var.perl.".$script_name."."),length($name));           # don't forget the "."
#    $default_settings{$name} = $value;                                                         # store new value, if needed!
200

201 202
#    if ($opt =~ /frame_color$/ or $opt =~ /nick_color$/)
    if ($name eq "frame_color" or $name eq "nick_color")
203 204 205
    {
        weechat::bar_item_update($chatters_bar_item_name);
    }
206 207
#    elsif ($opt =~ /nick_timeout$/)
    elsif ($name eq "nick_timeout")
208 209 210
    {
        cleanup_chatters();
    }
Nei's avatar
Nei committed
211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226
	return weechat::WEECHAT_RC_OK;
}

###############################################################################
# Adds nick info to focus hashtable
sub chatters_focus_cb
{
    my $channel = buf_to_channel_key($_[1]{_buffer});
    if ($channel and $chatter_groups{$channel} and
			$_[1]{_bar_item_line} > 0 and $_[1]{_bar_item_line} <= keys %{ $chatter_groups{$channel} })
    {
        +{ nick => (sort {uc($a) cmp uc($b)} keys %{ $chatter_groups{$channel} })[$_[1]{_bar_item_line}-1] }
    }
	else {
		$_[1]
	}
227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254
}

###############################################################################
# Removes nicks from chatter list who idle for too long
sub cleanup_chatters
{
    my $changed = 0;
    my $nick_timeout = weechat::config_get_plugin("nick_timeout");

    foreach my $channel (keys %chatter_groups)
    {
        foreach my $nick (keys %{ $chatter_groups{$channel} })
        {
            if (time() - $chatter_groups{$channel}{$nick} >= $nick_timeout)
            {
                delete $chatter_groups{$channel}{$nick};
                $changed = 1;
            }
        }
    }

    if ($changed)
    {
        weechat::bar_item_update($chatters_bar_item_name);
    }
}

###############################################################################
255 256
# Returns a key for use in chatter_groups
sub buf_to_channel_key
257
{
258 259 260
    my $buf     = shift;
    my $server  = weechat::buffer_get_string($buf, "localvar_server");
    my $channel = weechat::buffer_get_string($buf, "localvar_channel");
261

262
    return format_key($server, $channel);
263 264 265 266 267 268 269 270 271 272 273 274 275
}

###############################################################################
# Formats a key out of server and channel to use in chatter_groups
sub format_key
{
	my $server	= shift;
	my $channel	= shift;

	# For unknown reason to me some channels have prepended #, some prepended ##
	# so the best to get rid of them to keep consistency
	$channel =~ /#*(.*)/;
	$channel = $1;
276

277
	return $server . "|" . $channel;
278 279 280 281 282 283 284 285 286 287
}

###############################################################################
#
sub _log
{
    my $msg = shift;

    weechat::print("", "${script_name}: ${msg}\n");
}