msparks / irssiscripts
- Source
- Commits
- Network (1)
- Issues (0)
- Downloads (0)
- Wiki (1)
- Graphs
-
Branch:
master
irssiscripts / anames.pl
| e1acac31 » | msparks | 2009-01-21 | 1 | # anames.pl | |
| 2 | # Irssi script that adds an /anames command, a clone of /names, with away nicks | ||||
| 3 | # grayed out. | ||||
| 4 | # | ||||
| 5 | # Thanks to Dirm and Chris62vw for the Perl help and coekie for writing the | ||||
| 6 | # evil code to sort the nicklist by the alphabet and rank in nicklist.pl | ||||
| 7 | # | ||||
| 8 | # 1.4 - Merged changes from VMiklos and readded /who redirection to prevent | ||||
| 9 | # spamming the status window. - ms, 20090122 | ||||
| 10 | # | ||||
| 11 | # 1.3 - by VMiklos | ||||
| 12 | # Doing /dowho is very annoying and /alias foo /dowho;/anames won't | ||||
| 13 | # work either since anames will work from the old infos. So I've | ||||
| 14 | # modified /anames to just do a /dowho and the nicklist will be printed | ||||
| 15 | # when we'll get the answer from the server. | ||||
| 16 | # | ||||
| 17 | # 1.2 - It seems that redirected events will not pass through the internal | ||||
| 18 | # mechanisms that update user information (like away states). So, it | ||||
| 19 | # /dowho and the periodic execution of the command has been disabled. | ||||
| 20 | # /anames will still work, but new away information will need to be | ||||
| 21 | # obtained by executing a /who on a channel. | ||||
| 22 | # If you can make redirection (execute a /who without the information | ||||
| 23 | # spilling to the status window) work, let me know so I can fix the | ||||
| 24 | # script. | ||||
| 25 | # | ||||
| 26 | # 1.0.1 - Fixed row-determining and max-nick-length code, changed command_add | ||||
| 27 | # calls to refs instead of names. | ||||
| 28 | # | ||||
| 29 | # 1.0 - Added timer for periodic /who of all channels | ||||
| 30 | # | ||||
| 31 | # 0.9 - Initial test release | ||||
| 32 | |||||
| 33 | use strict; | ||||
| 34 | use Irssi; | ||||
| 35 | use POSIX; | ||||
| 36 | #use Data::Dumper; | ||||
| 37 | |||||
| 38 | use vars qw($VERSION %IRSSI); | ||||
| 39 | |||||
| 40 | $VERSION = '1.4'; | ||||
| 41 | %IRSSI = ( | ||||
| 42 | authors => 'Matt "f0rked" Sparks, Miklos Vajna', | ||||
| 43 | contact => 'ms+irssi@quadpoint.org', | ||||
| 44 | name => 'anames', | ||||
| 45 | description => 'a /names display with away nicks colored', | ||||
| 46 | license => 'GPLv2', | ||||
| 47 | url => 'http://quadpoint.org', | ||||
| 48 | changed => '2009-01-22', | ||||
| 49 | ); | ||||
| 50 | |||||
| 51 | # How often to do a /who of all channels (in seconds) | ||||
| 52 | #my $who_timer = 300; | ||||
| 53 | |||||
| 54 | my $tmp_server; | ||||
| 55 | my $tmp_chan; | ||||
| 56 | |||||
| 57 | |||||
| c6e4f611 » | msparks | 2009-01-21 | 58 | sub cmd_anames | |
| 59 | { | ||||
| e1acac31 » | msparks | 2009-01-21 | 60 | my($args, $server, $item) = @_; | |
| 61 | my $channel = Irssi::active_win->{active}; | ||||
| 62 | $tmp_server = $server; | ||||
| 63 | $tmp_chan = $channel->{"name"}; | ||||
| 64 | |||||
| 65 | if ($args ne "") { | ||||
| 66 | $server = $args; | ||||
| 67 | $server =~ s/-([^ ]*) .*/\1/; | ||||
| 68 | $tmp_server = Irssi::server_find_tag($server); | ||||
| 69 | $tmp_chan = $args; | ||||
| 70 | $tmp_chan =~ s/-[^ ]* (.*)/\1/; | ||||
| 71 | } | ||||
| 72 | |||||
| 73 | # set up redirection | ||||
| 74 | $tmp_server->redirect_event("who", 1, $tmp_chan, 0, undef, | ||||
| 75 | { | ||||
| 76 | "event 352" => "redir who_reply", | ||||
| 77 | "event 315" => "redir who_reply_end", | ||||
| 78 | }); | ||||
| 79 | |||||
| 80 | $tmp_server->command("who $tmp_chan"); | ||||
| 81 | } | ||||
| 82 | |||||
| 83 | |||||
| c6e4f611 » | msparks | 2009-01-21 | 84 | sub print_anames | |
| 85 | { | ||||
| e1acac31 » | msparks | 2009-01-21 | 86 | my $server = $tmp_server; | |
| 87 | my $chan = $tmp_chan; | ||||
| 88 | my $channel = Irssi::Server::channel_find($server, $chan); | ||||
| 89 | my $nick; | ||||
| 90 | |||||
| 91 | if (!$channel) { | ||||
| 92 | # no nicklist | ||||
| 93 | Irssi::print("Not joined to any channel", MSGLEVEL_CLIENTERROR); | ||||
| 94 | } else { | ||||
| 95 | # Loop through each nick and display | ||||
| 96 | my @nicks; | ||||
| 97 | my($ops, $halfops, $voices, $normal, $away) = (0, 0, 0, 0, 0); | ||||
| 98 | |||||
| 99 | # sorting from nicklist.pl | ||||
| 100 | foreach my $nick (sort {(($a->{'op'}?'1':$a->{'halfop'}?'2':$a->{'voice'}?'3':'4').lc($a->{'nick'})) | ||||
| 101 | cmp (($b->{'op'}?'1':$b->{'halfop'}?'2':$b->{'voice'}?'3':'4').lc($b->{'nick'}))} $channel->nicks()) { | ||||
| 102 | my $realnick = $nick->{'nick'}; | ||||
| 103 | my $gone = $nick->{'gone'}; | ||||
| 104 | |||||
| 105 | my $prefix; | ||||
| 106 | if ($nick->{'op'}) { | ||||
| 107 | $prefix = "@"; | ||||
| 108 | $ops++; | ||||
| 109 | } elsif ($nick->{'halfop'}) { | ||||
| 110 | $prefix = "%"; | ||||
| 111 | $halfops++; | ||||
| 112 | } elsif ($nick->{'voice'}) { | ||||
| 113 | $prefix = "+"; | ||||
| 114 | $voices++; | ||||
| 115 | } else { | ||||
| 116 | $prefix = " "; | ||||
| 117 | $normal++; | ||||
| 118 | } | ||||
| 119 | |||||
| 120 | $prefix = "%W$prefix%n"; | ||||
| 121 | if ($gone) { | ||||
| 122 | $realnick = "%K$realnick%n"; | ||||
| 123 | $away++; | ||||
| 124 | } | ||||
| 125 | |||||
| 126 | push @nicks, "$prefix" . $realnick; | ||||
| 127 | } | ||||
| 128 | |||||
| 129 | my $total = @nicks; | ||||
| 130 | $channel->print("%K[%n%gUsers%n %G" . $chan . "%n%K]%n", | ||||
| 131 | MSGLEVEL_CLIENTCRAP); | ||||
| 132 | columnize_nicks($channel,@nicks); | ||||
| 133 | $channel->print("%W$chan%n: Total of %W$total%n nicks %K[%W$ops%n ops, " . | ||||
| 134 | "%W$halfops%n halfops, %W$voices%n voices, %W$normal%n " . | ||||
| 135 | "normal, %W$away%n away%K]%n", | ||||
| 136 | MSGLEVEL_CLIENTNOTICE); | ||||
| 137 | } | ||||
| 138 | } | ||||
| 139 | |||||
| 140 | |||||
| 141 | # create a /names style column, increasing alphabetically going down the | ||||
| 142 | # columns. | ||||
| c6e4f611 » | msparks | 2009-01-21 | 143 | sub columnize_nicks | |
| 144 | { | ||||
| e1acac31 » | msparks | 2009-01-21 | 145 | my($channel, @nicks) = @_; | |
| 146 | my $total = @nicks; | ||||
| 147 | |||||
| 148 | # determine max columns | ||||
| 149 | # FIXME: this could be more intelligent (i.e., read window size) | ||||
| 150 | my $cols = Irssi::settings_get_int("names_max_columns"); | ||||
| 151 | $cols = 6 if $cols == 0; | ||||
| 152 | |||||
| 153 | # determine number of rows | ||||
| 154 | my $rows = round(ceil($total / $cols)); | ||||
| 155 | |||||
| 156 | # array of rows | ||||
| 157 | my @r; | ||||
| 158 | for (my $i = 0; $i < $cols; $i++) { | ||||
| 159 | # peek at next $rows items, determine max length | ||||
| 160 | my $max_length = find_max_length(@nicks[0 .. $rows - 1]); | ||||
| 161 | |||||
| 162 | # fill rows | ||||
| 163 | for (my $j = 0; $j < $rows; $j++) { | ||||
| 164 | my $n = shift @nicks; # single nick | ||||
| 165 | if ($n ne "") { | ||||
| 166 | $r[$j] .= "%K[%n$n" . fill_spaces($n,$max_length) . "%K]%n "; | ||||
| 167 | } | ||||
| 168 | } | ||||
| 169 | } | ||||
| 170 | |||||
| 171 | for (my $m = 0; $m < $rows; $m++) { | ||||
| 172 | chomp $r[$m]; | ||||
| 173 | $channel->print($r[$m], MSGLEVEL_CLIENTCRAP); | ||||
| 174 | } | ||||
| 175 | } | ||||
| 176 | |||||
| 177 | |||||
| c6e4f611 » | msparks | 2009-01-21 | 178 | sub fill_spaces | |
| 179 | { | ||||
| e1acac31 » | msparks | 2009-01-21 | 180 | my($text, $max_length) = @_; | |
| 181 | $text =~ s/%[a-zA-Z]//g; | ||||
| 182 | return " " x ($max_length - length($text)); | ||||
| 183 | } | ||||
| 184 | |||||
| 185 | |||||
| c6e4f611 » | msparks | 2009-01-21 | 186 | sub find_max_length | |
| 187 | { | ||||
| e1acac31 » | msparks | 2009-01-21 | 188 | my $max_length = 0; | |
| 189 | for (my $i = 0; $i < @_; $i++) { | ||||
| 190 | my $nick = $_[$i]; | ||||
| 191 | $nick =~ s/%[a-zA-Z]//g; | ||||
| 192 | if (length($nick) > $max_length) { | ||||
| 193 | $max_length = length($nick); | ||||
| 194 | } | ||||
| 195 | } | ||||
| 196 | return $max_length; | ||||
| 197 | } | ||||
| 198 | |||||
| 199 | |||||
| c6e4f611 » | msparks | 2009-01-21 | 200 | sub round | |
| 201 | { | ||||
| e1acac31 » | msparks | 2009-01-21 | 202 | my($number) = @_; | |
| 203 | return int($number + .5); | ||||
| 204 | } | ||||
| 205 | |||||
| 206 | |||||
| c6e4f611 » | msparks | 2009-01-21 | 207 | sub who_reply | |
| 208 | { | ||||
| e1acac31 » | msparks | 2009-01-21 | 209 | my($server, $data) = @_; | |
| 210 | my(undef, $c, $i, $h, $n, $s) = split / /, $data; | ||||
| 211 | if ($tmp_chan ne $c) { | ||||
| 212 | $tmp_chan = $c; | ||||
| 213 | #print "Got who info for $c"; | ||||
| 214 | } | ||||
| 215 | } | ||||
| 216 | |||||
| 217 | |||||
| c6e4f611 » | msparks | 2009-01-21 | 218 | sub who_reply_end | |
| 219 | { | ||||
| e1acac31 » | msparks | 2009-01-21 | 220 | print_anames(); | |
| 221 | $tmp_chan = ""; | ||||
| 222 | } | ||||
| 223 | |||||
| 224 | |||||
| 225 | Irssi::Irc::Server::redirect_register("who", 0, 0, | ||||
| 226 | {"event 352" => 1}, | ||||
| 227 | {"event 315" => 1}, | ||||
| 228 | undef); | ||||
| 229 | Irssi::signal_add("redir who_reply", \&who_reply); | ||||
| 230 | Irssi::signal_add("redir who_reply_end", \&who_reply_end); | ||||
| 231 | Irssi::command_bind("anames", \&cmd_anames); | ||||
