Assembla home | Assembla project page
 

Changeset 853

Show
Ignore:
Timestamp:
11/08/07 15:44:42 (1 year ago)
Author:
swiss
Message:

Added support for Last.FM. Features added include:

  • Configuration options on the "Internet Radio" config page, including separate username/password settings for each swisscenter user.
  • Scrobbling of all tracks played via the Swisscenter_Configuration
  • Playback of LastFM streams via a proxy script.

Playback of the following Last.FM radio streams are supported:

  • Similar Artists radio
  • Tag radio
  • My station
  • My recommendations
  • My loved tracks
  • My neighbourhood

Refs #72

Files:

Legend:

Unmodified
Added
Removed
Modified
Copied
Moved
  • trunk/swisscenter/base/html_form.php

    r820 r853  
    308308# 
    309309# Additionally you may pass an associative array of edit options. The keys in the array and the 
    310 # names of the table headings and must be all uppercase. The values can be one of three things: 
    311 #   * An empty string - This indicates a text editable field 
     310# names of the table headings and must be all uppercase. The values can be one of: 
     311
     312#   * An empty string, which indicates a text editable field 
     313#   * An exclamation mark ("!") which indicates the field should not be made editable. 
     314#   * An asterisk ("*") which indicates the field should be considered a password and blanked out. 
     315#   * An array - This array is an array of arrays, each element of the outer array is a single row 
     316#     in a table, the child arrays are column name/value pairs 
    312317#   * A string - This is a sql statement that returns exactly 2 columns, the first an ID that will 
    313318#     be used as the value of the selected item, and the second a string to display. This will be 
    314319#     displayed as a drop down list 
    315 #   * An array - This array is an array of arrays, each element of the outer array is a single row 
    316 #     in a table, the child arrays are column name/value pairs 
    317320# 
    318321# If an array of edit options is passed then an edit button will be placed on each row. It can 
     
    349352      { 
    350353        list($title, $size) = explode('|',$value); 
    351         echo '<th width="'.$size.'">'.$title.'</th>'; 
     354        echo '<th valign="bottom" width="'.$size.'">'.$title.'</th>'; 
    352355      } 
    353356      else 
    354         echo '<th>'.ucwords($value).'</th>'; 
     357        echo '<th valign="bottom">'.ucwords($value).'</th>'; 
    355358    } 
    356359 
     
    387390            $element_name = strtoupper($param.'_update:'.escape_form_names($cell_name)); 
    388391            $cell_edit_options = $edit_options[$cell_name]; 
    389             if (empty($cell_edit_options) || is_numeric($cell_edit_options)) 
     392 
     393            if ($cell_edit_options == "!")  
     394            { 
     395              echo $cell_value; 
     396            } 
     397            elseif ($cell_edit_options == "*")  
     398            { 
     399              echo "<input type='password' name='".$element_name."' value='".$cell_value."'>"; 
     400            } 
     401            elseif (empty($cell_edit_options) || is_numeric($cell_edit_options))  
    390402            { 
    391403              echo '<input type="text" name="'.$element_name.'" value="'.$cell_value.'"'. 
     
    393405                    '>'; 
    394406            } 
    395             elseif ($cell_edit_options == "*") 
    396             { 
    397               echo "<input type='password' name='".$element_name."' value='".$cell_value."'>"; 
    398             } 
    399             else 
     407            else  
    400408            { 
    401409              if(is_array($cell_edit_options)) 
     
    421429          { 
    422430            $cell_edit_options = $edit_options[$cell_name]; 
    423             if($cell_edit_options == "*"
     431            if($cell_edit_options == "*" && !empty($cell_value)
    424432              echo "********"; 
    425433            else 
     
    438446        { 
    439447          echo '<td align="center" width="60"><a href="javascript:update_'.$formname.'(\''.$row[strtoupper($id_col)].'\');"><img alt="Ok" title="Ok" src="/images/ico_tick.gif" border="0"></a>'; 
    440           echo '&nbsp;&nbsp;<a href="javascript:cancel_'.$formname.'();"><img alt="Cancel" title="Cancel" src="/images/ico_cross.gif" border="0"></a></td>'; 
     448          echo '&nbsp;<a href="javascript:cancel_'.$formname.'();"><img alt="Cancel" title="Cancel" src="/images/ico_cross.gif" border="0"></a></td>'; 
    441449        } 
    442450        else 
  • trunk/swisscenter/base/list_picker.class.php

    r820 r853  
    1616  var $page; 
    1717  var $focus; 
     18  var $back_url; 
    1819   
    1920  function list_picker() 
     
    4243  } 
    4344   
    44   function display_nodata() 
     45  function data_valid_chars( $search_string ) 
     46  { 
     47    return '';     
     48  } 
     49   
     50  function display_nodata( $search_string) 
    4551  { 
    4652    echo ''; 
     
    6470  function display() 
    6571  {         
     72    // Get data 
     73    $sql_search    = $this->prefix.db_escape_wildcards($this->search).'%'; 
     74    $data          = $this->data_list($sql_search, ($this->page*MAX_PER_PAGE), MAX_PER_PAGE); 
     75    $num_rows      = $this->data_count($sql_search); 
     76 
    6677    // Header 
    6778    page_header( $this->display_title($this->search), $this->display_subtitle($this->search),'', $this->focus); 
     
    6980    // A-Z picker 
    7081    echo '<table border=0 height="320px" width="100%"><tr><td width="200px" valign="top">'; 
    71     show_picker( $this->url.'?any='.$this->prefix.'&search=', $this->search); 
    72     echo '</td><td valign=top>'; 
    73      
    74     // Get data 
    75     $sql_search    = $this->prefix.db_escape_wildcards($this->search).'%'; 
    76     $data          = $this->data_list($sql_search, ($this->page*MAX_PER_PAGE), MAX_PER_PAGE); 
    77     $num_rows      = $this->data_count($sql_search); 
     82    show_picker( $this->url.'?any='.$this->prefix.'&search=', $this->search, '', ( empty($this->prefix) ? $this->data_valid_chars($sql_search) : '' ) ); 
     83    echo '</td><td valign=top>';     
    7884     
    7985    if ( $num_rows == 0) 
     
    95101        $this->menu->add_item($this->display_format_name($item), $this->link_url($item), true); 
    96102     
    97       $this->menu->display( 480 ); 
     103      $this->menu->display( 1, 480 ); 
    98104    } 
    99105     
     
    104110    $buttons[] = array('id'=>'A', 'text'=>str('SEARCH_ANYWHERE'), 'url'=>$this->url.'?search='.rawurlencode($this->search).'&any='.(empty($this->prefix) ? '%' : '')); 
    105111    $buttons[] = array('id'=>'B', 'text'=>str('SEARCH_CLEAR'),    'url'=>$this->url.'?any='.$this->prefix);     
    106     page_footer('music_radio.php', $buttons); 
     112    page_footer( $this->back_url , $buttons); 
    107113  } 
    108114} 
  • trunk/swisscenter/base/menu.php

    r820 r853  
    185185   */ 
    186186   
    187   function display_page( $page=1, $size=650) 
     187  function display_page( $page=1, $tvid=1, $size=650) 
    188188  { 
    189189    $start      = ($page-1) * MAX_PER_PAGE;  
     
    198198 
    199199    $this->menu_items = array_slice($this->menu_items,$start, MAX_PER_PAGE); 
    200     $this->display($size);     
     200    $this->display($tvid, $size);     
    201201  } 
    202202   
     
    207207   */ 
    208208   
    209   function display( $size=650 ) 
     209  function display( $tvid = 1, $size=650 ) 
    210210  { 
    211211    $num_cols    = 1; 
    212     $tvid        = 0; 
    213212    $font_open   = font_tags($this->font_size); 
    214213 
     
    250249      foreach ($this->menu_items as $item) 
    251250      { 
    252         $tvid++; 
    253251        $text = shorten($item["text"], $width-80, 1, $this->font_size, true, false); 
    254252         
     
    281279        // End row 
    282280        echo '</tr>'; 
     281        $tvid++; 
    283282      } 
    284283    } 
  • trunk/swisscenter/base/playlist.php

    r839 r853  
    256256define('LASTFM_TAG','globaltags'); 
    257257define('LASTFM_NEIGHBOUR','neighbour'); 
     258define('LASTFM_USER','user'); 
    258259 
    259260function play_lastfm($station_type, $name = '' ) 
     
    264265  switch ($station_type) 
    265266  { 
     267    case LASTFM_USER: 
     268         $station_id = "lastfm://user/".get_user_pref('LASTFM_USERNAME')."/$name"; 
     269         break; 
     270          
    266271    case LASTFM_ARTIST: 
    267272         $station_id = "lastfm://artist/".urlencode($name)."/similarartists"; 
  • trunk/swisscenter/base/search.php

    r846 r853  
    159159    } 
    160160 
    161     $menu->display(540); 
     161    $menu->display(1, 540); 
    162162  } 
    163163 
  • trunk/swisscenter/base/swisscenter_configuration.php

    r838 r853  
    8080    { 
    8181      $xpath = $this->xml->appendChild($this->settings_path,'<users />'); 
    82       $data = db_toarray("select u.name username, c.name certificate, c.scheme, u.pin from users u, certificates c where u.maxcert = c.cert_id"); 
     82      $data = db_toarray("select u.user_id, u.name username, c.name certificate, c.scheme, u.pin from users u, certificates c where u.maxcert = c.cert_id"); 
    8383      if ($data !== false && count($data)>0) 
    8484      { 
     
    8989          $this->xml->appendChild($user_path, '<pin>'.$row["PIN"].'</pin>'); 
    9090          $pref_path = $this->xml->appendChild($user_path, '<preferences />'); 
    91           $prefs = db_toarray("select * from user_prefs"); 
     91          $prefs = db_toarray("select * from user_prefs where user_id=$row[USER_ID]"); 
    9292          if ($prefs != false && count($prefs)>0) 
    9393          { 
     
    273273        } 
    274274         
     275        // Determine the user_id for importing settings. 
     276        $user_id = db_value("select user_id from users where name = '$name'"); 
     277         
    275278        // Import user preferences 
    276279        foreach ($this->xml->match($userpath.'/preferences[1]/setting') as $prefpath) 
     
    278281          $attrib  = $this->xml->getAttributes($prefpath); 
    279282          $value   = $this->xml->getData($prefpath); 
    280           $user_id = db_value("select user_id from users where name = '$name'"); 
    281283          if (db_value("select count(*) from user_prefs where user_id=$user_id and name = '".$attrib["NAME"]."'") == 0) 
    282284            db_insert_row('user_prefs',array("user_id"=>$user_id, "name"=>$attrib["NAME"], "value"=>$value)); 
  • trunk/swisscenter/base/urls.php

    r820 r853  
    8686 */ 
    8787 
    88 function http_post( $url, $data
     88function http_post( $url, $data, $timeout = 5
    8989{ 
     90  send_to_log(5,"Sending HTTP POST Request to $url"); 
    9091  $current = parse_url( current_url() ); 
    9192  $url = parse_url($url); 
     
    9697  // Generate the request header 
    9798  $data_len  = strlen($data); 
    98   $request   = "POST $path HTTP/1.1\n". 
    99                "Host: $host\n".    
    100                "Content-Type: application/x-www-form-urlencoded\n". 
    101                "Content-Length: $data_len\n". 
    102                "\n". 
    103                "$data\n"; 
     99  $request   = "POST $path HTTP/1.1\r\n". 
     100               "Host: $host\r\n".    
     101               "Content-Type: application/x-www-form-urlencoded\r\n". 
     102               "Content-Length: $data_len\r\n". 
     103               "Connection: close\r\n". 
     104               "\r\n". 
     105               "$data"; 
    104106 
    105107  // Open the connection to the host 
    106   echo "<p>about to open $host : $port"; 
    107   send_to_log(8,'Attempting HTTP POST request', array('Url'=>$host,'Port'=>$port,'Data'=>$request)); 
    108   if ( ($socket = fsockopen($host, $port, &$errno, &$errstr)) === false) 
     108  send_to_log(8,"HTTP POST Request (Host: $host Port: $port)",explode("\n",$request)); 
     109  if ( ($socket = fsockopen($host, $port, &$errno, &$errstr, $timeout)) === false) 
    109110  { 
    110     send_to_log(1,"Failed to open socket to '$host' on port '$port'."); 
     111    send_to_log(2,"Failed to open socket to '$host' on port '$port'."); 
    111112    return false;     
    112113  } 
     
    115116  fputs($socket, $request); 
    116117   
     118  // Ensure we are reading in blocking mode, and with the specified timeout 
     119  stream_set_blocking( $socket, TRUE ); 
     120  stream_set_timeout( $socket, $timeout ); 
     121  $info = stream_get_meta_data( $socket );  
     122 
    117123  // Get the response 
    118124  $response = ''; 
    119   while (!feof($socket)) 
     125  while (!feof($socket) && (!$info['timed_out'])) 
     126  { 
    120127    $response .= fgets($socket, 256); 
     128    $info = stream_get_meta_data($socket); 
     129  } 
    121130   
    122   /// Close the socket 
     131  // Record the fact that the socket timed out. 
     132  if ($info['timed_out']) 
     133    send_to_log(2,"Socket timed out while attempting a HTTP POST to '$socket:$port'"); 
     134   
     135  // Close the socket 
    123136  fclose($socket); 
    124137     
    125138  // Return result; 
     139  send_to_log(8,"HTTP POST Response",explode("\n",$response)); 
    126140  return $response; 
    127141} 
  • trunk/swisscenter/config/config_connect.php

    r820 r853  
    3737    form_radio_static('radio',str('INTERNET_RADIO'),$option_vals,get_sys_pref('radio_enabled','YES'),false,true); 
    3838    form_label(str('INTERNET_RADIO_PROMPT')); 
     39 
     40    form_radio_static('lastfm',str('LASTFM'),$option_vals,get_sys_pref('lastfm_enabled','YES'),false,true); 
     41    form_label(str('LASTFM_ENABLED_PROMPT')); 
    3942 
    4043    form_radio_static('web',str('BROWSE_WEB'),$option_vals,get_sys_pref('web_enabled','YES'),false,true); 
     
    7982    set_sys_pref('updates_enabled',$_REQUEST["update"]); 
    8083    set_sys_pref('messages_enabled',$_REQUEST["messages"]); 
     84    set_sys_pref('lastfm_enabled',$_REQUEST["lastfm"]); 
    8185    connect_display(str('SAVE_SETTINGS_OK')); 
    8286  } 
  • trunk/swisscenter/config/config_radio.php

    r820 r853  
    44 *************************************************************************************************/ 
    55   
    6   // ---------------------------------------------------------------------------------- 
    7   // Display current config 
    8   // ---------------------------------------------------------------------------------- 
     6  /** 
     7   * Displays the Internet Radio configuration options to the user 
     8   * 
     9   * @param string $lastfm_msg - A success/fail message when updating lastFM settings 
     10   * @param string $shoutmsg - A success/fail message when updating Shoutcast settings 
     11   * @param integer $lastfm_edit_id - The Row ID for editing the lastFM user credentials 
     12   */ 
    913   
    10   function radio_display( $message = ''
     14  function radio_display($lastfm_msg = '', $shoutmsg = '', $lastfm_edit_id = 0
    1115  { 
    12     echo '<p><h1>'.str('CONFIG_RADIO_OPTIONS').'<p>'; 
    13     message($message); 
     16    $option_vals  = array( str('ENABLED')=>'YES',str('DISABLED')=>'NO'); 
     17        $data = db_toarray("select u.user_id, u.name, un.value username, pw.value password 
     18                                 , ( CASE sc.value  WHEN 'NO' THEN '".str('NO')."' WHEN 'YES' THEN '".str('YES')."' ELSE '".str('NO')."' END) scrobble 
     19                                 , ( CASE im.value  WHEN 'NO' THEN '".str('NO')."' WHEN 'YES' THEN '".str('YES')."' ELSE '".str('NO')."' END) images 
     20                          from users u left outer join user_prefs un on (un.user_id = u.user_id and un.name = 'LASTFM_USERNAME') 
     21                                       left outer join user_prefs pw on (pw.user_id = u.user_id and pw.name = 'LASTFM_PASSWORD') 
     22                                       left outer join user_prefs sc on (sc.user_id = u.user_id and sc.name = 'LASTFM_SCROBBLE') 
     23                                       left outer join user_prefs im on (im.user_id = u.user_id and im.name = 'LASTFM_IMAGES') 
     24                      order by u.name"); 
     25         
     26    echo '<p><h1>'.str('CONFIG_LASTFM_TITLE').'</h1><p>'; 
     27    echo '<b>'.str('LASTFM_WHATIS').'</b>'; 
     28    echo '<p><a href="http://www.last.fm/" target="_blank"><img src="/images/lastfm.gif" align="right" hspace="20" vspace="16" border=0></a>'.str('LASTFM_ABOUT'); 
     29 
     30    message($lastfm_msg); 
     31 
     32    form_start("index.php", 150, "lastfm_auth"); 
     33    form_hidden('section','RADIO'); 
     34    form_hidden('action','UPDATE_LASTFM'); 
     35    form_select_table( "user_id" 
     36                     , $data 
     37                     , str('LASTFM_LOGIN_HEADINGS') 
     38                     , array("class"=>"form_select_tab","width"=>"100%") 
     39                     , "user_id" 
     40                     , array( "NAME"=>"!" 
     41                            , "USERNAME"=>"" 
     42                            , "PASSWORD"=>"*" 
     43                            , "SCROBBLE"=>array( array("VAL"=>'NO',"NAME"=>str('NO')),array("VAL"=>'YES',"NAME"=>str('YES'))) 
     44                            , "IMAGES"=>array( array("VAL"=>'NO',"NAME"=>str('NO')),array("VAL"=>'YES',"NAME"=>str('YES'))) 
     45                            ) 
     46                     , $lastfm_edit_id 
     47                     , "lastfm_auth"); 
     48    form_submit(str('CONFIG_LASTFM_CLEAR'), 1 ,"center"); 
     49    form_end(); 
     50 
     51    echo '<p><h1>'.str('CONFIG_SHOUTCAST_TITLE').'</h1><p>'; 
     52    message($shoutmsg); 
    1453    form_start('index.php'); 
    1554    form_hidden('section','RADIO'); 
    16     form_hidden('action','UPDATE'); 
     55    form_hidden('action','UPDATE_SHOUTCAST'); 
    1756    form_input('maxnum',str('IRADIO_MAX_STATIONS'),20,'2',get_sys_pref('iradio_max_stations',24)); 
    1857    form_label(str('IRADIO_MAX_STATIONS_PROMPT')); 
     
    2261    form_end(); 
    2362  } 
     63 
     64  /** 
     65   * Saves the LastFM login details and options 
     66   * 
     67   */ 
    2468   
    25   // ---------------------------------------------------------------------------------- 
    26   // Saves the new parameter 
    27   // ---------------------------------------------------------------------------------- 
     69  function radio_update_lastfm() 
     70  { 
     71    $selected    = form_select_table_vals("user_id"); 
     72    $edit_id     = form_select_table_edit("user_id", "lastfm_auth"); 
     73    $update_data = form_select_table_update("user_id", "lastfm_auth"); 
     74     
     75    if(!empty($edit_id)) 
     76    { 
     77        radio_display("", "", $edit_id); 
     78    } 
     79    elseif(!empty($update_data)) 
     80    {            
     81      $user_id  = $update_data["USER_ID"]; 
     82      $username = $update_data["USERNAME"]; 
     83      $password = $update_data["PASSWORD"]; 
     84      $scrobble = $update_data["SCROBBLE"]; 
     85      $download = $update_data["IMAGES"]; 
     86       
     87          if (empty($username) || empty($password)) 
     88        radio_display("!".str('LASTFM_MISSING_LOGIN')); 
     89      else  
     90      { 
     91        // Bit of a kludge, but if the password is characters then it's probably already a hash. 
     92        if ( strlen($password) != 32 ) 
     93          $password = md5($password); 
     94 
     95        set_user_pref('LASTFM_USERNAME',$username, $user_id); 
     96        set_user_pref('LASTFM_PASSWORD',$password, $user_id); 
     97        set_user_pref('LASTFM_SCROBBLE',$scrobble, $user_id); 
     98        set_user_pref('LASTFM_IMAGES'  ,$download, $user_id); 
     99        radio_display(str('SAVE_SETTINGS_OK')); 
     100      }       
     101    } 
     102    elseif(!empty($selected)) 
     103    { 
     104      foreach($selected as $user_id) 
     105        db_sqlcommand("delete from user_prefs where user_id=$user_id and name in ('LASTFM_USERNAME','LASTFM_PASSWORD','LASTFM_SCROBBLE')"); 
     106       
     107      radio_display(str('CONFIG_LASTFM_CLEAR_OK')); 
     108    } 
     109    else 
     110      radio_display();           
     111  } 
    28112   
    29   function radio_update() 
     113  /** 
     114   * Saves the Shoutcast and LiveRadio options. 
     115   * 
     116   */ 
     117   
     118  function radio_update_shoutcast() 
    30119  { 
    31120    $maxnum = (int) $_REQUEST["maxnum"]; 
     
    34123     
    35124    if (empty($_REQUEST["maxnum"])) 
    36       radio_display("!".str('IRADIO_ERROR_MAXNUM')); 
     125      radio_display('', "!".str('IRADIO_ERROR_MAXNUM')); 
    37126    elseif (empty($maxnum)) 
    38       radio_display("!".str('IRADIO_ERROR_MAXNUM_ZERO')); 
     127      radio_display('', "!".str('IRADIO_ERROR_MAXNUM_ZERO')); 
    39128    elseif (empty($_REQUEST["cache_expire"])) 
    40       radio_display("!".str('IRADIO_ERROR_CACHE_EXPIRE')); 
     129      radio_display('', "!".str('IRADIO_ERROR_CACHE_EXPIRE')); 
    41130    else  
    42131    { 
    43132      set_sys_pref('iradio_max_stations',$maxnum); 
    44133      set_sys_pref('iradio_cache_expire',$cache_expire); 
    45       radio_display(str('SAVE_SETTINGS_OK')); 
     134      radio_display('', str('SAVE_SETTINGS_OK')); 
    46135    } 
    47136  } 
  • trunk/swisscenter/config/index.php

    r822 r853  
    8686          $menu->add_item(str('CONFIG_IMAGE_OPTIONS')   ,'section=IMAGE&action=DISPLAY'); 
    8787          $menu->add_item(str('PLAYLISTS')              ,'section=PLAYLISTS&action=DISPLAY'); 
     88          $menu->add_item(str('CONFIG_RADIO_OPTIONS')   ,'section=RADIO&action=DISPLAY'); 
    8889          $menu->add_item(str('MOVIE_OPTIONS')          ,'section=MOVIE&action=INFO'); 
    8990          $menu->add_item(str('ORG_TITLE')              ,'section=MOVIE&action=DISPLAY'); 
     
    9596          $menu->add_item(str('CACHE_CONFIG_TITLE')     ,'section=CACHE&action=DISPLAY'); 
    9697          $menu->add_item(str('CONNECT_TITLE')          ,'section=CONNECT&action=DISPLAY'); 
    97           $menu->add_item(str('CONFIG_RADIO_OPTIONS')   ,'section=RADIO&action=DISPLAY'); 
    9898          $menu->add_item(str('MISC_TITLE')             ,'section=MISC&action=DISPLAY'); 
    9999           
  • trunk/swisscenter/ext/lastfm/lastfm.php

    r820 r853  
    11<?php 
    22  require_once( realpath(dirname(__FILE__).'/../../base/file.php')); 
    3    
    4   function lastfm_enabled() 
    5   { 
    6     if (!internet_available()) 
    7       return false; 
    8     elseif (get_user_pref('LASTFM_USERNAME') == '') 
    9       return false; 
    10     elseif (get_user_pref('LASTFM_PASSWORD') == '') 
    11       return false; 
    12     else  
    13       return true; 
    14   } 
     3  require_once( realpath(dirname(__FILE__).'/../../base/urls.php')); 
     4  require_once( realpath(dirname(__FILE__).'/../../base/prefs.php'));  
     5  
     6  /** 
     7   * Class to tune to a Last.FM radio station. 
     8   * 
     9   */ 
    1510   
    1611  class lastfm 
     
    1813    var $session_id; 
    1914    var $stream_url; 
    20      
     15 
    2116    /** 
    2217     * Constructor 
     
    6762      { 
    6863        send_to_log(2,'Failed to access the login URL'); 
     64        send_to_log(8,'Response from LastFM',$response); 
    6965        return false; 
    7066      } 
     
    241237      $matches = array(); 
    242238       
    243       if (empty($artist)) 
    244         return $pics; 
    245        
    246       $html = @file_get_contents('http://www.last.fm/music/'.urlencode($artist).'/+images'); 
    247       if ($html === false) 
    248         send_to_log(2,'Failed to access artist details on LastFM (details may not be available).'); 
    249       else 
    250       { 
    251         if (preg_match_all('#<a[^>]*href="([^"]*proposed[^"]*)"[^<]*<img[^>]*src="([^"]*proposed[^"]*)"#i',$html,$matches) === false) 
    252           send_to_log(5,'No photos found for "'.$artist.'"'); 
    253         else  
     239      if (!empty($artist)) 
     240      {     
     241        // Set a timeout on the downloading of artist photos. 
     242        ini_set('default_socket_timeout',3);     
     243        $html = @file_get_contents('http://www.last.fm/music/'.urlencode($artist).'/+images'); 
     244        if ($html === false) 
     245          send_to_log(2,'Failed to access artist details on LastFM (details may not be available).'); 
     246        else 
    254247        { 
    255           for ($i=0; $i<count($matches[1]); $i++) 
     248          // Find all images of the artist on the page using a regular expression. 
     249          if (preg_match_all('#<a[^>]*href="([^"]*images/[0-]*[^"]*)"[^<]*<img[^>]*src="([^"]*)"#i',$html,$matches) >0 ) 
    256250          { 
    257             // Original or thumbnail image? 
    258             if ($original)           
    259               $pics[] = $matches[1][$i]; 
    260             else 
    261               $pics[] = $matches[2][$i]; 
     251            for ($i=0; $i<count($matches[1]); $i++) 
     252            { 
     253              // Original or thumbnail image? 
     254              if ($original)           
     255                $pics[] = $matches[1][$i]; 
     256              else 
     257                $pics[] = $matches[2][$i]; 
     258            } 
    262259          } 
     260          else  
     261            send_to_log(5,'No photos found for "'.$artist.'"'); 
    263262        } 
    264263      } 
     
    267266      return $pics; 
    268267    } 
    269        
    270   }     
    271  
     268 
     269     
     270  } // End of class    
     271 
     272  /** 
     273   * Class to enable scrobbling of tracks played to the Last.FM website. 
     274   * 
     275   */ 
     276   
     277  class scrobble 
     278  { 
     279    var $session_id; 
     280    var $submission_url; 
     281    var $now_playing_url; 
     282    var $client_id = 'sce';  
     283    var $client_version = '0.1'; 
     284     
     285    /** 
     286     * Constructor 
     287     * 
     288     * @return lastfm 
     289     */ 
     290     
     291    function scrobble( ) 
     292    { 
     293    } 
     294     
     295    /** 
     296     * Utility function to search for a value in a LastFM response 
     297     * 
     298     * @param string $pattern - pattern to search for 
     299     * @param string $text - text to search 
     300     * @return string - text founc 
     301     */ 
     302     
     303    function get_pattern($pattern, $text) 
     304    { 
     305      $matches = array(); 
     306      if ( preg_match($pattern,$text,$matches) == 1) 
     307        return $matches[1]; 
     308      else  
     309        return '';     
     310    } 
     311     
     312    /** 
     313     * Sends a login request to LastFM and processes the result 
     314     * 
     315     * @return boolean - TRUE if the login succeeded, false otherwise. 
     316     */ 
     317 
     318    function handshake($username, $md5_password) 
     319    { 
     320      // Clear information about the current session (if there is any) 
     321      $this->session_id = ''; 
     322      $this->now_playing_url = ''; 
     323      $this->submission_url = ''; 
     324 
     325      // Parameters for the handshake 
     326      $timenow = time(); 
     327      $hs_url  = 'http://post.audioscrobbler.com/'. 
     328                 '?hs=true'. 
     329                 '&p=1.2'. 
     330                 '&c='.$this->client_id. 
     331                 '&v='.$this->client_version. 
     332                 '&u='.$username. 
     333                 '&t='.$timenow. 
     334                 '&a='.md5( $md5_password.$timenow); 
     335 
     336      // Set a timeout on the handshake 
     337      ini_set('default_socket_timeout',2);     
     338       
     339      // Attempt to handshake 
     340      send_to_log(5,"Attempting to login with username '$username' and encrypted password '$md5_password'");       
     341      if ( ($response = @file_get_contents($hs_url)) === false) 
     342      { 
     343        send_to_log(2,'Failed to access the login URL',$hs_url); 
     344        return false; 
     345      } 
     346 
     347      // Split the response by line 
     348      $response = explode("\n",$response); 
     349       
     350      // Authenticated successfully? 
     351      if ($response[0] != 'OK') 
     352      { 
     353        $this->session_id = ''; 
     354        send_to_log(2,'Authentication failed', $response); 
     355        return false; 
     356      } 
     357       
     358      // Parse the response 
     359      $this->session_id = $response[1]; 
     360      $this->now_playing_url = $response[2]; 
     361      $this->submission_url = $response[3];       
     362      send_to_log(6,'Successfully authenticated',array("Session"=>$this->session_id, "Now Playing URL"=>$this->now_playing_url, "Submission URL"=>$this->submission_url) ); 
     363      return true; 
     364    }     
     365      
     366    /** 
     367     * Function to submit at entry to the LastFM servers. 
     368     * 
     369     * @param integer:timestamp $started_playing 
     370     * @param string $artist 
     371     * @param string $title 
     372     * @param string $album (optional) 
     373     * @param integer $track_no (optional) 
     374     * @param integer $length_s (optional) 
     375     */ 
     376     
     377    function submit( $started_playing, $artist, $track, $album, $length, $track_no ) 
     378    { 
     379      // One of the Last.FM rules is that only tracks longer than 30s can be scrobbled. 
     380      if ( $length > 30) 
     381      { 
     382        $data = 's='.$this->session_id. 
     383                '&a[0]='.rawurlencode($artist). 
     384                '&t[0]='.rawurlencode($track). 
     385                '&i[0]='.rawurlencode($started_playing). 
     386                '&o[0]=P'. 
     387                '&r[0]='. 
     388                '&l[0]='.rawurlencode($length). 
     389                '&b[0]='.rawurlencode($album). 
     390                '&n[0]='.rawurlencode($track_no). 
     391                '&m[0]='; 
     392   
     393        if ( !empty($this->submission_url) ) 
     394        { 
     395          send_to_log(6,'Attempting to scrobble song',array("Artist"=>$artist, "Track"=>$track, "Album"=>$album)); 
     396          $response = http_post( $this->submission_url, $data, 1); 
     397           
     398          if (strpos($response,'OK') !== false) 
     399            return true; 
     400          elseif (strpos($response,'BADSESSION') !== false) 
     401            return false; 
     402          elseif (strpos($response,'FAILED') !== false) 
     403            return false; 
     404          else  
     405            return false; 
     406        } 
     407      } 
     408       
     409      // Unable to scrobble. 
     410      return false;       
     411    } 
     412     
     413    /** 
     414     * Submits the details of a song that has just started playing to the MusicIP server. 
     415     * 
     416     * @param string $artist 
     417     * @param string $track 
     418     * @param string $album 
     419     * @param string $length 
     420     * @param string $track_no 
     421     * @return boolean - true for successful submission, false otherwise. 
     422     */ 
     423     
     424    function playing ( $artist, $track, $album, $length, $track_no ) 
     425    { 
     426      $data = 's='.$this->session_id. 
     427              '&a='.rawurlencode($artist). 
     428              '&t='.rawurlencode($track). 
     429              '&b='.rawurlencode($album). 
     430              '&l='.rawurlencode($length). 
     431              '&n='.rawurlencode($track_no). 
     432              '&m='; 
     433 
     434      if ( !empty($this->now_playing_url) ) 
     435      { 
     436        send_to_log(6,'Attempting to inform Last.FM we are playing a track',array("Artist"=>$artist, "Track"=>$track, "Album"=>$album)); 
     437        $response = http_post( $this->now_playing_url, $data, 1); 
     438         
     439        if (strpos($response,'OK') !== false) 
     440          return true; 
     441        elseif (strpos($response,'BADSESSION') !== false) 
     442          return false; 
     443        else  
     444          return false; 
     445      } 
     446      else  
     447        return false;       
     448    } 
     449     
     450  }   
     451 
     452  /** 
     453   * Returns whether or not a valid username/password has been specified, and the user 
     454   * wishes to allow connections to Last.FM 
     455   * 
     456   * @return bool 
     457   */ 
     458   
     459  function lastfm_enabled() 
     460  { 
     461    if (!internet_available()) 
     462      return false; 
     463    elseif (get_user_pref('LASTFM_USERNAME') == '') 
     464      return false; 
     465    elseif (get_user_pref('LASTFM_PASSWORD') == '') 
     466      return false; 
     467    elseif (get_sys_pref('LASTFM_ENABLED','YES') != 'YES') 
     468      return false; 
     469    else  
     470      return true; 
     471  } 
     472 
     473  /** 
     474   * Returns whether or not the user wishes to scrobble music tracks on the Last.FM website. 
     475   * 
     476   * @return bool 
     477   */ 
     478   
     479  function lastfm_scrobble_enabled() 
     480  { 
     481    return ( lastfm_enabled() && get_user_pref('LASTFM_SCROBBLE','NO') == 'YES'); 
     482  } 
     483 
     484  /** 
     485   * Notifies the last.FM website that you have started playing a track 
     486   * 
     487   * @param string $artist 
     488   * @param string $track 
     489   * @param string $album 
     490   * @param string $length 
     491   * @param string $track_no 
     492   */ 
     493   
     494  function lastfm_now_playing ( $artist, $track, $album, $length, $track_no ) 
     495  {  
     496    if (lastfm_enabled()) 
     497    { 
     498      $obj = new scrobble(); 
     499      $obj->handshake( get_user_pref('LASTFM_USERNAME'), get_user_pref('LASTFM_PASSWORD') );  
     500      $obj->playing( $artist, $track, $album, $length, $track_no ); 
     501    } 
     502  } 
     503 
     504  /** 
     505   * Scrobbles the track (notifies the Last.FM website that the track has finished, and should therefore 
     506   * be added to the user's profile. 
     507   *  
     508   * Note: We have to fudge the "started playing time" because the hardware players caches the file (and so the track won't have 
     509   *      actually finished playing even though it's completed streaming) and there's no notification from the player when the 
     510   *      track is complete. 
     511   * 
     512   * @param string $artist 
     513   * @param string $track 
     514   * @param string $album 
     515   * @param string $length 
     516   * @param string $track_no 
     517   */ 
     518   
     519  function lastfm_scrobble( $artist, $track, $album, $length, $track_no ) 
     520  { 
     521    // Only tracks longer than 30s should be scrobbled. 
     522    if (lastfm_scrobble_enabled() && $length > 30) 
     523    { 
     524      $obj = new scrobble(); 
     525      $obj->handshake( get_user_pref('LASTFM_USERNAME'), get_user_pref('LASTFM_PASSWORD') );  
     526      $obj->submit( gmt_time()-$length, $artist, $track, $album, $length, $track_no ); 
     527    } 
     528     
     529  } 
    272530?> 
  • trunk/swisscenter/ext/lastfm/stream.php

    r820 r853  
    2525    // The playlist (pls) that causes the showcenter to connect to our proxy script 
    2626    header('Content-Type: audio/x-scpls'); 
     27    header('Content-Disposition: attachment; filename="Lastfm.pls"'); 
    2728    echo "[playlist]\n"; 
    2829    echo "NumberOfEntries=1\n"; 
     
    4243     
    4344    // Get artist picture list 
    44     $photos = $lastfm->artist_images($info["artist"]); 
    45     send_to_log(1,'Artist photos',$photos); 
     45    if (get_user_pref('LASTFM_IMAGES','YES') == 'YES') 
     46    { 
     47      $photos = $lastfm->artist_images($info["artist"]); 
     48      send_to_log(6,'Artist photos',$photos); 
     49    } 
    4650 
    4751    // Generate and display the "Now Playing" screen.     
    4852    $image = now_playing_image( array( "LENGTH"=>$info["trackduration"] 
    49                               , "ALBUMART"=>$info["albumcover_large"] 
    50                               , "TITLE"=>$info["track"] 
    51                               , "ARTIST"=>$info["artist"] 
    52                               , "ALBUM"=>$info["album"]),'','','',$photos ); 
     53                                     , "ALBUMART"=>$info["albumcover_large"] 
     54                                     , "TITLE"=>$info["track"] 
     55                                     , "ARTIST"=>$info["artist"] 
     56                                     , "ALBUM"=>$info["album"] 
     57                                     ) 
     58                              , '', '', '', $photos ); 
    5359 
    5460    // Output the image to the browser 
  • trunk/swisscenter/lang/en/en.txt

    r849 r853  
    242242PIN_MISMATCH            = The PIN numbers did not match, not changed 
    243243PLAY                    = Play 
    244 PLAYLISTS_CONFIG_PROMPT = Please specify the fully qualified directory where playlists should be stored by the SwissCenter. [p]For example: On Windows this might be [em]"C:\Documents and Settings\ Robert\My Documents\My Playlists"[/em] or on  a LINUX system it might be [em]"/home/Robert/Playlists"[/em] 
     244PLAYLISTS_CONFIG_PROMPT = Please specify the fully qualified directory where playlists should be stored by the SwissCenter. [p]For example: On Windows this might be [em]"C:\Documents and Settings\Robert\My Documents\My Playlists"[/em] or on  a LINUX system it might be [em]"/home/Robert/Playlists"[/em] 
    245245PLAYLISTS_ERROR_DIR     = Please select a playlist location 
    246246PLAYLISTS_ERROR_INVALID = I'm sorry, the directory you specified does not exist 
     
    595595CONFIG_IMAGE_OPTIONS    = Images 
    596596CONFIG_AUDIO_OPTIONS    = Audio  
    597 CONFIG_RADIO_OPTIONS    = Internet Radio Options 
     597CONFIG_RADIO_OPTIONS    = Internet Radio 
    598598PASS_PHP_FONTS          = Successfully located a TrueType Font for generating "Now Playing" images. 
    599599FAIL_PHP_FONTS          = Unable to lo