From 873305205fd6f7f559595ac70b71e5924c6ef0e0 Mon Sep 17 00:00:00 2001
From: Alexandre Morignot <erdnaxeli@cervoi.se>
Date: Thu, 31 Mar 2016 23:30:31 +0200
Subject: [PATCH] A module can now precise the external_id (the source'id)
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

If the external id is precised, it will be used to dynamically retrieves
the URL when printing this content. This is useful for some source that
change the content's URL (like soundcloud).

Fuck soundcloud.
---
 PlayBot/commands/get.pm     |  2 ++
 PlayBot/sites.pm            | 39 +++++++++++++++++----------------
 PlayBot/sites/soundcloud.pm | 19 ++++++++++++++++
 PlayBot/utils/db/get.pm     | 10 ++++-----
 PlayBot/utils/print.pm      | 43 ++++++++++++++++++++++++++-----------
 5 files changed, 78 insertions(+), 35 deletions(-)

diff --git a/PlayBot/commands/get.pm b/PlayBot/commands/get.pm
index 133e6cf..1cf5702 100644
--- a/PlayBot/commands/get.pm
+++ b/PlayBot/commands/get.pm
@@ -90,6 +90,8 @@ sub exec {
     $content_h{'title'} = $content->[2];
     $content_h{'url'} = $content->[3];
     $content_h{'duration'} = $content->[4];
+    $content_h{'external_id'} = $content->[5];
+    $content_h{'site'} = $content->[6];
     $content_h{'tags'} = \@tags;
 
     my $irc_msg = PlayBot::utils::print::print(\%content_h);
diff --git a/PlayBot/sites.pm b/PlayBot/sites.pm
index 369fa06..9c2fa4b 100644
--- a/PlayBot/sites.pm
+++ b/PlayBot/sites.pm
@@ -95,12 +95,12 @@ sub insert_content
 		$log->error("Couldn't prepare querie; aborting") unless (defined $sth);
 
 		$sth->execute(
-            $content->{'site'},
-            $content->{'url'},
-            $content->{'author'},
-            $content->{'title'},
-            $content->{'duration'},
-            $content->{'playlist'},
+            $content->{site},
+            $content->{url},
+            $content->{author},
+            $content->{title},
+            $content->{duration},
+            $content->{playlist},
         );
     };
     if ($@) {
@@ -108,19 +108,21 @@ sub insert_content
         $new = 0;
 
         my $sth = $dbh->prepare('
-            UPDATE playbot playbot SET
+            UPDATE playbot SET
             sender = ?,
             title = ?,
-            duration = ?
+            duration = ?,
+            external_id = ?
             WHERE url = ?
         ');
 		$log->error("Couldn't prepare querie; aborting") unless (defined $sth);
 
 		$sth->execute(
-            $content->{'author'},
-            $content->{'title'},
-            $content->{'duration'},
-            $content->{'url'},
+            $content->{author},
+            $content->{title},
+            $content->{duration},
+            $content->{external_id},
+            $content->{url},
         );
     }
 
@@ -128,7 +130,7 @@ sub insert_content
 	my $sth = $dbh->prepare('SELECT id FROM playbot WHERE url = ?');
 	$log->error("Couldn't prepare querie; aborting") unless (defined $sth);
 
-	$sth->execute($content->{'url'})
+	$sth->execute($content->{url})
         or $log->error("Couldn't finish transaction: " . $dbh->errstr);
 
 	$id = $sth->fetch->[0];
@@ -184,15 +186,16 @@ sub insert_content
 
     if ($new) {
         # schedule download
-        $kernel->post('downloader' => 'ddl' => $id, $content->{url});
+        $kernel->post(downloader => ddl => $id, $content->{url});
 
-        $content->{'id'} = '+'.$id;
+        $content->{id} = '+'.$id;
     }
     else {
-        $content->{'id'} = $id;
+        $content->{id} = $id;
     }
-    $content->{'tags'} = \@tags;
-    delete $content->{'url'};
+    $content->{tags} = \@tags;
+    delete $content->{url};
+    delete $content->{external_id};
 
     if (not $playlist)
     {
diff --git a/PlayBot/sites/soundcloud.pm b/PlayBot/sites/soundcloud.pm
index 7224e4b..cb2f659 100644
--- a/PlayBot/sites/soundcloud.pm
+++ b/PlayBot/sites/soundcloud.pm
@@ -33,6 +33,7 @@ sub get {
 	my $content = decode_json($response->decoded_content);
     my $infos = {
 	    author      => $content->{'user'}->{'username'},
+        external_id => $content->{'id'},
         duration    => $content->{'duration'} / 1000,
         site        => 'soundcloud',
         title       => $content->{'title'},
@@ -46,4 +47,22 @@ sub get {
 	return %{ $infos };
 }
 
+
+sub get_url
+{
+    shift;
+    my $id = shift;
+
+	my $ua = LWP::UserAgent->new(
+        timeout => 30,
+        env_proxy   => 1,
+    );
+
+	my $response = $ua->get($root.'/tracks/'.$id.'?client_id='.$clientId);
+	die($response->status_line) unless ($response->is_success);
+
+	my $content = decode_json($response->decoded_content);
+    return $content->{permalink_url};
+}
+
 1;
diff --git a/PlayBot/utils/db/get.pm b/PlayBot/utils/db/get.pm
index a0ceb9d..305135a 100644
--- a/PlayBot/utils/db/get.pm
+++ b/PlayBot/utils/db/get.pm
@@ -131,7 +131,7 @@ sub _prepare_request {
     }
 
     if ($query->id >= 0) {
-        $req = 'select p.id, p.sender, p.title, p.url, p.duration';
+        $req = 'select p.id, p.sender, p.title, p.url, p.duration, p.external_id, p.type';
         $req .= ' from playbot p where id = ?';
 
         @args = ($query->id);
@@ -146,7 +146,7 @@ sub _prepare_request {
         my $where = join ' and ' => @where;
 
         if ($query->is_global) {
-            $req = 'select p.id, p.sender, p.title, p.url, p.duration';
+            $req = 'select p.id, p.sender, p.title, p.url, p.duration, p.external_id, p.type';
             $req .= ' from playbot p where '.$where;
             $req .= ' and '.$words_sql if ($words_sql);
             $req .= ' and p.playlist is false';
@@ -155,7 +155,7 @@ sub _prepare_request {
             @args = (@{$query->tags}, @words_param);
         }
         else {
-            $req = 'select p.id, p.sender, p.title, p.url, p.duration';
+            $req = 'select p.id, p.sender, p.title, p.url, p.duration, p.external_id, p.type';
             $req .= ' from playbot p join playbot_chan pc on p.id = pc.content';
             $req .= ' where '.$where;
             $req .= ' and '.$words_sql if ($words_sql);
@@ -167,7 +167,7 @@ sub _prepare_request {
     }
     else {
         if ($query->is_global) {
-            $req = 'select p.id, p.sender, p.title, p.url, p.duration';
+            $req = 'select p.id, p.sender, p.title, p.url, p.duration, p.external_id, p.type';
             $req .= ' from playbot p';
             $req .= ' where '.$words_sql.' and' if ($words_sql);
             $req .= ' p.playlist is false';
@@ -176,7 +176,7 @@ sub _prepare_request {
             @args = (@words_param);
         }
         else {
-            $req = 'select p.id, p.sender, p.title, p.url, p.duration';
+            $req = 'select p.id, p.sender, p.title, p.url, p.duration, p.external_id, p.type';
             $req .= ' from playbot p join playbot_chan pc on p.id = pc.content';
             $req .= ' where pc.chan = ?';
             $req .= ' and '.$words_sql if ($words_sql);
diff --git a/PlayBot/utils/print.pm b/PlayBot/utils/print.pm
index 077730a..907ca76 100644
--- a/PlayBot/utils/print.pm
+++ b/PlayBot/utils/print.pm
@@ -9,25 +9,38 @@ use IRC::Utils qw(YELLOW ORANGE GREEN NORMAL LIGHT_BLUE GREY);
 # The public subroutine is print($content).
 # arg :
 #   - $content : a ref to a hash with the following keys :
-#       - id
-#       - title
 #       - author
 #       - duration (in seconds)
-#       - url
+#       - external_id (optional)
+#       - id
+#       - site (if external_id)
 #       - tags : a ref to a list of tags
+#       - title
+#       - url
 # returns :
 #   - a string well formated
 
-sub print {
+sub print
+{
     my ($content) = @_;
 
+    if (defined($content->{external_id}) and defined($content->{site}))
+    {
+        my $site = 'PlayBot::sites::'.$content->{site};
+        eval "require $site";
+        eval { $content->{url} = $site->get_url($content->{external_id}) };
+        # TOOD: log if $@
+    }
+
     my $msg = YELLOW.'['.$content->{'id'}.'] '.GREEN.$content->{'title'};
 
-	if (defined $content->{'author'}) {
+	if (defined $content->{'author'})
+    {
 		$msg .= ' | '.$content->{'author'};
 	}
 
-    if (defined $content->{'duration'}) {
+    if (defined $content->{'duration'})
+    {
         my $h = int($content->{'duration'} / 3600);
         my $m = int(($content->{'duration'} % 3600) / 60);
         my $s = int(($content->{'duration'} % 3600) % 60);
@@ -41,7 +54,8 @@ sub print {
 
     $msg .= ' => '.$content->{'url'}.ORANGE if (defined $content->{'url'});
 
-    if (defined $content->{'tags'}) {
+    if (defined $content->{'tags'})
+    {
         $msg .= ' '.$_ foreach (@{$content->{'tags'}});
     }
 
@@ -50,7 +64,8 @@ sub print {
     return $msg;
 }
 
-sub stats {
+sub stats
+{
     # a utils::db::stats object;
     my $stats = shift;
     my $line1; 
@@ -62,7 +77,8 @@ sub stats {
     $line1 .= ' le '.$stats->date;
     $line1 .= ' sur '.$stats->chan;
 
-    if ($stats->count > 1) {
+    if ($stats->count > 1)
+    {
         my $senders_count = keys %{$stats->senders};
         my $channels_count = keys %{$stats->channels};
 
@@ -73,20 +89,23 @@ sub stats {
         $line2 .= 's' if ($channels_count > 1);
 
         my $max_sender_count = $stats->senders->{$stats->max_sender};
-        if ($max_sender_count > 1) {
+        if ($max_sender_count > 1)
+        {
             $line3 .= $stats->max_sender. " l'a posté ";
             $line3 .= $max_sender_count. ' fois';
         }
 
         my $max_channel_count = $stats->channels->{$stats->max_channel};
-        if ($max_channel_count != $stats->count and $max_channel_count > 1) {
+        if ($max_channel_count != $stats->count and $max_channel_count > 1)
+        {
             $line3 .= ' et ' if ($max_sender_count > 1);
             $line3 .= 'il a été posté '.$max_channel_count;
             $line3 .= ' fois sur '.$stats->max_channel;
         }
     }
 
-    if ($stats->fav) {
+    if ($stats->fav)
+    {
         $line4 = "Sauvegardé dans ses favoris par ";
         $line4 .= $stats->fav.' personne';
         $line4 .= 's' if ($stats->fav > 1);
-- 
GitLab