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