Thank you for your donation!


Cloudsmith graciously provides open-source package management and distribution for our project.


Idea: Genius
#7
Ok, so here is a pure php-script!

It's based on the python script mentioned above. And I found a working function by Allen Fair which creates the api-call.

For the parsing of the lyrics page I used DOMXPath as replacement for the python function BeautifulSoup.

As DOMXPath (php xml) is not installed You have to install it manually with:
Code:
sudo apt-get install php7.3-xml 

then You may copy the code in a new file in /var/www/command/ - let's call it geniuslyrics.php
You need to put Your Genius client access token in the first line ($ClientAccessToken = '....')
When playing a song You then can open the webpage with http://moode.local/command/geniuslyrics.php 
PHP Code:
<?php
$ClientAccessToken 
'<<<PUT YOUR CLIENT ACCESS TOKEN HERE>>';
$ARTIST_=shell_exec('mpc --format %artist% | head -n 1');
$ARTIST_=str_replace("\n","",$ARTIST_);
$ARTIST=str_replace(" ","+",$ARTIST_);

$TITLE_=shell_exec('mpc --format %title% | head -n 1');
$TITLE_=str_replace("\n","",$TITLE_);
$TITLE=str_replace(" ","+",$TITLE_);

function 
http_request($url$opt=array()) {
/**
 * Makes a remote HTTP request and returns the response.
 *
 * @author    Allen Fair <allen.fair@gmail.com>
 * @copyright 2018 Allen Fair
 * @license   https://opensource.org/licenses/MIT  MIT
 * @code      https://gist.github.com/afair/a7c7adc52b7b49bf362935e665a87633
 *
 * @param string  $url     The full URL endpoint: "https://example.com/endpoint"
 * @param array   $opt     An Associative Array of extended request options
 *
 *        string  'method'       one of: GET, POST, PUT, PATCH, DELETE, HEAD
 *        string  'url'          URL override
 *        string  'endpoint'     Optional endpoint appended to URL
 *        string  'user'         user name to send for HTTP Basic Authorization
 *        string  'token'        creates an "Authorization: Bearer" header
 *        string  'accept'       creates an Accept: header for the mime/type
 *        string  'password'     password to send for HTTP Basic Authorization
 *        array   'headers'      array of "Header-Name: value", ...
 *        array   'query'        name=>value pairs for the Query String
 *        array   'post'         name=>value pairs for the POST Data body
 *        array   'files'        name=>['path'=>"/path/file", 'filename'=>"name.ext",
 *                                     'type'=>"mime1/mime2"] pairs of files to send
 *        array   'cookies'      name=value pairs for cookies to send
 *        array   'http_options' name=value pairs for "HTTP context options"
 *        callable 'notifications' a stream_notification_callback for events on the stream.
 *
 * @return array  [$http_status_code, $headers_hash, $body]
 *
 * Note: sending very large files/requests must fit into memory. Chunking is not supported.
 *
 * @example
 * list($status, $headers, $content) = http_request('https://www.example.com/endpoint', array(
 *   'method'       => 'POST',
 *   'headers'      => array('From'=>'pat@mycompany.com'),
 *   'accept'       => 'application/json',
 *   'user'         => $apikey, 'password'=>'', 'token'=>$token, // Authentication
 *   'query'        => array('q' => 'PHP HTTP request'),
 *   'post'         => array('email' => 'pat@mycompany.com'),
 *   'files'        => array('path'=> './avatar.png', 'filename'=>'avatar.png', 'type'=>'image/png'),
 *   'cookies'      => array('session' => $jwt),
 *   'http_options' => array('timeout'=> 5.0, 'user_agent'=>"php_request/1.0"),
 *   ));
 */
  $http_options array_key_exists('http_options'$opt) ? $opt['http_options'] : array();
  $headers      array_key_exists('headers'$opt) ? $opt['headers'] : array();
  $url          array_key_exists('url'$opt) ? $opt['url'] : $url;
  $endpoint     array_key_exists('endpoint'$opt) ? $opt['endpoint'] : null;
  $method       array_key_exists('method'$opt) ? strtoupper($opt['method']) : 'GET';
  $query        array_key_exists('query'$opt) ? $opt['query'] : null;
  $post         array_key_exists('post'$opt) ? $opt['post'] : null;
  $files        array_key_exists('files'$opt) ? $opt['files'] : null;
  $notificationsarray_key_exists('notifications'$opt) ? $opt['notifications'] : null;

  // Headers
  if (array_key_exists('accept'$opt)) {
    $headers[] = "Accept: " $opt['accept'];
  }
  if (array_key_exists('user'$opt)) {
    $headers[] = "Authorization: Basic ".base64_encode($opt['user'].':'.$opt['password']);
  }
  elseif (array_key_exists('token'$opt)) {
    $headers[] = "Authorization: Bearer ".$opt['token'];
  }
  if (array_key_exists('cookies'$opt)) {
    foreach ($opt['cookies'] as $n=>$v$headers[] = "Cookie: $n=$v";
  }

  // URL, appended Endpoint, and Query Parameters
  if ($endpoint$url .= $endpoint;
  if (!empty($query)) {
    $url .= (strpos("?",$url)===false "?" "&") . http_build_query($query);
  }
  // File + Post Parameters in multipart format
  if (!empty($files)) {
    $boundary '--------------------------'.microtime(true);
    $content = array();
    foreach ($files as $field=>$f) {
      $content[] ="--$boundary";
      $content[] = "Content-Disposition: form-data; name=\"$field\"; filename=\"".basename($filename)."\"";
      $content[] = "Content-Type: {$f['type']}";
      $content[] = "Content-Length: " filesize($f['path']);
      $content[] = "";
      $content[] = file_get_contents($f['path']);
      $content[] = "";
    }
    foreach ($post as $field=>$v) {
      $content[] ="--$boundary";
      $content[] = "Content-Disposition: form-data; name=\"$field\"";
      $content[] = "";
      $content[] = $v;
      $content[] = "";
    }
    $content[] = "--$boundary--";
    $headers[] = "Content-Type: multipart/form-data; boundary=$boundary";
    $http_options['content'] = implode("\r\n"$content);
    unset($content);
  }
  // Post Parameters in urlencoded format
  elseif (!empty($post)) {
    $headers[] = "Content-Type: application/x-www-form-urlencoded";
    $http_options['content'] = http_build_query($post);
  }

  // Make Request
  if (!$http_options['user_agent']) $http_options['user_agent'] = "http_request.php/1.0";
  $http_options['method'] = $method;
  if ($http_options['content']) $headers[] = "Content-Length: ".strlen($http_options['content']);
  if (!empty($headers)) {
    $http_options['header'] = implode("\r\n"$headers);
  }
  $context stream_context_create(array('http'=>$http_options));
  if ($notifications) {
    stream_context_set_params($context, array("notification" => $notifications));
  }
  if ($method == 'HEAD') {
    $headlist = @get_headers($url0$context);
    $response null;
  } else {
    $response = @file_get_contents($urlfalse$context);
    $headlist $http_response_header;
  }

  // Format Response
  $status preg_match("/(\d\d\d) (.+)/"$headlist[0], $m) ? $m[1] : 500;
  $headers = array("Status" => $headlist[0]);
  foreach ($headlist as $h) {
    if (preg_match("/^([\w\-]+):\s*(.+)/"$h$m)) $headers[$m[1]] = $m[2];
  }
  return array($status$headers$response);
}

?>
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Genius lyrics query</title>
</head>
<body>
<?php
if($TITLE!="" && $ARTIST!=""){
  $result = (http_request('https://api.genius.com/search', array(
   'method'       => 'GET',
   'accept'       => 'application/json',
   'token'         => $ClientAccessToken// Authentication
   'query'        => array('q' => $TITLE.' '.$ARTIST),
   'http_options' => array('timeout'=> 5.0'user_agent'=>"php_request/1.0"),
   )));

  $json json_decode($result[2], TRUE);
  // print_r($json);
  $val $json["response"]["hits"];
  // print_r($val);
  $song_api_path="";
  $song_url="";
  foreach($val as $hit){
    if(stripos ($hit["result"]["primary_artist"]["name"],$ARTIST_)!==False){
        //print('found' . chr(10));
        $artistFound=$hit["result"]["primary_artist"]["name"];
        $songFound=$hit["result"]["title"];
        $song_api_path $hit["result"]["api_path"];
        $song_url=$hit["result"]["url"];
        break;
    };
  };
  if($song_url != ""){
    $songlyrics="";
    $found=false;
    $i=0;
    while(!$found){
      $file file_get_contents($song_url);
//      file_put_contents ('tmp',$file);
      $file =str_replace("<br>","",$file);
      $dom = new DOMDocument;
      $dom->loadHTML($file);
      $xpath = new DOMXPath($dom);
      foreach( $xpath->query('//div[@class="lyrics"]') as $e ) {
         $songlyrics=$e->nodeValue;
         $found=true;
      };
      $i++;
      if($i>10){break;};
    };
    if($songlyrics!=""){
      $songlyrics=nl2br($songlyrics);
      $songlyrics=str_replace("]","]<br />",$songlyrics);
      $songlyrics=str_replace("[","<br />[",$songlyrics);
      echo $artistFound.' - '.$songFound;
      echo $songlyrics;
    }
  }
  else{echo "no lyrics found..." chr(10);};

//
}
else{echo 
"please start playback..." chr(10);}

?>
</body>
</html> 


Hope it is useful and maybe even gets integrated in moode ui someday...

Have a nice Christmas!

Cheers, Stephan
Reply


Messages In This Thread
Genius - by kit1cat - 12-20-2020, 08:18 PM
RE: Genius - by Tim Curtis - 12-20-2020, 08:39 PM
RE: Genius - by Stephanowicz - 12-20-2020, 09:34 PM
RE: Genius - by kit1cat - 12-20-2020, 09:24 PM
RE: Genius - by kit1cat - 12-20-2020, 09:43 PM
RE: Genius - by Stephanowicz - 12-22-2020, 05:19 PM
RE: Genius - by Stephanowicz - 12-24-2020, 06:54 PM
RE: Genius - by Tim Curtis - 12-24-2020, 10:06 PM
RE: Genius - by Stephanowicz - 01-17-2021, 11:42 AM
RE: Genius - by kit1cat - 01-17-2021, 12:31 PM
RE: Genius - by Stephanowicz - 01-17-2021, 12:58 PM
RE: Genius - by kit1cat - 01-17-2021, 05:00 PM
RE: Genius - by kit1cat - 01-17-2021, 05:56 PM

Forum Jump: