--- /dev/null
+#!/usr/bin/perl -w
+
+## Bugreports and Licence disclaimer.
+#
+# For bugreports and other improvements contact Geert Hauwaerts <geert@irssi.org>
+#
+# This program is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 2 of the License, or
+# (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this script; if not, write to the Free Software
+# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+#
+##
+
+use strict;
+use Irssi;
+use vars qw($VERSION %IRSSI);
+
+$VERSION = "1.07";
+
+%IRSSI = (
+ authors => 'Geert Hauwaerts',
+ contact => 'geert@irssi.org',
+ name => 'active_notice.pl',
+ description => 'This script shows notices into the active channel unless it has its own window.',
+ license => 'GNU General Public License',
+ url => 'http://irssi.hauwaerts.be/active_notice.pl',
+ changed => 'Wed Sep 17 23:00:11 CEST 2003',
+);
+
+Irssi::theme_register([
+ 'active_notice_loaded', '%R>>%n %_Scriptinfo:%_ Loaded $0 version $1 by $2.'
+]);
+
+sub notice_move {
+
+ my ($dest, $text, $stripped) = @_;
+ my $server = $dest->{server};
+
+ return if (!$server || !($dest->{level} & MSGLEVEL_NOTICES) || $server->ischannel($dest->{target}));
+
+ my $witem = $server->window_item_find($dest->{target});
+ my $awin = Irssi::active_win();
+
+ return if $witem;
+
+ $awin->print($text, MSGLEVEL_NOTICES);
+
+ Irssi::signal_stop();
+}
+
+Irssi::signal_add('print text', 'notice_move');
+Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'active_notice_loaded', $IRSSI{name}, $VERSION, $IRSSI{authors});
--- /dev/null
+../active_notice.pl
\ No newline at end of file
--- /dev/null
+../dim_nicks.pl
\ No newline at end of file
--- /dev/null
+../lastfm.pl
\ No newline at end of file
--- /dev/null
+../nohilight.pl
\ No newline at end of file
--- /dev/null
+../screen_away.pl
\ No newline at end of file
--- /dev/null
+../smshi.pl
\ No newline at end of file
--- /dev/null
+use strict;
+use warnings;
+
+our $VERSION = '0.4.8'; # baf75f08d3d32c9
+our %IRSSI = (
+ authors => 'Nei',
+ contact => 'Nei @ anti@conference.jabber.teamidiot.de',
+ url => "http://anti.teamidiot.de/",
+ name => 'dim_nicks',
+ description => 'Dims nicks that are not in channel anymore.',
+ license => 'GNU GPLv2 or later',
+ );
+
+# Usage
+# =====
+# Once loaded, this script will record the nicks of each new
+# message. If the user leaves the room, the messages will be rewritten
+# with the nick in another colour/style.
+#
+# Depending on your theme, tweaking the forms settings may be
+# necessary. With the default irssi theme, this script should just
+# work.
+
+# Options
+# =======
+# /set dim_nicks_color <colour>
+# * the colour code to use for dimming the nick, or a string of format
+# codes with the special token $* in place of the nick (e.g. %I$*%I
+# for italic)
+#
+# /set dim_nicks_history_lines <num>
+# * only this many lines of messages are remembered/rewritten (per
+# window)
+#
+# /set dim_nicks_ignore_hilights <ON|OFF>
+# * ignore lines with hilight when dimming
+#
+# /set dim_nicks_forms_skip <num>
+# /set dim_nicks_forms_search_max <num>
+# * these two settings limit the range where to search for the
+# nick.
+# It sets how many forms (blocks of irssi format codes or
+# non-letters) to skip at the beginning of line before starting to
+# search for the nick, and from then on how many forms to search
+# before stopping.
+# You should set this to the appropriate values to avoid (a) dimming
+# your timestamp (b) dimming message content instead of the nick.
+# To check your settings, you can use the command
+# /script exec Irssi::Script::dim_nicks::debug_forms
+
+
+no warnings 'redefine';
+use constant IN_IRSSI => __PACKAGE__ ne 'main' || $ENV{IRSSI_MOCK};
+use Irssi 20140701;
+use Irssi::TextUI;
+use Encode;
+
+
+sub setc () {
+ $IRSSI{name}
+}
+
+sub set ($) {
+ setc . '_' . $_[0]
+}
+
+my $history_lines = 100;
+my $skip_forms = 1;
+my $search_forms_max = 5;
+my $ignore_hilights = 1;
+my $color_letter = 'K';
+
+# nick object cache, chan object cache, line id cache, line id -> window map, -> channel, -> nick, -> nickname, channel -> line ids, channel->nickname->departure time, channel->nickname->{parts of line}
+my (%nick_reg, %chan_reg, %history_w, %history_c, %history_n, %history_nn, %history_st, %lost_nicks, %lost_nicks_fs, %lost_nicks_fc, %lost_nicks_bc, %lost_nicks_bs);
+
+our ($dest, $chanref, $nickref);
+
+
+sub msg_line_tag {
+ my ($srv, $msg, $nick, $addr, $targ) = @_;
+ local $chanref = $srv->channel_find($targ);
+ local $nickref = ref $chanref ? $chanref->nick_find($nick) : undef;
+ &Irssi::signal_continue;
+}
+
+my @color_code;
+
+sub color_to_code {
+ my $win = Irssi::active_win;
+ my $view = $win->view;
+ my $cl = $color_letter;
+ if (-1 == index $cl, '$*') {
+ $cl = "%$cl\$*";
+ }
+ $win->print_after(undef, MSGLEVEL_NEVER, "$cl ");
+ my $lp = $win->last_line_insert;
+ my $color_code = $lp->get_text(1);
+ $color_code =~ s/ $//;
+ $view->remove_line($lp);
+ @color_code = split /\$\*/, $color_code, 2;
+}
+
+sub setup_changed {
+ $history_lines = Irssi::settings_get_int( set 'history_lines' );
+ $skip_forms = Irssi::settings_get_int( set 'forms_skip' );
+ $search_forms_max = Irssi::settings_get_int( set 'forms_search_max' );
+ $ignore_hilights = Irssi::settings_get_bool( set 'ignore_hilights' );
+ my $new_color = Irssi::settings_get_str( set 'color' );
+ if ($new_color ne $color_letter) {
+ $color_letter = $new_color;
+ color_to_code();
+ }
+}
+
+sub init_dim_nicks {
+ setup_changed();
+}
+
+sub prt_text_issue {
+ my ($ld) = @_;
+ local $dest = $ld;
+ &Irssi::signal_continue;
+}
+
+sub expire_hist {
+ for my $ch (keys %history_st) {
+ if (@{$history_st{$ch}} > 2 * $history_lines) {
+ my @del = splice @{$history_st{$ch}}, 0, $history_lines;
+ delete @history_w{ @del };
+ delete @history_c{ @del };
+ delete @history_n{ @del };
+ delete @history_nn{ @del };
+ }
+ }
+}
+
+sub prt_text_ref {
+ return unless $nickref;
+ return unless $dest && defined $dest->{target};
+ return unless $dest->{level} & MSGLEVEL_PUBLIC;
+ return if $ignore_hilights && $dest->{level} & MSGLEVEL_HILIGHT;
+
+ my ($win) = @_;
+ my $view = $win->view;
+ my $line_id = $view->{buffer}{_irssi} .','. $view->{buffer}{cur_line}{_irssi};
+ $chan_reg{ $chanref->{_irssi} } = $chanref;
+ $nick_reg{ $nickref->{_irssi} } = $nickref;
+ if (exists $history_w{ $line_id }) {
+ }
+ $history_w{ $line_id } = $win->{_irssi};
+ $history_c{ $line_id } = $chanref->{_irssi};
+ $history_n{ $line_id } = $nickref->{_irssi};
+ $history_nn{ $line_id } = $nickref->{nick};
+ push @{$history_st{ $chanref->{_irssi} }}, $line_id;
+ expire_hist();
+ my @lost_forever = grep { $view->{buffer}{first_line}{info}{time} > $lost_nicks{ $chanref->{_irssi} }{ $_ } }
+ keys %{$lost_nicks{ $chanref->{_irssi} }};
+ delete @{$lost_nicks{ $chanref->{_irssi} }}{ @lost_forever };
+ delete @{$lost_nicks_fs{ $chanref->{_irssi} }}{ @lost_forever };
+ delete @{$lost_nicks_fc{ $chanref->{_irssi} }}{ @lost_forever };
+ delete @{$lost_nicks_bc{ $chanref->{_irssi} }}{ @lost_forever };
+ delete @{$lost_nicks_bs{ $chanref->{_irssi} }}{ @lost_forever };
+ return;
+}
+
+sub win_del {
+ my ($win) = @_;
+ for my $ch (keys %history_st) {
+ @{$history_st{$ch}} = grep { exists $history_w{ $_ } &&
+ $history_w{ $_ } != $win->{_irssi} } @{$history_st{$ch}};
+ }
+ my @del = grep { $history_w{ $_ } == $win->{_irssi} } keys %history_w;
+ delete @history_w{ @del };
+ delete @history_c{ @del };
+ delete @history_n{ @del };
+ delete @history_nn{ @del };
+ return;
+}
+
+sub _alter_lines {
+ my ($chan, $check_lr, $ad) = @_;
+ my $win = $chan->window;
+ return unless ref $win;
+ my $view = $win->view;
+ my $count = $history_lines;
+ my $buffer_id = $view->{buffer}{_irssi} .',';
+ my $lp = $view->{buffer}{cur_line};
+ my %check_lr = map { $_ => undef } @$check_lr;
+ my $redraw;
+ my $bottom = $view->{bottom};
+ while ($lp && $count) {
+ my $line_id = $buffer_id . $lp->{_irssi};
+ if (exists $check_lr{ $line_id }) {
+ $lp = _alter_line($buffer_id, $line_id, $win, $view, $lp, $chan->{_irssi}, $ad);
+ unless ($lp) {
+ last;
+ }
+ $redraw = 1;
+ }
+ } continue {
+ --$count;
+ $lp = $lp->prev;
+ }
+ if ($redraw) {
+ $win->command('^scrollback end') if $bottom && !$win->view->{bottom};
+ $view->redraw;
+ }
+}
+
+my $irssi_mumbo = qr/\cD[`-i]|\cD[&-@\xff]./;
+my $irssi_mumbo_no_partial = qr/(?<!\cD)(?<!\cD[&-@\xff])/;
+my $irssi_skip_form_re = qr/((?:$irssi_mumbo|[.,*@%+&!#$()=~'";:?\/><]+(?=$irssi_mumbo|\s))+|\s+)/;
+
+sub debug_forms {
+ my $win = Irssi::active_win;
+ my $view = $win->view;
+ my $lp = $view->{buffer}{cur_line};
+ my $count = $history_lines;
+ my $buffer_id = $view->{buffer}{_irssi} .',';
+ while ($lp && $count) {
+ my $line_id = $buffer_id . $lp->{_irssi};
+ if (exists $history_w{ $line_id }) {
+ my $line_nick = $history_nn{ $line_id };
+ my $text = $lp->get_text(1);
+ pos $text = 0;
+ my $from = 0;
+ for (my $i = 0; $i < $skip_forms; ++$i) {
+ last unless
+ scalar $text =~ /$irssi_skip_form_re/g;
+ $from = pos $text;
+ }
+ my $to = $from;
+ for (my $i = 0; $i < $search_forms_max; ++$i) {
+ last unless
+ scalar $text =~ /$irssi_skip_form_re/g;
+ $to = pos $text;
+ }
+ my $pre = substr $text, 0, $from;
+ my $search = substr $text, $from, $to-$from;
+ my $post = substr $text, $to;
+ unless ($to > $from) {
+ } else {
+ my @nick_reg;
+ unshift @nick_reg, quotemeta substr $line_nick, 0, $_ for 1 .. length $line_nick;
+ no warnings 'uninitialized';
+ for my $nick_reg (@nick_reg) {
+ last if $search
+ =~ s/(\Q$color_code[0]\E\s*)?((?:$irssi_mumbo)+)?$irssi_mumbo_no_partial($nick_reg)((?:$irssi_mumbo)+)?(\s*\Q$color_code[0]\E)?/<match>$1$2<nick>$3<\/nick>$4$5<\/match>/;
+ last if $search
+ =~ s/(?:\Q$color_code[0]\E)?(?:(?:$irssi_mumbo)+?)?$irssi_mumbo_no_partial($nick_reg)(?:(?:$irssi_mumbo)+?)?(?:\Q$color_code[1]\E)?/<nick>$1<\/nick>/;
+ }
+ }
+ my $msg = "$pre<search>$search</search>$post";
+ #$msg =~ s/([^[:print:]])/sprintf '\\x%02x', ord $1/ge;
+ $msg =~ s/\cDe/%|/g; $msg =~ s/%/%%/g;
+ $win->print(setc." form debug: [$msg]", MSGLEVEL_CLIENTCRAP);
+ return;
+ }
+ } continue {
+ --$count;
+ $lp = $lp->prev;
+ }
+ $win->print(setc." form debug: no usable line found", MSGLEVEL_CLIENTCRAP);
+}
+
+sub _alter_line {
+ my ($buffer_id, $lrp, $win, $view, $lp, $cid, $ad) = @_;
+ my $line_nick = $history_nn{ $lrp };
+ my $text = $lp->get_text(1);
+ pos $text = 0;
+ my $from = 0;
+ for (my $i = 0; $i < $skip_forms; ++$i) {
+ last unless
+ scalar $text =~ /$irssi_skip_form_re/g;
+ $from = pos $text;
+ }
+ my $to = $from;
+ for (my $i = 0; $i < $search_forms_max; ++$i) {
+ last unless
+ scalar $text =~ /$irssi_skip_form_re/g;
+ $to = pos $text;
+ }
+ return $lp unless $to > $from;
+ my @nick_reg;
+ unshift @nick_reg, quotemeta substr $line_nick, 0, $_ for 1 .. length $line_nick;
+ { no warnings 'uninitialized';
+ if ($ad) {
+ if (exists $lost_nicks_fs{ $cid }{ $line_nick }) {
+ my ($fs, $fc, $bc, $bs) = ($lost_nicks_fs{ $cid }{ $line_nick }, $lost_nicks_fc{ $cid }{ $line_nick }, $lost_nicks_bc{ $cid }{ $line_nick }, $lost_nicks_bs{ $cid }{ $line_nick });
+ my $sen = length $bs ? $color_code[0] : '';
+ for my $nick_reg (@nick_reg) {
+ last if
+ (substr $text, $from, $to-$from)
+ =~ s/(?:\Q$color_code[0]\E)?(?:(?:$irssi_mumbo)+?)?$irssi_mumbo_no_partial($nick_reg)(?:(?:$irssi_mumbo)+?)?(?:\Q$color_code[1]\E)?/$fc$1$bc$sen/;
+ }
+ }
+ }
+ else {
+ for my $nick_reg (@nick_reg) {
+ if (
+ (substr $text, $from, $to-$from)
+ =~ s/(\Q$color_code[0]\E\s*)?((?:$irssi_mumbo)+)?$irssi_mumbo_no_partial($nick_reg)((?:$irssi_mumbo)+)?(\s*\Q$color_code[0]\E)?/$1$2$color_code[0]$3$color_code[1]$4$5/) {
+ $lost_nicks_fs{ $cid }{ $line_nick } = $1;
+ $lost_nicks_fc{ $cid }{ $line_nick } = $2;
+ $lost_nicks_bc{ $cid }{ $line_nick } = $4;
+ $lost_nicks_bs{ $cid }{ $line_nick } = $5;
+ last;
+ }
+ }
+ } }
+ $win->gui_printtext_after($lp->prev, $lp->{info}{level} | MSGLEVEL_NEVER, "$text\n", $lp->{info}{time});
+ my $ll = $win->last_line_insert;
+ my $line_id = $buffer_id . $ll->{_irssi};
+ if (exists $history_w{ $line_id }) {
+ }
+ grep { $_ eq $lrp and $_ = $line_id } @{$history_st{ $cid }};
+ $history_w{ $line_id } = delete $history_w{ $lrp };
+ $history_c{ $line_id } = delete $history_c{ $lrp };
+ $history_n{ $line_id } = delete $history_n{ $lrp };
+ $history_nn{ $line_id } = delete $history_nn{ $lrp };
+ $view->remove_line($lp);
+ $ll;
+}
+
+sub nick_add {
+ my ($chan, $nick) = @_;
+ if (delete $lost_nicks{ $chan->{_irssi} }{ $nick->{nick} }) {
+ my @check_lr = grep { $history_c{ $_ } == $chan->{_irssi} &&
+ $history_n{ $_ } eq $nick->{nick} } keys %history_w;
+ if (@check_lr) {
+ $nick_reg{ $nick->{_irssi} } = $nick;
+ for my $li (@check_lr) {
+ $history_n{ $li } = $nick->{_irssi};
+ }
+ _alter_lines($chan, \@check_lr, 1);
+ }
+ }
+ delete $lost_nicks_fs{ $chan->{_irssi} }{ $nick->{nick} };
+ delete $lost_nicks_fc{ $chan->{_irssi} }{ $nick->{nick} };
+ delete $lost_nicks_bc{ $chan->{_irssi} }{ $nick->{nick} };
+ delete $lost_nicks_bs{ $chan->{_irssi} }{ $nick->{nick} };
+ return;
+}
+
+sub nick_del {
+ my ($chan, $nick) = @_;
+ my @check_lr = grep { $history_n{ $_ } eq $nick->{_irssi} } keys %history_w;
+ for my $li (@check_lr) {
+ $history_n{ $li } = $nick->{nick};
+ }
+ if (@check_lr) {
+ $lost_nicks{ $chan->{_irssi} }{ $nick->{nick} } = time;
+ _alter_lines($chan, \@check_lr, 0);
+ }
+ delete $nick_reg{ $nick->{_irssi} };
+ return;
+}
+
+sub nick_change {
+ my ($chan, $nick, $oldnick) = @_;
+ nick_add($chan, $nick);
+}
+
+sub chan_del {
+ my ($chan) = @_;
+ if (my $del = delete $history_st{ $chan->{_irssi} }) {
+ delete @history_w{ @$del };
+ delete @history_c{ @$del };
+ delete @history_n{ @$del };
+ delete @history_nn{ @$del };
+ }
+ delete $chan_reg{ $chan->{_irssi} };
+ delete $lost_nicks{$chan->{_irssi}};
+ delete $lost_nicks_fs{$chan->{_irssi}};
+ delete $lost_nicks_fc{$chan->{_irssi}};
+ delete $lost_nicks_bc{$chan->{_irssi}};
+ delete $lost_nicks_bs{$chan->{_irssi}};
+ return;
+}
+
+Irssi::settings_add_int( setc, set 'history_lines', $history_lines);
+Irssi::settings_add_bool( setc, set 'ignore_hilights', $ignore_hilights);
+Irssi::signal_add_last({
+ 'setup changed' => 'setup_changed',
+});
+Irssi::signal_add({
+ 'print text' => 'prt_text_issue',
+ 'gui print text finished' => 'prt_text_ref',
+ 'nicklist new' => 'nick_add',
+ 'nicklist changed' => 'nick_change',
+ 'nicklist remove' => 'nick_del',
+ 'window destroyed' => 'win_del',
+ 'message public' => 'msg_line_tag',
+ 'channel destroyed' => 'chan_del',
+});
+
+sub dumphist {
+ my $win = Irssi::active_win;
+ my $view = $win->view;
+ my $buffer_id = $view->{buffer}{_irssi} .',';
+ for (my $lp = $view->{buffer}{first_line}; $lp; $lp = $lp->next) {
+ my $line_id = $buffer_id . $lp->{_irssi};
+ if (exists $history_w{ $line_id }) {
+ my $k = $history_c{ $line_id };
+ my $kn = $history_n{ $line_id };
+ if (exists $chan_reg{ $k }) {
+ }
+ if (exists $nick_reg{ $kn }) {
+ }
+ if (exists $lost_nicks{ $k } && exists $lost_nicks{ $k }{ $kn }) {
+ }
+ }
+ }
+}
+Irssi::settings_add_str( setc, set 'color', $color_letter);
+Irssi::settings_add_int( setc, set 'forms_skip', $skip_forms);
+Irssi::settings_add_int( setc, set 'forms_search_max', $search_forms_max);
+
+init_dim_nicks();
+
+{ package Irssi::Nick }
+
+# Changelog
+# =========
+# 0.4.8
+# - optionally ignore hilighted lines
+# 0.4.7
+# - fix useless re-reading of settings colour
+# 0.4.6
+# - fix crash on some lines reported by pierrot
--- /dev/null
+#
+# This script will print hilighted messages into a window called 'hilight'.
+#
+# Originally written by Timo Sirainen <tss@iki.fi>
+# - Places all hilighted messages into a window called "hilight"
+# Amended by Mark Sangster <znxster@gmail.com>
+# - Prints a timestamp with the messages
+# - Now allows toggling private messages to show or not.
+# - Using formats to print (allows basic theme adjustment)
+#
+# This script is released in the Public Domain.
+#
+# Basic Usage:
+# /window new split
+# /window name hilight
+# /script load hilightwin.pl
+#
+# Suggested usage:
+# /window new split
+# /window name hilight
+# /window size 10
+# /statusbar topic type window
+# /statusbar topic visible active
+# /statusbar window_inact disable
+# /script load hilightwin.pl
+#
+# Toggle private messages with:
+# /toggle hilightwin_showprivmsg
+#
+
+use Irssi;
+use POSIX;
+use vars qw($VERSION %IRSSI);
+
+$VERSION = "0.03";
+%IRSSI = (
+ authors => "John Runyon",
+ contact => "https://github.com/zonidjan",
+ name => "hilightwin",
+ description => "Print arbitrary-level messages to window named \"hilight\"",
+ license => "Public Domain",
+ url => "http://github.com/zonidjan/irssi-scripts/",
+ changed => "2018-01-02",
+);
+
+# Setup the theme for the script
+Irssi::theme_register([
+ 'hilightwin_loaded', '%R>>%n %_hilightwin:%_ Version $0 by $1.',
+ 'hilightwin_missing', '%R>>%n %_hilightwin:%_ No window named "hilight" was found, please create it',
+ 'hilightwin_output', '$0 $1',
+ 'hilightwin_public_output', '$0 $1: $2',
+]);
+
+# Main
+sub hilightwin_signal {
+ my ($dest, $text, $ignored) = @_;
+ $window = Irssi::window_find_name('hilight');
+
+ # Skip if the named window doesn't exist
+ if($window) {
+ my $opt = Irssi::settings_get_level('hilightwin_show');
+
+ if( ($dest->{level} & ($opt)) && ($dest->{level} & MSGLEVEL_NOHILIGHT) == 0 ) {
+ $time = strftime( Irssi::settings_get_str('timestamp_format')." ", localtime );
+ if($dest->{level} & MSGLEVEL_PUBLIC) {
+ $window->printformat(MSGLEVEL_NEVER, 'hilightwin_public_output', $time, $dest->{target}, $text);
+ }
+ else {
+ $window->printformat(MSGLEVEL_NEVER, 'hilightwin_output', $time, $text);
+ }
+ }
+ }
+}
+
+# Settings
+Irssi::settings_add_level('hilightwin','hilightwin_show','HILIGHT MSGS');
+
+# Signals
+Irssi::signal_add('print text', 'hilightwin_signal');
+
+# On load
+$window = Irssi::window_find_name('hilight');
+Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'hilightwin_missing') if (!$window);
+Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'hilightwin_loaded', $VERSION, $IRSSI{authors});
+
+# vim:set ts=4 sw=4 noet:
--- /dev/null
+# vim: set expandtab ts=2:
+use vars qw($VERSION %IRSSI);
+$VERSION = "5.8";
+%IRSSI = (
+ authors => "Simon 'simmel' Lundström",
+ contact => 'simmel@(freenode|quakenet|efnet) http://last.fm/user/darksoy',
+ name => "lastfm",
+ date => "20110125",
+ description => 'A now-playing-script which uses Last.fm',
+ license => "BSD",
+ url => "http://soy.se/code/",
+);
+# USAGE
+# For details on how to use each setting, scroll down to the SETTINGS section.
+
+# QUICK START
+# * First of all, you need the libwww/LWP package installed. The package in
+# your package system is probably called something with libwww and perl and/or
+# p5 in it.
+# * /set lastfm_user to the username that you are using on Last.fm
+# * Show with /np or %np<TAB> what song "lastfm_user" last scrobbled to Last.fm via /say. If "lastfm_use_action" is set, it uses /me.
+# * To see what another user on Last.fm is playing is also possible via /np <username> or %np(<username>).
+# The now-playing message is configurable via via "lastfm_output" (and lastfm_output_tab_complete when using %np, if not set it will use lastfm_output by default.). "lastfm_strftime" can be used to configure the display of date and time when the song was scrobbled.
+
+# SETTINGS
+# NOTE: Do not set these options here, use /set <option> <value> in irssi!
+# These are just defaults and descriptions on what the options do.
+
+# The username which you are using on Last.fm
+Irssi::settings_add_str("lastfm", "lastfm_user", "");
+
+# The output that you want to use.
+# The substitution variables are:
+# %artist = Self explanatory
+# %album = Self explanatory
+# %name = Name of song*
+# %url = URL to song on Last.fm
+# %player = Player we are using to submit to Last.fm with. See setting "lastfm_get_player" below
+# %user = User that is playing, when /np <username> or %np(<username> is used
+# If "lastfm_output_tab_complete" is not defined, "lastfm_output" will be used instead.
+# Something bothered me for a long time and when something really starts to itch
+# I tend to want to do something about it. I'm /np:ing away displaying all sorts
+# of tracks to my friends until I get to a track which has no album information
+# on Last.fm and the output becomes really ugly "np: Kraftwerk-Aerodynamik
+# (Alex Gopher/Etienne de Crecy dynamik mix) ()". What's with that last ()!? Oh,
+# right we are using "np: %artist-%name (%album)" as "lastfm_output". Wouldn't
+# it be really cool if lastfm.pl knew when certain information from Last.fm
+# didn't exist and didn't display it? So thought I, so that's why I created a
+# conditional. It works that you have to put your tag (%album e.g.) within %()
+# e.g. "np: %artist-%name%( (%album))" and everything between %( and ) only gets
+# displayed if the tag inside actually exists! Cool, huh!?
+
+# *) Name is used instead of, the more logical IMO, track since that is what Last.fm reports in their .xml file that we parse.
+Irssi::settings_add_str("lastfm", "lastfm_output", '%(%user is )np: %artist-%name');
+Irssi::settings_add_str("lastfm", "lastfm_output_tab_complete", '');
+
+# If we should use /me instead of /say
+Irssi::settings_add_bool("lastfm", "lastfm_use_action", 0);
+
+# If we should make the subtitution variable %player available which is very slow to fetch but nice to have.
+Irssi::settings_add_bool("lastfm", "lastfm_get_player", 0);
+
+# Changelog#{{{
+
+# 5.8 -- Tue Jan 25 16:11:29 CET 2011
+# * Ignore a closure warning
+
+# 5.7 -- Mon Jan 24 16:39:06 CET 2011
+# * Fixed a bug where we forked when we still waited for a reply from last.fm
+
+# 5.6 -- Sun Jul 18 13:16:38 CEST 2010
+# * Made substitution variable %user available when /np <username> or
+# %np(<username>) is used.
+# * Made some checks a bit more strict.
+
+# 5.5 -- Mon Jul 12 19:04:26 CEST 2010
+# * Rewrote the whole error handling
+# * Fixed a bug where the error messages would be said and not printed.
+# * Fixed some minor bugs and removed some unneeded code.
+
+# 5.4 -- Wed May 26 17:04:08 CEST 2010
+# * Last.fm updated their profile HTML so that the %player macro didn't work.
+# Thanks to Keith Ward for mentioning this and suggesting a fix.
+# * A minor fix which removes some debug messages when error reporting.
+
+# 5.3 --
+# * I used POSIX::_exit() but I never did "use POSIX;". Leo Green, mortiis and
+# rissy reported this problem, thanks! This is an issue when you have a newer
+# version of Perl installed (>5.10)
+
+# 5.2 -- Mon Nov 16 08:25:20 CET 2009
+# * When you remove a subroutine you should remove all calls to it..
+
+# 5.1 -- Wed Nov 11 09:39:54 CET 2009
+# * Ok, I admit that using undocumented features in an API is bad, but come
+# on.. Anyway, fixed now, everything should work as it should and should
+# never break again (flw)...
+
+# 5.0 -- Mon Nov 9 08:34:48 CET 2009
+# * Fixed a warning reported by mm_mannen and did a yet another clean up
+
+# 4.9 -- Sat Nov 7 18:10:17 CET 2009
+# * Last.fm changed how their API behaved and that broke my code because
+# I'm a fool and I don't want to use an XML-lib because of your sake (so you
+# won't have to install yet another Perl-module). Thanks to supertobbe and
+# mm_mannen who saw and reported this!
+# * Fixed so that lastfm_get_player works again and made it say that it
+# doesn't work next time Last.fm changes their HTML.
+# * Removed the date support in lastfm_output and lastfm_output_tab_complete
+# since I use the API another way now.
+# * Removed cache. It was broken at times and I can't be arsed to debug it.
+# It's not that much faster but the complexity gets bigger. If someone REALLY
+# needs this, give me a shout.
+# * Removed, rewrote and cleaned up some parts of the script.
+
+# 4.8 -- Sun May 10 10:11:29 CEST 2009
+# * Fixed a bug with the cache ('There are only two hard things in
+# Computer Science: cache invalidation and naming things' -Phil Karlton)
+# * Started using HTML::Entities for decoding all sorts of HTML-chars, it's
+# included in libwww anyway.
+
+# 4.7 -- Tue Apr 8 13:37:11 CEST 2009
+# * Start using LWP::UserAgent instead of LWP::Simple and got rid of the idea to
+# start using my own HTTP-lib (it was finished, but..). I'm getting old ; P
+# * Made so that everything is cached and checks if the Last-Modified date when
+# getting information from Last.fm.
+# * Fixed some documentation bugs.
+
+# 4.6 -- Wed Mar 18 19:45:11 CET 2009
+# * Fixed an changed behavour in irssi-trunk with the error handling (which I should replace anyway!).
+# * Added %player substitute variable that shows what application you are using to scrobble with. This is very slow, so I made it an option, "lastfm_get_player".
+# * Fixed print_raw once and for all (famous last words..) so now debug output looks really neat.
+# * Added an quick start which should help get going faster
+# * Fixed an issue where %np(lastfmusername) would not work.
+# * Fixed error mesages for %np(lastfmusername)
+# * Fixed an problem with irssi-svn where die's message have changed. Thanks tto jnpplf for reporting this.
+
+# 4.5 -- Wed 1 Oct 2008 20:03:47 CEST
+# * Removed a debug output
+# * Fixed some datacorruption, references in Perl is hard! = (
+
+# 4.4 -- Wed 1 Oct 2008 16:34:34 CEST
+# * Changed so that all the tab-commands use % instead of $ so that it's consistent through out the script.
+# * Ripped out my sprintf crap and made it more sane. You should use %artist, %album, etc in your nowplaying-setting now. Since sprintf is nolonger used I renamed that setting too.
+# * Made everything that you can set in "lastfm_output" tabable so now you can do %artist<TAB>.
+# %() in "lastfm_output" really works. It really didn't before.
+# * Fixed some issues with the date probably not working, but should now.
+# * Made the script check if Last.fm's scrobbler server is alive and kicking before we blame them.
+
+# 4.3 -- Mon 21 Jul 2008 08:46:36 CEST
+# * Seem like I misunderstood the protocol. The date/time is only sent when we have scrobbled the track, not when we started to listen to it.
+
+# 4.2 -- Tue 15 Jul 2008 15:40:08 CEST
+# Yay! Three new version within a day! (No, I'm not bored at work)
+# * Made /np username and $np(username) make username the prefix of np: yadayada or whatever your lastfm_sprintf or lastfm_sprintf_tab_complete is.
+
+# 4.1 -- Tue 15 Jul 2008 15:23:03 CEST
+# Well, that version lasted long!
+# * Fixed a bug with /np not working.
+# * Fixed an issue where debug info would be printed even if lastfm_debug was off.
+
+# 4.0 -- Tue 15 Jul 2008 10:17:51 CEST
+# * Fixing a sprintfng-bug which didn't display time if album was not set.
+# * Rewrote the whole script to use Last.fm's API which is very accurate. There is no need for $np! and /np! now, so I'm removing them.
+# * Cleaned up abit.
+
+# 3.9 -- Fri 11 Jul 2008 21:49:20 CEST
+# * Fixing a few bugs noticed by supertobbe
+
+# 3.8 -- Fri 11 Jul 2008 18:21:52 CEST
+# * Shaped up error handling and now all error messages are shown.
+# * Added a user configurable debug mode, good for sending in bugs and weird behaviour.
+# * Minor cleanup
+
+# 3.7 -- Thu 22 May 2008 10:33:55 CEST
+# * Fixed so that /np! and $np! fetches the album title too. This is horribly slow and takes approx. 6s on very fast connection. Last.fm isnt very fast I'm afraid and this is not a good way to do it.
+# * Cleaned up a few places. Started to look at the error handling and it seems to be alot of work.
+
+# 3.6 -- Tue Nov 13 15:22:37 CET 2007
+# * Fixed encoding so that it always the data into the charset that you have specified in "term_charset" which irssi also uses.
+
+# 3.5 -- Mon Nov 12 11:50:46 CET 2007
+# * Fixed the regex for parsing Recently Listened Tracks so that it works when listening with the Lastfm client.
+
+# 3.4 -- Fri Nov 9 00:23:40 CET 2007
+# * Added /np lastfmusername
+
+# 3.3 -- Tue Nov 6 01:54:59 CET 2007
+# * Finally added conditional sprintf-syntax! Let's say you want to use 'np: %s-%s (%s)' as "lastfm_sprintf". If you use /np it works out fine and displays 'np: Boards of Canada-Energy Warning (Geogaddi)' but what if you use /np! then it displays 'np: Boards of Canada-Energy Warning ()' since /np! can't get the album information. Doesn't that look ugly? Meet conditional sprintf. Now set your "lastfm_sprintf" to 'np: %s-%s%( (%s))'. ' (%s)' will only be printed if we get a third value, the album name in this case. Smart, huh? Big thanks to rindolf, apeiron and Khisanth from #perl@freenode for help with scoping with global variables.
+# * Also added "lastfm_sprintf_tab_complete" which makes, if set, $np<TAB> use a different sprintf pattern than /np. Will default back to "lastfm_sprintf".
+
+# 3.2 -- Wed Oct 24 23:07:01 CEST 2007
+# * I don't like dependencies and I really wonder why I lastfm depended on DateTime. I remember now that it was morning and I was really tired when I coded it. Anyway, it's removed now along with Socket and URI::Escape. I'll try to remove the dependency for libwww later on.
+
+# 3.1 -- Sun Oct 21 22:52:36 CEST 2007
+# * Added /np! and $np! to use the "lastfm_be_accurate_and_slow" method without having to change the setting.
+
+# 3.0 -- Fri Oct 19 14:26:03 CEST 2007
+# * Created a new setting "lastfm_be_accurate_and_slow" which makes lastfm.pl parse your profile page to check what song you are playing right now. But be warned, this is slow and horrible (like my code! ; ). But it works until Last.fm makes this data available through their Web Services. This disables the album and "scrobbled at" features of "lastfm_sprintf" so you have to adapt it if you don't want it to look weird. I'm working on a new implementation of printf which allows for conditions but it took more time than I thought and time is something that I don't have much of ='(
+
+# 2.5 -- Tue Oct 9 11:29:56 CEST 2007
+# * Fixed the encoding issue by converting from Last.fms UTF-8 into Perls internal encoding. With $np<TAB> output will be looking UTF-8-in-latin1 if you don't have an UTF-8 enabled Terminal, but it will display correctly after you have sent it.
+
+# 2.4 -- Mon Oct 8 16:08:09 CEST 2007
+# * Fixed an error in error reporting ; P Bug noticed by supertobbe = *
+# * I should make an more generic and better error reporting.
+
+# 2.3 -- Sat Oct 6 16:38:34 CEST 2007
+# * Made /np a nonblocking operation. Irssi's fork handling is REALLY messy. Thanks to tss and tommie for inspiring me in their scripts. $np cannot be made nonblocking, I'm afraid (patches welcome).
+# * Cleaned up abit.
+
+# 2.2 -- Sat Aug 18 02:20:44 CEST 2007
+# * Now you can use $np(darksoy) to see what I play (or someone else for that matter ; ).
+
+# 2.1 -- Tue Jul 17 12:50:18 CEST 2007
+# * Now you can use $np or $nowplaying as a tab-completion too, but a warning here, this is a blocking action so irssi won't respond or be usable until it is finished or the timeout is hit.
+# * Abstracted it abit more so that it can be used in more ways, ex. for the reason above.
+
+# 2.0 -- Fri Jun 29 10:38:32 CEST 2007
+# * Now you can show the time that the song was submitted in lastfm_sprintf. Added lastfm_strftime to configure how the date is presented.
+# * Added $lastfm and $lfm as tab-completions to your own Last.fm profile URL. Ripoff of Jured's guts.pl (http://juerd.nl/irssi/)
+
+# 1.5 -- Sat May 12 03:30:24 CEST 2007
+# * Started using XML instead because we get more info from it, like album (but it's often wrong).
+
+# 1.0 -- Thu Apr 12 16:57:26 CEST 2007
+# * Got fedup with no good Last.fm-based now playing scripts around.
+
+# THANKS
+# Random individuals on #perl@freenode, could namedrop icke,
+# }}}
+
+# TODO
+# You tell me!
+
+# Move along now, there's nothing here to see.
+
+sub DEBUG {
+ Irssi::settings_add_bool("lastfm", "lastfm_debug", 0);
+ Irssi::settings_get_bool("lastfm_debug");
+};
+
+use strict;
+use warnings;
+no warnings 'closure';
+use Data::Dumper;
+use Encode;
+use HTML::Entities;
+use Irssi;
+use LWP::UserAgent;
+use POSIX;
+
+my $pipe_tag;
+my $waiting_for_reply;
+my $api_key = "eba9632ddc908a8fd7ad1200d771beb7";
+my $fields = "(artist|name|album|url|player|user)";
+my $ua = LWP::UserAgent->new(agent => "lastfm.pl/$VERSION", timeout => 10);
+
+sub lastfm_nowplaying {
+ my ($content, $url, $response, $tag, $value, %data);
+ my ($user_shifted, $is_tabbed, $nowplaying, $witem) = @_;
+ my $user = $user_shifted || Irssi::settings_get_str("lastfm_user");
+ $nowplaying ||= ((Irssi::settings_get_str("lastfm_output_tab_complete") ne "" && $is_tabbed) ? Irssi::settings_get_str("lastfm_output_tab_complete") : Irssi::settings_get_str("lastfm_output"));
+
+ my $command_message = ($is_tabbed) ? '%%np(username)' : '/np username';
+ if ($user eq '') {
+ return "ERROR: You must /set lastfm_user to a username on Last.fm or use $command_message";
+ }
+
+ if ($nowplaying =~ /^%(lastfm|lfm)$/) {
+ return "https://last.fm/user/$user/";
+ }
+ elsif ($nowplaying =~ /^%user$/) {
+ return $user;
+ }
+
+ $data{'user'} = $user if ($user_shifted);
+
+ $url = "http://ws.audioscrobbler.com/2.0/?method=user.getrecenttracks&user=$user&api_key=$api_key&limit=1";
+ print Dumper "Checking for scrobbles at: $url" if DEBUG;
+ $response = $ua->get($url);
+ $content = $response->content;
+
+ # TODO This should work, untested (fail more Last.fm! ; )
+ if ($content =~ m!<lfm status="failed">.*<error .*?>([^<]+)!s) {
+ return "ERROR: $1";
+ }
+ my @data = split('\n', $content);
+
+ if (!grep(m!<track nowplaying="true">!, @data)) {
+ print Dumper \$response if DEBUG;
+ print Dumper \$content if DEBUG;
+# return "ERROR: You are not playing anything according to Last.fm. Check https://www.last.fm/user/$user and see if they turn up there, otherwise restart your scrobbler.";
+ }
+
+ my $regex = qr!<$fields.*?(?:uts="(.*?)">.*?|>(.*?))</\1>!;
+
+ foreach my $data (@data) {
+ if ($data =~ m!</track>!) {
+ last;
+ }
+ elsif ($data =~ /$regex/) {
+ ($tag, $value) = ($1, (defined($2) ? $2 : $3));
+ print Dumper \$tag, \$value, \$data if DEBUG;
+ $data{$tag} = $value;
+ }
+ }
+
+ if (Irssi::settings_get_bool("lastfm_get_player")) {
+ $url = "https://www.last.fm/user/$user";
+ $content = $ua->get($url)->content;
+ if ($content =~ m!<span class="source">(.*?)</span>!) {
+ $_ = $1;
+ s/<[^>]*>//mgs;
+ $data{'player'} = $_;
+ }
+ else {
+ print "Couldn't find the player even though lastfm_get_player was set" if DEBUG;
+ }
+ }
+
+ print Dumper \%data if DEBUG;
+ print Dumper "Output pattern before: $nowplaying" if DEBUG;
+ $nowplaying =~ s/(%\((.*?%(\w+).?)\))/($data{$3} ? $2 : "")/ge;
+ print Dumper "Output pattern after: $nowplaying" if DEBUG;
+ $nowplaying =~ s/%$fields/$data{$1}/ge;
+ decode_entities($nowplaying);
+ Encode::from_to($nowplaying, "utf-8", Irssi::settings_get_str("term_charset"));
+ return $nowplaying;
+}
+
+sub lastfm_blocking {
+ my ($witem, $user) = @_;
+ my $nowplaying = lastfm_nowplaying($user, undef, undef, $witem);
+ lastfm_print($witem, $nowplaying);
+}
+
+sub lastfm_forky {
+ my ($witem, $user) = @_;
+ if ($waiting_for_reply) {
+ lastfm_print(Irssi::active_win(), "We are still waiting for Last.fm to return our results");
+ return;
+ }
+ # pipe is used to get the reply from child
+ my ($rh, $wh);
+ pipe($rh, $wh);
+
+ # non-blocking host lookups with fork()ing
+ my $pid = fork();
+ if (!defined($pid)) {
+ Irssi::print("Can't fork() - aborting");
+ close($rh);
+ close($wh);
+ return;
+ }
+
+ $waiting_for_reply = 1;
+
+ if ($pid > 0) {
+ # parent, wait for reply
+ close($wh);
+ Irssi::pidwait_add($pid);
+ $pipe_tag = Irssi::input_add(fileno($rh), INPUT_READ, \&pipe_input, [$witem, $rh]);
+ return;
+ }
+
+ my $text;
+ eval {
+ # child, do the lookup
+ $text = lastfm_nowplaying($user);
+ };
+
+ if (!$text) {
+ $text = "ERROR: Error message: $!";
+ }
+
+ eval {
+ # write the reply
+ print($wh $text);
+ close($wh);
+ };
+ POSIX::_exit(1);
+}
+
+
+sub pipe_input {
+ my ($witem, $rh) = @{$_[0]};
+ my $text = <$rh>;
+ close($rh);
+
+ Irssi::input_remove($pipe_tag);
+ $pipe_tag = -1;
+ undef $waiting_for_reply;
+
+ lastfm_print($witem, $text);
+}
+
+sub lastfm_print {
+ my ($witem, $text, $tabbed) = @_;
+ # Fugly error handling
+ if ($text =~ s/^ERROR: //) {
+ Irssi::active_win()->print($text);
+ return;
+ }
+
+ if ($tabbed) {
+ return $text;
+ }
+ elsif (defined $witem->{type} && $witem->{type} =~ /^QUERY|CHANNEL$/) {
+ if (Irssi::settings_get_bool("lastfm_use_action")) {
+ $witem->command("me $text");
+ }
+ else {
+ $witem->command("say $text");
+ }
+ }
+ else {
+ Irssi::active_win()->print($text);
+ }
+}
+
+sub cmd_np {
+ my ($data, $server, $witem) = @_;
+ $data =~ s/ .*//;
+ $data ||= 0;
+ if (DEBUG) {
+ lastfm_blocking($witem, $data);
+ }
+ else {
+ lastfm_forky($witem, $data);
+ }
+}
+Irssi::command_bind('np', \&cmd_np, 'lastfm');
+
+Irssi::signal_add_last 'complete word' => sub {
+ my ($complist, $window, $word, $linestart, $want_space) = @_;
+ my $is_tabbed = 1;
+ my $tab_fields = $fields;
+ $tab_fields =~ s/\(/(nowplaying|np|lastfm|lfm|/;
+ if ($word =~ /(\%(?:$tab_fields))\(?(\w+)?\)?/) {
+ my ($nowplaying, $user) = ($1, $3);
+ undef $nowplaying if ($nowplaying =~ /nowplaying|np/);
+ $nowplaying = lastfm_nowplaying($user, $is_tabbed, $nowplaying);
+ if (lastfm_print(Irssi::active_win(), $nowplaying, 1)) {
+ push @$complist, "$nowplaying";
+ }
+ }
+};
+
+Irssi::signal_add_last 'message public' => sub {
+ my ($server, $msg, $nick, $addr, $target) = @_;
+ if ($msg =~ s/^!np ?//) {
+ cmd_np($msg, $server, Irssi::window_item_find($target));
+ }
+};
--- /dev/null
+use Irssi;
+use vars qw($VERSION %IRSSI);
+
+$VERSION = "0.1";
+%IRSSI = (
+ authors => "Paul Traylor",
+ name => "nohilight",
+ description => "Do not hilight messages from a list of users",
+ license => 'MIT',
+ url => 'http://github.com/kfdm/irssi-nohilight',
+ contact => 'http://github.com/kfdm/irssi-nohilight/issues'
+);
+
+sub remove_hilight {
+ my ($dest, $text, $stripped) = @_;
+ if ($dest->{level} & MSGLEVEL_HILIGHT) {
+ my @nicks = map(quotemeta, split(/[, ]/, Irssi::settings_get_str('nohilight_nicks')));
+ foreach my $nick (@nicks) {
+ if ($stripped =~ /<.?$nick>/) {
+ my $window = $dest->{window};
+ $text =~ s/%/%%/g;
+ $window->print($text, MSGLEVEL_PUBLIC);
+ Irssi::signal_stop();
+ return;
+ }
+ }
+ }
+}
+
+Irssi::signal_add_first('print text', 'remove_hilight');
+Irssi::settings_add_str($IRSSI{'name'}, 'nohilight_nicks', '');
+Irssi::print('%G>>%n '.$IRSSI{name}.' '.$VERSION.' loaded');
--- /dev/null
+use Irssi;
+use strict;
+use FileHandle;
+
+use vars qw($VERSION %IRSSI);
+
+$VERSION = "0.9.7.1";
+%IRSSI = (
+ authors => 'Andreas \'ads\' Scherbaum <ads@wars-nicht.de>',
+ name => 'screen_away',
+ description => 'set (un)away, if screen is attached/detached',
+ license => 'GPL v2',
+ url => 'none',
+);
+
+# screen_away irssi module
+#
+# written by Andreas 'ads' Scherbaum <ads@ufp.de>
+#
+# changes:
+# 07.02.2004 fix error with away mode
+# thanks to Michael Schiansky for reporting and fixing this one
+# 07.08.2004 new function for changing nick on away
+# 24.08.2004 fixing bug where the away nick was not storedcorrectly
+# thanks for Harald Wurpts for help debugging this one
+# 17.09.2004 rewrote init part to use $ENV{'STY'}
+# 05.12.2004 add patch for remember away state
+# thanks to Jilles Tjoelker <jilles@stack.nl>
+# change "chatnet" to "tag"
+# 18.05.2007 fix '-one' for SILC networks
+#
+#
+# usage:
+#
+# put this script into your autorun directory and/or load it with
+# /SCRIPT LOAD <name>
+#
+# there are 5 settings available:
+#
+# /set screen_away_active ON/OFF/TOGGLE
+# /set screen_away_repeat <integer>
+# /set screen_away_message <string>
+# /set screen_away_window <string>
+# /set screen_away_nick <string>
+#
+# active means, that you will be only set away/unaway, if this
+# flag is set, default is ON
+# repeat is the number of seconds, after the script will check the
+# screen status again, default is 5 seconds
+# message is the away message sent to the server, default: not here ...
+# window is a window number or name, if set, the script will switch
+# to this window, if it sets you away, default is '1'
+# nick is the new nick, if the script goes away
+# will only be used it not empty
+#
+# normal you should be able to rename the script to something other
+# than 'screen_away' (as example, if you dont like the name) by simple
+# changing the 'name' parameter in the %IRSSI hash at the top of this script
+
+
+# variables
+my $timer_name = undef;
+my $away_status = 0;
+my %old_nicks = ();
+my %away = ();
+
+# Register formats
+Irssi::theme_register(
+[
+ 'screen_away_crap',
+ '{line_start}{hilight ' . $IRSSI{'name'} . ':} $0'
+]);
+
+# if we are running
+my $screen_away_used = 0;
+
+# try to find out, if we are running in a screen
+# (see, if $ENV{STY} is set
+if (!defined($ENV{STY})) {
+ # just return, we will never be called again
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
+ "could not open status file for parent process (pid: " . getppid() . "): $!");
+ return;
+}
+
+my ($socket_name, $socket_path);
+
+# search for socket
+# normal we could search the socket file, ... if we know the path
+# but so we have to call one time the screen executable
+# disable locale
+# the quotes around C force perl 5.005_03 to use the shell
+# thanks to Jilles Tjoelker <jilles@stack.nl> for pointing this out
+my $socket = `LC_ALL="C" screen -ls`;
+
+
+
+my $running_in_screen = 0;
+# locale doesnt seems to be an problem (yet)
+if ($socket !~ /^No Sockets found/s) {
+ # ok, should have only one socket
+ $socket_name = $ENV{'STY'};
+ $socket_path = $socket;
+ $socket_path =~ s/^.+\d+ Sockets? in ([^\n]+)\.\n.+$/$1/s;
+ if (length($socket_path) != length($socket)) {
+ # only activate, if string length is different
+ # (to make sure, we really got a dir name)
+ $screen_away_used = 1;
+ } else {
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
+ "error reading screen informations from:");
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
+ "$socket");
+ return;
+ }
+}
+
+# last check
+if ($screen_away_used == 0) {
+ # we will never be called again
+ return;
+}
+
+# build complete socket name
+$socket = $socket_path . "/" . $socket_name;
+
+# register config variables
+Irssi::settings_add_bool('misc', $IRSSI{'name'} . '_active', 1);
+Irssi::settings_add_int('misc', $IRSSI{'name'} . '_repeat', 5);
+Irssi::settings_add_str('misc', $IRSSI{'name'} . '_message', "not here ...");
+Irssi::settings_add_str('misc', $IRSSI{'name'} . '_window', "1");
+Irssi::settings_add_str('misc', $IRSSI{'name'} . '_nick', "");
+
+# init process
+screen_away();
+
+# screen_away()
+#
+# check, set or reset the away status
+#
+# parameter:
+# none
+# return:
+# 0 (OK)
+sub screen_away {
+ my ($away, @screen, $screen);
+
+ # only run, if activated
+ if (Irssi::settings_get_bool($IRSSI{'name'} . '_active') == 1) {
+ if ($away_status == 0) {
+ # display init message at first time
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
+ "activating $IRSSI{'name'} (interval: " . Irssi::settings_get_int($IRSSI{'name'} . '_repeat') . " seconds)");
+ }
+ # get actual screen status
+ my @screen = stat($socket);
+ # 00100 is the mode for "user has execute permissions", see stat.h
+ if (($screen[2] & 00100) == 0) {
+ # no execute permissions, Detached
+ $away = 1;
+ } else {
+ # execute permissions, Attached
+ $away = 2;
+ }
+
+ # check if status has changed
+ if ($away == 1 and $away_status != 1) {
+ # set away
+ if (length(Irssi::settings_get_str($IRSSI{'name'} . '_window')) > 0) {
+ # if length of window is greater then 0, make this window active
+ Irssi::command('window goto ' . Irssi::settings_get_str($IRSSI{'name'} . '_window'));
+ }
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
+ "Set away");
+ my $message = Irssi::settings_get_str($IRSSI{'name'} . '_message');
+ if (length($message) == 0) {
+ # we have to set a message or we wouldnt go away
+ $message = "not here ...";
+ }
+ my ($server);
+ foreach $server (Irssi::servers()) {
+ if (!$server->{usermode_away}) {
+ # user isnt yet away
+ $away{$server->{'tag'}} = 0;
+ $server->command("AWAY " . (($server->{chat_type} ne 'SILC') ? "-one " : "") . "$message") if (!$server->{usermode_away});
+ if (length(Irssi::settings_get_str($IRSSI{'name'} . '_nick')) > 0) {
+ # only change, if actual nick isnt already the away nick
+ if (Irssi::settings_get_str($IRSSI{'name'} . '_nick') ne $server->{nick}) {
+ # keep old nick
+ $old_nicks{$server->{'tag'}} = $server->{nick};
+ # set new nick
+ $server->command("NICK " . Irssi::settings_get_str($IRSSI{'name'} . '_nick'));
+ }
+ }
+ } else {
+ # user is already away, remember this
+ $away{$server->{'tag'}} = 1;
+ }
+ }
+ $away_status = $away;
+ } elsif ($away == 2 and $away_status != 2) {
+ # unset away
+ Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'screen_away_crap',
+ "Reset away");
+ my ($server);
+ foreach $server (Irssi::servers()) {
+ if ($away{$server->{'tag'}} == 1) {
+ # user was already away, dont reset away
+ $away{$server->{'tag'}} = 0;
+ next;
+ }
+ $server->command("AWAY" . (($server->{chat_type} ne 'SILC') ? " -one" : "")) if ($server->{usermode_away});
+ if (defined($old_nicks{$server->{'tag'}}) and length($old_nicks{$server->{'tag'}}) > 0) {
+ # set old nick
+ $server->command("NICK " . $old_nicks{$server->{'tag'}});
+ $old_nicks{$server->{'tag'}} = "";
+ }
+ }
+ $away_status = $away;
+ }
+ }
+ # but everytimes install a new timer
+ register_screen_away_timer();
+ return 0;
+}
+
+# register_screen_away_timer()
+#
+# remove old timer and install a new one
+#
+# parameter:
+# none
+# return:
+# none
+sub register_screen_away_timer {
+ if (defined($timer_name)) {
+ # remove old timer, if defined
+ Irssi::timeout_remove($timer_name);
+ }
+ # add new timer with new timeout (maybe the timeout has been changed)
+ $timer_name = Irssi::timeout_add(Irssi::settings_get_int($IRSSI{'name'} . '_repeat') * 1000, 'screen_away', '');
+}
+
--- /dev/null
+use Irssi;
+use vars qw($VERSION %IRSSI);
+
+use LWP::UserAgent;
+my $ua = LWP::UserAgent->new;
+$ua->agent("SMSHi/1.0 ");
+
+$VERSION = "0.1";
+%IRSSI = (
+ authors => "John Runyon",
+ name => "smshi",
+ description => "send highlights via sms",
+ license => 'public domain',
+ url => 'https://github.com/zonidjan/irssi-scripts',
+ contact => 'https://github.com/zonidjan'
+);
+
+sub msg {
+ return unless Irssi::settings_get_bool('smshi_active');
+
+ my ($dest, $text, $stripped) = @_;
+# my ($server, $msg, $nick, $addr, $target) = @_;
+ my $server = $dest->{server};
+ return unless ($dest->{level} & MSGLEVEL_HILIGHT);
+ return if (!$server->{usermode_away} && Irssi::settings_get_bool('smshi_away_only'));
+
+# $text =~ s/\003\d{0,2}//g;
+# $text =~ s/\002|\037//g;
+# $text = substr($text, Irssi::settings_get_int('smshi_skip_first'));
+ my $msg = '';
+ for my $c (split //, $stripped) {
+ if (ord($c) > 31 && ord($c) < 127) {
+ $msg .= $c;
+ } else {
+ $msg .= '\\x'.sprintf("%02x", ord($c));
+ }
+ }
+
+ my $sms = $server->{tag}.$msg;
+
+ my $sid = Irssi::settings_get_str('smshi_sid');
+ my $token = Irssi::settings_get_str('smshi_token');
+ my $from = Irssi::settings_get_str('smshi_from');
+ my $to = Irssi::settings_get_str('smshi_to');
+
+ my $url = "https://$sid:$token\@api.twilio.com/2010-04-01/Accounts/$sid/Messages.json";
+ my $req = HTTP::Request->new('POST', $url);
+ $req->content_type('application/x-www-form-urlencoded');
+ $req->content("To=$to&From=$from&Body=$sms");
+
+ my $res = $ua->request($req);
+ if ($res->is_success) {
+ print "Good.";
+ } else {
+ print $req->url;
+ print $req->content;
+ print $res->status_line;
+ print $res->content;
+ }
+}
+
+Irssi::settings_add_bool('smshi', 'smshi_active', 0);
+Irssi::settings_add_bool('smshi', 'smshi_away_only', 1);
+Irssi::settings_add_str('smshi', 'smshi_sid', '');
+Irssi::settings_add_str('smshi', 'smshi_token', '');
+Irssi::settings_add_str('smshi', 'smshi_from', '');
+Irssi::settings_add_str('smshi', 'smshi_to', '');
+Irssi::settings_add_int('smshi', 'smshi_skip_first', 0);
+
+Irssi::signal_add('print text', 'msg');
+Irssi::print('%G>>%n '.$IRSSI{name}.' '.$VERSION.' loaded');
--- /dev/null
+use Irssi;
+use DBI;
+use URI::Find qw(find_uris);
+
+use strict;
+use warnings;
+use vars qw($VERSION %IRSSI $dbh);
+
+$VERSION = "0.1";
+%IRSSI = (
+ authors => "John Runyon",
+ name => "urllog",
+ description => "Log URLs to MySQL",
+ license => "public domain",
+ url => "https://github.com/zonidjan/irssi-scripts",
+ contact => "https://github.com/zonidjan"
+);
+
+our @MAPPING = split(//, 'abcdefghijklmnopqrstuvwxyz0123456789');
+
+
+our $INURLLOG = 0;
+
+sub urllog { our $INURLLOG; return if $INURLLOG; $INURLLOG = 1; _urllog(@_); $INURLLOG = 0; }
+sub _urllog {
+ my ($dest, $text, $stripped) = @_;
+ return if $stripped =~ /URL:/;
+
+ if (defined($dest->{server}) && defined($dest->{server}->{tag}) && defined($dest->{target}) && $dest->{server}->{tag} && $dest->{target}) {
+ my $output = '';
+ find_uris($stripped, sub { found_url($dest->{server}->{tag}, $dest->{target}, \$output, $stripped, @_); });
+ unless ($output eq '') {
+ $dest->{window}->print($text =~ s/%/%%/gr, $dest->{level});
+ Irssi::signal_stop();
+ if (lc($dest->{target}) eq '#minix') {
+ $dest->{window}->command("msg ".$dest->{target}." URL: ".$output);
+ } else {
+ $dest->{window}->print("URL: ".$output, $dest->{level});
+ }
+ }
+ }
+}
+
+sub found_url { # found_url($server_tag, $target_name, \$output_buffer, $full_line, @find_uris_callback_args)
+ my ($tag, $target, $output, $line, $uriobj, $url) = @_;
+ my $ignorechansre = Irssi::settings_get_str('ignore_chans_re');
+ return if
+ ($ignorechansre && $target =~ m/$ignorechansre/i)
+ or $url =~ m!://jfr\.im/u[0-9a-z]+!i
+ or $line =~ m!\] has quit \[.*?\Q$url\E.*?\]$!;
+ $dbh->do("INSERT INTO urls(server,target,url,fullline) VALUES (?,?,?,?)", undef, $tag, $target, $url, $line);
+ $$output .= "http://jfr.im/u".numtoalpha($dbh->last_insert_id((undef) x 4))." ";
+}
+
+sub numtoalpha {
+ my $num = shift;
+
+ our @MAPPING;
+ my $alpha = '';
+
+ while ($num > 0) {
+ $alpha = $MAPPING[$num % scalar @MAPPING].$alpha;
+ $num = int($num / scalar @MAPPING);
+ }
+ return $alpha;
+}
+
+
+Irssi::settings_add_str('urllog', 'db_dsn', 'DBI:mysql:urllog');
+Irssi::settings_add_str('urllog', 'db_username', 'urllog');
+Irssi::settings_add_str('urllog', 'db_password', '');
+Irssi::settings_add_str('urllog', 'ignore_chans_re', '');
+
+$dbh = DBI->connect(
+ Irssi::settings_get_str('db_dsn'),
+ Irssi::settings_get_str('db_username'),
+ Irssi::settings_get_str('db_password'),
+) or warn $DBI::errstr;
+
+
+Irssi::signal_add('print text', 'urllog');
+Irssi::print('%G>>%n '.$IRSSI{name}.' '.$VERSION.' loaded');
+
+
+__END__
+
+CREATE DATABASE `urllog`;
+CREATE TABLE `urllog`.`urls` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT PRIMARY KEY,
+ `server` varchar(25) NULL DEFAULT NULL,
+ `target` varchar(100) NULL DEFAULT NULL,
+ `nick` varchar(40) NULL DEFAULT NULL,
+ `url` text NOT NULL,
+ `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `fullline` text NOT NULL
+) CHARSET=utf8;
+GRANT INSERT ON `urllog`.`urls` TO 'urllog'@'localhost';
--- /dev/null
+CREATE TABLE `urls` (
+ `id` int(10) unsigned NOT NULL AUTO_INCREMENT,
+ `server` varchar(25) NOT NULL DEFAULT '<None>',
+ `target` varchar(100) NOT NULL DEFAULT '<Unknown>',
+ `nick` varchar(40) NOT NULL DEFAULT '<Unknown>',
+ `url` text NOT NULL,
+ `time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP,
+ `fullline` text NOT NULL,
+ PRIMARY KEY (`id`)
+) ENGINE=InnoDB AUTO_INCREMENT=10108 DEFAULT CHARSET=latin1;