Your Ad Here

Posted By

lasavior on 04/22/11


Tagged

url feed itunes podcast


Versions (?)

Who likes this?

2 people have marked this snippet as a favorite

williamsww
bitfed


iTunes Podcast URL Extractor


 / Published in: PHP
 

URL: http://itunes.so-nik.com

If you've ever tried to subscribe to a podcast outside of iTunes but only have an iTunes URL, you know how frustrating it is. Turns out that you just need to spoof yourself as an iTunes client to see the direct feed URL. This script helps with exactly that. I even wrote a front-end @ http://itunes.so-nik.com so you can use it from a mobile device or desktop web browser.

NOTE: if you came here from Google, please use the "Versions" dropbox on the right to select the current version as you may be viewing an older copy with bugs.

[Change log moved into file]

  1. <?php
  2.  
  3. /*
  4.  * Podcast URL Extractor
  5.  * implemented at http://itunes.so-nik.com
  6.  *
  7.  * All code has been re-written by lasavior.
  8.  * Original code & inspiration from Michael Sitarzewski, zerologic.com
  9.  *
  10.  * Ex: http://ax.phobos.apple.com.edgesuite.net/WebObjects/MZStore.woa/wa/viewPodcast?id=269238657
  11.  * Ex: http://itunes.apple.com/us/podcast/hombre-potato/id319810190?uo=4
  12.  *
  13.  * Usage: itunes.php?http://itunes.apple.com/us/podcast/the-morning-stream/id414564832?uo=4
  14.  * Returns: http://myextralife.com/ftp/radio/morningstream.xml
  15.  
  16. CHANGE LOG:::
  17. EDIT 5/10/11: Removed flat-file database storing. Reformatted for SQLite (requires PHP 5 and above). Script will create database & table if they dont exist.
  18.  
  19. EDIT 6/2/11: Added safety catch for iTunes-U URL's. (Currently Apple does not offer a way to subscribe to these outside of iTunes [as far as i've seen]). Also touched up a little bit of code here & there.
  20.  
  21. EDIT 6/21/11: Added another safety catch for iTunes-U pages. Now instead of just checking the URL, it will also check the page content (as there are links that do not include the tag 'itunes-u' that was previously checked for).
  22.  
  23. EDIT 6/28/11: Previous iTunes-U update was flawed and resulted in a lot of false-positives. Fixed in new update.
  24.  
  25. EDIT 8/29/11: Added catch for material not available in the US store.
  26.  */
  27.  
  28.  
  29. //-----------------------------------------
  30. // a couple of settings
  31. $_SETT = array(
  32. 'hashalgo' => 'md5',
  33. 'contactemail' => '-INSERT-EMAIL-HERE-',
  34. 'dbtable' => 'feedurls',
  35. 'dbfilename' => 'itnfedb.sqdb'
  36. );
  37.  
  38. //-----------------------------------------
  39. // the base URL
  40. $url = ($_POST['terms'] != null) ? $_POST['terms'] : $_SERVER['QUERY_STRING'];
  41. $urlhash = hash($_SETT['hashalgo'], $url);
  42.  
  43. //-----------------------------------------
  44. //Functions
  45. function curlfeed($churl) {
  46.  
  47. $ch = curl_init();
  48. curl_setopt_array ($ch, array(
  49. CURLOPT_RETURNTRANSFER => TRUE,
  50. CURLOPT_FOLLOWLOCATION => TRUE,
  51. CURLOPT_MAXREDIRS => 10,
  52. CURLOPT_CONNECTTIMEOUT => 5,
  53. CURLOPT_URL => $churl,
  54. CURLOPT_USERAGENT => 'iTunes/9.1.1'
  55. ));
  56. $chresult = curl_exec($ch);
  57. curl_close($ch);
  58.  
  59. return $chresult;
  60. }
  61.  
  62. function subURL($urltosub, $string1 = 'feed-url="', $string2 ='"') {
  63.  
  64. $str1 = strpos($urltosub, $string1) + strlen($string1);
  65. $str2 = strpos($urltosub, $string2, $str1);
  66. $subbedstring = substr($urltosub, $str1, ($str2 - $str1));
  67.  
  68. return $subbedstring;
  69. }
  70.  
  71. function checkFEED($thefeed, $mainURL) {
  72.  
  73. global $feedURL, $invalidURL, $_SETT;
  74.  
  75. //For your reference, the following is called a HEREDOC
  76. $badURL = <<<BADURL
  77.   <div style="font-size:15px;white-space:normal;max-width:400px">iTunes failed to return the feed-url.
  78.   <br>
  79.   <br>This may be due to different reasons:
  80.   <br>&nbsp;&nbsp;1) the podcast has been deleted,
  81.   <br>&nbsp;&nbsp;2) the podcast has no items,
  82.   <br>and many other reasons im not aware of. Unfortunately iTunes isnt perfect (hence why your here).
  83.   <br>
  84.   <br>Im sorry my script was of no help to you. If you feel this was in error, you can <a href="outfeed.php?$mainURL" style="text-decoration:underline" target="_blank">view the source,</a><br> or you can always <a href="mailto:{$_SETT['contactemail']}?subject=IFE Error&body=URL i tried: $mainURL" style="display:inline;text-decoration:underline">email me</a> the URL and i will see if its fixable.</div>
  85. BADURL;
  86.  
  87. if (substr($thefeed, 0, 7) != "http://"):
  88.  
  89. $feedURL = $badURL;
  90. $invalidURL = "The cake is a lie.";
  91. endif;
  92.  
  93. }
  94.  
  95. //-----------------------------------------
  96. //Here we initiate the sqlite database and setup the cached variables
  97. if ($database = sqlite_open($_SETT['dbfilename'], 0666, $sqlerror)):
  98.  
  99. $check_cache_query = "SELECT url FROM {$_SETT['dbtable']} WHERE uniqueid='$urlhash'";
  100. $cache_file = @sqlite_single_query($database, $check_cache_query, true);
  101. if(sqlite_last_error($database)):
  102.  
  103. $create_table_query = "CREATE TABLE {$_SETT['dbtable']}(uniqueid TEXT, url TEXT, date TEXT)";
  104. @sqlite_exec($database, $create_table_query);
  105. $cache_file = NULL;
  106. endif;
  107. else:
  108.  
  109. $failed_to_initialize_sqlite = $sqlerror;
  110. endif;
  111.  
  112. //-----------------------------------------
  113. //For caching files, this determines if the cached file already exists
  114. if ($cache_file == NULL || isset($failed_to_initialize_sqlite)):
  115.  
  116. //-----------------------------------------
  117. //Here we identify the podcast url scheme
  118. $idstyles = array(
  119. '?id=',
  120. '&id=',
  121. '/id'
  122. );
  123.  
  124. for ($counter = 0; $counter < count($idstyles); $counter++):
  125.  
  126. if (strpos($url, $idstyles[$counter])):
  127.  
  128. $idstyle = $idstyles[$counter];
  129. $validID = "So, how are you holding up? Because I'm a potato!";
  130. break;
  131. endif;
  132. endfor;
  133.  
  134. //-----------------------------------------
  135. //Since iTunes-U uses the same identifier symbols,
  136. //this is where we rule them out until it is supported
  137. //Note: more checking for itunes-u content is done further below
  138. if (strpos($url, '/itunes-u/')):
  139.  
  140. unset($validID);
  141. $invalidID = "itunes-u";
  142. endif;
  143.  
  144. //-----------------------------------------
  145. // extract feed-id, get page from itunes & find feed-url
  146. if (isset($validID)):
  147.  
  148. preg_match("/[0-9]+/", $url, $podid, 0, strpos($url, $idstyle)); // here we extract the feed ID
  149. $curled1 = curlfeed("http://itunes.apple.com/podcast/id".$podid[0]);
  150. if (strpos($curled1, "<key>kind</key><string>Goto</string>") > 1):
  151.  
  152. $newURL = subURL($curled1, "<key>url</key><string>", "</string>");
  153. $curled1 = curlfeed($newURL);
  154. endif;
  155. if (strpos($curled1, 'iTunes U')):
  156.  
  157. $itunesU_title = subURL($curled1, '<title>', '</title>');
  158. $itunesU_title_char = urlencode($itunesU_title);
  159. $itunesU_crumbs = subURL($curled1, 'start breadcrumbs', 'end breadcrumbs');
  160. $itunesU_li = subURL($itunesU_crumbs, '<li>', '</li>');
  161. if (strpos($itunesU_li, 'iTunes U')):
  162.  
  163. $feedURL = <<<ITUNESU
  164.   <div style="font-size:15px;white-space:normal;max-width:400px">iTunes-U links not supported.
  165.   <br>
  166.   <br>Currently Apple does not offer a way to subscribe to iTunes-U material outside of iTunes (that i can find). A temporary solution is to search for a similar title as a podcast in hopes that the content providers also posted it to the iTunes Podcast Directory (do no expect this for password protected content). Try searching for:
  167.   <br>"$itunesU_title"
  168.   <br>
  169.   <br>You can <a href='http://itunes.so-nik.com/index.php?terms=$itunesU_title_char' style="display:inline;text-decoration:underline;color:blue">click here</a> to try that now.</div>
  170. ITUNESU;
  171. $invalidID_check = 1;
  172. $invalidID = 'itunes-u';
  173. endif;
  174. elseif (strpos($curled1, 'not currently available in the US store')):
  175.  
  176. $feedURL = <<<ITUNESFOREIGNSTORE
  177.   <div style="font-size:15px;white-space:normal;max-width:400px">This item is not available in the US store.
  178.   <br>
  179.   <br>Apple currently restricts access to some content based on geographic locations. As I reside in the United States, I unfortunately cannot help you with your podcast link.
  180.   <br>
  181.   <br>If you have any PHP knowledge you can use the public source code to retrieve the URL yourself:
  182.   <br>http://snipplr.com/view/52465</div>
  183. ITUNESFOREIGNSTORE;
  184. $invalidID_check = 1;
  185. $invalidID = 'itunes_foreign';
  186. endif;
  187. if ($invalidID_check != 1):
  188.  
  189. $feedURL = subURL($curled1);
  190. checkFEED($feedURL, $url);
  191. endif;
  192. if (!isset($failed_to_initialize_sqlite)):
  193.  
  194. $newfeedURL = sqlite_escape_string($feedURL);
  195. $cache_query_put_content = "INSERT INTO {$_SETT['dbtable']} (uniqueid,url,date) VALUES ('$urlhash', '$newfeedURL', '".date("r")."')";
  196. @sqlite_exec($database, $cache_query_put_content);
  197. endif;
  198. else:
  199.  
  200. if ($invalidID == "itunes-u"):
  201.  
  202. //Example URL: http://itunes.apple.com/itunes-u/the-civil-war-reconstruction/id341650730
  203. $itu_label = subURL($url, '/itunes-u/', '/');
  204. $itu_label_white = trim(ucwords(str_replace('-', ' ', $itu_label)));
  205. $itu_label_char = str_replace('-', '%20', $itu_label);
  206. $feedURL = <<<FEEDURL
  207.   <div style="font-size:15px;white-space:normal;max-width:400px">iTunes-U links not supported.
  208.   <br>
  209.   <br>Currently Apple does not offer a way to subscribe to iTunes-U material outside of iTunes (that i can find). A temporary solution is to search for a similar title as a podcast in hopes that the content providers also posted it to the iTunes Podcast Directory (do no expect this for password protected content). Try searching for:
  210.   <br>"$itu_label_white"
  211.   <br>
  212.   <br>You can <a href='http://itunes.so-nik.com/index.php?terms=$itu_label_char' style="display:inline;text-decoration:underline;color:blue">click here</a> to try that now.</div>
  213. FEEDURL;
  214. else:
  215.  
  216. $feedURL = "URL not supported. <br><br>Please contact <a href='mailto:{$_SETT['contactemail']}?subject=Feed-Error&body=Error on URL:$url' style=\"display:inline;text-decoration:underline\">{$_SETT['contactemail']}</a> <br>and notify me of the URL you are trying.";
  217. $invalidID = "I was doing fine. Noone was trying to murder me, or put me in a potato, or feed me to birds.";
  218. endif;
  219. endif;
  220. else:
  221.  
  222. $feedURL = $cache_file;
  223. if (!stripos($feedURL, 'itunes-u')):
  224.  
  225. checkFEED($feedURL, $url);
  226. else:
  227.  
  228. $invalidID = 'itunes-u';
  229. endif;
  230. endif;
  231.  
  232. //-----------------------------------------
  233. // html output to browser
  234. $podcastURL = (isset($invalidURL) || isset($invalidID)) ? $feedURL : "<a href=\"$feedURL\">$feedURL</a>";
  235.  
  236. echo <<<OUTTEXT
  237. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  238.   "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  239.  
  240. <html xmlns="http://www.w3.org/1999/xhtml" style="height: 100%;">
  241.   <head>
  242.   <title>Podcast URL</title>
  243.   <meta name="viewport" content="width=320; initial-scale=1.0; maximum-scale=1.0; user-scalable=0;"/>
  244.   <meta name="robots" content="NOINDEX, NOFOLLOW, NOARCHIVE, NOSNIPPET">
  245.   <style type="text/css" media="screen">@import "iphonenav.css";</style>
  246.   <link rel="apple-touch-icon" href="./icon.png" />
  247.   <link rel="shortcut icon" href="./favicon.ico">
  248.   </head>
  249.  
  250.   <!-- GUI, iTunes Store searching & feed extraction credited to lasavior, so-nik.com -->
  251.   <!-- Original idea & inspiration credited to Michael Sitarzewski, zerologic.com -->
  252.   <!-- For the PHP code to extract the podcast feed yourself, visit http://snipplr.com/view/52465 -->
  253.  
  254.   <body style="height: 100%;">
  255.  
  256.   <h1>Podcast URL:</h1>
  257.   <ul>
  258.   <li style="height: 100%; padding:10px 10px 10px 10px; font-size:20px; word-wrap:break-word">$podcastURL</li>
  259.   <li style="height: 100%; padding:10px 10px 10px 10px; font-size:10px; border-bottom: 0px solid;"><div style="color:LightGray;font-size:12px;"><a href="mailto:ife@so-nik.com" style="color:LightGray; font-size:12px; text-decoration:none;">ife@so-nik.com</a>&nbsp;&nbsp;&nbsp;/&nbsp;&nbsp;&nbsp;<a href="http://podcasturlextractor.blogspot.com/" style="color:LightGray; font-size:12px; text-decoration:none;" target="_blank">News</a>&nbsp;&nbsp;&nbsp;/&nbsp;&nbsp;&nbsp;<a href="http://podcasturlextractor.blogspot.com/p/what-it-is-and-why-its-here.html" style="color:LightGray; font-size:12px; text-decoration:none;" target="_blank">About</a></div></li>
  260.   </ul>
  261.   </body>
  262. </html>
  263. OUTTEXT;
  264.  
  265. ?>

Report this snippet  

Comments

RSS Icon Subscribe to comments
Posted By: Sarah on December 23, 2011

thanks for the help

You need to login to post a comment.