#!/usr/bin/perl
use strict;
use IO::Socket::INET;
use Irssi;

my $VERSION = '0.31';
# changelog:
# 0.31, 2009-10-15:
#  * formatting...
# 0.3:
#  * set the message level to CLIENTCRAP and put the text 
#         "youtube:" in yellow colour. 
# 0.21:
#  * whoa, fucked up bug. 
#         http://www.youtube.com/watch?hl=en&v=tqZiY2RdoO4&gl=US 
#         was posted to a channel, and my script got fucked up. 
#         it printed the title of the video ~5 times a second, 
#         until i checked irssi and had to kill the whole client.
#         Anyways, it could have to do with the weird order 
#         of the query string, which is not to say that it's not 
#         my fault - 1. i should handle it, and 2. i should not 
#         fuck up irssi. What I did wrong was to check for one 
#         regexp, and when found remove another regexp - i should 
#         have deleted the same regexp, which i do now. 
#
# 0.2:
#  * regexp didn't match all youtube videos. if you have a 
#         variable in the query string before the v, it will not 
#         find it. And i also found out that all vs isn't 11 
#         characters.

my %IRSSI = (
    authors     => 'Olof Johansson',
    contact     => 'zibri@ethup.se',
    name        => 'youtube-title',
    description => 'prints the title of a youtube video automatically',
    license     => 'BSD',
);

#does the message contain youtube.com/watch?v=<video id>?
sub isutube {
  my($server, $msg, $nick, $address, $target) = @_;
  $target=$nick if $target eq undef;
  
  # for each link to youtube.com/watch?v=... print the title
  # example: http://www.youtube.com/watch?v=59FCAYKyR00
  my $i = 0;
  my $announced = 0;
  while($i++ <= 3 && 
        $msg=~ m"(?:http://|www\.|http://www\.)(youtube\.com/watch\?\S*v=|youtu\.be/)([^\s&\?\.,!]{11})"x ) {
    my $title = get_title($2) if($2 ne undef);
    my $id = $2;
    
    if($title ne undef) {
      # Decode html entities. If more are 
      # needed - i.e are shown as &foo; when 
      # printed in irssi - open a ticket at
      # http://stdlib.se/cgi-bin/bts.cgi
      $title =~ s/&amp;/&/;
      $title =~ s/&lt;/</;
      $title =~ s/&gt;/>/;

      if ((lc $target eq "#mychannel2") or (lc $target eq "#orthischannel") or (lc $target eq "#orthisone") or (lc $target eq "#mychannel1") or (($announced == 0) and (lc $target eq "#foo"))) {
        $announced = 1;
        $server->command("msg $target youtube $id : $title");
      } else {
        $server->window_item_find($target)->print("youtube: $title", MSGLEVEL_CLIENTCRAP);
      }
    }

    $msg =~ s"(?:http://|www\.|http://www\.)(youtube\.com/watch\?\S*v=|youtu\.be/)[^\s&\?\.,!]{11}""x;
  }
}

# extract title using youtube api
# http://code.google.com/apis/youtube/2.0/developers_guide_protocol.html
sub get_title {
  return eval {
    my($vid)=@_;
    my $tries = 10;
    
    my $sock = undef;
    while ($sock eq undef && $tries-- > 0) {
      $sock = IO::Socket::INET->new( 
        PeerAddr=>'gdata.youtube.com',
        PeerPort=>'http(80)',
        Proto=>'tcp',
        Timeout=>'2500',
      );
    }
    
    my $req="GET /feeds/api/videos/$vid HTTP/1.0\r\n";
    $req.="host: gdata.youtube.com\r\n";
    $req.="user-agent: internets\r\n";
    $req.="\r\n";
    
    print $sock $req;
    while(<$sock>) {
      if(/<media:title type='plain'>(.*)<\/media:title>/) {
        close $sock;
        return $1;
      }
    }
    return undef;
  };
  
}

Irssi::signal_add("message public", \&isutube);
#Irssi::signal_add("message private", \&isutube);

