File indexing completed on 2025-01-05 04:26:52
0001 /*######################################################################### 0002 # Amarok script for interfacing with Librivox.org. # 0003 # # 0004 # Copyright # 0005 # (C) 2008 Nikolaj Hald Nielsen <nhnFreespirit@gmail.com> # 0006 # (C) 2008 Peter ZHOU <peterzhoulei@gmail.com> # 0007 # # 0008 # This program is free software; you can redistribute it and/or modify # 0009 # it under the terms of the GNU General Public License as published by # 0010 # the Free Software Foundation; either version 2 of the License, or # 0011 # (at your option) any later version. # 0012 # # 0013 # This program is distributed in the hope that it will be useful, # 0014 # but WITHOUT ANY WARRANTY; without even the implied warranty of # 0015 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the # 0016 # GNU General Public License for more details. # 0017 # # 0018 # You should have received a copy of the GNU General Public License # 0019 # along with this program; if not, write to the # 0020 # Free Software Foundation, Inc., # 0021 # 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. # 0022 #########################################################################*/ 0023 0024 Importer.loadQtBinding( "qt.core" ); 0025 Importer.loadQtBinding( "qt.xml" ); 0026 Importer.loadQtBinding( "qt.network" ); 0027 Importer.loadQtBinding( "qt.gui" ); //for QPixmap 0028 0029 QByteArray.prototype.toString = function() 0030 { 0031 ts = new QTextStream( this, QIODevice.ReadOnly ); 0032 return ts.readAll(); 0033 } 0034 0035 function Librivox() 0036 { 0037 var currentDir = Amarok.Info.scriptPath() + "/"; 0038 0039 var file = new QFile( currentDir + "LibrivoxService.html" ); 0040 file.open( QIODevice.OpenMode( QIODevice.ReadOnly, QIODevice.Text ) ); 0041 0042 while ( !file.atEnd() ) 0043 { 0044 html += file.readLine().toString(); 0045 } 0046 0047 html = html.replace( "_IMAGE_DIR_", currentDir ); 0048 0049 Amarok.debug ("creating service..."); 0050 //Amarok.debug ("html: " + html ); 0051 ScriptableServiceScript.call( this, "Librivox.org", 3, "Search for free audio books from Librivox", html, true ); 0052 0053 Amarok.debug ("done creating service!"); 0054 } 0055 0056 function onCustomize() 0057 { 0058 Amarok.debug ("customizing Librivox service"); 0059 var currentDir = Amarok.Info.scriptPath() + "/"; 0060 Amarok.debug ( "loading icon: " + currentDir + "LibrivoxIcon.png" ); 0061 var iconPixmap = new QPixmap( currentDir + "LibrivoxIcon.png" ); 0062 script.setIcon( iconPixmap ); 0063 0064 var emblemPixmap = new QPixmap( currentDir + "LibrivoxEmblem.png" ); 0065 script.setEmblem( emblemPixmap ); 0066 script.setScalableEmblem( currentDir + "LibrivoxScalableEmblem.svgz" ); 0067 } 0068 0069 function bookFetchResult( reply ) 0070 { 0071 try 0072 { 0073 var cover = Amarok.Info.scriptPath() + "/audio_book128.png"; 0074 0075 doc.setContent( reply ); 0076 0077 bookElements = doc.elementsByTagName( "book" ); 0078 0079 Amarok.debug ("got " + bookElements.length() + " books!"); 0080 0081 var titles = new Array( bookElements.length() ); 0082 var links = new Array( bookElements.length() ); 0083 0084 var i = 0; 0085 for ( ; i < bookElements.length(); i++ ) 0086 { 0087 elt = bookElements.at( i ); 0088 elt2 = elt.firstChildElement( "title" ); 0089 0090 var title = elt2.text(); 0091 0092 var rx = new RegExp( ".*\\(in\\s\\\"(.*)\\\"\\).*" ); 0093 var list = title.match( rx ); 0094 0095 if ( list != null ) 0096 { 0097 Amarok.debug( "got a match: " + list[0] ); 0098 title = list[1]; 0099 } 0100 0101 titles[i] = title; 0102 0103 elt2 = elt.firstChildElement( "url_rss" ); 0104 links[i] = elt2.text(); 0105 } 0106 0107 for( i = 0; i < bookElements.length(); i++ ) 0108 { 0109 title = titles[i]; 0110 link = links[i]; 0111 0112 item = Amarok.StreamItem; 0113 item.level = 1; 0114 item.callbackData = link; 0115 item.itemName = title; 0116 item.playableUrl = ""; 0117 item.infoHtml = ""; 0118 0119 item.coverUrl = cover; 0120 0121 script.insertItem( item ); 0122 } 0123 } 0124 catch( err ) 0125 { 0126 Amarok.debug( err ); 0127 } 0128 0129 script.donePopulating(); 0130 } 0131 0132 function episodeFetchResult( result ) 0133 { 0134 try 0135 { 0136 var cover = Amarok.Info.scriptPath() + "/audio_book128.png"; 0137 doc.setContent( result ); 0138 0139 //get book and author title as these might not match the filter that was used... 0140 0141 elt = doc.firstChildElement("rss"); 0142 elt = elt.firstChildElement("channel"); 0143 0144 elt2 = elt.firstChildElement( "title" ); 0145 var bookTitle = elt2.text(); 0146 0147 //give propper book titles for chpters in a compilation 0148 Amarok.debug( "Book title: " + bookTitle ); 0149 var rx = new RegExp( ".*\\(in\\s\\\"(.*)\\\"\\).*" ); 0150 var list = bookTitle.match( rx ); 0151 0152 if ( list != null ) 0153 { 0154 Amarok.debug( "got a match: " + list[0] ); 0155 bookTitle = list[1]; 0156 } 0157 0158 var author = "Librivox.com"; 0159 0160 //process chapters 0161 chapterElements = doc.elementsByTagName( "item" ); 0162 0163 Amarok.debug( "got " + chapterElements.length() + " items..." ); 0164 0165 for ( var i = 0; i < chapterElements.length(); i++ ) 0166 { 0167 elt = chapterElements.at( i ); 0168 0169 elt2 = elt.firstChildElement( "link" ); 0170 var url = elt2.text(); 0171 0172 elt2 = elt.firstChildElement( "title" ); 0173 var title = elt2.text(); 0174 0175 elt2 = elt.firstChildElement( "itunes:duration" ); 0176 var duration = elt2.text(); 0177 0178 url = url.replace( "_64kb.mp3", ".ogg" ); 0179 0180 //lets see if we have a propper title, if not, create soething that does not look like crap 0181 var rx = new RegExp( "(\\d*)_" ); 0182 var list = title.match( rx ); 0183 0184 if ( list != null ) 0185 title = "Chapter " + list[1]; 0186 0187 item = Amarok.StreamItem; 0188 item.level = 0; 0189 item.callbackData = ""; 0190 item.itemName = title; 0191 item.playableUrl = url; 0192 item.album = bookTitle; 0193 item.artist = author; 0194 item.coverUrl = cover; 0195 item.infoHtml = title; 0196 0197 script.insertItem( item ); 0198 0199 } 0200 } 0201 catch( err ) 0202 { 0203 Amarok.debug( err ); 0204 } 0205 0206 script.donePopulating(); 0207 } 0208 0209 function onPopulate( level, callback, filter ) 0210 { 0211 offset = 0; 0212 0213 filter = filter.replace(/^%20+|\%20+$/g,''); 0214 filter.trim(); 0215 0216 if ( filter != "" ) 0217 { 0218 name = filter.replace( /%20/g, " " ); 0219 } 0220 else 0221 { 0222 name = "Enter Query...(use \"Author-<last name>\" to search by author)"; 0223 } 0224 0225 if ( level == 2 ) 0226 { 0227 0228 if ( offset > 0 ) 0229 name = name + " ( " + offset + " - " + (offset + 100) + " )"; 0230 0231 item = Amarok.StreamItem; 0232 item.level = 2; 0233 item.callbackData = "dummy"; 0234 item.itemName = name; 0235 item.playableUrl = ""; 0236 item.infoHtml = ""; 0237 script.insertItem( item ); 0238 0239 script.donePopulating(); 0240 } 0241 else if ( level == 1 ) 0242 { 0243 Amarok.debug( " Populating book level..." ); 0244 0245 try 0246 { 0247 var list = filter.match( /^[\s]*author[\s]*-[\s]*(.*)/i ); 0248 var path; 0249 if( list !=null ) 0250 { 0251 Amarok.debug( "Searching by author: " + list[1] ); 0252 path = "http://librivox.org/api/feed/audiobooks/?offset=0&limit=1000&format=xml&author=%5E" + list[1]; 0253 } 0254 else 0255 { 0256 Amarok.debug("Searching by title: " + filter ); 0257 path = "http://librivox.org/api/feed/audiobooks/?offset=0&limit=1000&format=xml&title=%5E" + filter; 0258 } 0259 qurl = new QUrl( path ); 0260 a = new Downloader( qurl, bookFetchResult ); 0261 } 0262 catch( err ) 0263 { 0264 Amarok.debug( err ); 0265 } 0266 0267 } 0268 else if ( level == 0 ) 0269 { 0270 Amarok.debug( " Populating episode level..." ); 0271 Amarok.debug( " url: " + callback ); 0272 0273 try 0274 { 0275 path = callback; 0276 qurl = new QUrl( path ); 0277 b = new Downloader( qurl, episodeFetchResult ); 0278 } 0279 catch( err ) 0280 { 0281 Amarok.debug( err ); 0282 } 0283 } 0284 } 0285 0286 function onFetchInfo( level, callback ) 0287 { 0288 if ( level == 1 ) 0289 { 0290 qurl = new QUrl( callback ); 0291 b = new Downloader( qurl, parseInfo ); 0292 } 0293 } 0294 0295 function parseInfo( result ) 0296 { 0297 Amarok.debug( result ); 0298 0299 rx = new RegExp( "<description>(.*)<\\/description>" ); 0300 list = result.match( rx ); 0301 info = list[1]; 0302 0303 info = info.replace( "<![CDATA[", "" ); 0304 info = info.replace( "]]>", "" ); 0305 0306 script.setCurrentInfo( info ); 0307 } 0308 0309 0310 http = new QHttp; 0311 data = new QBuffer; 0312 doc = new QDomDocument("doc"); 0313 elt = new QDomElement; 0314 elt2 = new QDomElement; 0315 bookElements = new QDomNodeList; 0316 html = ""; 0317 0318 script = new Librivox(); 0319 script.populate.connect( onPopulate ); 0320 script.customize.connect( onCustomize ); 0321 script.fetchInfo.connect( onFetchInfo );