File: /home/mmickelson/theflexguys.com/baronconstruct/wp-content/plugins/podpress/podango-api.php
<?php
class PodangoAPI
{
var $serviceUrl = 'http://www.podango.com/api/';
var $fileUploader = 'http://www.podango.com/podcasts/file_upload.php';
var $mediaTrackerURL = 'http://download.podango.com/mediatracker/';
var $responseCode;
var $responseString;
var $parsed_xml;
var $accessKey;
var $secretKey;
var $defaultPodcast = '##ALL##';
var $defaultTranscribe = 0;
function PodangoAPI($accessKey, $secretKey)
{
$this->accessKey = $accessKey;
$this->secretKey = $secretKey;
}
/*************************************************************/
/* Functions for managing the users podcasts */
/*************************************************************/
function GetPodcasts($onlyBasics = false) {
$this->_GetPodcasts('##ALL##', $onlyBasics);
return $this->_ParsePodcasts($this->parsed_xml['Response']['_c']['User']['_c']['Podcast']);
}
function GetPodcast($podcastId, $onlyBasics = false) {
$this->_GetPodcasts($podcastId);
$result = $this->_ParsePodcasts($this->parsed_xml['Response']['_c']['Podcast'], $onlyBasics);
return $result[$podcastId];
}
function CreatePodcast($title, $description)
{
$params = array();
$params['Title'] = $title;
$params['Description'] = $description;
$result = $this->_call('podcast/', 'PUT', $params);
if ($this->responseCode != 200) {
return false;
}
return true;
}
function UpdatePodcast($podcastId, $title, $description)
{
$params = array();
$params['PodcastID'] = $podcastId;
$params['Title'] = $title;
$params['Description'] = $description;
$result = $this->_call('podcast/', 'POST', $params);
if ($this->responseCode != 200)
return false;
return true;
}
function DeletePodcast($podcastId)
{
$params = array();
$params['PodcastID'] = $podcastId;
$result = $this->_call('podcast/', 'DELETE', $params);
if ($this->responseCode != 200) {
return false;
}
return true;
}
function _GetPodcasts($podcastId = '##NOTSET##') {
$params = array();
if($podcastId == '##NOTSET##') {
$podcastId = $this->defaultPodcast;
}
if($podcastId != '##ALL##') {
$params['PodcastID'] = $podcastId;
}
$result = $this->_call('podcast/', 'GET', $params);
if ($this->responseCode != 200) {
return false;
}
return true;
}
/*************************************************************/
/* Functions for managing the users episodes */
/*************************************************************/
function GetEpisodes($requireFileURI = false) {
$this->_GetEpisodes();
$podcasts = $this->_ParsePodcasts($this->parsed_xml['Response']['_c']['User']['_c']['Podcast']);
foreach($podcasts as $podcast) {
foreach ($podcast['Episode'] as $episode)
{
if(!$requireFileURI || !empty($episode['FileURI'])) {
$result[$episode['ID']] = $episode;
$result[$episode['ID']]['Podcast'] = $podcast['ID'];
}
}
}
return $result;
}
function GetEpisode($episodeId) {
$this->_GetEpisodes($episodeId);
$result = $this->_ParseEpisode($this->parsed_xml['Response']['_c']['Podcast']['_c']);
return $result[$episodeId];
}
function CreateEpisode($podcastId, $title, $description, $transcript = '', $mediafile = '', $transcribe = '')
{
$params = array();
$params['PodcastID'] = $podcastId;
$params['Title'] = $title;
$params['Description'] = $description;
if(!empty($transcript)) {
$params['Transcript'] = $transcript;
}
if(!empty($mediaFileId)) {
$params['MediaFileId'] = $mediaFileId;
}
if(empty($transcribe)) {
$params['Transcribe'] = $this->defaultTranscribe;
} else {
$params['Transcribe'] = $transcribe;
}
$result = $this->_call('episode/', 'PUT', $params);
if ($this->responseCode != 200) {
return false;
}
return $this->parsed_xml['Response']['_c']['Podcast']['_c']['Episode']['_c']['ID']['_v'];
}
function UpdateEpisode($episodeId, $title, $description, $transcript = '', $mediaFileId = '', $transcribe = '')
{
$params = array();
$params['EpisodeID'] = $episodeId;
$params['Title'] = $title;
$params['Description'] = $description;
if(!empty($transcript)) {
$params['Transcript'] = $transcript;
}
if(!empty($mediaFileId)) {
$params['MediaFileId'] = $mediaFileId;
}
if(empty($transcribe)) {
$params['Transcribe'] = $this->defaultTranscribe;
} else {
$params['Transcribe'] = $transcribe;
}
$result = $this->_call('episode/', 'PUT', $params);
if ($this->responseCode != 200) {
return false;
}
return true;
}
function DeleteEpisode($episodeId) {
$params = array();
$params['EpisodeID'] = $episodeId;
$files = array();
$result = $this->_call('episode/', 'DELETE', $params, $files);
if ($this->responseCode != 200) {
return false;
}
return true;
}
function _GetEpisodes($episodeId = '##NOTSET##') {
$params = array();
if($podcastId == '##NOTSET##') {
$podcastId = $this->defaultPodcast;
}
if($episodeId != '##ALL##') {
$params['EpisodeID'] = $episodeId;
}
$result = $this->_call('episode/', 'GET', $params);
if ($this->responseCode != 200) {
return false;
}
return true;
}
/*************************************************************/
/* Functions for managing the users media files */
/*************************************************************/
function GetMediaFiles($podcastId = '##NOTSET##') {
if($podcastId == '##NOTSET##') {
$podcastId = $this->defaultPodcast;
}
$this->_GetMediaFiles($podcastId);
if(isset($this->parsed_xml['Response']['_c']['User']['_c']['Podcast'])) {
$podcasts = $this->_ParsePodcasts($this->parsed_xml['Response']['_c']['User']['_c']['Podcast']);
} else {
$podcasts = $this->_ParsePodcasts($this->parsed_xml['Response']['_c']['Podcast']);
}
foreach($podcasts as $podcast) {
foreach ($podcast['MediaFile'] as $mediaFile)
{
$result[$mediaFile['ID']] = $mediaFile;
$result[$mediaFile['ID']]['Podcast'] = $podcast['ID'];
}
}
return $result;
}
function GetMediaFile($mediaFileId) {
// temp solution while I work out some other bugs
$result = $this->GetMediaFiles();
return array($mediaFileId=>$result[$mediaFileId]);
// Heres a start at the more correct implementation
$this->_GetMediaFiles('##NOTSET##');
$result = $this->_ParseEpisode($this->parsed_xml['Response']['_c']['Podcast']['_c']);
return $result[$episodeId];
}
function GetMediaFileID($podcastId, $fileName) {
$params = array();
$params['PodcastID'] = $podcastId;
$params['FileName'] = $fileName;
$result = $this->_call('media_file/', 'GET', $params);
if ($this->responseCode != 200) {
return false;
}
return $this->parsed_xml['Response']['_c']['User']['_c']['Podcast']['_c']['MediaFile']['_c']['ID']['_v'];
}
/* Not yet implemented
function CreateMediaFile($podcastId, $mediafile)
{
$filename = basename($filePath);
$params = array();
$params['EpisodeID'] = $episodeId;
$params['Filename'] = $filename;
$fsize = filesize($filePath);
$readStream = new PodangoStreamReader();
$readStream->readHandle = fopen($filePath, "r");
$this->_putObjectStream($params, 'media_file/', array($readStream, "stream_function"), "binary/octet-stream", $fsize);
if ($this->responseCode != 200) {
return false;
}
return true;
}
function UpdateMediaFile($mediaFileId, $content)
{
$params = array();
$params['MediaFileId'] = $mediaFileId;
if ($filename != "") {
$filename = basename($filename);
$params['Filename'] = $filename;
}
$result = $this->_call('media_file/', 'PUT', $params);
if ($this->responseCode != 200) {
return false;
}
return true;
}
*/
function DeleteMediaFile($mediaFileId) {
$params = array();
$params['MediaFileId'] = $mediaFileId;
$result = $this->_call('media_file/', 'DELETE', $params);
if ($this->responseCode != 200) {
return false;
}
return true;
}
function _GetMediaFiles($podcastId = '##NOTSET##') {
$params = array();
if($podcastId == '##NOTSET##') {
$podcastId = $this->defaultPodcast;
}
if($podcastId != '##ALL##') {
$params['PodcastID'] = $podcastId;
}
$result = $this->_call('media_file/', 'GET', $params);
if ($this->responseCode != 200) {
return false;
}
return true;
}
/*************************************************************/
/* Parsing functions to handle the API responses */
/*************************************************************/
function _ParsePodcasts($input, $onlyBasics = false) {
$result = array();
if (is_array($input)) {
if (isset($input['_c'])) {
$input[] = $input;
}
foreach ($input as $podcast) {
if (isset($podcast['_a']['ID'])) {
$id = $podcast['_a']['ID'];
} else {
$id = $podcast['_c']['ID']['_v'];
}
if(!empty($id)) {
$result[$id] = array();
$result[$id]['ID'] = $id;
if(isset($podcast['_c']['Title'])) {
$result[$id]['Title'] = $podcast['_c']['Title']['_v'];
}
if(isset($podcast['_c']['Description'])) {
$result[$id]['Description'] = $podcast['_c']['Description']['_v'];
}
if(isset($podcast['_c']['RSSFeed'])) {
$result[$id]['RSSFeed'] = $podcast['_c']['RSSFeed']['_v'];
}
if(isset($podcast['_c']['Keywords'])) {
$result[$id]['Keywords'] = $podcast['_c']['Keywords']['_v'];
}
if(isset($podcast['_c']['Explicit'])) {
$result[$id]['Explicit'] = $podcast['_c']['Explicit']['_v'];
}
if(!$onlyBasics) {
if(isset($podcast['_c']['Episode'])) {
$result[$id]['Episode'] = $this->_ParseEpisodes($podcast['_c']['Episode']);
}
if(isset($podcast['_c']['MediaFile'])) {
$result[$id]['MediaFile'] = $this->_ParseMediaFiles($podcast['_c']['MediaFile']);
}
}
}
}
}
return $result;
}
function _ParseEpisodes($input) {
if (is_array($input)) {
if (isset($input['_c'])) {
$input[] = $input;
}
return $this->_ParseEpisode($input);
}
return array();
}
function _ParseEpisode($input) {
$result = array();
if (is_array($input)) {
if (isset($input['_c'])) {
$input[] = $input;
}
foreach ($input as $episode) {
if (isset($episode['_a']['ID'])) {
$id = $episode['_a']['ID'];
} else {
$id = $episode['_c']['ID']['_v'];
}
if(!empty($id)) {
$result[$id]['ID'] = $id;
if(isset($episode['_c']['Title'])) {
$result[$id]['Title'] = $episode['_c']['Title']['_v'];
}
if(isset($episode['_c']['Date'])) {
$result[$id]['Date'] = $episode['_c']['Date']['_v'];
}
if(isset($episode['_c']['Description'])) {
$result[$id]['Description'] = $episode['_c']['Description']['_v'];
}
if(isset($episode['_c']['Transcript'])) {
$result[$id]['Transcript'] = $episode['_c']['Transcript']['_v'];
}
if(isset($episode['_c']['MediaFileId'])) {
$result[$id]['MediaFileId'] = $episode['_c']['MediaFileId']['_v'];
}
if(isset($episode['_c']['FileURI']) && $episode['_c']['FileURI']['_v'] != 'sucksforyou-no-url') {
$result[$id]['FileURI'] = $episode['_c']['FileURI']['_v'];
$result[$id]['Filename'] = basename($episode['_c']['FileURI']['_v']);
}
if(isset($episode['_c']['Length'])) {
$result[$id]['Length'] = $episode['_c']['Length']['_v'];
}
if(isset($episode['_c']['FileSize'])) {
$result[$id]['FileSize'] = $episode['_c']['FileSize']['_v'];
}
if(isset($episode['_c']['ImageURI'])) {
$result[$id]['ImageURI'] = $episode['_c']['ImageURI']['_v'];
}
if(isset($episode['_c']['Status'])) {
$result[$id]['Status'] = $episode['_c']['Status']['_v'];
}
}
}
}
return $result;
}
function _ParseMediaFiles($input) {
if (is_array($input)) {
if (isset($input['_c'])) {
$input[] = $input;
}
return $this->_ParseMediaFile($input);
}
return array();
}
function _ParseMediaFile($input) {
$result = array();
if (is_array($input)) {
if (isset($input['_c'])) {
$input[] = $input;
}
foreach ($input as $mediaFile) {
if (isset($mediaFile['_a']['ID'])) {
$id = $mediaFile['_a']['ID'];
} else {
$id = $mediaFile['_c']['ID']['_v'];
}
if(!empty($id)) {
$result[$id]['ID'] = $id;
if(isset($mediaFile['_c']['Filename'])) {
$result[$id]['Filename'] = $mediaFile['_c']['Filename']['_v'];
}
if(isset($mediaFile['_c']['FileURI'])) {
$result[$id]['FileURI'] = $mediaFile['_c']['FileURI']['_v'];
}
if(empty($result[$id]['Filename'])) {
$result[$id]['Filename'] = basename($result[$id]['FileURI']);
}
if(isset($mediaFile['_c']['ByteSize'])) {
$result[$id]['ByteSize'] = $mediaFile['_c']['ByteSize']['_v'];
}
if(isset($mediaFile['_c']['Episode']['_c']['ID'])) {
$result[$id]['EpisodeID'] = $mediaFile['_c']['Episode']['_c']['ID']['_v'];
}
if(isset($mediaFile['_c']['Episode']['_c']['Title'])) {
$result[$id]['EpisodeTitle'] = $mediaFile['_c']['Episode']['_c']['Title']['_v'];
}
}
}
}
return $result;
}
/*************************************************************/
/* Functions to handle the actual API calls */
/*************************************************************/
function _call($URIFolder, $method, $params, $files = '##NOTSET##')
{
if (!isset($params)) {
$params = array();
}
if ($files == '##NOTSET##') {
$files = array();
}
$timestamp = gmdate('Y-m-d\TH:i:s\Z');
$stringToSign = $method.$timestamp.$this->accessKey;
// Add Actions
//$params['Action'] = $action;
$params['Version'] = '2007-01-15';
$params['AccessKey'] = $this->accessKey;
$params['Authorization'] = $this->_constructSig($stringToSign);
$params['Timestamp'] = $timestamp;
$request = '';
foreach ($params as $name => $value) {
$request .= $name . '=' . urlencode($value) . '&';
}
$this->_pchop($request);
$req = & new PodangoHTTPRequest($this->serviceUrl.$URIFolder);
$req->setMethod($method);
$req->setQueryString($request);
$this->responseString = $req->DownloadToString();
$this->responseCode = $req->getResponseCode();
$this->parsed_xml = $this->_getParsedXMLString($this->responseString);
}
function _hex2b64($str)
{
$raw = '';
for ($i=0; $i < strlen($str); $i+=2) {
$raw .= chr(hexdec(substr($str, $i, 2)));
}
return base64_encode($raw);
}
function _constructSig($str)
{
return $this->_hex2b64($this->_cryptHMAC($this->secretKey, $str));
}
/**
* implementation of Perl's "chop" function
*/
function _pchop($string) {
if (is_array($string)) {
foreach($string as $i => $val) {
$endchar = $this->_pchop($string[$i]);
}
} else {
$endchar = substr("$string", strlen("$string") - 1, 1);
$string = substr("$string", 0, -1);
}
return $endchar;
}
function _putObjectStream($params, $URIFolder, $streamFunction, $contentType, $contentLength)
{
$timestamp = gmdate('Y-m-d\TH:i:s\Z');
$stringToSign = 'PUT'.$timestamp.$this->accessKey;
$params['Version'] = '2007-01-15';
$params['AccessKey'] = $this->accessKey;
$params['Authorization'] = $this->_constructSig($stringToSign);
$params['Timestamp'] = $timestamp;
$request = '';
foreach ($params as $name => $value) {
$request .= $name . '=' . urlencode($value) . '&';
}
$this->_pchop($request);
$curl_inst = curl_init();
curl_setopt ($curl_inst, CURLOPT_CONNECTTIMEOUT, 300);
curl_setopt ($curl_inst, CURLOPT_LOW_SPEED_LIMIT, 1);
curl_setopt ($curl_inst, CURLOPT_LOW_SPEED_TIME, 180);
curl_setopt ($curl_inst, CURLOPT_NOSIGNAL, 1);
curl_setopt ($curl_inst, CURLOPT_READFUNCTION, $streamFunction);
curl_setopt ($curl_inst, CURLOPT_URL, $this->serviceUrl.$URIFolder.'?'.$request);
curl_setopt ($curl_inst, CURLOPT_UPLOAD, true);
curl_setopt ($curl_inst, CURLINFO_CONTENT_LENGTH_UPLOAD, $contentLength);
$header[] = "Date: $timestamp";
$header[] = "Content-Type: $contentType";
$header[] = "Content-Length: $contentLength";
$header[] = "Expect: ";
$header[] = "Transfer-Encoding: ";
curl_setopt($curl_inst, CURLOPT_HTTPHEADER, $header);
curl_setopt($curl_inst, CURLOPT_RETURNTRANSFER, 1);
$this->responseString = curl_exec ($curl_inst);
$this->responseCode = curl_getinfo($curl_inst, CURLINFO_HTTP_CODE);
$this->parsed_xml = $this->_getParsedXMLString($this->responseString);
curl_close($curl_inst);
}
/* function to generate HMAC hash */
function _cryptHMAC($key, $data) {
$func = 'sha1';
$pack = 'H40';
if (strlen($key) > 64) {
$key = pack($pack, $func($key));
}
if (strlen($key) < 64) {
$key = str_pad($key, 64, chr(0));
}
$ipad = (substr($key, 0, 64) ^ str_repeat(chr(0x36), 64));
$opad = (substr($key, 0, 64) ^ str_repeat(chr(0x5C), 64));
return $func($opad . pack($pack, $func($ipad . $data)));
}
// _Internal: Remove recursion in result array
function _del_p($ary) {
foreach ($ary as $k=>$v) {
if ($k==='_p') {
unset($ary[$k]);
} elseif (is_array($ary[$k])) {
$this->_del_p($ary[$k]);
}
}
}
function _getParsedXMLString($xml) {
/*Format XML->Array
_c - children
_v - value
_a - attributes
*/
$parser = xml_parser_create();
xml_parser_set_option($parser, XML_OPTION_CASE_FOLDING, 0);
xml_parse_into_struct($parser, $xml, $vals, $index);
xml_parser_free($parser);
$mnary=array();
$ary=&$mnary;
foreach ($vals as $r) {
$t=$r['tag'];
if ($r['type']=='open') {
if (isset($ary[$t])) {
if (isset($ary[$t][0])) {
$ary[$t][]=array();
} else {
$ary[$t]=array($ary[$t], array());
}
$cv=&$ary[$t][count($ary[$t])-1];
} else $cv=&$ary[$t];
if (isset($r['attributes'])) {
foreach ($r['attributes'] as $k=>$v) {
$cv['_a'][$k]=$v;
}
}
$cv['_c']=array();
$cv['_c']['_p']=&$ary;
$ary=&$cv['_c'];
} elseif ($r['type']=='complete') {
if (isset($ary[$t])) { // same as open
if (isset($ary[$t][0])) $ary[$t][]=array(); else $ary[$t]=array($ary[$t], array());
$cv=&$ary[$t][count($ary[$t])-1];
} else $cv=&$ary[$t]; {
if (isset($r['attributes'])) {
foreach ($r['attributes'] as $k=>$v) $cv['_a'][$k]=$v;
}
$cv['_v']=(isset($r['value']) ? $r['value'] : '');
}
} elseif ($r['type']=='close') {
$ary=&$ary['_p'];
}
}
$this->_del_p($mnary);
return $mnary;
}
}
/*************************************************************/
/* Support classes for specific tasks */
/*************************************************************/
class PodangoStreamReader
{
var $readHandle;
function stream_function($handle, $fd, $length)
{
return fread($this->readHandle, $length);
}
}
class PodangoHTTPRequest
{
var $_fp; // HTTP socket
var $_url; // full URL
var $_method; // HTTP method
var $_host; // HTTP host
var $_protocol; // protocol (HTTP/HTTPS)
var $_uri; // request URI
var $_port; // port
var $_GET_params;
var $_POST_params;
var $_raw_request;
var $_headers;
// constructor
function PodangoHTTPRequest($url) {
$this->_url = $url;
$this->_scan_url();
}
function setMethod($method) {
$this->_method = $method;
}
function setQueryString($str) {
$this->_GET_params = $str;
}
function setPostData($str) {
$this->_POST_params = $str;
}
function getResponseCode() {
$pos = strpos($this->_headers['status'], ' ');
return substr($this->_headers['status'], $pos+1, 3);
}
// scan url
function _scan_url()
{
$req = $this->_url;
$pos = strpos($req, '://');
$this->_protocol = strtolower(substr($req, 0, $pos));
$req = substr($req, $pos+3);
$pos = strpos($req, '/');
if($pos === false) {
$pos = strlen($req);
}
$host = substr($req, 0, $pos);
if(strpos($host, ':') !== false) {
list($this->_host, $this->_port) = explode(':', $host);
} else {
$this->_host = $host;
$this->_port = ($this->_protocol == 'https') ? 443 : 80;
}
$this->_uri = substr($req, $pos);
if($this->_uri == '') {
$this->_uri = '/';
}
}
function parse_http_headers(){
if($this->_raw_header === false){
return false;
}
$this->_raw_header = str_replace("\r","",$this->_raw_header);
$headers = explode("\n",$this->_raw_header);
foreach($headers as $value){
$header = explode(": ",$value);
if($header[0] && !$header[1]){
$headerdata['status'] = $header[0];
} elseif($header[0] && $header[1]) {
$headerdata[$header[0]] = $header[1];
}
}
$this->_headers = $headerdata;
return $this->_headers;
}
// download URL to string
function DownloadToString() {
$crlf = "\r\n";
// generate request
$this->_raw_request = $this->_method.' '.$this->_uri;
if(!empty($this->_GET_params)) {
$this->_raw_request .= '?'.$this->_GET_params;
}
$this->_raw_request .= ' HTTP/1.0'.$crlf.'Host: '.$this->_host.$crlf.$crlf;
if(!empty($this->_POST_params)) {
$this->_raw_request .= '?'.$this->_GET_params;
}
// fetch
$this->_fp = fsockopen(($this->_protocol == 'https' ? 'ssl://' : '') . $this->_host, $this->_port);
fwrite($this->_fp, $this->_raw_request);
while(is_resource($this->_fp) && $this->_fp && !feof($this->_fp)) {
$response .= fread($this->_fp, 1024);
}
fclose($this->_fp);
// split header and body
$pos = strpos($response, $crlf . $crlf);
if($pos === false) {
return($response);
}
$this->_raw_header = substr($response, 0, $pos);
$body = substr($response, $pos + 2 * strlen($crlf));
// parse headers
$headers = array();
$lines = explode($crlf, $this->_raw_header);
foreach($lines as $line) {
if(($pos = strpos($line, ':')) !== false) {
$headers[strtolower(trim(substr($line, 0, $pos)))] = trim(substr($line, $pos+1));
}
}
$this->_headers = $this->parse_http_headers();
// redirection?
if(isset($headers['location'])) {
if(substr($headers['location'],0,1) == '/') {
$headers['location'] = $this->_protocol . '://' . $this->_host . $headers['location'];
}
$http = new PodangoHTTPRequest($headers['location']);
return($http->DownloadToString());
} else {
return($body);
}
}
}