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 21use strict; 22use vars qw($VERSION %IRSSI); 23 24use LWP::UserAgent; 25use POSIX '_exit'; 26use IO::File; 27use 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 40our $agent = sprintf("Irssi %s ", version); 41our $active = 0; 42our $active_max = 3; 43our @url = (); 44our %tags = (); 45our %cache = (); 46our $maxlength = 0; 47 48theme_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 55sub 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 120sub 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 127sub 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 146sub 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 161sub do_setup { $maxlength = settings_get_int('shortenurl_autoconvert_minlen'); }; 162 163command_bind('shortenurl', 'shortenurl'); 164command_bind('42.pl', 'shortenurl'); 165signal_add_last('message public' => sub { do_shortenurl($_[0], $_[1], $_[2], $_[4], $_[4]) }); 166signal_add_last('message private' => sub { do_shortenurl($_[0], $_[1], $_[2], $_[3], $_[2]) }); 167signal_add_last('setup changed', 'do_setup'); 168settings_add_int('misc', 'shortenurl_autoconvert_minlen', $maxlength); 169 170do_setup(); 171