CueBrainz v1.3

By Naja Melan Last update Oct 31, 2007 — Installed 891 times.
// ==UserScript==
// @name           CueBrainz v1.3
// @namespace      naja.nitewinds.org
// @description    Generate a cue sheet directly from musicbrainz.org
// @include        http://*musicbrainz.org/release/*
// @include        http://*musicbrainz.org/show/release/*
// @include        http://*musicbrainz.org/album/*
// ==/UserScript==

// Add our link to the page
//=========================



//Select the right td field to add our link

var node = document.evaluate( '//table [@class = "releaselinks"] // td [@class = "links"] // td [@class = "info"]',
                               document,
                               null,
                               XPathResult.FIRST_ORDERED_NODE_TYPE,
                               null ).singleNodeValue;

node.removeChild( node.lastChild ); //get rid of the ']'

sepText = document.createTextNode( " | " );
endText = document.createTextNode( " ] " );
ourLinkText = document.createTextNode( "Generate Cue-Sheet" );
link = document.createElement( "a" );

link.href = "javascript: var dfd1fFCF;"; //we just need some href attribute to keep it a link. This shouldn't do nothing,
link.appendChild( ourLinkText );         //however, we still prevent it later with event.preventdefault();
                                         //If you wonder why it needs to be a link; just so we dont have to care about the style.
node.appendChild( sepText ); 
node.appendChild( link ); 
node.appendChild( endText ); 

//Create our function to generate the cue sheet
//This function is big, because it has to hold everything after the greasemonkey
//script stops running, this way, we don't have to use unsafeWindow
//==============================================================================

link.addEventListener( "click", function( event )
{   

  //Retrieve the MBID from the link in the Release section.
  //don't use the document.location because this exists also:
  //http://musicbrainz.org/show/release/?releaseid=532461

  var linkText = document.evaluate( '//table [ @class = "releasebegin" ] // a [ contains( @id,"link::" ) ]',
                                     document,
                                    null,
                                    XPathResult.FIRST_ORDERED_NODE_TYPE,
                                    null ).singleNodeValue.href;

  var expr = /\/release\/([^\.]+)/; //Get everything between "/release/" and "."
  expr.test( linkText );
  var MBID = RegExp.$1;
  
  //Request the album info from musicbrainz webservice
  var req = new XMLHttpRequest();

  try
  {
    req.open("GET", "http://" + document.domain + "/ws/1/release/" + MBID + "?type=xml&inc=tracks+artist", true);  
  } 
  catch( oException )
  {
    alert( "We encountered a javascript exception while trying to request data from musicbrainz.org.\n"  + 
           "If this error persists, please write to: najamelan->gmail.com with information on how\n" +
           "to reproduce it.\n\n" +
           "Now follows the exception thrown by the mozilla javascript engine:\n\"" +
           oException + "\"" );
  }

  req.setRequestHeader( "User-agent", "Mozilla/4.0 (compatible) Greasemonkey/ Cue-Sheet Generator v1.0 / najamelan->gmail.com" );
  req.setRequestHeader( "Accept", "application/xml, text/xml" );
  
  req.onreadystatechange = function (aEvt)
  {
    if( req.readyState == 4 ) //If it's fully loaded
    {
      if( req.status == 200 ) //And it was succesfull
      {
        var dom = req.responseXML;
        
        //Add the disc info to the cuesheet
        //=================================
        //make sure it has no double quotes, cause that fucks up bad style
        
        
        
        var cueSheet = "REM Cue-Sheet generated from musicbrainz.org\r\n" 

        if( performer = dom.getElementsByTagName("artist")[0].getElementsByTagName("name")[0].firstChild.nodeValue.replace( /"/g, "''") )
        {
           cueSheet  += "PERFORMER \"" + performer;
        }
        
        if( cdTitle = dom.getElementsByTagName("title")[0].firstChild.nodeValue.replace( /"/g, "''") )
        {
          cueSheet   += "\"\r\nTITLE \"" + cdTitle;
        }
        
        cueSheet += "\"\r\nFILE \"PUT YOUR FILENAME HERE\" WAVE\r\n";
        
        //Add our tracks
        //==============
        function convDuration( x )
          //Convert duration in milliseconds from musicbrains to mm:ss:ff (frames) for cuesheets
          //thanx to Sven Hoffmeister for the convertion code
        {
          var frames = Math.round( x*0.075 ) % 75;                                 //  calculate inaccurate frames (0.075 is the ratio frames/ms)
          var msec   = frames / 0.075;                                             // calculate accurate  equivalent of frames
          var sec    = Math.round( ( x - msec ) / 1000 ) % 60;
          var min    = Math.round( ( x - msec - ( sec*1000 ) ) / (60 * 1000) );
          
          return ( min <10 ? "0" + min : min ) + ":" + ( sec <10 ? "0" + sec : sec ) + ":" + ( frames <10 ? "0" + frames : frames );
        }
       
        var trackList = dom.getElementsByTagName( "track" ); //get a list of all the tracks
        var trackCount = trackList.length;
        var timeOffset = 0;
        var duration = 0;
        var timeProblemFlag = 0; //For when time for certain tracks is unknown, we should stop writing indexes
        
        for( var i = 1; i <= trackCount; ++i )
           //Iterate trough the tracks, to build the entries
        {
 
           cueSheet += "  TRACK " + ( i <10 ? "0" + i : i ) + " AUDIO\r\n"; 

           //For various artist discs, include the performer with the track.           
           if( trackList[i-1].getElementsByTagName("artist")[0] )
           {
             var trPerformer = trackList[i-1].getElementsByTagName("name")[0].firstChild.nodeValue.replace( /"/g, "''")
             cueSheet += "    PERFORMER \"" + trPerformer + "\"\r\n"
           }
 
           if( trackList[i-1].getElementsByTagName("title")[0] )
           {
             var trTitle = trackList[i-1].getElementsByTagName("title")[0].firstChild.nodeValue.replace( /"/g, "''");
             cueSheet += "    TITLE \"" + trTitle + "\" \r\n";
           }
           
           if( timeProblemFlag ) //if there have been tracks without duration
           {
              cueSheet +=  "    INDEX 01 ??:??:??\r\n";
              continue;
           }

           cueSheet +=  "    INDEX 01 " + convDuration( duration + timeOffset ) + "\r\n";//so far so good, so write it.

           if ( !trackList[i-1].getElementsByTagName("duration")[0] && !timeProblemFlag ) //if this is the first one without duration
           {
              timeProblemFlag = 1;
           }
           
           if( !timeProblemFlag ) //calculate values for the next track
           {
             timeOffset += duration;         
             duration = parseInt( trackList[i-1].getElementsByTagName("duration")[0].firstChild.nodeValue );
           }
        }
        
        //Give a save as box to download the CueSheet
	      document.location = "data:text/CueSheet;charset=utf-8," + encodeURI( cueSheet ); //dataURL
      }
      
      else alert( "We encountered an error trying to retrieve data from musicbrainz.org\n"  + 
                  "If this error persists, and musicbrainz is not down, please write to:\n" +
                  "najamelan->gmail.com with information on how to reproduce it.\n\n"          +
                  "Now follows the error message retrieved from musicbrainz.org:\n\n"         +
                  req.responseText ); // if the status code was not 200
    }
  }; //end of our XMLHttpRequest onreadystatechange
  
  try
  {
    req.send(null);  
  }
  catch( exception )
  {
    alert( "We encountered a javascript exception while trying to request data from musicbrainz.org.\n"  + 
           "If this error persists, please write to: najamelan@gmail.com with information on how\n" +
           "to reproduce it.\n\n" +
           "Now follows the exception thrown by the mozilla javascript engine:\n" +
           "=======================================================\n" +
           exception + "\"" );
  }
 
  event.preventDefault();

}, true ); //end of our addEventListener()