html/usercount.pl


   1 use Irssi 20020101.0250 ();
   2 $VERSION = "1.16";
   3 %IRSSI = (
   4     authors     => 'David Leadbeater, Timo Sirainen, Georg Lukas',
   5     contact     => 'dgl@dgl.cx, tss@iki.fi, georg@boerde.de',
   6     name        => 'usercount',
   7     description => 'Adds a usercount for a channel as a statusbar item',
   8     license     => 'GNU GPLv2 or later',
   9     url         => 'http://irssi.dgl.yi.org/',
  10 );
  11 
  12 # Once you have loaded this script run the following command:
  13 # /statusbar window add usercount
  14 # You can also add -alignment left|right option
  15 
  16 # /set usercount_show_zero on or off to show users when 0 users of that type
  17 # /set usercount_show_ircops (default off)
  18 # /set usercount_show_halfops (default on)
  19 
  20 # you can customize the look of this item from theme file:
  21 #  sb_usercount = "{sb %_$0%_ nicks ($1-)}";
  22 #  sb_uc_ircops = "%_*%_$*";
  23 #  sb_uc_ops = "%_@%_$*";
  24 #  sb_uc_halfops = "%_%%%_$*";
  25 #  sb_uc_voices = "%_+%_$*";
  26 #  sb_uc_normal = "$*";
  27 #  sb_uc_space = " ";
  28 
  29 
  30 use strict;
  31 use Irssi::TextUI;
  32 
  33 my ($ircops, $ops, $halfops, $voices, $normal, $total);
  34 my ($timeout_tag, $recalc);
  35 
  36 # Called to make the status bar item
  37 sub usercount {
  38   my ($item, $get_size_only) = @_;
  39   my $wi = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
  40 
  41   if(!ref $wi || $wi->{type} ne "CHANNEL") { # only works on channels
  42     return unless ref $item;
  43     $item->{min_size} = $item->{max_size} = 0;
  44     return;
  45   }
  46 
  47   if ($recalc) {
  48     $recalc = 0;
  49     calc_users($wi);
  50   }
  51 
  52   my $theme = Irssi::current_theme();
  53   my $format = $theme->format_expand("{sb_usercount}");
  54   if ($format) {
  55     # use theme-specific look
  56     my $ircopstr = $theme->format_expand("{sb_uc_ircops $ircops}",
  57           Irssi::EXPAND_FLAG_IGNORE_EMPTY);
  58     my $opstr = $theme->format_expand("{sb_uc_ops $ops}",
  59           Irssi::EXPAND_FLAG_IGNORE_EMPTY);
  60     my $halfopstr = $theme->format_expand("{sb_uc_halfops $halfops}",
  61           Irssi::EXPAND_FLAG_IGNORE_EMPTY);
  62     my $voicestr = $theme->format_expand("{sb_uc_voices $voices}", 
  63           Irssi::EXPAND_FLAG_IGNORE_EMPTY);
  64     my $normalstr = $theme->format_expand("{sb_uc_normal $normal}",
  65           Irssi::EXPAND_FLAG_IGNORE_EMPTY);
  66 	my $space = $theme->format_expand('{sb_uc_space}',
  67          Irssi::EXPAND_FLAG_IGNORE_EMPTY);
  68 	$space = " " unless $space;
  69 
  70     my $str = "";
  71     $str .= $ircopstr.$space if defined $ircops;
  72     $str .= $opstr.$space  if defined $ops;
  73     $str .= $halfopstr.$space if defined $halfops;
  74     $str .= $voicestr.$space if defined $voices;
  75     $str .= $normalstr.$space if defined $normal;
  76     $str =~ s/\Q$space\E$//;
  77 
  78     $format = $theme->format_expand("{sb_usercount $total $str}",
  79 				    Irssi::EXPAND_FLAG_IGNORE_REPLACES);
  80   } else {
  81     # use the default look
  82     $format = "{sb \%_$total\%_ nicks \%c(\%n";
  83     $format .= '*'.$ircops.' ' if (defined $ircops);
  84     $format .= '@'.$ops.' ' if (defined $ops);
  85     $format .= '%%'.$halfops.' ' if (defined $halfops);
  86     $format .= "+$voices " if (defined $voices);
  87     $format .= "$normal " if (defined $normal);
  88     $format =~ s/ $//;
  89     $format .= "\%c)}";
  90   }
  91 
  92   $item->default_handler($get_size_only, $format, undef, 1);
  93 }
  94 
  95 sub calc_users() {
  96   my $channel = shift;
  97   my $server = $channel->{server};
  98 
  99   $ircops = $ops = $halfops = $voices = $normal = 0;
 100   for ($channel->nicks()) {
 101     if ($_->{serverop}) {
 102       $ircops++;
 103 	}
 104 
 105     if ($_->{op}) {
 106       $ops++;
 107 	} elsif ($_->{halfop}) {
 108 	   $halfops++;
 109     } elsif ($_->{voice}) {
 110       $voices++;
 111     } else {
 112       $normal++;
 113     }
 114   }
 115 
 116   $total = $ops+$halfops+$voices+$normal;
 117   if (!Irssi::settings_get_bool('usercount_show_zero')) {
 118     $ircops = undef if ($ircops == 0);
 119     $ops = undef if ($ops == 0);
 120     $halfops = undef if ($halfops == 0);
 121     $voices = undef if ($voices == 0);
 122     $normal = undef if ($normal == 0);
 123   }
 124   $halfops = undef unless Irssi::settings_get_bool('usercount_show_halfops');
 125   $ircops = undef unless Irssi::settings_get_bool('usercount_show_ircops');
 126 }
 127 
 128 sub refresh {
 129    if ($timeout_tag > 0) {
 130       Irssi::timeout_remove($timeout_tag);
 131       $timeout_tag = 0;
 132    }
 133    Irssi::statusbar_items_redraw('usercount');
 134 }
 135 
 136 sub refresh_check {
 137    my $channel = shift;
 138    my $wi = ref Irssi::active_win() ? Irssi::active_win()->{active} : 0;
 139 
 140    return unless ref $wi && ref $channel;
 141    return if $wi->{name} ne $channel->{name};
 142    return if $wi->{server}->{tag} ne $channel->{server}->{tag};
 143 
 144    # don't refresh immediately, or we'll end up refreshing 
 145    # a lot around netsplits
 146    $recalc = 1;
 147    Irssi::timeout_remove($timeout_tag) if ($timeout_tag > 0);
 148    $timeout_tag = Irssi::timeout_add(500, 'refresh', undef);
 149 }
 150 
 151 sub refresh_recalc {
 152   $recalc = 1;
 153   refresh();
 154 }
 155 
 156 $recalc = 1;
 157 $timeout_tag = 0;
 158 
 159 Irssi::settings_add_bool('usercount', 'usercount_show_zero', 1);
 160 Irssi::settings_add_bool('usercount', 'usercount_show_ircops', 0);
 161 Irssi::settings_add_bool('usercount', 'usercount_show_halfops', 1);
 162 
 163 Irssi::statusbar_item_register('usercount', undef, 'usercount');
 164 Irssi::statusbars_recreate_items();
 165 
 166 Irssi::signal_add_last('nicklist new', 'refresh_check');
 167 Irssi::signal_add_last('nicklist remove', 'refresh_check');
 168 Irssi::signal_add_last('nick mode changed', 'refresh_check');
 169 Irssi::signal_add_last('setup changed', 'refresh_recalc');
 170 Irssi::signal_add_last('window changed', 'refresh_recalc');
 171 Irssi::signal_add_last('window item changed', 'refresh_recalc');
 172