Last active
February 4, 2019 10:31
-
-
Save wodim/9527266 to your computer and use it in GitHub Desktop.
Irssi script that implements a notify list using the WATCH command
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
use Irssi; | |
use strict; | |
use vars qw($VERSION %IRSSI); | |
# Changelog | |
# 0.9: initial release | |
# 0.91: show online/offline notifications in query windows if open | |
# 0.92: fix connection time in stopped_watching_host_last | |
# 0.93: fix removal of nicks from the notify list | |
# 0.94: reduced the max length of WATCH commands | |
# 0.95: disallows the use of /watch in networks not in watch_networks | |
# 0.96: added an option to beep when someone comes online | |
$VERSION = "0.96"; | |
%IRSSI = ( | |
authors => "wodim", | |
contact => 'wodim@vortigaunt.net', | |
name => "Watch-NG", | |
description => "Implements a notify list using the WATCH command", | |
license => "BSD", | |
url => "", | |
); | |
our $locked = 0; | |
our $extended = 0; | |
our @current_online; | |
our @current_offline; | |
sub is_locked { | |
($locked > (time - 5)); | |
} | |
sub clean_setting { | |
my ($string) = @_; | |
$string =~ s/^\s+|\s+$//g; | |
$string =~ s/\s{2,}/ /g; | |
$string; | |
} | |
sub setting_add { | |
my ($setting, $params) = @_; | |
my $new_setting = Irssi::settings_get_str($setting); | |
foreach (my @parts = split(/ /, $params)) { | |
if ($new_setting !~ m/\Q\b$_\b/) { | |
$new_setting = "$new_setting $_"; | |
} | |
} | |
Irssi::settings_set_str($setting, clean_setting($new_setting)); | |
} | |
sub setting_del { | |
my ($setting, $params) = @_; | |
my $new_setting = Irssi::settings_get_str($setting); | |
foreach (my @parts = split(/ /, $params)) { | |
$new_setting =~ s/\b\Q$_\E\b//ig; | |
} | |
Irssi::settings_set_str($setting, clean_setting($new_setting)); | |
} | |
sub command_watch { | |
my ($args) = @_; | |
my ($command, $params) = split(/\s+/, $args, 2); | |
my $server = Irssi::active_server(); | |
if ($command =~ m/^enable$/i) { | |
$params = $server->{tag} if not $params; | |
setting_add("watch_networks", $params); | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "watch_enabled", $params); | |
} | |
if ($command =~ m/^disable$/i) { | |
$params = $server->{tag} if not $params; | |
setting_del("watch_networks", $params); | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "watch_disabled", $params); | |
} | |
if (Irssi::settings_get_str("watch_networks") !~ m/\b$server->{tag}\b/i) { | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "watch_not_enabled", $server->{tag}); | |
return; | |
} | |
if ($command =~ m/^add|del|delete|rem|remove$/i) { | |
return unless $params; | |
my $nicklen = int(Irssi::active_server()->isupport("NICKLEN")); | |
my @nicks = split(/\s+/, $params); | |
my $pre_nick; | |
if ($command =~ m/^add$/i) { | |
setting_add("watch_nicks", $params); | |
$pre_nick = "+"; | |
} elsif ($command =~ m/^del|delete|rem|remove$/i) { | |
setting_del("watch_nicks", $params); | |
$pre_nick = "-"; | |
} | |
my @commands = divider("QUOTE WATCH ", $pre_nick, $nicklen, @nicks); | |
foreach (@commands) { | |
Irssi::active_server()->command($_); | |
} | |
} elsif ($command =~ m/^help$/i) { | |
Irssi::print(<<"SCRIPTHELP_EOF", MSGLEVEL_CLIENTCRAP); | |
WATCH | |
WATCH LIST | |
WATCH ADD [nicks] | |
WATCH DEL [nicks] | |
WATCH ENABLE [network] | |
WATCH DISABLE [network] | |
A more detailed list of users is shown when using the LIST parameter, including the date of last connection. | |
SCRIPTHELP_EOF | |
} else { | |
return if is_locked() or ($command !~ m/^(list|)$/i); | |
undef @current_online; | |
undef @current_offline; | |
$locked = time; | |
$extended = ($command =~ m/^list$/i); | |
Irssi::active_server()->command("QUOTE WATCH L"); | |
} | |
} | |
sub went_online { | |
my ($server, $data) = @_; | |
my ($me, $nick, $username, $host, $lastnick) = split(/ /, $data); | |
my $query_window = $server->query_find($nick); | |
if ($query_window) { | |
$query_window->printformat(MSGLEVEL_CLIENTNOTICE, "went_online", $nick, $username, $host); | |
} else { | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "went_online", $nick, $username, $host); | |
} | |
if (Irssi::settings_get_bool("watch_beep")) { | |
Irssi::command("beep") | |
} | |
} | |
sub went_offline { | |
my ($server, $data) = @_; | |
my ($me, $nick, $username, $host, $lastnick) = split(/ /, $data); | |
my $query_window = $server->query_find($nick); | |
if ($query_window) { | |
$query_window->printformat(MSGLEVEL_CLIENTNOTICE, "went_offline", $nick, $username, $host); | |
} else { | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "went_offline", $nick, $username, $host); | |
} | |
} | |
sub stopped_watching { | |
my ($server, $data) = @_; | |
my ($me, $nick, $username, $host, $lastnick) = split(/ /, $data); | |
if ($username eq "*" && $host eq "*") { | |
if ($lastnick eq "0") { | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "stopped_watching", $nick); | |
} else { | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "stopped_watching_last", $nick, scalar localtime($lastnick)); | |
} | |
} else { | |
if ($lastnick eq "0") { | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "stopped_watching_host", $nick, $username, $host); | |
} else { | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "stopped_watching_host_last", $nick, $username, $host, scalar localtime($lastnick)); | |
} | |
} | |
} | |
sub is_online { | |
my ($server, $data) = @_; | |
my ($me, $nick, $username, $host, $lastnick) = split(/ /, $data); | |
if (is_locked()) { | |
push @current_online, $data; | |
} else { | |
if ($lastnick eq "0") { | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "is_online", $nick, $username, $host); | |
} else { | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "is_online_last", $nick, $username, $host, scalar localtime($lastnick)); | |
} | |
} | |
} | |
sub is_offline { | |
my ($server, $data) = @_; | |
my ($me, $nick, $username, $host, $lastnick) = split(/ /, $data); | |
if (is_locked()) { | |
push @current_offline, $data; | |
} else { | |
if ($lastnick eq "0") { | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "is_offline", $nick, $username, $host); | |
} else { | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "is_offline_last", $nick, $username, $host, scalar localtime($lastnick)); | |
} | |
} | |
} | |
sub end_of_list { | |
my ($server, $data) = @_; | |
if ($extended) { | |
foreach (@current_online) { | |
my ($me, $nick, $username, $host, $lastnick) = split(/ /, $_); | |
if ($lastnick) { | |
Irssi::printformat(MSGLEVEL_CLIENTCRAP, "is_online_last", $nick, $username, $host, scalar localtime($lastnick)); | |
} else { | |
Irssi::printformat(MSGLEVEL_CLIENTCRAP, "is_online", $nick, $username, $host); | |
} | |
} | |
foreach (@current_offline) { | |
my ($me, $nick, $username, $host, $lastnick) = split(/ /, $_); | |
if ($lastnick) { | |
Irssi::printformat(MSGLEVEL_CLIENTCRAP, "is_offline_last", $nick, $username, $host, scalar localtime($lastnick)); | |
} else { | |
Irssi::printformat(MSGLEVEL_CLIENTCRAP, "is_offline", $nick, $username, $host); | |
} | |
} | |
} else { | |
my (@online_list, @offline_list); | |
foreach (@current_online) { | |
my ($me, $nick, $username, $host, $lastnick) = split(/ /, $_); | |
push @online_list, $nick; | |
} | |
foreach (@current_offline) { | |
my ($me, $nick, $username, $host, $lastnick) = split(/ /, $_); | |
push @offline_list, $nick; | |
} | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "watch_online", join(", ", @online_list)); | |
Irssi::printformat(MSGLEVEL_CLIENTNOTICE, "watch_offline", join(", ", @offline_list)); | |
} | |
$locked = 0; | |
} | |
sub watch_setup { | |
my ($server) = @_; | |
return unless (Irssi::settings_get_str("watch_networks") =~ m/\b$server->{tag}\b/i); | |
my $nicklen = int($server->isupport("NICKLEN")); | |
my @nicks = split(/\s+/, Irssi::settings_get_str("watch_nicks")); | |
my @commands = divider("QUOTE WATCH ", "+", $nicklen, @nicks); | |
foreach (@commands) { | |
$server->command($_); | |
} | |
} | |
sub divider { | |
my ($pre_line, $pre_nick, $nicklen, @nicks) = @_; | |
my @commands; | |
while (@nicks) { | |
my $line = $pre_line; | |
while (@nicks && length($line) < (450 - ($nicklen + 1 + length($pre_nick)))) { | |
my $nick = pop @nicks; | |
$line .= "$pre_nick$nick "; | |
} | |
push @commands, $line; | |
} | |
@commands; | |
} | |
Irssi::theme_register([ | |
"is_online_last", 'Online: {nick $0} [$1@$2] (joined: $3)', | |
"is_offline_last", 'Offline: {nick $0} (last seen: $3)', | |
"is_online", 'Online: {nick $0} [$1@$2]', | |
"is_offline", 'Offline: {nick $0}', | |
"watch_online", 'Online: {hilight $0}', | |
"watch_offline", 'Offline: $0', | |
"went_online", '{nick $0} [$1@$2] has connected', | |
"went_offline", '{nick $0} [$1@$2] has disconnected', | |
"stopped_watching", '{nick $0} is no longer being watched', | |
"stopped_watching_host", '{nick $0} [$1@$2] is no longer being watched', | |
"stopped_watching_last", '{nick $0} is no longer being watched (joined or last seen: $1)', | |
"stopped_watching_host_last", '{nick $0} [$1@$2] is no longer being watched (joined or last seen: $3)', | |
"watch_not_enabled", 'WATCH is not enabled for $0. Use /WATCH ENABLE to enable it', | |
"watch_enabled", 'WATCH has been enabled for $0', | |
"watch_disabled", 'WATCH has been disabled for $0', | |
]); | |
Irssi::settings_add_str("watch", "watch_nicks", ""); | |
Irssi::settings_add_str("watch", "watch_networks", ""); | |
Irssi::settings_add_bool("watch", "watch_beep", 1); | |
Irssi::command_bind("watch", "command_watch"); | |
Irssi::signal_add("event 600", "went_online"); | |
Irssi::signal_add("event 601", "went_offline"); | |
Irssi::signal_add("event 602", "stopped_watching"); | |
Irssi::signal_add("event 604", "is_online"); | |
Irssi::signal_add("event 605", "is_offline"); | |
Irssi::signal_add("event 607", "end_of_list"); | |
Irssi::signal_add_last("event connected", "watch_setup"); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment