html/shortenurl.pl
1 # shortenurl.pl v 0.7.1 by Marcin Ró¿ycki (derwan@irssi.pl)
2 #
3 # Usage:
4 # /shortenurl [url]
5 # /shortenurl -L
6 # /shortenurl [index]
7 #
8 # Settings:
9 # shortenurl_autoconvert_minlen [length]
10 # if shortenurl_autoconvert_minlen is greater than 0 and length of url is
11 # greater than shortenurl_autoconvert_minlen then link will be
12 # converted automaticaly
13 #
14 # Simultaneously there can be three links converted!
15 #
16 # Special thanks to Piotr Kucharski (Beeth) for changes in 42.pl/url/ service which
17 # made communication between script and web easier.
18 #
19
20
21 use strict;
22 use vars qw($VERSION %IRSSI);
23
24 use LWP::UserAgent;
25 use POSIX '_exit';
26 use IO::File;
27 use Irssi qw( command_bind version settings_add_int settings_get_int signal_add_last theme_register active_win );
28
29 $VERSION = '0.7.1';
30 %IRSSI = (
31 authors => 'Marcin Rozycki',
32 contact => 'derwan@irssi.pl',
33 name => 'shortenurl',
34 description => 'shortenurl',
35 license => 'GNU GPL v2',
36 url => 'http://derwan.irssi.pl',
37 changed => 'Sat Jun 26 19:17:02 CEST 2004',
38 );
39
40 our $agent = sprintf("Irssi %s ", version);
41 our $active = 0;
42 our $active_max = 3;
43 our @url = ();
44 our %tags = ();
45 our %cache = ();
46 our $maxlength = 0;
47
48 theme_register([
49 'shortenurl_url_list', '[%_$0%_] url %_$1%_ [by $2 ($3), $4 secs ago]',
50 'shortenurl_url_show', 'Shortened url $0 => %_$1%_',
51 'shortenurl_connect', 'Connecting to http://42.pl/url, this may take a while...',
52 'shortenurl_url_error', 'Cannot connect to http://42.pl/url service!'
53 ]);
54
55 sub shortenurl ($$$) {
56 my ($data, $server, $witem) = @_;
57 $witem = $server->window_item_find($1) if ( $data =~ s/^-w\s([^\s]+)\s// );
58 $witem = active_win() unless $witem;
59 if ( $data =~ /^-L/i ) {
60 my $time = time();
61 for (my $idx = 0; $idx <= $#url; $idx++) {
62 Irssi::printformat(MSGLEVEL_CLIENTCRAP, 'shortenurl_url_list', sprintf('%2d',($idx + 1)),
63 url2short($url[$idx]->[0]), $url[$idx]->[1], $url[$idx]->[2], ($time - $url[$idx]->[3]) );
64 }
65 return;
66 } elsif ( $data =~ m/^\d+$/ ) {
67 if ( my $url = $url[--$data] ) {
68 $server->command('shortenurl ' . $url->[0]);
69 } else {
70 Irssi::print("shortenurl: index too high", MSGLEVEL_CRAP);
71 }
72 return;
73 } elsif ( not $data ) {
74 Irssi::print('Usage: /shortenurl [url]', MSGLEVEL_CRAP);
75 Irssi::print('Usage: /shortenurl -L', MSGLEVEL_CRAP);
76 Irssi::print('Usage: /shortenurl [index]', MSGLEVEL_CRAP);
77 return;
78 }
79
80 my $url = $data;
81 $url =~ s/([^\w])/sprintf("%%%02X",ord($1))/ge;
82
83 my $hash = unpack('H*', $url);
84 if ( exists $cache{$hash} ) {
85 $witem->printformat(MSGLEVEL_CRAP, 'shortenurl_url_show', url2short($data), $cache{$hash});
86 return;
87 }
88
89 return if ( $active > $active_max );
90
91 my $reader = IO::File->new() or return;
92 my $writer = IO::File->new() or return;
93 pipe($reader, $writer);
94 my $pid = fork();
95
96 if ( $pid ) {
97 $active++;
98 close($writer);
99 Irssi::pidwait_add($pid);
100 $witem->printformat(MSGLEVEL_CRAP, 'shortenurl_connect');
101 $tags{$reader} = [ Irssi::input_add(fileno($reader), INPUT_READ, \&do_fork, $reader), $server->{tag}, $witem->{name} ];
102 } elsif ( defined $pid ) {
103 close($reader);
104 my $ua = new LWP::UserAgent;
105 $ua->agent($agent . $ua->agent);
106 my $request = new HTTP::Request GET => "http://42.pl/url/?auto=1&url=$url";
107 my $s = $ua->request($request);
108 my $content = $s->content();
109 my $buf = ( $content =~ m/(http\:\/\/[^\s]+)/ ) ? "$1 -- $hash -- $data\n" : 0;
110 print($writer "$buf\n");
111 close($writer);
112 POSIX::_exit(1);
113 } else {
114 close($reader);
115 close($writer);
116 Irssi::print("Cannot fork!");
117 }
118 }
119
120 sub url2short ($) {
121 my $url = shift;
122 my $length = length($url);
123 substr($url, 15, $length - 32) = '...' if ( $length - 32 > 0 );
124 return $url;
125 }
126
127 sub do_fork {
128 my $reader = shift();
129 my $data = <$reader>;
130 Irssi::input_remove($tags{$reader}->[0]);
131 close($reader);
132 my $server = Irssi::server_find_tag($tags{$reader}->[1]);
133 my $window = ( $server ) ? $server->window_item_find($tags{$reader}->[2]) : undef;
134 $tags{$reader} = ();
135 delete $tags{$reader};
136 $active--;
137 $window = active_win() unless $window;
138 if ( $data =~ m/(.*) -- (.*) -- (.*)/ ) {
139 $window->printformat(MSGLEVEL_CRAP, 'shortenurl_url_show', url2short($3), $1);
140 $cache{$2} = $1;
141 } else {
142 $window->printformat(MSGLEVEL_CRAP, 'shortenurl_url_error');
143 }
144 }
145
146 sub do_shortenurl ($$$$$) {
147 my ($server, $data, $who, $where, $winname) = @_;
148 while ( $data =~ m/((http|ftp|https):\/\/[^\s]+)/g ) {
149 my ($test, $url) = (0, $1);
150 $server->command(sprintf('shortenurl -w %s %s', $winname, $url)) if
151 ( $url !~ m/^http:\/\/42\.pl\/url/ and $maxlength > 0 and length($url) > $maxlength );
152 foreach my $u ( @url ) {
153 $test = 1, last if ( $u->[0] eq $url );
154 }
155 next if $test;
156 unshift @url, [ $url, $who, $where, time ];
157 $#url = 9 if ( $#url > 9 );
158 }
159 }
160
161 sub do_setup { $maxlength = settings_get_int('shortenurl_autoconvert_minlen'); };
162
163 command_bind('shortenurl', 'shortenurl');
164 command_bind('42.pl', 'shortenurl');
165 signal_add_last('message public' => sub { do_shortenurl($_[0], $_[1], $_[2], $_[4], $_[4]) });
166 signal_add_last('message private' => sub { do_shortenurl($_[0], $_[1], $_[2], $_[3], $_[2]) });
167 signal_add_last('setup changed', 'do_setup');
168 settings_add_int('misc', 'shortenurl_autoconvert_minlen', $maxlength);
169
170 do_setup();