Scripts backup from msparks/irssiscripts
This commit is contained in:
parent
6f16d64929
commit
db98087730
233
scripts/anames.pl
Normal file
233
scripts/anames.pl
Normal file
|
@ -0,0 +1,233 @@
|
|||
# anames.pl
|
||||
# Irssi script that adds an /anames command, a clone of /names, with away nicks
|
||||
# grayed out.
|
||||
#
|
||||
# Thanks to Dirm and Chris62vw for the Perl help and coekie for writing the
|
||||
# evil code to sort the nicklist by the alphabet and rank in nicklist.pl
|
||||
#
|
||||
# 1.5 - Fixed halfop display bug (patch by epinephrine), 20100712
|
||||
#
|
||||
# 1.4 - Merged changes from VMiklos and readded /who redirection to prevent
|
||||
# spamming the status window. - ms, 20090122
|
||||
#
|
||||
# 1.3 - by VMiklos
|
||||
# Doing /dowho is very annoying and /alias foo /dowho;/anames won't
|
||||
# work either since anames will work from the old infos. So I've
|
||||
# modified /anames to just do a /dowho and the nicklist will be printed
|
||||
# when we'll get the answer from the server.
|
||||
#
|
||||
# 1.2 - It seems that redirected events will not pass through the internal
|
||||
# mechanisms that update user information (like away states). So, it
|
||||
# /dowho and the periodic execution of the command has been disabled.
|
||||
# /anames will still work, but new away information will need to be
|
||||
# obtained by executing a /who on a channel.
|
||||
# If you can make redirection (execute a /who without the information
|
||||
# spilling to the status window) work, let me know so I can fix the
|
||||
# script.
|
||||
#
|
||||
# 1.0.1 - Fixed row-determining and max-nick-length code, changed command_add
|
||||
# calls to refs instead of names.
|
||||
#
|
||||
# 1.0 - Added timer for periodic /who of all channels
|
||||
#
|
||||
# 0.9 - Initial test release
|
||||
|
||||
use strict;
|
||||
use Irssi;
|
||||
use POSIX;
|
||||
#use Data::Dumper;
|
||||
|
||||
use vars qw($VERSION %IRSSI);
|
||||
|
||||
$VERSION = '1.5';
|
||||
%IRSSI = (
|
||||
authors => 'Matt "f0rked" Sparks, Miklos Vajna',
|
||||
contact => 'ms+irssi@quadpoint.org',
|
||||
name => 'anames',
|
||||
description => 'a /names display with away nicks colored',
|
||||
license => 'GPLv2',
|
||||
url => 'http://quadpoint.org',
|
||||
changed => '2010-07-12',
|
||||
);
|
||||
|
||||
# How often to do a /who of all channels (in seconds)
|
||||
#my $who_timer = 300;
|
||||
|
||||
my $tmp_server;
|
||||
my $tmp_chan;
|
||||
|
||||
|
||||
sub cmd_anames
|
||||
{
|
||||
my($args, $server, $item) = @_;
|
||||
my $channel = Irssi::active_win->{active};
|
||||
$tmp_server = $server;
|
||||
$tmp_chan = $channel->{"name"};
|
||||
|
||||
if ($args ne "") {
|
||||
$server = $args;
|
||||
$server =~ s/-([^ ]*) .*/\1/;
|
||||
$tmp_server = Irssi::server_find_tag($server);
|
||||
$tmp_chan = $args;
|
||||
$tmp_chan =~ s/-[^ ]* (.*)/\1/;
|
||||
}
|
||||
|
||||
# set up redirection
|
||||
$tmp_server->redirect_event("who", 1, $tmp_chan, 0, undef,
|
||||
{
|
||||
"event 352" => "redir who_reply",
|
||||
"event 315" => "redir who_reply_end",
|
||||
});
|
||||
|
||||
$tmp_server->command("who $tmp_chan");
|
||||
}
|
||||
|
||||
|
||||
sub print_anames
|
||||
{
|
||||
my $server = $tmp_server;
|
||||
my $chan = $tmp_chan;
|
||||
my $channel = Irssi::Server::channel_find($server, $chan);
|
||||
my $nick;
|
||||
|
||||
if (!$channel) {
|
||||
# no nicklist
|
||||
Irssi::print("Not joined to any channel", MSGLEVEL_CLIENTERROR);
|
||||
} else {
|
||||
# Loop through each nick and display
|
||||
my @nicks;
|
||||
my($ops, $halfops, $voices, $normal, $away) = (0, 0, 0, 0, 0);
|
||||
|
||||
# sorting from nicklist.pl
|
||||
foreach my $nick (sort {(($a->{'op'}?'1':$a->{'halfop'}?'2':$a->{'voice'}?'3':'4').lc($a->{'nick'}))
|
||||
cmp (($b->{'op'}?'1':$b->{'halfop'}?'2':$b->{'voice'}?'3':'4').lc($b->{'nick'}))} $channel->nicks()) {
|
||||
my $realnick = $nick->{'nick'};
|
||||
my $gone = $nick->{'gone'};
|
||||
|
||||
my $prefix;
|
||||
if ($nick->{'op'}) {
|
||||
$prefix = "@";
|
||||
$ops++;
|
||||
} elsif ($nick->{'halfop'}) {
|
||||
$prefix = "%%";
|
||||
$halfops++;
|
||||
} elsif ($nick->{'voice'}) {
|
||||
$prefix = "+";
|
||||
$voices++;
|
||||
} else {
|
||||
$prefix = " ";
|
||||
$normal++;
|
||||
}
|
||||
|
||||
$prefix = "%W$prefix%n";
|
||||
if ($gone) {
|
||||
$realnick = "%K$realnick%n";
|
||||
$away++;
|
||||
}
|
||||
|
||||
push @nicks, "$prefix" . $realnick;
|
||||
}
|
||||
|
||||
my $total = @nicks;
|
||||
$channel->print("%K[%n%gUsers%n %G" . $chan . "%n%K]%n",
|
||||
MSGLEVEL_CLIENTCRAP);
|
||||
columnize_nicks($channel,@nicks);
|
||||
$channel->print("%W$chan%n: Total of %W$total%n nicks %K[%W$ops%n ops, " .
|
||||
"%W$halfops%n halfops, %W$voices%n voices, %W$normal%n " .
|
||||
"normal, %W$away%n away%K]%n",
|
||||
MSGLEVEL_CLIENTNOTICE);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# create a /names style column, increasing alphabetically going down the
|
||||
# columns.
|
||||
sub columnize_nicks
|
||||
{
|
||||
my($channel, @nicks) = @_;
|
||||
my $total = @nicks;
|
||||
|
||||
# determine max columns
|
||||
# FIXME: this could be more intelligent (i.e., read window size)
|
||||
my $cols = Irssi::settings_get_int("names_max_columns");
|
||||
$cols = 6 if $cols == 0;
|
||||
|
||||
# determine number of rows
|
||||
my $rows = round(ceil($total / $cols));
|
||||
|
||||
# array of rows
|
||||
my @r;
|
||||
for (my $i = 0; $i < $cols; $i++) {
|
||||
# peek at next $rows items, determine max length
|
||||
my $max_length = find_max_length(@nicks[0 .. $rows - 1]);
|
||||
|
||||
# fill rows
|
||||
for (my $j = 0; $j < $rows; $j++) {
|
||||
my $n = shift @nicks; # single nick
|
||||
if ($n ne "") {
|
||||
$r[$j] .= "%K[%n$n" . fill_spaces($n,$max_length) . "%K]%n ";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (my $m = 0; $m < $rows; $m++) {
|
||||
chomp $r[$m];
|
||||
$channel->print($r[$m], MSGLEVEL_CLIENTCRAP);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub fill_spaces
|
||||
{
|
||||
my($text, $max_length) = @_;
|
||||
$text =~ s/%[a-zA-Z]//g;
|
||||
return " " x ($max_length - length($text));
|
||||
}
|
||||
|
||||
|
||||
sub find_max_length
|
||||
{
|
||||
my $max_length = 0;
|
||||
for (my $i = 0; $i < @_; $i++) {
|
||||
my $nick = $_[$i];
|
||||
$nick =~ s/%[a-zA-Z]//g;
|
||||
if (length($nick) > $max_length) {
|
||||
$max_length = length($nick);
|
||||
}
|
||||
}
|
||||
return $max_length;
|
||||
}
|
||||
|
||||
|
||||
sub round
|
||||
{
|
||||
my($number) = @_;
|
||||
return int($number + .5);
|
||||
}
|
||||
|
||||
|
||||
sub who_reply
|
||||
{
|
||||
my($server, $data) = @_;
|
||||
my(undef, $c, $i, $h, $n, $s) = split / /, $data;
|
||||
if ($tmp_chan ne $c) {
|
||||
$tmp_chan = $c;
|
||||
#print "Got who info for $c";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub who_reply_end
|
||||
{
|
||||
print_anames();
|
||||
$tmp_chan = "";
|
||||
}
|
||||
|
||||
|
||||
Irssi::Irc::Server::redirect_register("who", 0, 0,
|
||||
{"event 352" => 1},
|
||||
{"event 315" => 1},
|
||||
undef);
|
||||
Irssi::signal_add("redir who_reply", \&who_reply);
|
||||
Irssi::signal_add("redir who_reply_end", \&who_reply_end);
|
||||
Irssi::command_bind("anames", \&cmd_anames);
|
321
scripts/automode.pl
Normal file
321
scripts/automode.pl
Normal file
|
@ -0,0 +1,321 @@
|
|||
# automode.pl
|
||||
#
|
||||
# Passively learn and actively maintain the ops/voices/halfops in channels.
|
||||
# This is a no-maintenance auto-op/auto-voice script for irssi.
|
||||
#
|
||||
# INSTALL:
|
||||
# 1) /script load automode.pl
|
||||
# 2) Be a channel operator
|
||||
#
|
||||
# HOW IT WORKS:
|
||||
# When someone joins a channel and is given ops/voice/halfop, the script
|
||||
# will record that user's mask, as a combination of their nickname and part
|
||||
# of their hostname or IP address. When that person leaves and rejoins, the
|
||||
# script will check against its database and regrant the user the modes
|
||||
# he or she had before leaving.
|
||||
#
|
||||
# If a user is kicked from a channel, all modes for that person are removed.
|
||||
# They must therefore be regiven by another operator manually. Note this.
|
||||
#
|
||||
# Also, this script relies on the "chatnet" attribute being set for a
|
||||
# particular connection. Use /network (or /ircnet) to set up your networks
|
||||
# and such. This script will spit out (lots of) warnings if the chatnet is
|
||||
# not set.
|
||||
#
|
||||
# IGNORING CHANNELS:
|
||||
# If you do not wish to maintain modes on a channel, add it to the setting
|
||||
# "automode_ignore" in the form <tag>:<channel>, separated by spaces.
|
||||
#
|
||||
# For example: /set automode_ignore FreeNode:#perl EFnet:#irssi
|
||||
# (should) not maintain modes in #perl on FreeNode or #irssi
|
||||
# on EFnet, provided FreeNode and EFnet are the tags for those
|
||||
# connections.
|
||||
#
|
||||
# NOTES:
|
||||
# The Perl module Data::Serializer is needed for this script.
|
||||
# The database file is not written instantaneously; it is on a timer and is
|
||||
# written to every five minutes or so. If the script is reloaded before it has
|
||||
# had a chance to save will result in forgotten modes.
|
||||
#
|
||||
use strict;
|
||||
use Irssi;
|
||||
use Data::Serializer;
|
||||
use Data::Dumper;
|
||||
|
||||
use vars qw($VERSION %IRSSI);
|
||||
|
||||
$VERSION = '1.3';
|
||||
%IRSSI = (
|
||||
authors => 'Matt "f0rked" Sparks',
|
||||
contact => 'ms+irssi@quadpoint.org',
|
||||
name => 'automode',
|
||||
description => 'Mode maintainer',
|
||||
license => 'BSD',
|
||||
url => 'http://quadpoint.org',
|
||||
changed => '2008-06-14',
|
||||
);
|
||||
|
||||
# show debug lines
|
||||
my $debug = 0;
|
||||
|
||||
my $s = new Data::Serializer;
|
||||
my $file = Irssi::get_irssi_dir."/automode_list";
|
||||
|
||||
if (!-e $file) {
|
||||
print "[automode] creating $file";
|
||||
system("touch $file");
|
||||
}
|
||||
|
||||
my $listref = $s->retrieve($file);
|
||||
my %list = $listref ? %{$listref} : ();
|
||||
|
||||
#print Dumper %list;
|
||||
|
||||
my $save_tag;
|
||||
my %buffer_tags;
|
||||
my %buffer;
|
||||
|
||||
|
||||
sub save_list
|
||||
{
|
||||
$s->store(\%list,$file);
|
||||
}
|
||||
|
||||
|
||||
sub clear_list
|
||||
{
|
||||
%list = ();
|
||||
}
|
||||
|
||||
|
||||
sub make_mask
|
||||
{
|
||||
my($address) = @_;
|
||||
return if !$address;
|
||||
my($ident, $host) = split /@/, $address;
|
||||
my @split = split /\./, $host;
|
||||
|
||||
if (@split <= 2) {
|
||||
# host is something like "foo.com". We cannot make the mask *.com.
|
||||
} else {
|
||||
if ($split[$#split] =~ /^\d+$/) {
|
||||
# Looks like an IP address.
|
||||
pop @split;
|
||||
$host = join(".", @split) . ".\d{1,3}";
|
||||
} else {
|
||||
# Mask the first segment.
|
||||
shift @split;
|
||||
$host = ".+?." . join(".", @split);
|
||||
}
|
||||
}
|
||||
|
||||
return ".+?!.*${ident}@" . "${host}";
|
||||
}
|
||||
|
||||
|
||||
sub show
|
||||
{
|
||||
my($net, $channel) = @_;
|
||||
print Dumper %{$list{$net}->{$channel}};
|
||||
}
|
||||
|
||||
|
||||
sub show_all
|
||||
{
|
||||
my $list;
|
||||
print Dumper %list;
|
||||
}
|
||||
|
||||
|
||||
sub clear_channel
|
||||
{
|
||||
my($net, $channel) = @_;
|
||||
delete $list{$net}->{$channel};
|
||||
}
|
||||
|
||||
|
||||
sub set_modes
|
||||
{
|
||||
my($net, $channel) = @{$_[0]};
|
||||
return if !$buffer{$net}->{$channel};
|
||||
|
||||
my($nicks, $modes) = values(%{$buffer{$net}->{$channel}});
|
||||
print "[automode] modes: $modes, nicks: $nicks" if $debug;
|
||||
my $c = Irssi::server_find_chatnet($net)->channel_find($channel);
|
||||
|
||||
# iterate through the modes and see which ones we don't have to set
|
||||
my($final_modes, $final_nicks);
|
||||
|
||||
my $i = 0;
|
||||
for (split //,$modes) {
|
||||
my $m = $_;
|
||||
my $n = (split / /, $nicks)[$i];
|
||||
$i++;
|
||||
|
||||
next if (!$c->nick_find($n));
|
||||
next if ($m eq "o" && $c->nick_find($n)->{"op"});
|
||||
next if ($m eq "v" && $c->nick_find($n)->{"voice"});
|
||||
next if ($m eq "h" && $c->nick_find($n)->{"halfop"});
|
||||
|
||||
# if we made it this far, add this to the final modes
|
||||
$final_modes .= $m;
|
||||
$final_nicks .= "$n ";
|
||||
}
|
||||
|
||||
print "[automode] final modes: +$final_modes $final_nicks" if $debug;
|
||||
|
||||
$c->command("MODE $channel +$final_modes $final_nicks")
|
||||
if ($final_modes && $final_nicks);
|
||||
delete $buffer{$net}->{$channel};
|
||||
}
|
||||
|
||||
|
||||
sub mode2letter
|
||||
{
|
||||
my($mode) = @_;
|
||||
if ($mode eq "@") {
|
||||
return "o";
|
||||
} elsif ($mode eq "+") {
|
||||
return "v";
|
||||
} elsif ($mode eq "%") {
|
||||
return "h";
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
sub remove_mode
|
||||
{
|
||||
my($net, $channel, $mask, $mode) = @_;
|
||||
my $letter = mode2letter($mode);
|
||||
$list{$net}->{$channel}->{$mask} =~ s/$letter//
|
||||
if user_modes($net, $channel, $mask);
|
||||
delete $list{$net}->{$channel}->{$mask}
|
||||
if exists $list{$net}->{$channel}->{$mask}
|
||||
and !$list{$net}->{$channel}->{$mask};
|
||||
}
|
||||
|
||||
|
||||
sub remove_all
|
||||
{
|
||||
my($net, $channel, $mask) = @_;
|
||||
delete $list{$net}->{$channel}->{$mask}
|
||||
if exists $list{$net}->{$channel}->{$mask};
|
||||
}
|
||||
|
||||
|
||||
sub user_modes
|
||||
{
|
||||
my($net, $channel, $mask) = @_;
|
||||
return $list{$net}->{$channel}->{$mask};
|
||||
}
|
||||
|
||||
|
||||
sub add_mode
|
||||
{
|
||||
my($net, $channel, $mask, $mode) = @_;
|
||||
return if !$mask or !$net or !$channel or !$mode;
|
||||
|
||||
my $letter = mode2letter($mode);
|
||||
$list{$net}->{$channel}->{$mask} .= $letter
|
||||
if $list{$net}->{$channel}->{$mask} !~ /$letter/;
|
||||
|
||||
Irssi::timeout_remove($save_tag);
|
||||
$save_tag = Irssi::timeout_add_once(300, "save_list", []);
|
||||
}
|
||||
|
||||
|
||||
sub event_mode
|
||||
{
|
||||
my($channel, $nick, $setby, $mode, $type) = @_;
|
||||
return if check_ignore($channel->{server}, $channel->{name});
|
||||
my $w = Irssi::active_win;
|
||||
return if $mode != '@' and $mode != '%' and $mode != '+';
|
||||
|
||||
my $chatnet = $channel->{server}->{chatnet};
|
||||
my $tag = $channel->{server}->{tag};
|
||||
print ("[automode] The 'chatnet' attribute is missing for the tag '$tag'. " .
|
||||
"Use /network (or /ircnet) to properly manage this.") if !$chatnet;
|
||||
return if !$chatnet;
|
||||
|
||||
my $mask = make_mask($nick->{host});
|
||||
print "[automode] failed to make mask ($mask)" if (!$mask && $debug);
|
||||
return if !$mask;
|
||||
|
||||
if ($type eq "+") {
|
||||
print ("[automode] adding mode '$mode' for $mask in $channel->{name} on " .
|
||||
$chatnet) if $debug;
|
||||
add_mode($chatnet, $channel->{name}, $mask, $mode);
|
||||
} else {
|
||||
# don't remove op if they deop themselves.
|
||||
return if $setby eq $nick->{nick};
|
||||
print ("[automode] removing mode '$mode' for $mask in $channel->{name} " .
|
||||
" on $chatnet") if $debug;
|
||||
remove_mode($chatnet, $channel->{name}, $mask, $mode);
|
||||
}
|
||||
|
||||
#show($chatnet, $channel->{name});
|
||||
}
|
||||
|
||||
|
||||
sub event_join
|
||||
{
|
||||
my($server, $channel, $nick, $address) = @_;
|
||||
return if check_ignore($server, $channel);
|
||||
my $mask = make_mask($address);
|
||||
return if !user_modes($server->{chatnet}, $channel, $mask);
|
||||
my $c = $server->channel_find($channel);
|
||||
return if not $c->{chanop};
|
||||
|
||||
if (my $modes = user_modes($server->{chatnet}, $channel, $mask)) {
|
||||
print "[automode] Matched mask ($mask) with modes: $modes" if $debug;
|
||||
my $nick_list = "$nick " x length($modes);
|
||||
my %buf = ($buffer{$server->{chatnet}}->{$channel} ?
|
||||
%{$buffer{$server->{chatnet}}->{$channel}} : ());
|
||||
$buf{modes} .= $modes;
|
||||
$buf{nicks} .= $nick_list;
|
||||
$buffer{$server->{chatnet}}->{$channel} = \%buf;
|
||||
my $tag = $server->{chatnet} . "_$channel";
|
||||
Irssi::timeout_remove($buffer_tags{$tag});
|
||||
$buffer_tags{$tag} = Irssi::timeout_add_once(1000 + int(rand(250) * 3),
|
||||
"set_modes",
|
||||
[$server->{chatnet},
|
||||
$channel]);
|
||||
#print Dumper %buffer;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub event_kick
|
||||
{
|
||||
my($server, $channel, $nick, $kicker, $address, $reason) = @_;
|
||||
my $n = $server->channel_find($channel)->nick_find($nick);
|
||||
#print Dumper $n;
|
||||
my $mask = make_mask($n->{host});
|
||||
remove_all($server->{chatnet}, $channel, $mask) if $mask;
|
||||
}
|
||||
|
||||
|
||||
sub check_ignore
|
||||
{
|
||||
my($server, $channel) = @_;
|
||||
my $chatnet = $server->{chatnet};
|
||||
my $ignore = Irssi::settings_get_str("automode_ignore") . " ";
|
||||
return ($ignore =~ /$chatnet:$channel /i) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
# I don't think this does what I want it to do.
|
||||
sub event_exit
|
||||
{
|
||||
save_list;
|
||||
}
|
||||
|
||||
|
||||
Irssi::signal_add("gui exit", "event_exit");
|
||||
|
||||
Irssi::signal_add("message kick", "event_kick");
|
||||
Irssi::signal_add("message join", "event_join");
|
||||
Irssi::signal_add("nick mode changed", "event_mode");
|
||||
|
||||
Irssi::settings_add_str("automode", "automode_ignore", "IM:&bitlbee");
|
62
scripts/bitlbee_autoreply.pl
Normal file
62
scripts/bitlbee_autoreply.pl
Normal file
|
@ -0,0 +1,62 @@
|
|||
# Sends autoreplies to IM users when they message while you are away.
|
||||
#
|
||||
# SETTINGS
|
||||
# [bitlbee]
|
||||
# bitlbee_autoreply_duration = OFF
|
||||
# -> Send how long you have been away in your auto-reply. This requires
|
||||
# Time::Duration.
|
||||
# Example auto-reply: "gone (away: 3 minutes and 2 seconds)"
|
||||
use strict;
|
||||
use Irssi;
|
||||
use Time::Duration qw/duration_exact/;
|
||||
|
||||
use vars qw($VERSION %IRSSI);
|
||||
|
||||
$VERSION = '0.12';
|
||||
%IRSSI = (
|
||||
authors => 'Matt "f0rked" Sparks',
|
||||
contact => 'ms+irssi@quadpoint.org',
|
||||
name => 'bitlbee status notice',
|
||||
description => 'Sends autoreplies to IM users while you are away',
|
||||
license => 'GPLv2',
|
||||
url => 'http://quadpoint.org',
|
||||
changed => '2005-12-04',
|
||||
);
|
||||
|
||||
my $bitlbee_channel = "&bitlbee";
|
||||
my $bitlbee_server_tag = "IM";
|
||||
|
||||
my(%times, $away, $away_time);
|
||||
|
||||
|
||||
sub away
|
||||
{
|
||||
$away_time=time;
|
||||
%times=();
|
||||
}
|
||||
|
||||
|
||||
sub event_msg
|
||||
{
|
||||
my($server, $msg, $nick, $address, $target) = @_;
|
||||
return if $server->{tag} ne $bitlbee_server_tag;
|
||||
return unless $server->{usermode_away};
|
||||
#return unless $address =~ /\@login\.oscar\.aol\.com$/; # Only send for AIM.
|
||||
return unless !$target or ($target eq $bitlbee_channel and $nick ne "root");
|
||||
return unless time - $times{$nick} > 3600; # send an auto-reply once an hour.
|
||||
|
||||
$times{$nick} = time;
|
||||
my $append;
|
||||
if (Irssi::settings_get_bool("bitlbee_autoreply_duration") && $away_time) {
|
||||
$append = " (away: " . duration_exact(time - $away_time) . ")";
|
||||
}
|
||||
|
||||
$server->command("/notice $nick $server->{away_reason}$append");
|
||||
}
|
||||
|
||||
|
||||
Irssi::signal_add("message private", "event_msg");
|
||||
Irssi::signal_add("message public", "event_msg");
|
||||
Irssi::signal_add("away mode changed", "away");
|
||||
|
||||
Irssi::settings_add_bool("bitlbee", "bitlbee_autoreply_duration", 0);
|
460
scripts/bitlbee_html.pl
Normal file
460
scripts/bitlbee_html.pl
Normal file
|
@ -0,0 +1,460 @@
|
|||
# This script is a drop-in HTML filter and parser for use with bitlbee and
|
||||
# irssi. HTML that can be rendered will be, and the rest will be stripped.
|
||||
# This should not interfere with other scripts for bitlbee; it is intended to be
|
||||
# a transparent mangler.
|
||||
#
|
||||
# TO USE:
|
||||
# 1) Adjust the channel and server tag settings below.
|
||||
# 2) Load the script
|
||||
# 3) In the bitlbee control channel (&bitlbee), type: set strip_html false
|
||||
# 4) Enjoy.
|
||||
#
|
||||
# For use with bitlbee 1.0+. ChangeLog is available at the bottom of the file.
|
||||
#
|
||||
# SETTINGS
|
||||
# [bitlbee]
|
||||
# bitlbee_replace_html = ON
|
||||
# -> replaces HTML in incoming AIM messages
|
||||
# bitlbee_replace_control_codes = OFF
|
||||
# -> replaces control codes (bold, underline, reverse) in outgoing private
|
||||
# messages to AIM users with HTML equivalents. This is turned off by
|
||||
# default due to the known bug below. If this wouldn't bother you, and you
|
||||
# would like to have this feature, there's no real harm in turning it on.
|
||||
# bitlbee_strip_trailing_whitespace = OFF
|
||||
# -> removes whitespace at the end of messages
|
||||
#
|
||||
# KNOWN BUGS
|
||||
# * This script is somewhat incompatible with splitlong.pl. When long messages
|
||||
# get split up, and bitlbee_replace_control_codes is ON, the control codes
|
||||
# will properly get replaced when they are sent to the remote user, but when
|
||||
# the subsequent split parts are displayed, they may contain the html that
|
||||
# is supposed to be hidden.
|
||||
use strict;
|
||||
use Irssi::TextUI;
|
||||
use Data::Dumper;
|
||||
|
||||
use vars qw($VERSION %IRSSI);
|
||||
|
||||
$VERSION = '0.95';
|
||||
%IRSSI = (
|
||||
authors => 'Matt "f0rked" Sparks',
|
||||
contact => 'ms+irssi@quadpoint.org',
|
||||
name => 'bitlbee_html',
|
||||
description => 'Adds some HTML parsing to bitlbee messages',
|
||||
license => 'GPLv2',
|
||||
url => 'http://quadpoint.org',
|
||||
changed => '2005-12-18',
|
||||
);
|
||||
|
||||
# TODO: Make these settings (?)
|
||||
my $bitlbee_channel = "&bitlbee";
|
||||
my $bitlbee_server_tag = "IM";
|
||||
|
||||
# Time to wait to collect all parts of a message from bitlbee server
|
||||
my $buffer_timeout = 200; # milliseconds
|
||||
|
||||
# How long does a message have to be before we consider it a split?
|
||||
my $split_length = 425;
|
||||
|
||||
my %buffer;
|
||||
my %emitting;
|
||||
my $debug = 0;
|
||||
|
||||
|
||||
# Thanks to timing (http://the-timing.nl) for this
|
||||
Irssi::signal_add_last 'channel sync' => sub
|
||||
{
|
||||
my($channel) = @_;
|
||||
if ($channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information.") {
|
||||
$bitlbee_server_tag = $channel->{server}->{tag};
|
||||
$bitlbee_channel = $channel->{name};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
# Debug to the active window
|
||||
sub adebug
|
||||
{
|
||||
return if !$debug;
|
||||
my($t) = @_;
|
||||
my $w = Irssi::active_win();
|
||||
$w->print($t, MSGLEVEL_CLIENTCRAP);
|
||||
}
|
||||
|
||||
|
||||
# Debug to the status window
|
||||
sub sdebug
|
||||
{
|
||||
return if !$debug;
|
||||
my($t) = @_;
|
||||
print $t;
|
||||
}
|
||||
|
||||
|
||||
sub trim
|
||||
{
|
||||
($_) = @_;
|
||||
s/^\s*(.+)\s*$/$1/;
|
||||
return $_;
|
||||
}
|
||||
|
||||
|
||||
# return true if given address supports HTML, false if not.
|
||||
sub does_html
|
||||
{
|
||||
my($address) = @_;
|
||||
return ($address =~ /^[a-z].*\@login\.oscar\.aol\.com$/i ||
|
||||
$address =~ /^[a-z].*\@login\.icq\.com$/i) ? 1 : 0;
|
||||
}
|
||||
|
||||
|
||||
# More advanced checking in the future?
|
||||
sub bee_server
|
||||
{
|
||||
my($server) = @_;
|
||||
return 0 if !$server;
|
||||
return ($server->{tag} ne $bitlbee_server_tag) ? 0 : 1;
|
||||
}
|
||||
|
||||
|
||||
sub html2irc
|
||||
{
|
||||
($_) = @_;
|
||||
#print "Before: $_";
|
||||
|
||||
s/<br ?\/?>/\n/isg;
|
||||
s/<font .+?>//isg;
|
||||
s/<\/font>//ig;
|
||||
s/<\/?body.*?>//isg;
|
||||
s/<\/?html>//ig;
|
||||
s/<a .*?href="(.+?)".*?>(.*?)<\/a>/handle_link($1,$2)/iesg;
|
||||
|
||||
# note for <b>,<i>, and <u>, these are encapsulating tags, and they _may_
|
||||
# contain newlines. This script will split by newlines and emit message
|
||||
# signals for each part, and a part may end up looking like "<b>foo" with
|
||||
# no end tag, because the end tag is on the next message. To fix this, we
|
||||
# have to also check for <b>foo\n and ^foo</b> and put the control codes
|
||||
# in the appropriate places to avoid formatting the wrong text.
|
||||
s/<b>(.*?)<\/b>/\002$1\002/ig; # bold
|
||||
s/<b>(.*?)\n/\002$1\n/isg;
|
||||
s/^(.*?)<\/b>/\002$1\002/isg;
|
||||
|
||||
s/<u>(.*?)<\/u>/\037$1\037/ig; # underline
|
||||
s/<u>(.*?)\n/\037$1\n/isg;
|
||||
s/^(.*?)<\/u>/\037$1\037/isg;
|
||||
|
||||
s/<i>(.*?)<\/i>/\026$1\026/ig; # reverse (for italics)
|
||||
s/<i>(.*?)\n/\026$1\n/isg;
|
||||
s/^(.*?)<\/i>/\026$1\026/isg;
|
||||
|
||||
s/"/"/ig;
|
||||
s/</</ig;
|
||||
s/>/>/ig;
|
||||
s/&/&/ig;
|
||||
|
||||
#print "After: $_";
|
||||
return $_;
|
||||
}
|
||||
|
||||
|
||||
sub irc2html
|
||||
{
|
||||
($_) = @_;
|
||||
my $ret;
|
||||
adebug "irc2html input: $_";
|
||||
|
||||
if (/^<html>/) {
|
||||
# Already htmlized? This shouldn't happen. Assume that html tags were
|
||||
# manually inserted, in which case we should just escape the html and
|
||||
# return.
|
||||
s/&/&/g;
|
||||
s/"/"/g;
|
||||
s/</</g;
|
||||
s/>/>/g;
|
||||
$ret = "<html>$_</html>";
|
||||
adebug "irc2html return: $ret";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
my $orig = $_;
|
||||
|
||||
s/&/&/g;
|
||||
s/"/"/g;
|
||||
s/</</g;
|
||||
s/>/>/g;
|
||||
|
||||
s/\002(.*?)\002/<b>$1<\/b>/sg; # bold
|
||||
s/\002(.*)/<b>$1<\/b>/sg; # unended bold
|
||||
s/\037(.*?)\037/<u>$1<\/u>/sg; # underline
|
||||
s/\037(.*)/<u>$1<\/u>/sg;
|
||||
s/\026(.*?)\026/<i>$1<\/i>/sg; # reverse (italics)
|
||||
s/\026(.*)/<i>$1<\/i>/sg;
|
||||
s/\003/<br>/g; # newlines.. this is ctrl+c in irssi.
|
||||
|
||||
#print "After: $_, length: ".length($_);
|
||||
my $ret = ($_ ne $orig) ? "<html>$_</html>" : $orig;
|
||||
adebug "irc2html return: $ret";
|
||||
return $ret;
|
||||
}
|
||||
|
||||
|
||||
sub handle_link
|
||||
{
|
||||
my($url, $title) = @_;
|
||||
$title = html2irc($title);
|
||||
#adebug $url;
|
||||
#adebug $title;
|
||||
|
||||
if ($url eq $title) {
|
||||
return $url;
|
||||
} elsif ($url eq "mailto:$title") {
|
||||
return $title;
|
||||
} else {
|
||||
my $str = "[$title]($url)";
|
||||
$str =~ s/^\[(\n)*/$1\[/;
|
||||
return $str;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub event_privmsg
|
||||
{
|
||||
my($server, $msg, $nick, $address) = @_;
|
||||
return if !Irssi::settings_get_bool("bitlbee_replace_html");
|
||||
return if !does_html($address);
|
||||
return if $emitting{"priv_$nick"}; # don't catch if we're sending signal
|
||||
return if !bee_server($server);
|
||||
|
||||
#print "Received msg: $msg";
|
||||
# Check the buffer. If it is empty, set a timeout. Fill it in either
|
||||
# case. This step is necessary because long messages will naturally
|
||||
# get split up, and to avoid the HTML cutting split up, we buffer
|
||||
# and then parse everything at once.
|
||||
if (!$buffer{"priv_$nick"}) {
|
||||
# We have no buffer, this is a new message
|
||||
my @data = ("priv", $server, $nick, $address);
|
||||
Irssi::timeout_add_once($buffer_timeout, "check_buffer", \@data);
|
||||
}
|
||||
|
||||
$msg .= " ";
|
||||
sdebug "Adding part: '$msg'";
|
||||
$buffer{"priv_$nick"} .= $msg;#."\002|\002";
|
||||
|
||||
# Length hack. Sometimes we get multiple messages quickly from bitlbee
|
||||
# that aren't html formatted with <br>. Detect this and add newlines
|
||||
# appropriately.
|
||||
my $length = length("$nick $address $msg");
|
||||
sdebug "Length: $length";
|
||||
if ($length < $split_length) {
|
||||
$buffer{"priv_$nick"} .= "\n";
|
||||
}
|
||||
|
||||
Irssi::signal_stop;
|
||||
}
|
||||
|
||||
|
||||
sub event_pubmsg
|
||||
{
|
||||
my($server, $msg, $nick, $address, $target) = @_;
|
||||
return if !Irssi::settings_get_bool("bitlbee_replace_html");
|
||||
return if !bee_server($server);
|
||||
return if !does_html($address) and $nick ne "root"; # only aim does html.
|
||||
return if $emitting{"pub_$nick"};
|
||||
|
||||
if (!$buffer{"pub_$nick"}) {
|
||||
my @data = ("pub", $server, $nick, $address, $target);
|
||||
Irssi::timeout_add_once($buffer_timeout, "check_buffer", \@data);
|
||||
}
|
||||
|
||||
$buffer{"pub_$nick"} .= $msg;
|
||||
if (length("$nick $address $msg $target") < $split_length) {
|
||||
$buffer{"pub_$nick"} .= "\n";
|
||||
}
|
||||
|
||||
Irssi::signal_stop;
|
||||
}
|
||||
|
||||
|
||||
sub event_action
|
||||
{
|
||||
my($server, $msg, $nick, $address, $target) = @_;
|
||||
#print $msg;
|
||||
return if !Irssi::settings_get_bool("bitlbee_replace_html");
|
||||
return if !does_html($address);
|
||||
return if $emitting{"act_$nick"};
|
||||
return if !bee_server($server);
|
||||
|
||||
if (!$buffer{"act_$nick"}) {
|
||||
my @data = ("act", $server, $nick, $address, $target);
|
||||
Irssi::timeout_add_once($buffer_timeout, "check_buffer", \@data);
|
||||
}
|
||||
|
||||
$buffer{"act_$nick"} .= $msg;
|
||||
if (length("$nick $address $msg $target") < $split_length) {
|
||||
$buffer{"act_$nick"} .= "\n";
|
||||
}
|
||||
|
||||
Irssi::signal_stop;
|
||||
}
|
||||
|
||||
|
||||
sub event_send_text
|
||||
{
|
||||
my($text, $server, $witem) = @_;
|
||||
return if !bee_server($server);
|
||||
return if !Irssi::settings_get_bool("bitlbee_replace_control_codes");
|
||||
|
||||
# This will make sure that the person we are talking to is on AIM.
|
||||
my $address;
|
||||
my $modified_text = $text;
|
||||
if ($witem->{type} eq "CHANNEL") {
|
||||
if (my($n, $s, $m) = $text =~ /^([^ ]+):([ ]*)(.*)$/) {
|
||||
$address = $witem->nick_find($n)->{host};
|
||||
$modified_text = "$n:$s" . irc2html($m);
|
||||
}
|
||||
} else {
|
||||
$address = $witem->{address};
|
||||
$modified_text = irc2html($text);
|
||||
}
|
||||
return if !does_html($address);
|
||||
|
||||
#print Dumper $witem;
|
||||
#print "Sending: $modified_text";
|
||||
Irssi::signal_stop;
|
||||
Irssi::signal_continue($modified_text, $server, $witem);
|
||||
}
|
||||
|
||||
|
||||
sub event_send_command
|
||||
{
|
||||
my($args, $server, $witem) = @_;
|
||||
return if !bee_server($server);
|
||||
adebug "send command: $args";
|
||||
}
|
||||
|
||||
|
||||
sub event_message_own
|
||||
{
|
||||
my($server, $msg, $target, $orig_target) = @_;
|
||||
return if !bee_server($server);
|
||||
return if !Irssi::settings_get_bool("bitlbee_replace_control_codes");
|
||||
return if !Irssi::settings_get_bool("bitlbee_replace_html");
|
||||
|
||||
if ($msg =~ /^<html>/ || $msg =~ /^([^ ]+):[ ]*<html>/) {
|
||||
# If we're on the bitlbee server and the message looks like html,
|
||||
# we're here.
|
||||
#print "$server '$msg' $target $orig_target";
|
||||
|
||||
if ($orig_target && (my $qu = $server->query_find($target))) {
|
||||
#print "orig target, found query.";
|
||||
if ($qu->{address} && !does_html($qu->{address})) {
|
||||
# The person we're talking to is not using an HTML-compatible
|
||||
# protocol. Don't treat this as html.
|
||||
return;
|
||||
}
|
||||
} elsif (!$orig_target &&
|
||||
(my $ch = $server->channel_find($target)) &&
|
||||
(my($t) = $msg =~ /^([^ ]+):/)) {
|
||||
my $to_nick = $ch->nick_find($t);
|
||||
if ($to_nick->{address} && !does_html($to_nick->{address})) {
|
||||
# We're talking to someone in a particular channel on
|
||||
# bitlbee, but they don't support HTML.
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
# If we made it this far, treat the message as HTML.
|
||||
Irssi::signal_stop;
|
||||
Irssi::signal_continue($server, html2irc($msg), $target, $orig_target);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub check_buffer
|
||||
{
|
||||
my($type, $server, $nick, $address, $target) = @{@_[0]};
|
||||
# We should now have a full buffer for $nick, we can examine it, parse
|
||||
# it, and re-emit the appropriate signals without any HTML splitting
|
||||
# problems.
|
||||
my $msg = $buffer{"${type}_${nick}"};
|
||||
sdebug "Complete msg: $msg";
|
||||
return if !$msg;
|
||||
$msg = html2irc($msg);
|
||||
$msg =~ s/[\s]*$//
|
||||
if Irssi::settings_get_bool("bitlbee_strip_trailing_whitespace");
|
||||
|
||||
# $msg is now in the appropriate format, we can emit the signal.
|
||||
$emitting{"${type}_${nick}"} = 1;
|
||||
my $sig = "message ";
|
||||
if ($type eq "priv") {
|
||||
$sig.="private";
|
||||
} elsif ($type eq "pub") {
|
||||
$sig.="public";
|
||||
} else {
|
||||
$sig.="irc action";
|
||||
}
|
||||
#print "Emitting $sig";
|
||||
for (split /\n/, $msg) {
|
||||
Irssi::signal_emit($sig, $server, $_, $nick, $address, $target);
|
||||
}
|
||||
|
||||
delete($buffer{"${type}_${nick}"});
|
||||
delete($emitting{"${type}_${nick}"});
|
||||
}
|
||||
|
||||
|
||||
sub event_301
|
||||
{
|
||||
return if !Irssi::settings_get_bool("bitlbee_replace_html");
|
||||
my($server, $data, $foo, $bar)=@_;
|
||||
return if !bee_server($server);
|
||||
my($me, $them, @msg) = split / /, $data;
|
||||
my $msg = join " ", @msg;
|
||||
$msg = html2irc($msg);
|
||||
$msg = ~s/[\s]*$//
|
||||
if Irssi::settings_get_bool("bitlbee_strip_trailing_whitespace");
|
||||
Irssi::signal_stop;
|
||||
Irssi::signal_continue($server, "$me $them $msg", $foo, $bar);
|
||||
}
|
||||
|
||||
|
||||
Irssi::signal_add_first("message private", "event_privmsg");
|
||||
Irssi::signal_add_first("message public", "event_pubmsg");
|
||||
Irssi::signal_add_first("event 301", "event_301");
|
||||
Irssi::signal_add_first("message irc action", "event_action");
|
||||
|
||||
Irssi::signal_add_first("send text", "event_send_text");
|
||||
Irssi::signal_add_first("send command", "event_send_command");
|
||||
Irssi::signal_add_first("message own_private", "event_message_own");
|
||||
Irssi::signal_add_first("message own_public", "event_message_own");
|
||||
Irssi::signal_add_first("message irc own_action", "event_message_own");
|
||||
|
||||
# Settings
|
||||
Irssi::settings_add_bool("bitlbee", "bitlbee_replace_html", 1);
|
||||
Irssi::settings_add_bool("bitlbee", "bitlbee_replace_control_codes", 0);
|
||||
Irssi::settings_add_bool("bitlbee", "bitlbee_strip_trailing_whitespace", 0);
|
||||
|
||||
|
||||
### ChangeLog ###
|
||||
# Version 0.95
|
||||
# - fixed a small bug causing links to sometimes not be properly formatted
|
||||
# Version 0.94
|
||||
# - fixed bug causing a script error when typing in the status window and on
|
||||
# startup of irssi
|
||||
# Version 0.93
|
||||
# - fixed a stupid case issue in address recognization.
|
||||
# Version 0.92
|
||||
# - code cleanups
|
||||
# - control codes are allowed in control channel, but targets must be used
|
||||
# (remoteuser: I'm talking to you) (this is the default)
|
||||
# Version 0.91
|
||||
# - more intelligent checking for HTML support
|
||||
# - allowed html from AIM users over ICQ connections
|
||||
# Version 0.9
|
||||
# - removed html parsing for non-AIM connections
|
||||
# - added support for replacing control codes (created by ctrl+b, ctrl+v, and
|
||||
# cltr+-) with html equivalents. Disabled by default.
|
||||
#
|
||||
# Version 0.8 (2005-12-02)
|
||||
# - Initial public release
|
||||
|
211
scripts/bitlbee_status_notice.pl
Normal file
211
scripts/bitlbee_status_notice.pl
Normal file
|
@ -0,0 +1,211 @@
|
|||
# bitlbee_status_notice.pl
|
||||
# Adds detailed information about status changed to bitlbee query windows
|
||||
# Information about known offline, online, and away durations will be printed
|
||||
# to open query windows of buddies. Away messages will also be asked for when
|
||||
# using the Oscar network.
|
||||
|
||||
# To use:
|
||||
# Set the correct values for $bitlbee_* below, and then:
|
||||
# /script load bitlbee_status_notice.pl
|
||||
|
||||
# Settings:
|
||||
# /set bitlbee_hide_joins ON|OFF
|
||||
# Prevents joins from showing up in #bitlbee control channel when buddies
|
||||
# sign on
|
||||
# /set bitlbee_hide_quits ON|OFF
|
||||
# Same for buddies signing off, except it also applies to query windows,
|
||||
# because Irssi shows quit notices in query windows automatically.
|
||||
#
|
||||
# As of version 1.4, these settings default to OFF.
|
||||
# If you wish also to ignore mode changes (voicing/devoicing):
|
||||
# /ignore &bitlbee MODES
|
||||
use strict;
|
||||
use Irssi;
|
||||
use Time::Duration;
|
||||
use Data::Dumper;
|
||||
|
||||
use vars qw($VERSION %IRSSI);
|
||||
|
||||
$VERSION = '1.4';
|
||||
%IRSSI = (
|
||||
authors => 'Matt "f0rked" Sparks',
|
||||
contact => 'ms+irssi@quadpoint.org',
|
||||
name => 'bitlbee_status_notice',
|
||||
description => 'Adds detailed information about status changes to bitlbee query windows',
|
||||
license => 'GPLv2',
|
||||
url => 'http://quadpoint.org',
|
||||
changed => '2010-03-04',
|
||||
);
|
||||
|
||||
my $bitlbee_channel = "&bitlbee";
|
||||
my $bitlbee_server_tag = "IM";
|
||||
|
||||
my %away_watch;
|
||||
my %away_times;
|
||||
my %online_times;
|
||||
my %offline_times;
|
||||
|
||||
my $hide_it;
|
||||
my $requested_info;
|
||||
|
||||
Irssi::theme_register([
|
||||
'state_away', '{channick $0} {chanhost $1} has gone away',
|
||||
'state_back', '{channick_hilight $0} {chanhost_hilight $1} has come back$2',
|
||||
'away_msg', '{chanhost msg} $0',
|
||||
'join', '{channick_hilight $0} {chanhost_hilight $1} has signed on$2',
|
||||
'quit', '{channick $0} {chanhost $1} has signed off$2',
|
||||
]);
|
||||
|
||||
|
||||
Irssi::signal_add_last 'channel sync' => sub
|
||||
{
|
||||
my($channel) = @_;
|
||||
if ($channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information.") {
|
||||
$bitlbee_server_tag = $channel->{server}->{tag};
|
||||
$bitlbee_channel = $channel->{name};
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
sub get_channel
|
||||
{
|
||||
my @channels = Irssi::channels();
|
||||
foreach my $channel (@channels) {
|
||||
if ($channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information.") {
|
||||
$bitlbee_channel = $channel->{name};
|
||||
$bitlbee_server_tag = $channel->{server}->{tag};
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
sub event_join
|
||||
{
|
||||
my($server, $channel, $nick, $address) = @_;
|
||||
if ($channel eq $bitlbee_channel && $server->{tag} eq $bitlbee_server_tag) {
|
||||
my $off_time;
|
||||
$off_time = time - $offline_times{$nick} if $offline_times{$nick};
|
||||
delete $offline_times{$nick} if $offline_times{$nick};
|
||||
|
||||
my $str;
|
||||
$str = " (last seen: " . ago_exact($off_time) . ")" if $off_time;
|
||||
$online_times{$nick} = time;
|
||||
|
||||
my $window = $server->query_find($nick);
|
||||
if ($window) {
|
||||
$window->printformat(MSGLEVEL_JOINS, "join", $nick, $address, $str);
|
||||
}
|
||||
|
||||
Irssi::signal_stop() # don't print the join announcement in &bitlbee
|
||||
if Irssi::settings_get_bool("bitlbee_hide_joins");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub event_quit
|
||||
{
|
||||
my($server, $nick, $address, $reason) = @_;
|
||||
if ($server->{tag} eq $bitlbee_server_tag) {
|
||||
my $on_time;
|
||||
$on_time = time - $online_times{$nick} if $online_times{$nick};
|
||||
delete $online_times{$nick} if $online_times{$nick};
|
||||
|
||||
my $str;
|
||||
$str = " (duration: " . duration($on_time) . ")" if $on_time;
|
||||
$offline_times{$nick} = time;
|
||||
|
||||
my $window = $server->query_find($nick);
|
||||
if ($window) {
|
||||
$window->printformat(MSGLEVEL_QUITS, "quit", $nick, $address, $str);
|
||||
}
|
||||
|
||||
Irssi::signal_stop() # don't print the quit announcement anywhere
|
||||
if Irssi::settings_get_bool("bitlbee_hide_quits");
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub event_mode
|
||||
{
|
||||
my($channel, $nick, $setby, $mode, $type) = @_;
|
||||
#print Dumper $nick;
|
||||
#print Dumper $channel;
|
||||
if ($mode eq "+" && $channel->{name} eq $bitlbee_channel &&
|
||||
$channel->{server}->{tag} eq $bitlbee_server_tag) {
|
||||
my $window = $channel->{server}->query_find($nick->{nick});
|
||||
my $gone_time;
|
||||
|
||||
if ($type eq "-") {
|
||||
$away_times{$nick->{nick}} = time;
|
||||
} elsif ($type eq "+") {
|
||||
if (my $time = $away_times{$nick->{nick}}) {
|
||||
$gone_time = time-$time;
|
||||
delete $away_times{$nick->{nick}};
|
||||
}
|
||||
}
|
||||
|
||||
if ($window) {
|
||||
if ($type eq "+") {
|
||||
my $gone_str;
|
||||
$gone_str = " (gone: ".duration($gone_time).")" if $gone_time;
|
||||
$window->printformat(MSGLEVEL_MODES, "state_back", $nick->{nick},
|
||||
$nick->{host}, $gone_str)
|
||||
if (time-$online_times{$nick->{nick}} > 2);
|
||||
} elsif ($type eq "-") {
|
||||
$window->printformat(MSGLEVEL_MODES, "state_away", $nick->{nick},
|
||||
$nick->{host});
|
||||
if ($nick->{host} =~ /login\.oscar\.aol\.com$/) {
|
||||
$away_watch{nick} = $nick->{nick};
|
||||
$channel->{server}->send_message($channel->{name},
|
||||
"info $nick->{nick}", 0);
|
||||
$requested_info = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub pub_msg
|
||||
{
|
||||
my($server, $msg, $nick, $address, $target) = @_;
|
||||
#print "$msg $nick $address $target";
|
||||
if ($nick eq "root" && $server->{tag} eq $bitlbee_server_tag &&
|
||||
$target eq $bitlbee_channel) {
|
||||
my $window = $server->channel_find($target);
|
||||
if ($window) {
|
||||
my $qwin;
|
||||
$qwin = $server->query_find($away_watch{nick}) if $away_watch{nick};
|
||||
if ($msg =~ /^TOC\(?.*\)? \- Away Message/g ||
|
||||
$msg =~ /^oscar \- Away Message/) {
|
||||
$away_watch{watch} = 1;
|
||||
$hide_it = 1 if $requested_info;
|
||||
Irssi::timeout_add_once(400,
|
||||
sub { $hide_it = 0; $requested_info = 0; },
|
||||
"");
|
||||
#$qwin->print("Away message:",MSGLEVEL_CRAP) if $qwin;
|
||||
} elsif ($msg =~ /^TOC\(?.*\)? \- .+$/ || $msg =~ /^oscar \- .+$/) {
|
||||
delete $away_watch{watch};
|
||||
delete $away_watch{nick};
|
||||
} elsif ($away_watch{watch} && $qwin) {
|
||||
$qwin->printformat(MSGLEVEL_CRAP, "away_msg", $msg) if $qwin;
|
||||
}
|
||||
}
|
||||
|
||||
Irssi::signal_stop if $hide_it;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
get_channel();
|
||||
|
||||
|
||||
Irssi::settings_add_bool("bitlbee", "bitlbee_hide_joins", 0);
|
||||
Irssi::settings_add_bool("bitlbee", "bitlbee_hide_quits", 0);
|
||||
|
||||
Irssi::signal_add("message public", "pub_msg");
|
||||
Irssi::signal_add("nick mode changed", "event_mode");
|
||||
Irssi::signal_add("message join", "event_join");
|
||||
Irssi::signal_add("message quit", "event_quit");
|
319
scripts/bitlbee_typing_notice.pl
Normal file
319
scripts/bitlbee_typing_notice.pl
Normal file
|
@ -0,0 +1,319 @@
|
|||
# INSTALLATION
|
||||
# [&bitlbee] set typing_notice true
|
||||
# <@root> typing_notice = `true'
|
||||
# AND
|
||||
# /statusbar window add typing_notice
|
||||
#
|
||||
# SETTINGS
|
||||
# [bitlbee]
|
||||
# bitlbee_send_typing = ON
|
||||
# -> send typing messages to buddies
|
||||
# bitlbee_typing_allwin = OFF
|
||||
# -> show typing notifications in all windows
|
||||
#
|
||||
#
|
||||
# Changelog:
|
||||
#
|
||||
# 2006-11-02 (version 1.6.1_
|
||||
# * Sending typing works again.
|
||||
#
|
||||
# 2006-10-27 (version 1.6)
|
||||
# * 'channel sync' re-implemented.
|
||||
# * bitlbee_send_typing was a string setting, It's a boolean now, like it should.
|
||||
#
|
||||
# 2006-10-24 (version 1.5)
|
||||
# * Sending notices to online users only.
|
||||
# * Using the new get_channel function;
|
||||
#
|
||||
# 2005-12-15 (version 1.42):
|
||||
# * Fixed small bug with typing notices disappearing under certain circumstances
|
||||
# in channels
|
||||
# * Fixed bug that caused outgoing notifications not to work
|
||||
# * root cares not about our typing status.
|
||||
#
|
||||
# 2005-12-04 (version 1.41):
|
||||
# * Implemented stale states in statusbar (shows "(stale)" for OSCAR connections)
|
||||
# * Introduced bitlbee_typing_allwin (default OFF). Set this to ON to make
|
||||
# typing notifications visible in all windows.
|
||||
#
|
||||
# 2005-12-03 (version 1.4):
|
||||
# * Major code cleanups and rewrites for bitlbee 1.0 with the updated typing
|
||||
# scheme. TYPING 0, TYPING 1, and TYPING 2 are now supported from the server.
|
||||
# * Stale states (where user has typed in text but has stopped typing) are now
|
||||
# recognized.
|
||||
# * Bug where user thinks you are still typing if you close the window after
|
||||
# typing something and then erasing it quickly.. fixed.
|
||||
# * If a user signs off while they are still typing, the notification is removed
|
||||
# This update by Matt "f0rked" Sparks
|
||||
#
|
||||
# 2005-08-26:
|
||||
# Some fixes for AIM, Thanks to Dracula.
|
||||
#
|
||||
# 2005-08-16:
|
||||
# AIM supported, for sending notices, using CTCP TYPING 0. (Use the AIM patch from Hanji http://get.bitlbee.org/patches/)
|
||||
#
|
||||
# 2004-10-31:
|
||||
# Sends typing notice to the bitlbee server when typing a message in irssi. bitlbee > 0.92
|
||||
#
|
||||
# 2004-06-11:
|
||||
# shows [typing: ] in &bitlbee with multiple users.
|
||||
#
|
||||
use strict;
|
||||
use Irssi;
|
||||
use Irssi::TextUI;
|
||||
|
||||
use vars qw($VERSION %IRSSI);
|
||||
|
||||
$VERSION = '1.6.1';
|
||||
%IRSSI = (
|
||||
authors => 'Tijmen "timing" Ruizendaal, Matt "f0rked" Sparks',
|
||||
contact => 'tijmen.ruizendaal@gmail.com, ms+irssi@quadpoint.org',
|
||||
name => 'BitlBee_typing_notice',
|
||||
description => '1. Adds an item to the status bar wich shows [typing] when someone is typing a message on the supported IM-networks
|
||||
2. Sending typing notices to the supported IM networks (the other way around)',
|
||||
license => 'GPLv2',
|
||||
url => 'http://the-timing.nl/stuff/irssi-bitlbee, http://quadpoint.org',
|
||||
changed => '2006-11-02',
|
||||
);
|
||||
|
||||
my $bitlbee_channel = "&bitlbee";
|
||||
my $bitlbee_server_tag = "localhost";
|
||||
|
||||
my $KEEP_TYPING_TIMEOUT = 1;
|
||||
my $STOP_TYPING_TIMEOUT = 7; # How often to check if we are typing, or on msn,
|
||||
# how long to keep the typing notice up, or check
|
||||
# if the other user is still typing...
|
||||
|
||||
my %timer_tag;
|
||||
|
||||
my %typing;
|
||||
my %tag;
|
||||
my $line;
|
||||
my %out_typing;
|
||||
my $lastkey;
|
||||
my $keylog_active = 1;
|
||||
my $command_char = Irssi::settings_get_str('cmdchars');
|
||||
my $to_char = Irssi::settings_get_str("completion_char");
|
||||
|
||||
get_channel();
|
||||
|
||||
Irssi::signal_add_last 'channel sync' => sub {
|
||||
my($channel) = @_;
|
||||
if ($channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information.") {
|
||||
$bitlbee_server_tag = $channel->{server}->{tag};
|
||||
$bitlbee_channel = $channel->{name};
|
||||
}
|
||||
};
|
||||
|
||||
sub get_channel {
|
||||
my @channels = Irssi::channels();
|
||||
foreach my $channel(@channels) {
|
||||
if ($channel->{topic} eq "Welcome to the control channel. Type \x02help\x02 for help information.") {
|
||||
$bitlbee_channel = $channel->{name};
|
||||
$bitlbee_server_tag = $channel->{server}->{tag};
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
sub event_ctcp_msg {
|
||||
my ($server, $msg, $from, $address) = @_;
|
||||
#print "CTCP: $msg $from $address";
|
||||
return if $server->{tag} ne $bitlbee_server_tag;
|
||||
if (my($type) = $msg =~ "TYPING ([0-9])") {
|
||||
Irssi::signal_stop();
|
||||
if ($type == 0) {
|
||||
unset_typing($from);
|
||||
}
|
||||
elsif ($type == 1) {
|
||||
$typing{$from}=1;
|
||||
if ($address !~ /\@login\.oscar\.aol\.com/
|
||||
and $address !~ /\@YAHOO/
|
||||
and $address !~ /\@login\.icq\.com/) {
|
||||
#Irssi::timeout_remove($tag{$from});
|
||||
#$tag{$from}=Irssi::timeout_add_once($STOP_TYPING_TIMEOUT*1000,"unset_typing",$from);
|
||||
}
|
||||
redraw($from);
|
||||
}
|
||||
elsif ($type == 2) {
|
||||
stale_typing($from);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub unset_typing {
|
||||
my($from, $no_redraw)=@_;
|
||||
delete $typing{$from} if $typing{$from};
|
||||
Irssi::timeout_remove($tag{$from});
|
||||
redraw($from) if !$no_redraw;
|
||||
}
|
||||
|
||||
sub stale_typing {
|
||||
my($from) = @_;
|
||||
$typing{$from} = 2;
|
||||
redraw($from);
|
||||
}
|
||||
|
||||
sub redraw {
|
||||
my($from)=@_;
|
||||
my $window = Irssi::active_win();
|
||||
my $channel = $window->get_active_name();
|
||||
if ($from eq $channel || $channel eq $bitlbee_channel
|
||||
|| $channel =~ /&chat_0/
|
||||
|| Irssi::settings_get_bool("bitlbee_typing_allwin")) {
|
||||
Irssi::statusbar_items_redraw('typing_notice');
|
||||
}
|
||||
}
|
||||
|
||||
sub event_msg {
|
||||
my ($server,$data,$from,$address,$target) = @_;
|
||||
return if $server->{tag} ne $bitlbee_server_tag;
|
||||
my $channel=Irssi::active_win()->get_active_name();
|
||||
unset_typing $from, "no redraw";
|
||||
unset_typing $channel;
|
||||
}
|
||||
|
||||
sub event_quit {
|
||||
my($server,$nick,$address,$reason)=@_;
|
||||
return if $server->{tag} ne $bitlbee_server_tag;
|
||||
unset_typing $nick;
|
||||
}
|
||||
|
||||
sub typing_notice {
|
||||
my ($item, $get_size_only) = @_;
|
||||
my $window = Irssi::active_win();
|
||||
my $channel = $window->get_active_name();
|
||||
|
||||
if (exists($typing{$channel})) {
|
||||
my $append=$typing{$channel}==2 ? " (stale)" : "";
|
||||
$item->default_handler($get_size_only, "{sb typing$append}", 0, 1);
|
||||
}
|
||||
else {
|
||||
$item->default_handler($get_size_only, "", 0, 1);
|
||||
Irssi::timeout_remove($tag{$channel});
|
||||
}
|
||||
if ($channel eq $bitlbee_channel || $channel =~ /&chat_0/
|
||||
|| Irssi::settings_get_bool("bitlbee_typing_allwin")) {
|
||||
foreach my $key (keys(%typing)) {
|
||||
$line .= " ".$key;
|
||||
if ($typing{$key}==2) { $line .= " (stale)"; }
|
||||
}
|
||||
if ($line ne "") {
|
||||
$item->default_handler($get_size_only, "{sb typing:$line}", 0, 1);
|
||||
$line = "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub empty {
|
||||
my $from = shift;
|
||||
delete($typing{$from});
|
||||
Irssi::statusbar_items_redraw('typing_notice');
|
||||
}
|
||||
|
||||
sub window_change {
|
||||
Irssi::statusbar_items_redraw('typing_notice');
|
||||
my $win = !Irssi::active_win() ? undef : Irssi::active_win()->{active};
|
||||
if (ref $win && ($win->{server}->{tag} eq $bitlbee_server_tag)) {
|
||||
if (!$keylog_active) {
|
||||
$keylog_active = 1;
|
||||
Irssi::signal_add_last('gui key pressed', 'key_pressed');
|
||||
#print "Keylog started";
|
||||
}
|
||||
}
|
||||
else {
|
||||
if ($keylog_active) {
|
||||
$keylog_active = 0;
|
||||
Irssi::signal_remove('gui key pressed', 'key_pressed');
|
||||
#print "Keylog stopped";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sub key_pressed {
|
||||
return if !Irssi::settings_get_bool("bitlbee_send_typing");
|
||||
my $key = shift;
|
||||
if ($key != 9 && $key != 10 && $lastkey != 27 && $key != 27
|
||||
&& $lastkey != 91 && $key != 126 && $key != 127)
|
||||
{
|
||||
my $server = Irssi::active_server();
|
||||
my $window = Irssi::active_win();
|
||||
my $nick = $window->get_active_name();
|
||||
if ($server->{tag} eq $bitlbee_server_tag &&
|
||||
$nick ne "(status)" &&
|
||||
$nick ne "root")
|
||||
{
|
||||
if ($nick eq $bitlbee_channel) {
|
||||
my $input = Irssi::parse_special("\$L");
|
||||
my ($first_word) = split(/ /,$input);
|
||||
if ($input !~ /^$command_char.*/ && $first_word =~ s/$to_char$//){
|
||||
send_typing($first_word);
|
||||
}
|
||||
}
|
||||
else {
|
||||
my $input = Irssi::parse_special("\$L");
|
||||
if ($input !~ /^$command_char.*/ && length($input) > 0){
|
||||
send_typing($nick);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
$lastkey = $key;
|
||||
}
|
||||
|
||||
sub out_empty {
|
||||
my ($a) = @_;
|
||||
my($nick,$tag)=@{$a};
|
||||
delete($out_typing{$nick});
|
||||
#print $winnum."|".$nick;
|
||||
if (my $server=Irssi::server_find_tag($tag)) {
|
||||
$server->command("^CTCP $nick TYPING 0");
|
||||
}
|
||||
}
|
||||
|
||||
sub send_typing {
|
||||
my $nick = shift;
|
||||
if (!exists($out_typing{$nick}) || time - $out_typing{$nick} > $KEEP_TYPING_TIMEOUT) {
|
||||
my @nicks = Irssi::server_find_tag($bitlbee_server_tag)->channel_find($bitlbee_channel)->nicks();
|
||||
my $exists=0;
|
||||
foreach my $nick1(@nicks) { #check if the nickname is in the BitlBee channel
|
||||
if($nick1->{'nick'} eq $nick) {
|
||||
#print "Exists!";
|
||||
$exists=1;
|
||||
}
|
||||
}
|
||||
if (!$exists) {
|
||||
#print "Does not exist";
|
||||
return;
|
||||
}
|
||||
|
||||
#print "Send typing";
|
||||
my $server = Irssi::active_server();
|
||||
$server->command("^CTCP $nick TYPING 1");
|
||||
|
||||
$out_typing{$nick} = time;
|
||||
|
||||
### Reset 'stop-typing' timer
|
||||
if ($timer_tag{$nick}) {
|
||||
Irssi::timeout_remove($timer_tag{$nick});
|
||||
delete($timer_tag{$nick});
|
||||
}
|
||||
$timer_tag{$nick} = Irssi::timeout_add_once($STOP_TYPING_TIMEOUT*1000, 'out_empty', ["$nick", $server->{tag}]);
|
||||
}
|
||||
}
|
||||
|
||||
# README: Delete the old bitlbee_send_typing string from ~/.irssi/config.
|
||||
# A boolean is better.
|
||||
|
||||
Irssi::settings_add_bool("bitlbee","bitlbee_send_typing",1);
|
||||
Irssi::settings_add_bool("bitlbee","bitlbee_typing_allwin",0);
|
||||
|
||||
Irssi::signal_add("ctcp msg", "event_ctcp_msg");
|
||||
Irssi::signal_add("message private", "event_msg");
|
||||
Irssi::signal_add("message public", "event_msg");
|
||||
Irssi::signal_add("message quit", "event_quit");
|
||||
Irssi::signal_add_last('window changed', 'window_change');
|
||||
Irssi::signal_add_last('gui key pressed', 'key_pressed');
|
||||
Irssi::statusbar_item_register('typing_notice', undef, 'typing_notice');
|
||||
Irssi::statusbars_recreate_items();
|
115
scripts/grumble.pl
Normal file
115
scripts/grumble.pl
Normal file
|
@ -0,0 +1,115 @@
|
|||
# grumble.pl provides sane integration of Irssi with Growl [http://growl.info/]
|
||||
# and Mumbles [http://www.mumbles-project.org/]. These programs both support the
|
||||
# Growl network protocol that the Perl module Net::Growl uses to communicate.
|
||||
#
|
||||
# This script supports multiple targets, each with a potentially unique Growl
|
||||
# password.
|
||||
#
|
||||
# SETTINGS
|
||||
# Targets are specified in the "grumble_targets" setting:
|
||||
# /set grumble_targets localhost:mypass
|
||||
# sends messages to an instance running on localhost with password "mypass"
|
||||
# /set grumble_targets localhost:mypass othermachine:otherpass
|
||||
# sends messages to two separate machines with different passwords
|
||||
#
|
||||
# To turn on/off notifications while /away, toggle the setting
|
||||
# 'grumble_notify_when_away'. Default: OFF.
|
||||
#
|
||||
# To enable/disable notifications for the active window, toggle the setting
|
||||
# 'grumble_notify_for_active_window'. Default: ON.
|
||||
use strict;
|
||||
use Irssi;
|
||||
use Net::Growl;
|
||||
use IO::Socket::INET;
|
||||
|
||||
use vars qw($VERSION %IRSSI);
|
||||
|
||||
$VERSION = '1.3';
|
||||
%IRSSI = (
|
||||
authors => 'Matt "f0rked" Sparks',
|
||||
contact => 'ms+irssi@quadpoint.org',
|
||||
name => 'grumble',
|
||||
description => 'Irssi integration with growl and mumbles',
|
||||
license => 'BSD',
|
||||
url => 'http://quadpoint.org',
|
||||
changed => '2010-02-08'
|
||||
);
|
||||
|
||||
|
||||
sub send_growl
|
||||
{
|
||||
my($host, $password, $title, $text) = @_;
|
||||
my %addr = (PeerAddr => $host,
|
||||
PeerPort => Net::Growl::GROWL_UDP_PORT,
|
||||
Proto => "udp");
|
||||
my $s = IO::Socket::INET->new(%addr) || die "Could not create socket: $!\n";
|
||||
my $r = Net::Growl::RegistrationPacket->new(application => "grumble.pl",
|
||||
password => $password);
|
||||
$r->addNotification();
|
||||
print $s $r->payload();
|
||||
|
||||
# send a notification
|
||||
my $p = Net::Growl::NotificationPacket->new(application => "grumble.pl",
|
||||
title => $title,
|
||||
description => $text,
|
||||
priority => 2,
|
||||
sticky => 'True',
|
||||
password => $password);
|
||||
print $s $p->payload();
|
||||
close $s;
|
||||
}
|
||||
|
||||
|
||||
sub send_to_all
|
||||
{
|
||||
my($title, $text) = @_;
|
||||
my @targets = split / /, Irssi::settings_get_str("grumble_targets");
|
||||
|
||||
for my $target (@targets) {
|
||||
my($host, $pass) = split /:/, $target, 2;
|
||||
send_growl($host, $pass, $title, $text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
sub event_privmsg
|
||||
{
|
||||
my($server, $msg, $nick, $address, $target) = @_;
|
||||
|
||||
my $active = Irssi::active_win();
|
||||
return if ($active->get_active_name() eq $nick &&
|
||||
!Irssi::settings_get_bool("grumble_notify_for_active_window"));
|
||||
|
||||
return if ($server->{usermode_away} &&
|
||||
!Irssi::settings_get_bool("grumble_notify_when_away"));
|
||||
|
||||
send_to_all("irssi: $nick", "new private message from $nick");
|
||||
}
|
||||
|
||||
|
||||
sub event_printtext
|
||||
{
|
||||
my ($dest, $text, $stripped) = @_;
|
||||
my $server = $dest->{server};
|
||||
|
||||
my $active = Irssi::active_win();
|
||||
return if ($active->get_active_name() eq $dest->{window}->get_active_name() &&
|
||||
!Irssi::settings_get_bool("grumble_notify_for_active_window"));
|
||||
|
||||
return if ($server->{usermode_away} &&
|
||||
!Irssi::settings_get_bool("grumble_notify_when_away"));
|
||||
|
||||
# Run the command if we're hilighted
|
||||
if (($dest->{level} & (MSGLEVEL_HILIGHT)) &&
|
||||
($dest->{level} & MSGLEVEL_NOHILIGHT) == 0) {
|
||||
send_to_all("irssi: hilight", $stripped);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Irssi::signal_add("message private", \&event_privmsg);
|
||||
Irssi::signal_add("print text", \&event_printtext);
|
||||
|
||||
Irssi::settings_add_str("grumble", "grumble_targets", "localhost:grwlpass");
|
||||
Irssi::settings_add_bool("grumble", "grumble_notify_when_away", 0);
|
||||
Irssi::settings_add_bool("grumble", "grumble_notify_for_active_window", 1);
|
41
scripts/hilight_notice.pl
Normal file
41
scripts/hilight_notice.pl
Normal file
|
@ -0,0 +1,41 @@
|
|||
# hilight_notice.pl for irssi
|
||||
#
|
||||
# This script changes the message level for notices to the level used by private
|
||||
# messages. Notices go to the status window by default, so when this script is
|
||||
# loaded, the status window will be hilighted like a query window.
|
||||
#
|
||||
# Based off of active_notice.pl by Geert.
|
||||
|
||||
use strict;
|
||||
use Irssi;
|
||||
|
||||
use vars qw($VERSION %IRSSI);
|
||||
|
||||
$VERSION = '1.1';
|
||||
%IRSSI = (
|
||||
authors => 'Matt "f0rked" Sparks',
|
||||
contact => 'ms+irssi@quadpoint.org',
|
||||
name => 'hilight_notice',
|
||||
description => 'hilight status window on notices',
|
||||
license => 'GPLv2',
|
||||
url => 'http://quadpoint.org',
|
||||
changed => '2006-12-15',
|
||||
);
|
||||
|
||||
|
||||
sub hilight_notice
|
||||
{
|
||||
my ($dest, $text, $stripped) = @_;
|
||||
my $server = $dest->{server};
|
||||
|
||||
return if (!$server || !($dest->{level} & MSGLEVEL_NOTICES));
|
||||
|
||||
# Change the message level to level used by PRIVMSGs
|
||||
my $witem = $server->window_item_find($dest->{target});
|
||||
$witem->print($text, MSGLEVEL_MSGS) if $witem;
|
||||
Irssi::print($text, MSGLEVEL_MSGS) if !$witem;
|
||||
Irssi::signal_stop();
|
||||
}
|
||||
|
||||
|
||||
Irssi::signal_add("print text", "hilight_notice");
|
38
scripts/hilightcmd.pl
Normal file
38
scripts/hilightcmd.pl
Normal file
|
@ -0,0 +1,38 @@
|
|||
use strict;
|
||||
use Irssi;
|
||||
|
||||
use vars qw($VERSION %IRSSI);
|
||||
|
||||
$VERSION = '1.0';
|
||||
%IRSSI = (
|
||||
authors => 'Matt "f0rked" Sparks',
|
||||
contact => 'ms+irssi@quadpoint.org',
|
||||
name => 'hilightcmd',
|
||||
description => 'Executes command on hilight',
|
||||
license => 'Public domain',
|
||||
url => 'http://quadpoint.org',
|
||||
changed => '2005-06-16',
|
||||
);
|
||||
|
||||
# Run the command when away?
|
||||
my $run_cmd_when_away = 0;
|
||||
my $cmd_to_run = "~/bin/notify.sh";
|
||||
|
||||
|
||||
sub sig_printtext
|
||||
{
|
||||
my($dest, $text, $stripped) = @_;
|
||||
my $server = $dest->{server};
|
||||
|
||||
# Do not run the command if we're not supposed to when away
|
||||
return if ($server->{usermode_away} && !$run_cmd_when_away);
|
||||
|
||||
# Run the command if we're hilighted
|
||||
if (($dest->{level} & (MSGLEVEL_HILIGHT)) &&
|
||||
($dest->{level} & MSGLEVEL_NOHILIGHT) == 0) {
|
||||
system($cmd_to_run, $text);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Irssi::signal_add("print text", \&sig_printtext);
|
77
scripts/rtm.pl
Normal file
77
scripts/rtm.pl
Normal file
|
@ -0,0 +1,77 @@
|
|||
# rtm.pl - add new tasks to rememberthemilk.com
|
||||
#
|
||||
# Install:
|
||||
# 1) /script load rtm
|
||||
# 2) /set rtm_email <your remember the milk email address>
|
||||
# 3) /save
|
||||
#
|
||||
# Usage:
|
||||
# /rtm <task>
|
||||
#
|
||||
# where:
|
||||
# <task> task name, e.g. "do laundry"
|
||||
# Uses RTM's 'Smart Add' for due dates, priority, etc.
|
||||
#
|
||||
# Examples:
|
||||
# Do the dishes for an hour, priority 2.
|
||||
# /rtm do dishes =1 hour !2
|
||||
#
|
||||
# Do homework, due tomorrow.
|
||||
# /rtm homework ^tomorrow
|
||||
#
|
||||
# See also:
|
||||
# http://www.rememberthemilk.com/services/email/
|
||||
use strict;
|
||||
use Irssi;
|
||||
|
||||
use vars qw($VERSION %IRSSI);
|
||||
|
||||
$VERSION = '1.0';
|
||||
%IRSSI = (
|
||||
authors => 'Matt "f0rked" Sparks',
|
||||
contact => 'ms+irssi@quadpoint.org',
|
||||
name => 'rtm',
|
||||
description => 'Add new tasks to rememberthemilk.com',
|
||||
license => 'BSD',
|
||||
url => 'http://quadpoint.org',
|
||||
changed => '2010-12-20',
|
||||
);
|
||||
|
||||
|
||||
sub rtm_print
|
||||
{
|
||||
my($text) = @_;
|
||||
my $window = Irssi::active_win();
|
||||
my $b = chr(2);
|
||||
$window->print("[${b}rtm${b}] $text", MSGLEVEL_CRAP);
|
||||
}
|
||||
|
||||
|
||||
sub add_task
|
||||
{
|
||||
my($email, $text) = @_;
|
||||
open SM, qq(| mail -s "$text" $email);
|
||||
print SM "\n\n";
|
||||
close SM;
|
||||
}
|
||||
|
||||
|
||||
sub cmd_rtm
|
||||
{
|
||||
my($data, $server, $witem) = @_;
|
||||
my $email_addr = Irssi::settings_get_str("rtm_email");
|
||||
if (!$email_addr) {
|
||||
rtm_print("your rememberthemilk.com email address is not set. ".
|
||||
"Use /set rtm_email <email address> to set it. Don't forget ".
|
||||
"to /save.");
|
||||
return;
|
||||
}
|
||||
|
||||
add_task($email_addr, $data);
|
||||
|
||||
rtm_print($data);
|
||||
}
|
||||
|
||||
|
||||
Irssi::command_bind("rtm", "cmd_rtm");
|
||||
Irssi::settings_add_str("rtm", "rtm_email", "");
|
246
scripts/socket-interface.pl
Normal file
246
scripts/socket-interface.pl
Normal file
|
@ -0,0 +1,246 @@
|
|||
use strict;
|
||||
use IO::Socket;
|
||||
use Fcntl;
|
||||
use Irssi;
|
||||
use Time::Format qw(%strftime);
|
||||
#use Data::Dumper;
|
||||
|
||||
use vars qw($VERSION %IRSSI);
|
||||
|
||||
$VERSION = '1.0.1';
|
||||
%IRSSI = (
|
||||
authors => 'Matt "f0rked" Sparks, Miklos Vajna',
|
||||
contact => 'ms+irssi@quadpoint.org',
|
||||
name => 'socket-interface',
|
||||
description => 'provides an interface to irssi via unix sockets',
|
||||
license => 'GPLv2',
|
||||
url => 'http://quadpoint.org',
|
||||
changed => '2009-01-22',
|
||||
);
|
||||
|
||||
my $socket = $ENV{"HOME"} . "/.irssi/socket";
|
||||
|
||||
# create the socket
|
||||
unlink $socket;
|
||||
my $server = IO::Socket::UNIX->new(Local => $socket,
|
||||
Type => SOCK_STREAM,
|
||||
Listen => 5) or die $@;
|
||||
|
||||
# set this socket as nonblocking so we can check stuff without interrupting
|
||||
# irssi.
|
||||
nonblock($server);
|
||||
|
||||
|
||||
# method to set a socket handle as nonblocking
|
||||
sub nonblock
|
||||
{
|
||||
my($fd) = @_;
|
||||
my $flags = fcntl($fd, F_GETFL, 0);
|
||||
fcntl($fd, F_SETFL, $flags | O_NONBLOCK);
|
||||
}
|
||||
|
||||
|
||||
# check the socket for data and act upon it
|
||||
sub check_sock
|
||||
{
|
||||
my $msg;
|
||||
if (my $client = $server->accept()) {
|
||||
$client->recv($msg, 1024);
|
||||
#print "Got message: $msg" if $msg;
|
||||
|
||||
if ($msg =~ /^activelog ?(\d*)$/) {
|
||||
my $lines = ($1) ? $1 : 5;
|
||||
#print "found lines: $lines";
|
||||
#print Dumper $win;
|
||||
my $ref = get_active_refnum();
|
||||
my $name = get_active_name();
|
||||
my $tag = get_active_tag();
|
||||
my $fname = get_log_fname(get_active_tag(), get_active_name());
|
||||
my $log = tail_log($fname, $lines);
|
||||
if (!$log) {
|
||||
$log = "Could not open log";
|
||||
}
|
||||
|
||||
chomp $log;
|
||||
$client->send(">> $ref: $name ($tag)\n$log");
|
||||
} elsif ($msg eq "windowlist") {
|
||||
# send back a list of the windows
|
||||
my $out;
|
||||
for (2 .. last_refnum()) {
|
||||
$out .= ("$_: " . name_of($_) . " (".tag_of($_).") " .
|
||||
level_of($_) . "\n");
|
||||
}
|
||||
|
||||
chomp $out;
|
||||
$client->send($out);
|
||||
} elsif ($msg =~ /^switch (\d+)$/) {
|
||||
$client->send(switch_to($1));
|
||||
} elsif ($msg =~ /^get_lines (\d+)$/) {
|
||||
$client->send(get_lines($1));
|
||||
} elsif ($msg =~ /^send (.+)$/) {
|
||||
$client->send(msg_active($1));
|
||||
} elsif ($msg =~ /^command (.+)$/) {
|
||||
$client->send(command($1));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# returns the name of the active window item. If there is no active window
|
||||
# item, return the name of the window itself.
|
||||
sub get_active_name
|
||||
{
|
||||
my $win = Irssi::active_win();
|
||||
return $win->get_active_name();
|
||||
}
|
||||
|
||||
|
||||
# returns the server tag of the active window item
|
||||
sub get_active_tag
|
||||
{
|
||||
my $win = Irssi::active_win();
|
||||
return ($win->{active}) ? $win->{active}->{server}->{tag} : "";
|
||||
}
|
||||
|
||||
|
||||
# returns refnum of active window
|
||||
sub get_active_refnum
|
||||
{
|
||||
return (Irssi::active_win())->{refnum};
|
||||
}
|
||||
|
||||
|
||||
# switches windows to the given refnum
|
||||
sub switch_to
|
||||
{
|
||||
my($refnum) = @_;
|
||||
my $window = Irssi::window_find_refnum($refnum);
|
||||
if ($window) {
|
||||
$window->set_active();
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# gets the lines from a buffer of a window
|
||||
sub get_lines
|
||||
{
|
||||
my($refnum) = @_;
|
||||
my $window = Irssi::window_find_refnum($refnum);
|
||||
if ($window) {
|
||||
my $view = $window->view;
|
||||
my $line = $view->get_lines();
|
||||
my $ret = "";
|
||||
while (defined $line) {
|
||||
$ret .= $line->get_text(0) . "\n";
|
||||
$line = $line->next();
|
||||
}
|
||||
return $ret;
|
||||
}
|
||||
else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
# return highest refnum
|
||||
sub last_refnum
|
||||
{
|
||||
return Irssi::windows_refnum_last();
|
||||
}
|
||||
|
||||
|
||||
# name of given refnum's window
|
||||
sub name_of
|
||||
{
|
||||
my($refnum) = @_;
|
||||
my $win = Irssi::window_find_refnum($refnum);
|
||||
return $win->get_active_name();
|
||||
}
|
||||
|
||||
|
||||
# tag of given refnum's window
|
||||
sub tag_of
|
||||
{
|
||||
my($refnum) = @_;
|
||||
my $win = Irssi::window_find_refnum($refnum);
|
||||
return ($win->{active}) ? $win->{active}->{server}->{tag} : "";
|
||||
}
|
||||
|
||||
|
||||
# level of given refnum's window
|
||||
sub level_of
|
||||
{
|
||||
my($refnum) = @_;
|
||||
my $win = Irssi::window_find_refnum($refnum);
|
||||
return $win->{data_level};
|
||||
}
|
||||
|
||||
|
||||
sub msg
|
||||
{
|
||||
my($refnum, $text) = @_;
|
||||
my $win = Irssi::window_find_refnum($refnum);
|
||||
return unless $win;
|
||||
if ($text =~ /^\//) {
|
||||
# this is a command, don't prepend /msg *
|
||||
$win->command($text);
|
||||
} else {
|
||||
$win->command("msg * $text");
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sub command
|
||||
{
|
||||
my($command) = @_;
|
||||
if (my $s = Irssi::active_server()) {
|
||||
$s->command($command);
|
||||
} else {
|
||||
Irssi::command($command);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
sub msg_active
|
||||
{
|
||||
my($text) = @_;
|
||||
return msg(get_active_refnum(), $text);
|
||||
}
|
||||
|
||||
|
||||
sub get_log_fname
|
||||
{
|
||||
my($servertag, $name) = @_;
|
||||
$name = lc($name);
|
||||
my $log_path = Irssi::settings_get_str("autolog_path");
|
||||
|
||||
# fill in variables
|
||||
my $log_file = $strftime{$log_path};
|
||||
$log_file =~ s/^~/$ENV{HOME}/;
|
||||
$log_file =~ s/\$tag/$servertag/g;
|
||||
$log_file =~ s/\$0/$name/g;
|
||||
#print "log file: $log_file";
|
||||
|
||||
return $log_file; # hope this is filled in enough.
|
||||
}
|
||||
|
||||
|
||||
# return the last x lines of a given filename
|
||||
sub tail_log
|
||||
{
|
||||
my($filename, $lines) = @_;
|
||||
$lines ||= 5;
|
||||
#print "found $filename";
|
||||
return 0 if !-e $filename;
|
||||
my $t = qx(tail -n $lines '$filename');
|
||||
chomp $t;
|
||||
return $t;
|
||||
}
|
||||
|
||||
|
||||
my $timer = Irssi::timeout_add(250, \&check_sock, []);
|
Loading…
Reference in New Issue
Block a user