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 );