Advertisement
YM_Industries

Improved Pandora Script

Jul 26th, 2017
6,796
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. (function() {
  2.     var pageSize = 100;
  3.     var stationPageSize = 250; // IMPORTANT: This script only gets the first page of stations. If you have more than 250 this may be a problem, sorry.
  4.     var webname = location.pathname.split("/").pop(); // Seems to be a variation of the username, can be retrieved from the URL
  5.     var includeThumbsDown = true;
  6.  
  7.     var allThumbs = [];
  8.  
  9.     // Step one, obtain the AuthToken and CsrfToken which will allow us to make requests to the Pandora API.
  10.     var authToken = undefined;
  11.     var csrfToken = undefined;
  12.  
  13.     var originalSetRequestHeader = XMLHttpRequest.prototype.setRequestHeader;
  14.     XMLHttpRequest.prototype.setRequestHeader = function(name, value) { // If I had more time maybe I wouldn't need to use this hook
  15.         if(name === "X-AuthToken") {
  16.             authToken = value;
  17.         }
  18.         if(name === "X-CsrfToken") {
  19.             csrfToken = value;
  20.         }
  21.         originalSetRequestHeader.apply(this, arguments);
  22.         if(authToken && csrfToken) { // We've got them both, let's get a move on
  23.             XMLHttpRequest.prototype.setRequestHeader = originalSetRequestHeader; // Deregister our hook...
  24.             getStations(); // ...and get to work
  25.         }
  26.     };
  27.     window.scrollTo(0,document.body.scrollHeight); // Scroll to the bottom of the page to trigger a load so we can hook the event
  28.  
  29.     // Step two, get a list of all stations
  30.     function getStations() {
  31.         var req = new XMLHttpRequest();
  32.         req.open('POST', "/api/v1/station/getStations", true);
  33.         req.setRequestHeader("Content-Type", "application/json"); // Pandora API rejects requests without this content type set
  34.         req.setRequestHeader("X-AuthToken", authToken);
  35.         req.setRequestHeader("X-CsrfToken", csrfToken);
  36.         req.onreadystatechange = function() {
  37.             if(req.readyState == XMLHttpRequest.DONE && req.status == 200) {
  38.                 var data = JSON.parse(req.responseText);
  39.                 var stations = [];
  40.                 for(var i = 0; i < data.stations.length; i++) {
  41.                     stations.push(data.stations[i].stationId);
  42.                 }
  43.                 getTracks(stations);
  44.             }
  45.         };
  46.         req.send(JSON.stringify({
  47.             pageSize: stationPageSize
  48.         }));
  49.     };
  50.    
  51.     // Step three, fetch the tracks
  52.     function getTracks(stations) {
  53.         function callback() {
  54.             currentStationId++;
  55.             if(currentStationId < stations.length) {
  56.                 console.log("Getting tracks for station", currentStationId+1, "of", stations.length);
  57.                 fetchPage(stations[currentStationId], true, 0, callback);
  58.             } else {
  59.                 finalize();
  60.             }
  61.         };
  62.         var currentStationId = -1;
  63.         callback();
  64.     };
  65.    
  66.     function fetchPage(stationId, positive, pageNumber, callback) {
  67.         var req = new XMLHttpRequest();
  68.         req.open('POST', "/api/v1/station/getStationFeedback", true);
  69.         req.setRequestHeader("Content-Type", "application/json"); // Pandora API rejects requests without this content type set
  70.         req.setRequestHeader("X-AuthToken", authToken);
  71.         req.setRequestHeader("X-CsrfToken", csrfToken);
  72.         req.onreadystatechange = function() {
  73.             if(req.readyState == XMLHttpRequest.DONE && req.status == 200) {
  74.                 var data = JSON.parse(req.responseText);
  75.                 data.feedback = data.feedback.map(function(item) {
  76.                     item.type = item.isPositive ? "Thumbs Up" : "Thumbs Down";
  77.                     return item;
  78.                 });
  79.                 allThumbs = allThumbs.concat(data.feedback);
  80.                 if(data.feedback.length > 0) {
  81.                     fetchPage(stationId, positive, pageNumber+1, callback);
  82.                 } else {
  83.                     if(positive && includeThumbsDown) {
  84.                         fetchPage(stationId, false, 0, callback);
  85.                     } else {
  86.                         callback();
  87.                     }
  88.                 }
  89.             }
  90.         };
  91.         req.send(JSON.stringify({
  92.             pageSize: pageSize,
  93.             positive: positive,
  94.             startIndex: pageNumber * pageSize,
  95.             stationId: stationId
  96.         }));
  97.     }
  98.  
  99.     // Step four, compile the output
  100.     function finalize() {
  101.         var string = "Artist\tAlbum\tSong\tStation\tType\tAmazon Link\tiTunes Link\tDisc Number\tTrack Number\tDuration (Seconds)";
  102.         for(var i = 0; i < allThumbs.length; i++) {
  103.             var thumb = allThumbs[i];
  104.             string += "\n" +
  105.                 thumb.artistName.replace(/\t/g, "    ").replace(/\n|\r/g, "") + "\t" +
  106.                 thumb.albumTitle.replace(/\t/g, "    ").replace(/\n|\r/g, "") + "\t" +
  107.                 thumb.songTitle.replace(/\t/g, "    ").replace(/\n|\r/g, "") + "\t" +
  108.                 thumb.stationName.replace(/\t/g, "    ").replace(/\n|\r/g, "") + "\t" +
  109.                 thumb.type + "\t" +
  110.                 thumb.amazonUrl + "\t" +
  111.                 thumb.itunesUrl + "\t" +
  112.                 thumb.discNum + "\t" +
  113.                 thumb.trackNum + "\t" +
  114.                 thumb.trackLength;
  115.         }
  116.         console.log(string);
  117.     }
  118. })();
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement