home *** CD-ROM | disk | FTP | other *** search
/ Personal Computer World 2006 May / PCWMAY06.iso / Software / Toolkit / Songbird 0.1 / Songbird_0_1_0.exe / components / sbIPlaylistReaderHTML.js < prev    next >
Encoding:
Text File  |  2006-02-08  |  13.1 KB  |  459 lines

  1. /*
  2.  //
  3. // BEGIN SONGBIRD GPL
  4. // 
  5. // This file is part of the Songbird web player.
  6. //
  7. // Copyright⌐ 2006 Pioneers of the Inevitable LLC
  8. // http://songbirdnest.com
  9. // 
  10. // This file may be licensed under the terms of of the
  11. // GNU General Public License Version 2 (the ôGPLö).
  12. // 
  13. // Software distributed under the License is distributed 
  14. // on an ôAS ISö basis, WITHOUT WARRANTY OF ANY KIND, either 
  15. // express or implied. See the GPL for the specific language 
  16. // governing rights and limitations.
  17. //
  18. // You should have received a copy of the GPL along with this 
  19. // program. If not, go to http://www.gnu.org/licenses/gpl.html
  20. // or write to the Free Software Foundation, Inc., 
  21. // 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
  22. // 
  23. // END SONGBIRD GPL
  24. //
  25.  */
  26.  
  27. //
  28. // sbIPlaylistReader Object (HTML)
  29. //
  30.  
  31. const SONGBIRD_PLAYLISTHTML_CONTRACTID = "@songbird.org/Songbird/Playlist/Reader/HTML;1";
  32. const SONGBIRD_PLAYLISTHTML_CLASSNAME = "Songbird HTML Playlist Interface";
  33. const SONGBIRD_PLAYLISTHTML_CID = Components.ID("{63607801-7CA1-45fe-BD31-8659E43173D4}");
  34. const SONGBIRD_PLAYLISTHTML_IID = Components.interfaces.sbIPlaylistReader;
  35.  
  36. function CPlaylistHTML()
  37. {
  38.   jsLoader = Components.classes["@mozilla.org/moz/jssubscript-loader;1"].getService(Components.interfaces.mozIJSSubScriptLoader);
  39.   jsLoader.loadSubScript( "chrome://rmp_demo/content/songbird_interfaces.js", this );
  40. }
  41.  
  42. /* I actually need a constructor in this case. */
  43. CPlaylistHTML.prototype.constructor = CPlaylistHTML;
  44.  
  45. /* the CPlaylistHTML class def */
  46. CPlaylistHTML.prototype = 
  47. {
  48.   originalURL: "",
  49.  
  50.   m_HREFArray: new Array(),
  51.  
  52.   Read: function( strURL, strGUID, strDestTable, replace, /* out */ errorCode )
  53.   {
  54.     try
  55.     {
  56.       // Twick the filename off the end of the url.
  57.       if ( this.originalURL && this.originalURL.length )
  58.       {
  59.         this.originalURL = this.originalURL.substr( 0, this.originalURL.lastIndexOf("/") ) + "/";
  60.       }
  61.       
  62.       // Setup the file input stream and pass it to a function to parse the html
  63.       var retval = false;
  64.       errorCode.value = 0;
  65.       
  66.       var pFileReader = (Components.classes["@mozilla.org/network/file-input-stream;1"]).createInstance(Components.interfaces.nsIFileInputStream);
  67.       var pFile = (Components.classes["@mozilla.org/file/local;1"]).createInstance(Components.interfaces.nsILocalFile);
  68.       var pURI = (Components.classes["@mozilla.org/network/simple-uri;1"]).createInstance(Components.interfaces.nsIURI);
  69.  
  70.       if ( pFile && pURI && pFileReader )
  71.       {
  72.         pURI.spec = strURL;
  73.         if ( pURI.scheme == "file" )
  74.         {
  75.           var cstrPathToPLS = pURI.path;
  76.           cstrPathToPLS = cstrPathToPLS.substr( 3, cstrPathToPLS.length ); // .Cut(0, 3); //remove '///'
  77.           pFile.initWithPath(cstrPathToPLS);
  78.           if ( pFile.isFile() )
  79.           {
  80.             pFileReader.init( pFile, /* PR_RDONLY */ 1, 0, /*nsIFileInputStream::CLOSE_ON_EOF*/ 0 );
  81.             retval = this.HandleHTMLStream( strGUID, strDestTable, pFileReader, replace );
  82.             pFileReader.close();
  83.           }
  84.         }
  85.       }
  86.       return retval;
  87.     }
  88.     catch ( err )
  89.     {
  90.       throw "CPlaylistHTML::Read - " + err;
  91.     }
  92.   },
  93.   
  94.   Vote: function( strURL )
  95.   {
  96.     try
  97.     {
  98.       return 10000;
  99.     }
  100.     catch ( err )
  101.     {
  102.       throw "CPlaylistHTML::Vote - " + err;
  103.     }
  104.   },
  105.   
  106.   Name: function()
  107.   {
  108.     try
  109.     {
  110.       return "HTML Playlist"; // ????
  111.     }
  112.     catch ( err )
  113.     {
  114.       throw "CPlaylistHTML::Name - " + err;
  115.     }
  116.   },
  117.   
  118.   Description: function()
  119.   {
  120.     try
  121.     {
  122.       return "HTML Playlist"; // ????
  123.     }
  124.     catch ( err )
  125.     {
  126.       throw "CPlaylistHTML::Description - " + err;
  127.     }
  128.   },
  129.   
  130.   SupportedMIMETypes: function( /* out */ nMIMECount )
  131.   {
  132.     var retval = new Array;
  133.     nMIMECount.value = 0;
  134.  
  135.     try
  136.     {
  137.       retval.push( "text/html" );
  138.       nMIMECount.value = retval.length;
  139.     }
  140.     catch ( err )
  141.     {
  142.       throw "CPlaylistHTML::SupportedMIMETypes - " + err;
  143.     }
  144.     return retval;
  145.   },
  146.   
  147.   SupportedFileExtensions: function( /* out */ nExtCount )
  148.   {
  149.     var retval = new Array;
  150.     nExtCount.value = 0;
  151.     
  152.     try
  153.     {
  154.       retval.push( "html" );
  155.       retval.push( "htm" );
  156.       retval.push( "php" );
  157.       retval.push( "php3" );
  158.       retval.push( "" );
  159.       
  160.       nExtCount.value = retval.length;
  161.     }
  162.     catch ( err )
  163.     {
  164.       throw "CPlaylistHTML::SupportedFileExtensions - " + err;
  165.     }
  166.     
  167.     return retval;
  168.   },
  169.   
  170.   HandleHTMLStream: function( strGUID, strDestTable, streamIn, replace )
  171.   {
  172.     var retval = false;
  173.     try
  174.     {
  175.       streamIn = streamIn.QueryInterface( Components.interfaces.nsILineInputStream );
  176.       var links = new Array();
  177.       var inTag = false;
  178.       var inATag = false;
  179.       // Parse the file (line by line! woo hoo!)
  180.       var out = {};
  181.       var count = 0;
  182.       while ( streamIn.readLine( out ) )
  183.       {
  184.         ++count;
  185.         var line = out.value;
  186.         while ( line.length && line.length > 0 )
  187.         {
  188.           // What state were we in when we last got in here?
  189.           if ( inTag )
  190.           {
  191.             // See if we can find an href attribute
  192.             if ( inATag )
  193.             {
  194.               var href_idx = line.indexOf( 'href="' );
  195.               if ( href_idx > -1 )
  196.               {
  197.                 var temp = line.substr( href_idx + 6, line.length );
  198.                 var href = temp.substr( 0, temp.indexOf('"') );
  199.                 if ( this.IsMediaUrl( href ) )
  200.                 {
  201.                   if ( href.indexOf( '://' ) == -1 )
  202.                   {
  203.                     href = this.originalURL + href;
  204.                   }
  205.                   links.push( href );
  206.                 }
  207.               }
  208.             }
  209.             // Look for the closing of a tag
  210.             var close = line.indexOf( '>' );
  211.             if ( close > -1 )
  212.             {
  213.               inTag = false;
  214.               inATag = false;
  215.               line = line.substr( close + 1, line.length );
  216.             }
  217.             else
  218.             {
  219.               break; // EOL
  220.             }
  221.           }
  222.           else
  223.           {
  224.             // Look for the opening of a tag
  225.             var open = line.indexOf( '<' );
  226.             if ( open > -1 )
  227.             {
  228.               inTag = true;
  229.               line = line.substr( open + 1, line.length );
  230.               if ( ( line[ 0 ] == "a" ) || ( line[ 0 ] == "A" ) )
  231.               {
  232.                 inATag = true;
  233.               }
  234.             }
  235.             else
  236.             {
  237.               break; // EOL
  238.             }
  239.           }
  240.         }
  241.       }
  242.       // I'm tired of this function.  Let's have a different one.
  243.       retval = this.CreatePlaylist( strGUID, strDestTable, links, replace );
  244.     }
  245.     catch ( err )
  246.     {
  247.       throw "CPlaylistHTML::HandleHTMLBuffer - " + err;
  248.     }
  249.     return retval;
  250.   },
  251.   
  252.   CreatePlaylist: function( strGUID, strDestTable, links_array, replace )
  253.   {
  254.     try
  255.     {
  256.       retval = false;
  257.       if ( links_array.length > 0 )
  258.       {
  259.         var pQuery = new this.sbIDatabaseQuery();
  260.         pQuery.SetAsyncQuery(true);
  261.         pQuery.SetDatabaseGUID(strGUID);
  262.  
  263.         const MediaLibrary = new Components.Constructor("@songbird.org/Songbird/MediaLibrary;1", "sbIMediaLibrary");
  264.         var pLibrary = (new MediaLibrary()).QueryInterface( Components.interfaces.sbIMediaLibrary );
  265.         const PlaylistManager = new Components.Constructor("@songbird.org/Songbird/PlaylistManager;1", "sbIPlaylistManager");
  266.         var pPlaylistManager = (new PlaylistManager()).QueryInterface( Components.interfaces.sbIPlaylistManager );
  267.         
  268.         pLibrary.SetQueryObject(pQuery);
  269.         pPlaylist = pPlaylistManager.GetPlaylist(strDestTable, pQuery);
  270.  
  271.         var inserted = new Array();        
  272.         for ( var i in links_array )
  273.         {
  274.           var url = links_array[ i ];
  275.           
  276.           // Don't insert it if we already did.
  277.           var skip = false;
  278.           for ( var j in inserted )
  279.           {
  280.             if ( inserted[ j ] == url )
  281.             {
  282.               skip = true;
  283.               break;
  284.             }
  285.           }
  286.         
  287.           if ( !skip )
  288.           {
  289.             var aMetaKeys = new Array("title");
  290.             var aMetaValues = new Array( this.ConvertUrlToDisplayName( url ) );
  291.  
  292.             var guid = pLibrary.AddMedia( url, aMetaKeys.length, aMetaKeys, aMetaValues.length, aMetaValues, replace, true );
  293.             pPlaylist.AddByGUID( guid, strGUID, -1, replace, true );
  294.             
  295.             inserted.push( url );
  296.           }
  297.         }
  298.         pQuery.Execute();
  299.         retval = true;
  300.       }
  301.       return retval;
  302.     }
  303.     catch ( err )
  304.     {
  305.       throw "CPlaylistHTML::HandleHTMLBuffer - " + err;
  306.     }
  307.   },
  308.  
  309.   IsMediaUrl: function( the_url )
  310.   {
  311.     if ( ( the_url.indexOf ) && 
  312.           (
  313.             // Protocols at the beginning
  314.             ( the_url.indexOf( "mms:" ) == 0 ) || 
  315.             ( the_url.indexOf( "rtsp:" ) == 0 ) || 
  316.             // File extensions at the end
  317.             ( the_url.indexOf( ".pls" ) != -1 ) || 
  318.             ( the_url.indexOf( ".m3u" ) == ( the_url.length - 4 ) ) || 
  319. //            ( the_url.indexOf( ".rm" ) == ( the_url.length - 3 ) ) || 
  320. //            ( the_url.indexOf( ".ram" ) == ( the_url.length - 4 ) ) || 
  321. //            ( the_url.indexOf( ".smil" ) == ( the_url.length - 5 ) ) || 
  322.             ( the_url.indexOf( ".mp3" ) == ( the_url.length - 4 ) ) ||
  323.             ( the_url.indexOf( ".m4a" ) == ( the_url.length - 4 ) ) ||
  324.             ( the_url.indexOf( ".ogg" ) == ( the_url.length - 4 ) ) ||
  325.             ( the_url.indexOf( ".wma" ) == ( the_url.length - 4 ) ) ||
  326.             ( the_url.indexOf( ".wmv" ) == ( the_url.length - 4 ) ) ||
  327.             ( the_url.indexOf( ".asx" ) == ( the_url.length - 4 ) ) ||
  328.             ( the_url.indexOf( ".asf" ) == ( the_url.length - 4 ) ) ||
  329.             ( the_url.indexOf( ".avi" ) == ( the_url.length - 4 ) ) ||
  330.             ( the_url.indexOf( ".mov" ) == ( the_url.length - 4 ) ) ||
  331.             ( the_url.indexOf( ".mp4" ) == ( the_url.length - 4 ) )
  332.           )
  333.         )
  334.     {
  335.       return true;
  336.     }
  337.     return false;
  338.   },
  339.   
  340.   ConvertUrlToDisplayName: function( url )
  341.   {
  342.     // Set the title display  
  343.     var the_value = "";
  344.     if ( url.lastIndexOf('/') != -1 )
  345.     {
  346.       the_value = url.substring( url.lastIndexOf('/') + 1, url.length );
  347.     }
  348.     else if ( url.lastIndexOf('\\') != -1 )
  349.     {
  350.       the_value = url.substring( url.lastIndexOf('\\') + 1, url.length );
  351.     }
  352.     else
  353.     {
  354.       the_value = url;
  355.     }
  356.     // Convert any %XX to space
  357.     var percent = the_value.indexOf('%');
  358.     if ( percent != -1 )
  359.     {
  360.       var remainder = the_value;
  361.       the_value = "";
  362.       while ( percent != -1 )
  363.       {
  364.         the_value += remainder.substring( 0, percent );
  365.         remainder = remainder.substring( percent + 3, url.length );
  366.         percent = remainder.indexOf('%');
  367.         the_value += " ";
  368.         if ( percent == -1 )
  369.         {
  370.           the_value += remainder;
  371.         }
  372.       }
  373.     }
  374.     if ( the_value.length == 0 )
  375.     {
  376.       the_value = url;
  377.     }
  378.     return the_value;
  379.   },
  380.  
  381.   QueryInterface: function(iid)
  382.   {
  383.       if (!iid.equals(Components.interfaces.nsISupports) &&
  384.           !iid.equals(SONGBIRD_PLAYLISTHTML_IID))
  385.           throw Components.results.NS_ERROR_NO_INTERFACE;
  386.       return this;
  387.   }
  388. };
  389.  
  390. /**
  391.  * \class sbPlaylistHTMLModule
  392.  * \brief 
  393.  */
  394. var sbPlaylistHTMLModule = 
  395. {
  396.   //firstTime: true,
  397.   
  398.   registerSelf: function(compMgr, fileSpec, location, type)
  399.   {
  400.     //if(this.firstTime)
  401.     //{
  402.       //this.firstTime = false;
  403.       //throw Components.results.NS_ERROR_FACTORY_REGISTER_AGAIN;
  404.     //}
  405.  
  406.     compMgr = compMgr.QueryInterface(Components.interfaces.nsIComponentRegistrar);
  407.     compMgr.registerFactoryLocation(SONGBIRD_PLAYLISTHTML_CID, 
  408.                                     SONGBIRD_PLAYLISTHTML_CLASSNAME, 
  409.                                     SONGBIRD_PLAYLISTHTML_CONTRACTID, 
  410.                                     fileSpec, 
  411.                                     location,
  412.                                     type);
  413.   },
  414.  
  415.   getClassObject: function(compMgr, cid, iid) 
  416.   {
  417.     if(!cid.equals(SONGBIRD_PLAYLISTHTML_CID))
  418.         throw Components.results.NS_ERROR_NO_INTERFACE;
  419.  
  420.     if(!iid.equals(Components.interfaces.nsIFactory))
  421.         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  422.  
  423.     return sbPlaylistHTMLFactory;
  424.   },
  425.  
  426.   canUnload: function(compMgr)
  427.   { 
  428.     return true; 
  429.   }
  430. };
  431.  
  432. /**
  433.  * \class sbPlaylistHTMLFactory
  434.  * \brief 
  435.  */
  436. var sbPlaylistHTMLFactory =
  437. {
  438.   createInstance: function(outer, iid)
  439.   {
  440.     if (outer != null)
  441.         throw Components.results.NS_ERROR_NO_AGGREGATION;
  442.  
  443.     if (!iid.equals(SONGBIRD_PLAYLISTHTML_IID) &&
  444.         !iid.equals(Components.interfaces.nsISupports))
  445.         throw Components.results.NS_ERROR_INVALID_ARG;
  446.  
  447.     return (new CPlaylistHTML()).QueryInterface(iid);
  448.   }
  449. }; //sbPlaylistHTMLFactory
  450.  
  451. /**
  452.  * \function NSGetModule
  453.  * \brief 
  454.  */
  455. function NSGetModule(comMgr, fileSpec)
  456.   return sbPlaylistHTMLModule;
  457. } //NSGetModule
  458.