<?php
/*
Plugin Name: last.fm weekly artists
Version: 0.4
Plugin URI: http://theboywonder.co.uk/2006/08/08/last-fm-weekly-artists-wordpress-plugin/
Description: Provides a function to display the weekly artists from a last.fm profile
Author: Tijs Teulings (modified by Robin Malik)
Author URI: http://blog.tijs.org/

Based on the del.icio.us plugin by Tom Gilbert (http://linuxbrit.co.uk)

Copyright (c) 2004
Released under the GPL license
http://www.gnu.org/licenses/gpl.txt
*/

/*
 version history: 
    v0.4 (09-03-2006) - changed caching behaviour & using xml instead of rss
    v0.3 (01-11-2005) - <ul> tags generated by the plugin
    v0.2 (01-11-2005) - fixed a problem with caching
    v0.1 (01-11-2005) - initial release
*/

/*
 usage: just call the weekly_artists function somewhere in your
        template, and style the output using CSS. Don't forget to enable
        the plugin on the wordpress admin page.
        example: <?php weekly_artists('theboywonder'); ?>
        You do not need to change anything below. No, not even $user haha.
*/

function weekly_artists(
  
$user,                       # your last.fm username
  
$display_metalinks false,    # display feed and site info
  
$cache_time=10,            # how long to cache the results for (default=10 minutes)
  
$cache_file ""             # cache file (defaults to
                               # /tmp/last.fm.$user.$cache_time.cache)
) {
  
    global 
$_fpwrite;
      global 
$_last_user;
      global 
$_curl_error_code;

    global 
$insideitem;
    global 
$tag;
    global 
$artist;
    global 
$playcount;
    global 
$link;
    
    global 
$items;
    
    
$insideitem FALSE;
    
$tag "";
    
$artist "";
    
$playcount "";
    
$link "";
    
$items 0;
  
    
$_last_user $user;
      
$api_url "http://ws.audioscrobbler.com/1.0/user/$_last_user/weeklyartistchart.xml";

    if (
$cache_file == ""
    {
        
$cache_file  =  "/tmp/last.fm.$_last_user.$cache_time.cache";
        
//$cache_file  =  "/tmp/last.fm.$cache_time.cache";
    
}
      
    
$cache_file_tmp "$cache_file.tmp";

    
$time split(" "microtime());
    
srand((double)microtime()*1000000);
    
    
# randomise a bit, between 30 and 60s "off the mark" to avoid a bunch of
    # requests all simultaneously deciding to refresh the file
    
$cache_time_rnd 30 rand(060);

    if (
        !
file_exists($cache_file)
          || !
filesize($cache_file) > 20
          
|| ((filemtime($cache_file) + $cache_time $time[1]) + $cache_time_rnd 0)
          || (
filemtime(__FILE__) > filemtime($cache_file))
      ) 
    {
      
        
$c curl_init($api_url);
          
curl_setopt($cCURLOPT_RETURNTRANSFER,1); 
          
//curl_setopt($c, CURLOPT_USERPWD,"$user:$pass"); 
          
curl_setopt($cCURLOPT_CONNECTTIMEOUT2);
          
curl_setopt($cCURLOPT_TIMEOUT4);
          
curl_setopt($cCURLOPT_USERAGENT"Last.fm WordPress Plugin v0.4 (http://blog.tijs.org/)");
          
$response curl_exec($c);
          
$info curl_getinfo($c);
        
// check if the response contains artists
        
$findme  '<artist>';
        
$pos strpos($response$findme);
        
        if (
$pos !== false
        {
        
            
//echo "write new cache file";
            
              
$_curl_error_code $info['http_code'];
              
curl_close($c);
            if (
$_curl_error_code == 200// STATUS OK
            
{
                
$_fpwrite fopen($cache_file_tmp'w');
                 if (
$_fpwrite
                {
                    
# parse the XML, then write out includable html to the cache file.
                       
if (!($xml_parser xml_parser_create()))
                         die(
"Couldn't create parser.");

                       
xml_set_element_handler($xml_parser"startElement""endElement");
                       
fputs($_fpwrite"<ul>\n");
                    
xml_set_character_data_handler($xml_parser"characterData"); 
                     
xml_parse($xml_parser$response);
                    if (
$display_metalinks
                    {
                         
fputs($_fpwrite"<li><a href='http://www.last.fm/user/"
                            
."$user'><strong>more</strong></a> | "
                            
."<a href='http://ws.audioscrobbler.com/1.0/user/$user/recenttracks.rss'>"
                            
."<strong>feed</strong></a></li>");
                       }
                       
fputs($_fpwrite"</ul>\n");

                       
xml_parser_free($xml_parser);
                       
fclose($_fpwrite);
                       
# be atomic
                    
rename($cache_file_tmp$cache_file);
                }
            }
        }
    }
        
    if ((
file_exists($cache_file)) && filesize($cache_file) > 20
    {
        include(
$cache_file);
    } 
    elseif (
$_curl_error_code
    {
        echo 
"<li>No recent artists (error $_curl_error_code)</li>";
    } 
    else 
    {
        echo 
"<li>No recent artists</li>";
    }
}

function 
startElement($parser$name$attrs) {
    global 
$insideitem$tag$artist$playcount$link$_fpwrite;
    if (
$insideitem
    {
        
$tag $name;
    } 
    elseif (
$name == "ARTIST"
    {
        
$insideitem true;
        
$items++;
    }
}

function 
endElement($parser$name) {
    global 
$insideitem$tag$artist$playcount$link$_fpwrite;
    if (
$name == "ARTIST"
    {
        
fputs($_fpwrite"<li><a href=\"".trim($link)."\">".htmlspecialchars(trim($artist))." (".htmlspecialchars(trim($playcount)).")</a></li>");
        
$artist "";
        
$playcount "";
        
$link "";
        
$insideitem false;
    }
}

function 
characterData($parser$data) {
    global 
$insideitem$tag$artist$playcount$link;
    if (
$insideitem
    {
        switch (
$tag) {
            case 
"NAME":
            
$artist .= $data;
            break;
            case 
"PLAYCOUNT":
            
$playcount .= $data;
            break;
            case 
"URL":
            
$link .= $data;
            break;
        }
    }
}

?>