1# Show IRC gallery (http://irc-galleria.net, finnish only) information
2# on /WHOIS or /GALLERY
3
4# version 1.13
5# for irssi 0.8.0 by Timo Sirainen
6use strict;
7use Symbol;
8use vars qw($VERSION %IRSSI);
9$VERSION = "1.13";
10%IRSSI = (
11    authors	=> "Timo \'cras\' Sirainen",
12    contact	=> "tss\@iki.fi",
13    name	=> "ircgallery",
14    description	=> "Show IRC gallery (http://irc-galleria.net, finnish only) information on /WHOIS or /GALLERY",
15    license	=> "Public Domain",
16    url		=> "http://irssi.org/",
17    changed	=> "2002-03-04T22:47+0100"
18);
19
20
21Irssi::theme_register([
22  'whois_gallery', '{whois gallery $1}',
23  'gallery_header', '{hilight $0} - IRC gallery information',
24  'gallery_line', ' $[8]0 : $1',
25  'gallery_footer', 'End of info',
26  'gallery_notfound', '$0 is not in IRC gallery',
27  'gallery_nolist', 'Nick list of IRC gallery not downloaded yet - please wait'
28]);
29
30
31my $cache_path = glob "~/.irssi/ircgallery";
32my @print_queue;
33
34my $nicklist_path = "$cache_path/nicks.list";
35my $gallery_nicks_time = 0;
36my %gallery_nicks = {};
37
38my $last_whois_nick;
39
40sub get_view_url {
41  return 'http://irc-galleria.net/view.php?nick='.$_[0];
42}
43
44# print the gallery information - assumes the file is in cache directory
45sub print_gallery {
46  my %print_notfound;
47  my $nick = shift;
48
49  my $found = 0;
50  my $next_channels = 0;
51  my $channels;
52
53  local $/ = "\n";
54  my $f = gensym;
55  if (!open($f, "<", "$cache_path/$nick")) {
56    Irssi::print("Couldn't open file $cache_path/$nick: $!", MSGLEVEL_CLIENTERROR);
57    return;
58  }
59  while (<$f>) {
60    last if (/\<title\>.*Etsi nick/); # unknown nick
61
62    if ($next_channels) {
63      if (m,\<a .*\>(#.*)\</a>,) {
64        $channels .= "$1 ";
65        next;
66      } else {
67        $next_channels = 0;
68        if ($channels) {
69          Irssi::printformat(MSGLEVEL_CRAP, 'gallery_line',
70		"channels", $channels);
71	  $channels = "";
72	}
73      }
74    }
75
76    if (/\<h1\>[^\(]*\(([^\)]*)/) {
77      my $realname = $1;
78      Irssi::printformat(MSGLEVEL_CRAP, 'gallery_header', $nick);
79      Irssi::printformat(MSGLEVEL_CRAP, 'gallery_line',
80                "ircname", $realname);
81      Irssi::printformat(MSGLEVEL_CRAP, 'gallery_line',
82		"url", get_view_url($nick));
83      $found = 1;
84      next;
85    }
86
87    if (/\<img.*src="([^"]*)".*alt="$nick"/) {
88      Irssi::printformat(MSGLEVEL_CRAP, 'gallery_line',
89		"image", "http://irc-galleria.net/$1");
90      next;
91    }
92
93    my ($title, $value) = $_ =~ m,\<span class="otsikko"\>([^:]+):\</span\> (.*)\<br /\>,;
94    if ($value =~ m,\<a .*\>(.*)\</a\>,) {
95      $value = $1;
96    }
97    $next_channels = 1 if (m,\<span class="otsikko"\>Kanavat,);
98
99    if ($title && $value) {
100      if ($title eq "Maili") {
101        $title = "e-mail";
102      } elsif ($title =~ /Kaupunki/) {
103        $title = "city";
104      } elsif ($title eq "Syntynyt") {
105        $title = "birthday";
106      } elsif ($title eq "Muutettu") {
107        $title = "last modified";
108      }
109      Irssi::printformat(MSGLEVEL_CRAP, 'gallery_line', $title, $value);
110    }
111  }
112  close($f);
113
114  if ($found) {
115    Irssi::printformat(MSGLEVEL_CRAP, 'gallery_footer', $nick);
116  } elsif ($print_notfound{$nick}) {
117    Irssi::printformat(MSGLEVEL_CRAP, 'gallery_notfound', $nick);
118  }
119
120  delete $print_notfound{$nick};
121}
122
123# download the info from gallery to cache dir,
124# if the files aren't there already.
125sub download_nicks_info {
126  foreach my $nick (@_) {
127    my $filename = "$cache_path/$nick";
128    if (! -f $filename) {
129      # FIXME: we could do this ourself with sockets...
130      Irssi::command("exec - wget -O$filename.tmp -q -UMozilla ".get_view_url($nick)."; mv $filename.tmp $filename");
131    }
132  }
133}
134
135# print info from all given nicks that have file in cache dir
136sub gallery_show {
137  foreach my $nick (@_) {
138    if (-f "$cache_path/$nick") {
139      print_gallery($nick);
140    } else {
141      push @print_queue, $nick;
142    }
143  }
144}
145
146sub print_whois_gallery {
147  my ($server, $nick) = @_;
148
149  if ($gallery_nicks{lc $nick}) {
150    $server->printformat($nick, MSGLEVEL_CRAP, 'whois_gallery',
151			 $nick, get_view_url($nick));
152  }
153}
154
155# /WHOIS - print the gallery URL after realname
156sub event_whois {
157  my ($server, $data) = @_;
158  my ($temp, $nick) = split(" ", $data);
159
160  print_whois_gallery($server, $last_whois_nick) if ($last_whois_nick);
161  $last_whois_nick = $nick;
162}
163
164sub event_end_of_whois {
165  my ($server) = @_;
166
167  if ($last_whois_nick) {
168    print_whois_gallery($server, $last_whois_nick);
169    $last_whois_nick = undef;
170  }
171}
172
173# /GALLERY <nicks>
174sub cmd_gallery {
175  my @nicks = split(/[, ]/, $_[0]);
176
177  if (!$gallery_nicks_time) {
178    Irssi::printformat(MSGLEVEL_CLIENTERROR, 'gallery_nolist');
179    return;
180  }
181
182  my @new_list;
183  foreach my $nick (@nicks) {
184    my $gallery_nick = $gallery_nicks{lc $nick};
185    if (!$gallery_nick) {
186      Irssi::printformat(MSGLEVEL_CRAP, 'gallery_notfound', $nick);
187    } else {
188      push @new_list, $gallery_nick;
189    }
190  }
191
192  download_nicks_info(@new_list);
193  gallery_show(@new_list);
194
195  if ($gallery_nicks_time < time()-(3600*8)) {
196    # nicklist hasn't been updated for a while, refresh it
197    download_nicklist();
198  }
199}
200
201# parse all known nicks from nick index file
202sub parse_nicks {
203  my $filename = shift;
204
205  %gallery_nicks = {};
206  $gallery_nicks_time = time();
207
208  my $f = gensym;
209  if (!open($f, "<", $filename)) {
210    Irssi::print("Couldn't open file $filename: $!", MSGLEVEL_CLIENTERROR);
211    return;
212  }
213  while (<$f>) {
214    if (m,\<a href="view.php.*\>(.*)\</a\>,) {
215      $gallery_nicks{lc $1} = $1;
216    }
217  }
218  close($f);
219}
220
221# /EXEC finished - maybe there's new files downloaded in cache dir?
222sub sig_exec_remove {
223  my @new_queue;
224
225  if (-f $nicklist_path) {
226    parse_nicks($nicklist_path);
227    unlink($nicklist_path);
228  }
229
230  foreach my $nick (@print_queue) {
231    if (-f "$cache_path/$nick") {
232      print_gallery($nick);
233    } else {
234      push @new_queue, $nick;
235    }
236  }
237  @print_queue = @new_queue;
238}
239
240sub download_nicklist {
241  Irssi::command("exec - wget -O$nicklist_path -q -UMozilla http://irc-galleria.net/list.php?letter=_");
242}
243
244# clear cache dir
245if (-d $cache_path) {
246  unlink(<$cache_path/*>);
247} else {
248  mkdir($cache_path, 0700) || die "Can't create cache directory $cache_path";
249}
250
251# we need the nick list, get it once per hour
252download_nicklist();
253
254Irssi::signal_add_first('event 311', 'event_whois');
255Irssi::signal_add_first('event 318', 'event_end_of_whois');
256Irssi::signal_add('exec remove', 'sig_exec_remove');
257Irssi::command_bind('gallery', 'cmd_gallery');
258