File indexing completed on 2025-01-05 04:25:26
0001 /*########################################################################### 0002 # A script that lets you browse content made available by the NPR # 0003 # API. It also retrieves context specific content # 0004 # # 0005 # Copyright # 0006 # (C) 2008 Casey Link <unnamedrambler@gmail.com> # 0007 # (C) 2008 Nikolaj Hald Nielsen <nhnFreespirit@gmail.com> # 0008 # (C) 2008 Peter ZHOU <peterzhoulei@gmail.com> # 0009 # (C) 2008 Sven Krohlas <sven@asbest-online.de> # 0010 # # 0011 # This program is free software; you can redistribute it and/or modify # 0012 # it under the terms of the GNU General Public License as published by # 0013 # the Free Software Foundation; either version 2 of the License, or # 0014 # (at your option) any later version. # 0015 # # 0016 # This program is distributed in the hope that it will be useful, # 0017 # but WITHOUT ANY WARRANTY; without even the implied warranty of # 0018 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 0019 # GNU General Public License for more details. # 0020 # # 0021 # You should have received a copy of the GNU General Public License # 0022 # along with this program; if not, write to the # 0023 # Free Software Foundation, Inc., # 0024 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # 0025 ###########################################################################*/ 0026 0027 Importer.loadQtBinding( "qt.core" ); 0028 Importer.loadQtBinding( "qt.xml" ); 0029 Importer.loadQtBinding( "qt.network" ); 0030 0031 service_name = "NPR"; 0032 html = "NPR"; 0033 0034 0035 apikey = "MDAyMjI0OTQyMDEyMjU3MjgzNDM3ZDBjZg001"; 0036 baseUrl = "http://api.npr.org/query?apikey="+apikey+"&id="; 0037 artistsUrl = new QUrl( "http://api.npr.org/list?id=3009" ); 0038 topicsUrl = new QUrl( "http://api.npr.org/list?id=3002" ); 0039 genresUrl = new QUrl( "http://api.npr.org/list?id=3018" ); 0040 programsUrl = new QUrl( "http://api.npr.org/list?id=3004" ); 0041 biosUrl = new QUrl( "http://api.npr.org/list?id=3007" ); 0042 columnsUrl = new QUrl( "http://api.npr.org/list?id=3003" ); 0043 seriesUrl = new QUrl( "http://api.npr.org/list?id=3006" ); 0044 doc = new QDomDocument("doc"); 0045 elt = new QDomElement; 0046 elt2 = new QDomElement; 0047 topics = new QDomNodeList; 0048 artists = new QDomNodeList; 0049 initials = new QDomNodeList; 0050 storyelements = new QDomNodeList; 0051 0052 storiesNeedingUrls = new Array(); 0053 0054 /* Initialization of service */ 0055 function NPRService() { 0056 Amarok.debug( "creating npr service..." ); 0057 ScriptableServiceScript.call( this, "NPR", 3, "Content made available via the NPR API. Over 250,000 articles, stories, and reviews.", html, false ); 0058 Amarok.debug( "done creating npr service!" ); 0059 } 0060 0061 /* Get info for topics */ 0062 function topicsDownloadResult( reply ) { 0063 Amarok.debug( "start npr topics xml parsing..." ); 0064 try { 0065 doc.setContent( reply ); 0066 topics = doc.elementsByTagName( "item" ); 0067 Amarok.debug ("got " + topics.length() + " topics!"); 0068 0069 var item = Amarok.StreamItem; 0070 item.level = 1; 0071 item.playableUrl = ""; 0072 0073 var i = 0; 0074 var ids = ""; 0075 for ( ; i < topics.length(); i++ ) { 0076 elt = topics.at( i ); 0077 elt2 = elt.firstChildElement( "title" ); 0078 item.itemName = elt2.text(); 0079 0080 elt2 = elt.firstChildElement( "additionalInfo" ); 0081 item.infoHtml = elt2.text(); 0082 var topicid = ""; 0083 topicid = elt.toElement().attribute("id"); 0084 Amarok.debug("got id " + topicid); 0085 // this is needed to identify the item when we need to expand 0086 // it in onPopulate( level, -->callbackData<--, filter ) 0087 item.callbackData = topicid; // the <item id=""> field 0088 script.insertItem( item ); 0089 } 0090 script.donePopulating() 0091 } catch( err ) { 0092 Amarok.debug( err ); 0093 } 0094 } 0095 /*get info for artists*/ 0096 function artistsDownloadResult( reply ) { 0097 Amarok.debug( "start npr artists xml parsing..." ); 0098 try { 0099 doc.setContent( reply ); 0100 initials = doc.elementsByTagName( "subcategory" ); 0101 //Amarok.debug ("got " + topics.length() + " artists!"); 0102 0103 var item = Amarok.StreamItem; 0104 item.level = 1; 0105 item.playableUrl = ""; 0106 var j = 0; 0107 for( ; j < initials.length(); j++ ) { 0108 artists = initials.at(j).toElement().elementsByTagName( "item" ); 0109 0110 var i = 0; 0111 for ( ; i < artists.length(); i++ ) { 0112 elt = artists.at( i ); 0113 elt2 = elt.firstChildElement( "title" ); 0114 item.itemName = elt2.text(); 0115 item.infoHtml = ""; 0116 0117 var artistid = ""; 0118 artistid = elt.toElement().attribute("id"); 0119 Amarok.debug("got id " + artistid); 0120 // this is needed to identify the item when we need to expand 0121 // it in onPopulate( level, -->callbackData<--, filter ) 0122 item.callbackData = artistid; // the <item id=""> field 0123 script.insertItem( item ); 0124 } 0125 } 0126 script.donePopulating() 0127 } catch( err ) { 0128 Amarok.debug( err ); 0129 } 0130 } 0131 /*get info for stories*/ 0132 function storiesDownloadResult( reply ) { 0133 Amarok.debug ("got stories..." ); 0134 doc.setContent( reply ); 0135 storyelements = doc.elementsByTagName( "story" ); 0136 Amarok.debug ("got " + storyelements.length() + " stories!"); 0137 try { 0138 var j = 0; 0139 for ( ; j < storyelements.length(); j++ ) { 0140 elt = storyelements.at( j ); 0141 0142 var id = elt.toElement().attribute("id", "" ); 0143 0144 elt2 = elt.firstChildElement( "title" ); 0145 var title = elt2.text(); 0146 0147 elt2 = elt.firstChildElement( "teaser" ); 0148 var teaser = elt2.text(); 0149 0150 elt2 = elt.firstChildElement( "storyDate" ); 0151 var datetime = elt2.text(); 0152 var date = datetime.substring(0, datetime.indexOf(":") - 3); 0153 if( date.length > 0 ) 0154 title += " - " + date; 0155 /* var date = new QDateTime; 0156 title += " - " + date.fromString(elt2.text(), "ddd, dd MMM yyyy hh:mm:ss -0400").toString("ddd, dd MMM yyyy");*/ 0157 0158 0159 elt2 = elt.firstChildElement( "audio" ); 0160 elt2 = elt2.firstChildElement( "format" ); 0161 elt2 = elt2.firstChildElement( "mp3" ); 0162 var m3uurl = elt2.text(); 0163 0164 elt2 = elt.firstChildElement( "byline" ); 0165 elt2 = elt2.firstChildElement( "name" ); 0166 var writer = elt2.text(); 0167 //Amarok.debug ("url: " + item.playableUrl); 0168 0169 Amarok.debug("Adding " + title + " by " + writer + " @ " + m3uurl); 0170 var data = title + "\\" + m3uurl + "\\" + writer + "\\" + teaser; 0171 storiesNeedingUrls.push(data); 0172 } 0173 Amarok.debug( " fetching playable urls " + storiesNeedingUrls.length); 0174 if(storiesNeedingUrls.length > 0 ) { 0175 var url = new QUrl( storiesNeedingUrls[storiesNeedingUrls.length-1].split("\\")[1] ) 0176 a = new Downloader( url, playableUrlDownloadResult ); 0177 } 0178 } catch( err ) { 0179 Amarok.debug( err ); 0180 } 0181 0182 } 0183 0184 function playableUrlDownloadResult( reply ) { 0185 Amarok.debug( "Got playable url result" ); 0186 Amarok.debug(reply); 0187 try { 0188 html = reply; 0189 urlrRx = new RegExp( "(http://.*\.mp3)" ); 0190 Amarok.debug("made regex"); 0191 var matches = html.match( urlrRx ); 0192 var data = storiesNeedingUrls.pop().split("\\"); 0193 if( matches ) { 0194 var actualurl = matches[1]; 0195 var item = Amarok.StreamItem; 0196 item.level = 0; 0197 item.callbackData = ""; 0198 item.itemName = data[0]; 0199 item.playableUrl = actualurl; 0200 item.artist = "NPR"; 0201 item.infoHtml = data[3]; 0202 item.album = data[2]; 0203 script.insertItem( item ); 0204 } 0205 if(storiesNeedingUrls.length > 0 ) { 0206 var newurl = new QUrl( storiesNeedingUrls[storiesNeedingUrls.length-1].split("\\")[1] ); 0207 Amarok.debug("fetching " + newurl + " with " + storiesNeedingUrls.length + " to go!!!"); 0208 a = new Downloader( newurl, playableUrlDownloadResult ); 0209 } 0210 else // we're done getting urls 0211 doneFetchingUrls(); 0212 0213 } catch( err ) { 0214 Amarok.debug( err ); 0215 } 0216 } 0217 function doneFetchingUrls() 0218 { 0219 storiesNeedingUrls = new Array(); 0220 script.donePopulating() 0221 } 0222 /* Fill tree view in Amarok */ 0223 function onPopulate( level, callbackData, filter ) { 0224 var i = 0; 0225 Amarok.debug( "populating npr level: " + level ); 0226 if( level == 2 ) { 0227 item = Amarok.StreamItem; 0228 item.level = 2; 0229 item.playableUrl = ""; 0230 0231 item.callbackData = "stories_topic"; 0232 item.itemName = "Topics"; 0233 item.infoHtml = "Collection of NPR stories that represent a given topic or subject matter. (eg. Health Care, Interviews)"; 0234 script.insertItem( item ); 0235 0236 item.callbackData = "artist_stories"; 0237 item.itemName = "Music Artists"; 0238 item.infoHtml = "Collection of stories that are about music artists. Artists are sorted by letter. (eg. Bob Dylan, Death Cab For Cutie)"; 0239 script.insertItem( item ); 0240 0241 item.callbackData = "genre_stories"; 0242 item.itemName = "Music Genres"; 0243 item.infoHtml = "Collection of NPR stories that represent a given musical genre. (eg. Rock/Pop/Folk, Jazz)"; 0244 script.insertItem( item ); 0245 0246 item.callbackData = "program_stories"; 0247 item.itemName = "Programs"; 0248 item.infoHtml = "Collection of NPR stories that aired on an NPR program. (eg. All Things Considered, Tell Me More)"; 0249 script.insertItem( item ); 0250 0251 item.callbackData = "bios_stories"; 0252 item.itemName = "Bios"; 0253 item.infoHtml = "Collection of NPR stories as reported by an NPR personality. Personalities are sorted by letter. (eg. Nina Totenburg, Steve Inskeep)"; 0254 script.insertItem( item ); 0255 0256 item.callbackData = "columns_stories"; 0257 item.itemName = "Columns"; 0258 item.infoHtml = "Collection of stories containing opinions and perspectives of an NPR personality. (eg. Watching Washington, Song of the Day)"; 0259 script.insertItem( item ); 0260 0261 item.callbackData = "series_stories"; 0262 item.itemName = "Series"; 0263 item.infoHtml = "An ongoing collection of NPR stories on a topic. (eg. Climate Connections, Summer Books)"; 0264 script.insertItem( item ); 0265 0266 script.donePopulating(); 0267 } else if ( level == 1 ) { // the shows 0268 Amarok.debug( "fetching npr xml..." ); 0269 Amarok.Window.Statusbar.longMessage( "NPR: Fetching and parsing stories. This might take a little bit, depending on the speed of your internet connection..." ); 0270 try { 0271 if( callbackData == "stories_topic" ) 0272 a = new Downloader( topicsUrl, topicsDownloadResult ); 0273 else if( callbackData == "artist_stories" ) 0274 a = new Downloader( artistsUrl, artistsDownloadResult ); 0275 else if( callbackData == "genre_stories" ) 0276 a = new Downloader( genresUrl, topicsDownloadResult ); 0277 else if( callbackData == "program_stories" ) 0278 a = new Downloader( programsUrl, topicsDownloadResult ); 0279 else if( callbackData == "columns_stories" ) 0280 a = new Downloader( columnsUrl, topicsDownloadResult ); 0281 else if( callbackData == "series_stories" ) 0282 a = new Downloader( seriesUrl, topicsDownloadResult ); 0283 else if( callbackData == "bios_stories" ) 0284 a = new Downloader( biosUrl, artistsDownloadResult ); 0285 0286 0287 } 0288 catch( err ) { 0289 Amarok.debug( err ); 0290 } 0291 0292 } else if ( level == 0 ) { // the stories from each topic 0293 try { 0294 url = new QUrl( baseUrl + callbackData + "&action=Or&fields=title,teaser,storyDate,audio&output=NPRML&numResults=20" ); 0295 Amarok.debug("Fetching stories for topic: " + callbackData); 0296 Amarok.debug(url); 0297 a = new Downloader( url, storiesDownloadResult ); 0298 } catch( err ) { 0299 Amarok.debug( err ); 0300 } 0301 } 0302 } 0303 0304 script = new NPRService(); 0305 script.populate.connect( onPopulate );