All files / src/soundcloud soundcloud.js

8.93% Statements 5/56
0% Branches 0/31
22.22% Functions 2/9
8.93% Lines 5/56
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312                                      31x         31x                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                             1751x   1751x           31x                
/**
 * Imports the config module
 * @module config
 */
import config from "../config.js";
 
/**
 * Imports the initializer
 * @module init/AmplitudeInitializer
 */
import AmplitudeInitializer from "../init/init.js";
 
/**
 * These helpers wrap around the basic methods of the Soundcloud API
 * and get the information we need from SoundCloud to make the songs
 * streamable through Amplitude
 *
 * @module soundcloud/SoundCloud
 */
let SoundCloud = (function() {
  /**
   * Defines the temporary user config used while we configure soundcloud
   * @type {object}
   */
  let tempUserConfig = {};
 
  /**
   * Loads the soundcloud SDK for use with Amplitude so the user doesn't have
   * to load it themselves.
   * With help from: http://stackoverflow.com/questions/950087/include-a-javascript-file-in-another-javascript-file
   *
   * @access public
   * @param {object} userConfig 	- The config defined by the user for AmplitudeJS
   */
  function loadSoundCloud(userConfig) {
    /*
			Sets the temporary config to the config passed by the user so we can make changes
			and not break the actual config.
		*/
    tempUserConfig = userConfig;
 
    /*
			Gets the head tag for the document and create a script element.
		*/
    let head = document.getElementsByTagName("head")[0];
    let script = document.createElement("script");
 
    script.type = "text/javascript";
 
    /*
			URL to the remote soundcloud SDK
		*/
    script.src = "https://connect.soundcloud.com/sdk.js";
    script.onreadystatechange = initSoundcloud;
    script.onload = initSoundcloud;
 
    /*
			Add the script to the head of the document.
		*/
    head.appendChild(script);
  }
 
  /**
   * Initializes soundcloud with the key provided.
   *
   * @access private
   */
  function initSoundcloud() {
    /*
			Calls the SoundCloud initialize function
			from their API and sends it the client_id
			that the user passed in.
		*/
    SC.initialize({
      client_id: config.soundcloud_client
    });
 
    /*
			Gets the streamable URLs to run through Amplitue. This is
			VERY important since Amplitude can't stream the copy and pasted
			link from the SoundCloud page, but can resolve the streaming
			URLs from the link.
		*/
    getStreamableURLs();
  }
 
  /**
   * Gets the streamable URL from the URL provided for
   * all of the soundcloud links.  This will loop through
   * and set all of the information for the soundcloud
   * urls.
   *
   * @access private
   */
  function getStreamableURLs() {
    /*
			Define the regex to find the soundcloud URLs
		*/
    let soundcloud_regex = /^https?:\/\/(soundcloud.com|snd.sc)\/(.*)$/;
 
    for (let i = 0; i < config.songs.length; i++) {
      /*
				If the URL matches soundcloud, we grab
				that url and get the streamable link
				if there is one.
			*/
      if (config.songs[i].url.match(soundcloud_regex)) {
        config.soundcloud_song_count++;
        resolveStreamable(config.songs[i].url, i);
      }
    }
  }
 
  /**
   * Resolves an individual streamable URL.
   *
   * @param {string} url - The URL of the SoundCloud song to get the streamable URL from.
   * @param {string} playlist - The playlist we are getting the streamable URL for.
   * @param {Integer} index - The index of the song in the playlist or the songs array.
   * @param {boolean} addToShuffleList - Whether we add to the shuffle list for the songs or playlist.
   *
   */
  function resolveIndividualStreamableURL(
    url,
    playlist,
    index,
    addToShuffleList = false
  ) {
    SC.get("/resolve/?url=" + url, function(sound) {
      /*
        If streamable we get the url and bind the client ID to the end
        so Amplitude can just stream the song normally. We then overwrite
        the url the user provided with the streamable URL.
      */
      if (sound.streamable) {
        if (playlist != null) {
          config.playlists[playlist].songs[index].url =
            sound.stream_url + "?client_id=" + config.soundcloud_client;
 
          if (addToShuffleList) {
            config.playlists[playlist].shuffle_list[index].url =
              sound.stream_url + "?client_id=" + config.soundcloud_client;
          }
          /*
            If the user want's to use soundcloud art, we overwrite the
            cover_art_url with the soundcloud artwork url.
          */
          if (config.soundcloud_use_art) {
            config.playlists[playlist].songs[index].cover_art_url =
              sound.artwork_url;
 
            if (addToShuffleList) {
              config.playlists[playlist].shuffle_list[index].cover_art_url =
                sound.artwork_url;
            }
          }
 
          /*
            Grab the extra metadata from soundcloud and bind it to the
            song.  The user can get this through the public function:
            getActiveSongMetadata
          */
          config.playlists[playlist].songs[index].soundcloud_data = sound;
 
          if (addToShuffleList) {
            config.playlists[playlist].shuffle_list[
              index
            ].soundcloud_data = sound;
          }
        } else {
          config.songs[index].url =
            sound.stream_url + "?client_id=" + config.soundcloud_client;
 
          if (addToShuffleList) {
            config.shuffle_list[index].stream_url +
              "?client_id=" +
              config.soundcloud_client;
          }
 
          /*
            If the user want's to use soundcloud art, we overwrite the
            cover_art_url with the soundcloud artwork url.
          */
          if (config.soundcloud_use_art) {
            config.songs[index].cover_art_url = sound.artwork_url;
 
            if (addToShuffleList) {
              config.shuffle_list[index].cover_art_url = sound.artwork_url;
            }
          }
 
          /*
            Grab the extra metadata from soundcloud and bind it to the
            song.  The user can get this through the public function:
            getActiveSongMetadata
          */
          config.songs[index].soundcloud_data = sound;
 
          if (addToShuffleList) {
            config.shuffle_list[index].soundcloud_data = sound;
          }
        }
      } else {
        if (playlist != null) {
          AmplitudeHelpers.writeDebugMessage(
            config.playlists[playlist].songs[index].name +
              " by " +
              config.playlists[playlist].songs[index].artist +
              " is not streamable by the Soundcloud API"
          );
        } else {
          /*
            If not streamable, then we print a message to the user stating
            that the song with name X and artist X is not streamable. This
            gets printed ONLY if they have debug turned on.
          */
          AmplitudeHelpers.writeDebugMessage(
            config.songs[index].name +
              " by " +
              config.songs[index].artist +
              " is not streamable by the Soundcloud API"
          );
        }
      }
    });
  }
 
  /**
   * Due to Soundcloud SDK being asynchronous, we need to scope the
   * index of the song in another function. The privateGetSoundcloudStreamableURLs
   * function does the actual iteration and scoping.
   *
   * @access private
   * @param {string} url 		- URL of the soundcloud song
   * @param {number} index 	- The index of the soundcloud song in the songs array.
   */
  function resolveStreamable(url, index) {
    SC.get("/resolve/?url=" + url, function(sound) {
      /*
				If streamable we get the url and bind the client ID to the end
				so Amplitude can just stream the song normally. We then overwrite
				the url the user provided with the streamable URL.
			*/
      if (sound.streamable) {
        config.songs[index].url =
          sound.stream_url + "?client_id=" + config.soundcloud_client;
 
        /*
					If the user want's to use soundcloud art, we overwrite the
					cover_art_url with the soundcloud artwork url.
				*/
        if (config.soundcloud_use_art) {
          config.songs[index].cover_art_url = sound.artwork_url;
        }
 
        /*
					Grab the extra metadata from soundcloud and bind it to the
					song.  The user can get this through the public function:
					getActiveSongMetadata
				*/
        config.songs[index].soundcloud_data = sound;
      } else {
        /*
					If not streamable, then we print a message to the user stating
					that the song with name X and artist X is not streamable. This
					gets printed ONLY if they have debug turned on.
				*/
        AmplitudeHelpers.writeDebugMessage(
          config.songs[index].name +
            " by " +
            config.songs[index].artist +
            " is not streamable by the Soundcloud API"
        );
      }
      /*
				Increments the song ready counter.
			*/
      config.soundcloud_songs_ready++;
 
      /*
				When all songs are accounted for, then amplitude is ready
				to rock and we set the rest of the config.
			*/
      if (config.soundcloud_songs_ready == config.soundcloud_song_count) {
        AmplitudeInitializer.setConfig(tempUserConfig);
      }
    });
  }
 
  /**
   * Determines if a given URL is a SoundCloud URL.
   *
   * @param {string} url - The URL to test if it's a SoundCloud URL.
   */
  function isSoundCloudURL(url) {
    let soundcloud_regex = /^https?:\/\/(soundcloud.com|snd.sc)\/(.*)$/;
 
    return url.match(soundcloud_regex);
  }
 
  /*
		Returns the publically accessible methods
	*/
  return {
    loadSoundCloud: loadSoundCloud,
    resolveIndividualStreamableURL: resolveIndividualStreamableURL,
    isSoundCloudURL: isSoundCloudURL
  };
})();
 
export default SoundCloud;