File: podcast.php

Recommend this page to a friend!
  Classes of Karl Holz   SalamCast Podcast Player   podcast.php   Download  
File: podcast.php
Role: Auxiliary data
Content type: text/plain
Description: podcast cache class
Class: SalamCast Podcast Player
Play podcast episodes from RSS feed using jPlayer
Author: By
Last change: Update of podcast.php
Date: 3 years ago
Size: 8,042 bytes
 

Contents

Class file image Download
<?php /* ################################################################################ # # HolzCast Player is now: # # SalamCast Podcast Player, August 25, 2012 # # Copyright 2012 Karl Holz, newaeon _AT_ mac _DOT_ com # # http://www.salamcast.com # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. # ################################################################################ */ class podcast { private $ini; private $podcast=array(); private $feeds=array(); function __construct($ini='') { header("Expires: Mon, 26 Jul 1997 05:00:00 GMT"); header("Last-Modified: " . gmdate( "D, d M Y H:i:s" ) . "GMT"); header("Cache-Control: no-cache, must-revalidate"); header("Pragma: no-cache"); header("Content-type: application/json"); // use config with class name by default if ($ini=='') { $ini=__CLASS__.'.ini'; $this->data=dirname(__FILE__).'/data/'; } elseif (is_file($ini)) { $this->data=dirname(__FILE__).'/'.__CLASS__.'/'.basename($ini, '.ini').'/'; } else { $this->data=dirname(__FILE__).'/'.__CLASS__.'/'.$_SERVER['PATH_INFO'].'/'; } $this->ini = (is_file($ini)) ? parse_ini_file($ini) : parse_ini_string($ini); // load ini configuration if (! is_array($this->ini) || count($this->ini) < 1 ) die(" couldent load the configuration file"); // setup podcast cacheing for this webserver $this->base='http://192.168.0.242/'.$_SERVER['SCRIPT_NAME']; if (! array_key_exists("PATH_INFO", $_SERVER)) $_SERVER['PATH_INFO']=""; if (array_key_exists("HTTP_HOST", $_SERVER)) { $this->base='http://'.$_SERVER['HTTP_HOST'].$_SERVER['SCRIPT_NAME'].$_SERVER['PATH_INFO']; } // data dir for files, make it if it's not there if (! is_dir($this->data)) mkdir($this->data, 0751, TRUE); // check if the user has queried an rss file if (array_key_exists('QUERY_STRING',$_SERVER) && $_SERVER['QUERY_STRING'] != '') { $this->uuid=$_SERVER['QUERY_STRING']; echo $this; exit(); } // str2time format // update automaticly evey week $this->update="-1 Day"; // User Agent $this->agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10_7_4) AppleWebKit/536.25 (KHTML, like Gecko) Version/6.0 Safari/536.25"; if (array_key_exists("HTTP_USER_AGENT", $_SERVER)) { $this->agent=$_SERVER["HTTP_USER_AGENT"]; } // invoke update and scan, return a list of found feeds $this(); } function __invoke() { $this->load_feeds(); if (count($this->feeds) > 0 ) { echo json_encode($this->feeds); } else { //Cli $this->download_feeds(); $this->load_feeds(); echo json_encode($this->feeds); } exit(); } function __toString() { if (! is_file($this->data.$this->uuid)) die("The Feed you requested is not found"); header("Content-type: text/xml"); return file_get_contents($this->data.$this->uuid); } function __destruct() { return TRUE; } function __set($key, $val){ $this->podcast[$key]=$val; return TRUE; } function __get($key) { if(array_key_exists($key,$this->podcast)) return $this->podcast[$key]; return; } function load_feeds() { $this->feeds=array(); //reset foreach (glob($this->data."*" ) as $g) { $this->feeds[]=array( 'title' => $this->xslt_apply($g, $this->get_rss_title()), 'href' => $this->base.'?'.str_replace(array($this->data), array(''), $g) ); } } /** * Download and process each feed */ function download_feeds() { foreach ($this->ini as $k => $v) $this->process_feeds($k, $v); } /** * private functions */ private function process_feeds($title, $feed){ $xml_load=$this->get_from_url($feed, $this->update); if ($xml_load != '' && preg_match('/^</', $xml_load)) { $xsltmpl=$this->get_rss_xsl(); $ini= parse_ini_string($this->xslt_apply($xml_load, $xsltmpl)); if (array_key_exists('url', $ini) && count($ini['url']) > 0) { foreach($ini['url'] as $k => $v) $this->process_feeds($ini['title'][$k], $v); unlink($this->data.$this->uuid($feed).".xml"); } else { $this->feeds[]=array( 'title' => $title, 'url' => $this->base.'?'.$this->uuid($feed), 'src' => $feed ); } } } private function xslt_apply($xml_load, $xsltmpl) { $xml=new DOMDocument(); if (is_file($xml_load)) { $xml->load($xml_load); } else { $xml->loadXML($xml_load); } //loads XSL template file $xsl=new DOMDocument(); $xsl->loadXML($xsltmpl); //process XML and XSLT files and return result $xslproc = new XSLTProcessor(); $xslproc->importStylesheet($xsl); return $xslproc->transformToXml($xml); } /** * XSLT to extract rss channel title */ private function get_rss_title() { return <<<X <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="text"/> <xsl:template match="/"><xsl:value-of select="/rss/channel/title"/></xsl:template> </xsl:stylesheet> X ; } /** * Extract rss types from enclosure tags with XSLT 1.0 */ private function get_rss_xsl() { return <<<X <?xml version="1.0" encoding="UTF-8"?> <xsl:stylesheet xmlns:xsl="http://www.w3.org/1999/XSL/Transform" version="1.0"> <xsl:output method="text"/> <xsl:template match="/">[podcasts]<xsl:apply-templates select="/rss/channel/item"/> </xsl:template> <xsl:template match="/rss/channel/item"> <xsl:if test="enclosure/@type = 'application/rss+xml'"> title[]="<xsl:value-of select="title"/>" url[]="<xsl:value-of select="enclosure/@url"/>"</xsl:if></xsl:template> </xsl:stylesheet> X ; } /** * update cached file from url */ private function get_from_url($url, $time='-24 hours') { $file=$this->data.$this->uuid($url).".xml"; if (! is_file($file) || filectime($file) > strtotime($time) ) { $this->cache_podcast($url); } if (is_file($file)) return file_get_contents($file); return ; } /** * Genarates an UUID * @author Anis uddin Ahmad, modified by Karl Holz * @param string an optional prefix * @return string the formated uuid */ private function uuid($key = null, $prefix =__CLASS__) { $key = ($key == null)? $this->base : $key; $chars = md5($key); $uuid = substr($chars,0,8) . '-'; $uuid .= substr($chars,8,4) . '-'; $uuid .= substr($chars,12,4) . '-'; $uuid .= substr($chars,16,4) . '-'; $uuid .= substr($chars,20,12); return $prefix .'-'. $uuid; } // @TODO add header checking for 404 etc private function cache_podcast($url) { $file=$this->data.$this->uuid($url).".xml"; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // mimic users web browser curl_setopt($ch, CURLOPT_USERAGENT, $this->agent); if ($xml = curl_exec($ch)) { curl_close($ch); file_put_contents($file, $xml); return TRUE; } return FALSE; } } ?>