1#!/usr/bin/perl
2
3# Notification script for irssi and gkrellm-trayicons.
4#
5#   mkdir ~/.trayicons
6#
7#   mkdir ~/.trayicons/1
8#   mkdir ~/.trayicons/2
9#   mkdir ~/.trayicons/3
10#   ...
11#
12# Configure gkrellm-trayicons to use ~/.trayicons/X as
13# activation directories.
14#
15# Example irssi settings:
16#
17#   traylet_active = ON
18#   traylet_hilight_regexp = peter.*|george.*
19#   traylet_watch_nicks = thomas:2 simon:2 alice:3 michael:3 john:4
20#
21# Author:
22# Tomas Styblo <tripie@cpan.org>
23
24use strict;
25use Irssi;
26use Irssi::Irc;
27use Data::Dumper;
28
29use vars qw($VERSION %IRSSI);
30$VERSION = "0.2";
31%IRSSI = (
32    authors => 'Tomas Styblo',
33    contact => 'tripie@cpan.org',
34    name => 'trayicons notify script',
35    name => 'trayicons notify script',
36    licence => 'GPL',
37);
38
39my $BASEDIR = $ENV{"HOME"}."/.trayicons/";
40my $TRAYLET_PRIVATE_MSG = "$BASEDIR/1";
41my $TRAYLET_HILIGHT_CHANNEL = "$BASEDIR/1";
42my $TRAYLET_TOPIC = "$BASEDIR/2";
43
44my $LAST_MSG_PRIVATE_TIME = time();
45my $LAST_MSG_CONTENT = "";
46
47sub event_message_private {
48    my ($server, $msg, $nick, $address) = @_;
49
50    # my $tooltip = "MSG: $nick($address): $msg";
51    my $tooltip = "MSG: $nick($address)";
52
53    if (Irssi::settings_get_bool("traylet_active") &&
54        (time() - $LAST_MSG_PRIVATE_TIME >= 2 || $tooltip ne $LAST_MSG_CONTENT)) {
55        &traylet_notify($TRAYLET_PRIVATE_MSG, $tooltip);
56        $LAST_MSG_PRIVATE_TIME = time();
57        $LAST_MSG_CONTENT = $tooltip;
58    }
59}
60
61sub event_message_public {
62    my ($server, $msg, $nick, $address, $target) = @_;
63
64    if (Irssi::settings_get_bool("traylet_active")) {
65        my $hilight_regexp = Irssi::settings_get_str("traylet_hilight_regexp");
66        if (length($hilight_regexp) > 0 && $msg =~ /$hilight_regexp/i) {
67            # my $tooltip = "HILIGHT: $nick($address): $target [$msg]";
68            my $tooltip = "HILIGHT: $nick($address): $target";
69            &traylet_notify($TRAYLET_HILIGHT_CHANNEL, $tooltip);
70        }
71    }
72}
73
74sub event_topic {
75    my ($server, $channel, $topic, $nick, $address) = @_;
76
77    if (Irssi::settings_get_bool("traylet_active")) {
78        my $tooltip = "TOPIC: $nick($address): $channel [$topic]";
79        &traylet_notify($TRAYLET_TOPIC, $tooltip);
80    }
81}
82
83sub in_watch {
84    my ($nick, $tray_ref) = @_;
85
86    my @watch_nicks = split(/\s+/, Irssi::settings_get_str("traylet_watch_nicks"));
87    my $traylet = undef;
88    foreach my $watch (@watch_nicks) {
89        if ($watch =~ /(.+):(\d+)/) {
90            $watch = $1;
91            $traylet = $2;
92        }
93
94        if ($nick =~ /$watch.*/i) {
95            if (defined($traylet)) {
96                ${$tray_ref} = "$BASEDIR/$traylet";
97            }
98            return 1;
99        }
100    }
101
102    return 0;
103}
104
105sub event_join {
106    my ($server, $channel, $nick, $address) = @_;
107
108    if (Irssi::settings_get_bool("traylet_active")) {
109        my $traylet = undef;
110        if (&in_watch($nick, \$traylet)) {
111            my $tooltip = "JOIN: $nick($address): $channel";
112            &traylet_notify($traylet, $tooltip);
113        }
114    }
115}
116
117sub event_part {
118    my ($server, $channel, $nick, $address, $reason) = @_;
119
120    if (Irssi::settings_get_bool("traylet_active")) {
121        my $traylet = undef;
122        if (&in_watch($nick, \$traylet)) {
123            my $tooltip = "PART: $nick($address) $channel [$reason]";
124            &traylet_notify($traylet, $tooltip);
125        }
126    }
127}
128
129sub event_quit {
130    my ($server, $nick, $address, $reason) = @_;
131
132    if (Irssi::settings_get_bool("traylet_active")) {
133        my $traylet = undef;
134        if (&in_watch($nick, \$traylet)) {
135            my $tooltip = "QUIT: $nick($address) $reason";
136            &traylet_notify($traylet, $tooltip);
137        }
138    }
139}
140
141sub event_kick {
142    my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
143
144    if (Irssi::settings_get_bool("traylet_active")) {
145        my $traylet = undef;
146        if (&in_watch($nick, \$traylet)) {
147            my $tooltip = "KICK: $nick($address) $channel [$kicker\:$reason]";
148            &traylet_notify($traylet, $tooltip);
149        }
150    }
151}
152
153sub event_nl_joined {
154    my ($server, $nick, $user, $host, $realname, $awaymsg) = @_;
155
156    if (Irssi::settings_get_bool("traylet_active")) {
157        my $traylet = undef;
158        if (&in_watch($nick, \$traylet)) {
159            my $tooltip = "IRC JOIN: $nick($user\@$host) $realname";
160            &traylet_notify($traylet, $tooltip);
161        }
162    }
163}
164
165sub traylet_notify {
166    my ($traylet, $tooltip) = @_;
167    my $unique_filename = sprintf("%d.%d.%d", time(), $$, int(rand(999999)));
168    my $traylet_filename = "$traylet/$unique_filename";
169    if (! open(TRAYLET, ">$traylet_filename")) {
170        &error("Cannot write to traylet file ($traylet_filename): $!");
171    }
172    print TRAYLET "$tooltip\n";
173    if (! close(TRAYLET)) {
174        &error("Cannot close traylet file ($traylet_filename): $!");
175    }
176}
177
178sub error {
179    my ($msg) = @_;
180    Irssi::print("Traylet notify error: $msg");
181}
182
183Irssi::settings_add_str("misc", "traylet_watch_nicks", "");
184Irssi::settings_add_str("misc", "traylet_hilight_regexp", "");
185Irssi::settings_add_bool("misc", "traylet_active", 1);
186
187Irssi::signal_add("message private", "event_message_private");
188Irssi::signal_add("message join", "event_join");
189Irssi::signal_add("message part", "event_part");
190Irssi::signal_add("message kick", "event_kick");
191Irssi::signal_add("message quit", "event_quit");
192Irssi::signal_add("message topic", "event_topic");
193Irssi::signal_add("message public", "event_message_public");
194
195Irssi::signal_add("notifylist joined", "event_nl_joined");
196