Base, YouTube: add a function to decode URL query strings and make the Youtube grabbe...
[videosite.git] / videosite.pl
index 372e62b..d87b598 100644 (file)
@@ -22,7 +22,9 @@ use vars qw($VERSION %IRSSI);
 use XML::Simple;
 use Data::Dumper;
 use File::Spec;
+use File::Temp qw(tempfile);
 use BettIrssi 101 qw(_bcb _bcs);
+use LWP::UserAgent;
 
 my @grabbers;
 my @getters;
@@ -148,6 +150,67 @@ sub write_debug {
     }
 }
 
+sub expand_url_shortener {
+    my $s = shift;
+    my $os = '';
+    my @urlshortener = (
+        'is\.gd/[[:alnum:]]+',
+        'otf\.me/[[:alnum:]]+',
+        'hel\.me/[[:alnum:]]+',
+        '7ax\.de/[[:alnum:]]+',
+        'ow\.ly/[[:alnum:]]+',
+        'j\.mp/[[:alnum:]]+',
+        'bit\.ly/[[:alnum:]]+',
+        'tinyurl\.com/[[:alnum:]]+',
+        'pop\.is/[[:alnum:]]+',
+        'post\.ly/[[:alnum:]]+',
+        '1\.ly/[[:alnum:]]+',
+        '2\.ly/[[:alnum:]]+',
+        't\.co/[[:alnum:]]+',
+        'shar\.es/[[:alnum:]]+',
+        'goo\.gl/[[:alnum:]]+',
+        );
+    my $ua = LWP::UserAgent->new(agent => 'Mozilla', max_redirect => 0);
+    my $i = 10;
+
+    OUTER: while (($os ne $s) and ($i > 0)) {
+        study($s);
+        $os = $s;
+        $i--;
+
+        foreach my $pattern (@urlshortener) {
+            my $p = "https?:\/\/" . $pattern;
+
+            write_debug("Matching %s against %s", $p, $s);
+            if ($s =~ m|($p)|) {
+                my $matched = $1;
+                my $res;
+
+                write_debug("Found %s", $matched);
+                $res = $ua->head($matched);
+                if ($res->is_redirect()) {
+                    my $new = $res->headers()->header("Location");
+
+                    write_debug("Replacing %s with %s", $matched, $new);
+                    $s =~ s/$matched/$new/;
+                    next OUTER;
+                } else {
+                    write_debug("Error resolving %s", $matched);
+                }
+            }
+        }
+    }
+
+    if ($i == 0) {
+        write_debug("Loop terminated by counter");
+    }
+
+    write_debug("Final string: %s", $s);
+
+    return $s;
+}
+
+
 sub check_for_link {
     my $event = shift;
     my $message = $event->message();
@@ -163,11 +226,12 @@ sub check_for_link {
     }
 
     push_output($event->ewpf);
+    $message = expand_url_shortener($message);
 
     study($message);
 
     # Offer the message to all Grabbers in turn
-    foreach $g (@grabbers) {
+    GRABBER: foreach $g (@grabbers) {
         ($m, $p) = $g->get($message);
         while (defined($m)) {
             write_debug('Metadata: %s', Dumper($m));
@@ -186,6 +250,7 @@ sub check_for_link {
             # more!)
             $message =~ s/$p//;
             study($message);
+            last GRABBER if ($message =~ /^\s*$/);
 
             ($m, $p) = $g->get($message);
         }
@@ -196,10 +261,12 @@ sub check_for_link {
 
 sub cmd_save {
 
+
     eval {
-        open(CONF, '>'.$conffile) or die 'Could not open config file';
-        print CONF XML::Simple::XMLout($conf, KeepRoot => 1, KeyAttr => {'config' => 'module', 'option' => 'key'});
-        close(CONF);
+        my ($tempfile, $tempfn) = tempfile("videosite.xml.XXXXXX", dir => Irssi::get_irssi_dir());
+        print $tempfile XML::Simple::XMLout($conf, KeepRoot => 1, KeyAttr => {'config' => 'module', 'option' => 'key'});
+        close($tempfile);
+        rename($tempfn, $conffile);
     };
     if ($@) {
         write_irssi('Could not save config to %s: %s', ($conffile, $@));