greglamb
1/21/2011 - 9:02 PM

Web scrape your TiVo recording schedule into iCal format for use with Google Calendar

Web scrape your TiVo recording schedule into iCal format for use with Google Calendar

<?

/*
	TiVo To-Do List to iCal
	Requires iCalcreator (http://www.kigkonsult.se/iCalcreator/)
	
	See your recording schedule in Google Calendar!
*/

ini_set('display_errors','Off');
require_once('iCalcreator.class.php');

$cache_only = 0;			# For testing
$maxcache = (60 * 60);			# Time to cache TiVo site pull In Seconds
$username = 'username@domain.com';	# TiVo web site username
$password= 'yourpassword';		# TiVo web site password
$cookiedir = '/tmp';			# Path to Cookie Jar
$cache = "cache/tivo";			# Path to cache file

function GetTivo() {
	global $username;
	global $password;
	global $cookiedir;
	
	$ckfile = tempnam($cookiedir, 'TIVOCOOKIEJAR');
	$ch = curl_init('https://www3.tivo.com/tivo-tco/login.do?WT.rv=1&WT.z_login=Logged+in');
	curl_setopt($ch, CURLOPT_POST, 1);
	curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
	curl_setopt($ch, CURLOPT_COOKIEJAR, $ckfile);
	curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
	curl_setopt($ch, CURLOPT_POSTFIELDS, 'cams_cb_partner=&cams_security_domain=tivocom&cams_login_config=http&cams_cb_username='.$username.'&cams_cb_password='.$password.'&cams_original_url&/tivo-tco/index.do');
	$loginReturn = curl_exec ($ch);
	
	$offsets = array(0, 20, 40, 60);
	foreach($offsets as $offset) {
		$ch = curl_init('https://www3.tivo.com/tivo-tco/go.do?def=todo.content.body&orderBy=startTime&groupBy=&offset='.$offset);
		curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
		curl_setopt ($ch, CURLOPT_COOKIEFILE, $ckfile);
		curl_setopt ($ch, CURLOPT_RETURNTRANSFER, true);
		$xml_input .= curl_exec ($ch);
	}

	return $xml_input;
}

$time = time();
$cachetime = filemtime($cache);

if (file_exists($cache)) {
	if ((($time - $cachetime) > ($maxcache)) and (!$cache_only)) {
		$xml_raw = GetTivo();
		if (!$xml_raw) {
			$xml_raw = file_get_contents($cache);
			error_log("TiVo is angry", 0);
		}
		file_put_contents($cache, $xml_raw);
	} else {
		$xml_raw = file_get_contents($cache);
	}
} else {
	$xml_raw = GetTivo();
	file_put_contents($cache, $xml_raw);
}

$xml_input = preg_replace('/href=".*"/', '', $xml_raw);
$doc = new DOMDocument();
$doc->strictErrorChecking = FALSE;
$doc->loadHTML($xml_input);
$xml_input = simplexml_import_dom($doc);

$v = new vcalendar( array( 'unique_id' => 'tivotodoical' ));
$v->setProperty( 'method', 'PUBLISH' );
$v->setProperty( "x-wr-calname", "TiVo Schedule" );
$v->setProperty( "X-WR-TIMEZONE", "America/Los_Angeles" );

foreach ($xml_input->body->div as $page) {
	foreach($page->div[0]->ul->li as $entry) {
		$Date = $entry->span[2]."/".date("Y");
		$Time = $entry->span[3];
		$Stamp = DateTime::createFromFormat('n/j/Y g:i a', $Date.' '.$Time);
		$Description = trim($entry->a);

		$e = & $v->newComponent( 'vevent' );
		$e->setProperty( 'dtstart',  $Stamp->format('Y'), $Stamp->format('m'), $Stamp->format('d'), $Stamp->format('H'), $Stamp->format('i'), 00);
		$e->setProperty( 'duration', 0, 0, 0, 30 );
		$e->setProperty( 'summary', $Description );
	}
}

$v->returnCalendar();