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
47my $SOUND_PLAYER = "play";
48my $SOUND_PRIVATE_MSG = "/usr/local/share/centericq/msg.wav";
49
50sub event_message_private {
51    my ($server, $msg, $nick, $address) = @_;
52
53    # my $tooltip = "MSG: $nick($address): $msg";
54    my $tooltip = "MSG: $nick($address)";
55
56    if (Irssi::settings_get_bool("traylet_active") &&
57        (time() - $LAST_MSG_PRIVATE_TIME >= 2 || $tooltip ne $LAST_MSG_CONTENT)) {
58        &traylet_notify($TRAYLET_PRIVATE_MSG, $tooltip);
59        $LAST_MSG_PRIVATE_TIME = time();
60        $LAST_MSG_CONTENT = $tooltip;
61
62        # sound
63        system("$SOUND_PLAYER $SOUND_PRIVATE_MSG 2>/dev/null");
64    }
65}
66
67sub event_message_public {
68    my ($server, $msg, $nick, $address, $target) = @_;
69
70    if (Irssi::settings_get_bool("traylet_active")) {
71        my $hilight_regexp = Irssi::settings_get_str("traylet_hilight_regexp");
72        if (length($hilight_regexp) > 0 && $msg =~ /$hilight_regexp/i) {
73            # my $tooltip = "HILIGHT: $nick($address): $target [$msg]";
74            my $tooltip = "HILIGHT: $nick($address): $target";
75            &traylet_notify($TRAYLET_HILIGHT_CHANNEL, $tooltip);
76        }
77    }
78}
79
80sub event_topic {
81    my ($server, $channel, $topic, $nick, $address) = @_;
82
83    if (Irssi::settings_get_bool("traylet_active")) {
84        my $tooltip = "TOPIC: $nick($address): $channel [$topic]";
85        &traylet_notify($TRAYLET_TOPIC, $tooltip);
86    }
87}
88
89sub in_watch {
90    my ($nick, $tray_ref) = @_;
91
92    my @watch_nicks = split(/\s+/, Irssi::settings_get_str("traylet_watch_nicks"));
93    my $traylet = undef;
94    foreach my $watch (@watch_nicks) {
95        if ($watch =~ /(.+):(\d+)/) {
96            $watch = $1;
97            $traylet = $2;
98        }
99
100        if ($nick =~ /$watch.*/i) {
101            if (defined($traylet)) {
102                ${$tray_ref} = "$BASEDIR/$traylet";
103            }
104            return 1;
105        }
106    }
107
108    return 0;
109}
110
111sub event_join {
112    my ($server, $channel, $nick, $address) = @_;
113
114    if (Irssi::settings_get_bool("traylet_active")) {
115        my $traylet = undef;
116        if (&in_watch($nick, \$traylet)) {
117            my $tooltip = "JOIN: $nick($address): $channel";
118            &traylet_notify($traylet, $tooltip);
119        }
120    }
121}
122
123sub event_part {
124    my ($server, $channel, $nick, $address, $reason) = @_;
125
126    if (Irssi::settings_get_bool("traylet_active")) {
127        my $traylet = undef;
128        if (&in_watch($nick, \$traylet)) {
129            my $tooltip = "PART: $nick($address) $channel [$reason]";
130            &traylet_notify($traylet, $tooltip);
131        }
132    }
133}
134
135sub event_quit {
136    my ($server, $nick, $address, $reason) = @_;
137
138    if (Irssi::settings_get_bool("traylet_active")) {
139        my $traylet = undef;
140        if (&in_watch($nick, \$traylet)) {
141            my $tooltip = "QUIT: $nick($address) $reason";
142            &traylet_notify($traylet, $tooltip);
143        }
144    }
145}
146
147sub event_kick {
148    my ($server, $channel, $nick, $kicker, $address, $reason) = @_;
149
150    if (Irssi::settings_get_bool("traylet_active")) {
151        my $traylet = undef;
152        if (&in_watch($nick, \$traylet)) {
153            my $tooltip = "KICK: $nick($address) $channel [$kicker\:$reason]";
154            &traylet_notify($traylet, $tooltip);
155        }
156    }
157}
158
159sub event_nl_joined {
160    my ($server, $nick, $user, $host, $realname, $awaymsg) = @_;
161
162    if (Irssi::settings_get_bool("traylet_active")) {
163        my $traylet = undef;
164        if (&in_watch($nick, \$traylet)) {
165            my $tooltip = "IRC JOIN: $nick($user\@$host) $realname";
166            &traylet_notify($traylet, $tooltip);
167        }
168    }
169}
170
171sub traylet_notify {
172    my ($traylet, $tooltip) = @_;
173    my $unique_filename = sprintf("%d.%d.%d", time(), $$, int(rand(999999)));
174    my $traylet_filename = "$traylet/$unique_filename";
175    if (! open(TRAYLET, ">$traylet_filename")) {
176        &error("Cannot write to traylet file ($traylet_filename): $!");
177    }
178    print TRAYLET "$tooltip\n";
179    if (! close(TRAYLET)) {
180        &error("Cannot close traylet file ($traylet_filename): $!");
181    }
182}
183
184sub error {
185    my ($msg) = @_;
186    Irssi::print("Traylet notify error: $msg");
187}
188
189Irssi::settings_add_str("misc", "traylet_watch_nicks", "");
190Irssi::settings_add_str("misc", "traylet_hilight_regexp", "");
191Irssi::settings_add_bool("misc", "traylet_active", 1);
192
193Irssi::signal_add("message private", "event_message_private");
194Irssi::signal_add("message join", "event_join");
195Irssi::signal_add("message part", "event_part");
196Irssi::signal_add("message kick", "event_kick");
197Irssi::signal_add("message quit", "event_quit");
198Irssi::signal_add("message topic", "event_topic");
199Irssi::signal_add("message public", "event_message_public");
200
201Irssi::signal_add("notifylist joined", "event_nl_joined");
202