<?php
/*
Plugin Name: Netflix Queue
Version: 1.0
Plugin URI: http://grahame.com/blog/2005/05/08/netflix-queue-10
Description: Displays entries from your Netflix Queue.  Click for <a target="_blank" href="../wp-content/plugins/netflix-queue.php?help=setup">detailed installation instructions</a>.
Author: Grahame Murray
Author URI: http://grahame.com/
*/


// NetflixID: Your NetflixID number for RSS feeds
// (See the plugin's description in the WordPress Plugins admin page for help)
$NetflixID "";


// CacheDirectory: where to store previously downloaded RSS Files
// (this directory must be world writable)
$CacheDirectory "";


// CacheTimeout: how many minutes to keep a previosuly downloaded RSS file
// (Netflix indicates that they would prefer you keep this at 60 minutes)
$CacheTimeout 60;


// DateFormat: just like WordPress' "Default date format"
// (uses the PHP date syntax: http://php.net/date)
$DateFormat "m/d/y";



/****************************************
 *  There should be no need to edit     *
 *  below this line.  Beware!!          *
 ****************************************/



// Handle the Pop Assistant, for the people who just won't read READMEs.
if(ISSET($_GET["help"])) {
require(
"../../wp-blog-header.php");
?>
<html>
  <head>
    <title>Netflix Queue Setup Assistant</title>
<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); ?>" type="text/css" media="screen" />

  </head>
  <body>
   <div style="font-family: Verdana">

    <h1>Netflix Queue Setup Assistant</h1>

   <h2>Step One: Configure your NetflixID</h2>
   <? $c = @count(get_netflix_queue("")); ?>
   <? if("" == $NetflixID || $c==0) { ?>

<?if("" == $NetflixID) { ?>
You have not yet setup your NetflixID.  To find it...

<? } else { ?>

Hmmmmmm.  It looks like you've tried to set your NetflixID to "<?=$NetflixID?>", but nothing is in the queue for that NetflixID.  If your queue is actually empty, ignore this, but otherwise double check your NetflixID is exactly (no extra spaces) what appears when using the following instructions...

<? ?>

<p/>

Login to your Netflix Account, visit Netflix's <a href="http://www.netflix.com/RSSFeeds?lnkctr=mfRSS">RSS Feeds</a> page.  You can also find this via the RSS link in the Netflix site navigation footer.  This page contains links to RSS feeds of your Queue, Most Recent Rental Activity, and Recommendations.  Look for the Personalized Feeds section, with Queue and Most Recent Rental Activity beneath it.  

<p />

The links presented there all have ?id= followed by a big number. You're interested in that number, something like P6235749730512420570347411841874294.  Copy this number into the $NetflixID variable in netflix-queue.php.

<? } else { ?>

Your NetflixID of "<?=$NetflixID?>" appears to be ok.  Nice work.

<? ?>

  <h2>Step Two: Setup the Cache Directory</h2>
  <?
    
if($CacheDirectory == "") {
  
?>
You still have not set a value for the $CacheDirectory.  I suggest something like "<?=realpath("../cache/netflix-queue")?>".  You will need to edit your copy of netflix-queue.php to set this variable.  You will also need to make this directory world writeable, so that the webserver can write to it.

<p />

<b>Note</b>: You will be able to retreive your Netflix queue without caching it.  But every request to a page that uses Netflix functions will have to wait for a full request to the Netflix site.  This is not a great idea, performance WILL be affected and besides, it is a bit rude.
  <?
    
}
    else {
      
$stats = @stat($CacheDirectory);
  
?>
  netflix-queue.php is currently configured to use "<?= $CacheDirectory ?>" as a cache directory.  This directory currently <? if(file_exists($CacheDirectory)) {?>
  exists, good job.
<? } else { ?>
  does not exist, you need to make it.
 <? 
    if(!
is_writeable($CacheDirectory)) { ?>
   However, the directory is not writable by the web server (typically user 'nobody').  Make sure there are world write permissions on this directory.
 <? } else { ?>
   And the directory is writeable, excellent.  You are good to go for this step!
  <?  
    }
  
?>

  <h2>Step Three: Update your index.php</h2>
  There are several functions that you can make use of from any WordPress script.  The first two are probably the most interesting most people:
  <br /><br />
  <code>print_netflix_athome( [string template [, int limit]] )</code> - echoes the results of get_netflix_athome to the screen.<br />
  <code>print_netflix_queue( [string template [, int limit]] )</code> - echoes the results of get_netflix_queue to the screen<br /><br />
  <code>get_netflix_athome( string template, int limit )</code> - returns an array of strings, one for each item the "at home"<br />
  <code>get_netflix_queue( string template, int limit )</code> - returns an array of strings, one for each item in the queue<br /><br />
  <code>render_netflix_item( array item, string template )</code> - Does string substitutions on the given $template replacing keys from the given $item with their associated value.<br /><br />
  <code>get_netflix_items( string file )</code> - Returns an array of item arrays representing the items in the given file.  $file can be either Queue, Tracking, or Recommendation.<br /><br />
  <code>get_netflix_cached_file( string file )</code> - Returns the contents of the given Netflix RSS file.<br /><br />
  
  <h3>Parameter Notes</h3>
  <b>template</b> - is a string such as "&lt;li>{number} {title}&lt;/li>".  The values within curly-braces {} are substituted, if they exist, for each item.  The available values are: number, title, link, linked_title, and description. shipped is also available for calls to the athome functions.  The format of this date can be affected by modifying the $DateFormat configuration variable.
  <br /><br />
  <b>limit</b> - is the maximum number of entries to process (useful for really large queues).
  <br /><br />
  <b>file</b> - can be "Queue", "Tracking", or "Recommendations".  These are used in constructing the RSS URL to request from the Netflix website</li>
   </div>
  </body>
</html>
<?
}

function 
print_netflix_athome($line_template '<li>{linked_title}</li>') {
  
$items get_netflix_athome($line_template);
  foreach(
$items as $item) {
    echo 
"$item\n";
  }
}

function 
print_netflix_queue($line_template '<li>{number}: {linked_title}</li>'$limit = -1) {
  
$items get_netflix_queue($line_template$limit);
  foreach(
$items as $item) {
    echo 
"$item\n";
  }
}


function 
get_netflix_athome($line_template) {
  global 
$DateFormat;

  
$contents get_netflix_cached_file("Tracking");
  
$items get_netflix_items($contents);
  
$results = array();
  for(
$i 0$i count($items); $i++) {
    
$item $items[$i];
    if(
strpos($item["title"], "Shipped: ") !== false) {
      
$item["title"] = str_replace("Shipped: """$item["title"]); 
    }
    else {
      continue;
    }

    if(
preg_match("|^<p>Shipped on (\d\d)/(\d\d)/(\d\d)\.</p>|"$item["description"], $matches)) {
      
$item["description"] = str_replace($matches[0], ""$item["description"]);
      
$date mktime(000$matches[1], $matches[2], $matches[3]);
      
$item["shipped"] = date($DateFormat$date);
    }

    
$item["number"] = $i+1;
    
$item["linked_title"] = "<a href='$item[link]'>$item[title]</a>";

    
$results[] = render_netflix_item($item$line_template);
  }

  return 
$results;
}

function 
get_netflix_queue($line_template$limit = -1) {
  
$contents get_netflix_cached_file("Queue");
  
$items get_netflix_items($contents);
  
$results = array();

  
// If no upper limit is set, set it to the actual size
  
if($limit == -1) {
    
$limit count($items);
  }
  else if(
$limit count($items)) {
    
$limit count($items);
  }

  for(
$i 0$i $limit$i++) {
    
$item $items[$i];
    
$item["title"] = preg_replace("/\d+- /"""$item["title"]);
    
$item["number"] = $i+1;
    
$item["linked_title"] = "<a href='$item[link]'>$item[title]</a>";

    
$results[] = render_netflix_item($item$line_template);
  }

  return 
$results;
}

function 
render_netflix_item($item$line_template) {
  
// apply template
  
$result $line_template;
  foreach(
array_keys($item) as $key) {
    
$result str_replace("{".$key."}"$item[$key], $result);
  }   
  return 
$result;
}


/**
 * Quick and dirty XML parser, relies on item tree being only two nodes deep
 *
 * Generic function to divide the given contents up into item elements
 * then further by each child element
 */
function get_netflix_items($contents) {
  
preg_match_all("|<item>(.+?)</item>|s"$contents$itemsPREG_SET_ORDER);
  
$results = array();
  foreach(
$items as $item) {
    
preg_match_all("#<(.+?)>(<!\[CDATA\[.+?\]\]>|.+?)</.+?>#s"$item[1], $elementsPREG_SET_ORDER);
    
$result = array();
    foreach(
$elements as $element) {
      
$str str_replace("<![CDATA["""$element[2]);
      
$str str_replace("]]>"""$str);
      
$result[$element[1]] = $str;
    }
    
$results[] = $result;
  }

  return 
$results;
}

// $file should be Queue or Tracking
function get_netflix_cached_file($file) {
  global 
$CacheTimeout$CacheDirectory$NetflixID;
  
// Look for the file
  
$path "$CacheDirectory/$file.xml";
  
$stats = @stat($path);

  
// file doesn't exist or has expired
  
if($stats === false || (mktime() - $stats[9]) > ($CacheTimeout*60)) {
    
$url "http://rss.netflix.com/${file}RSS?id=$NetflixID";
    
$ch curl_init($url);
    
curl_setopt($chCURLOPT_RETURNTRANSFER1);
    
$contents curl_exec($ch);
    
curl_close($ch);
    
$fh = @fopen($path"w");
    @
fwrite($fh$contents);
    @
fclose($fh);
    return 
$contents;
  }
  else {
    return 
file_get_contents($path);
  }


?>