<commit_before>import React, { Component } from 'react';
import * as $ from 'axios';

const stateKey = 'spotify_auth_state';

export default class App extends Component {

	constructor(props) {
		super(props);
		this.state = {
			user: null,
			playlists: null,
			access_token: null,
			multiFileExport: false
		}
		this.spotifyAuth = this.spotifyAuth.bind(this);
		this.exportSelectedPlaylists = this.exportSelectedPlaylists.bind(this);
		this.toggleSelectedPlaylists = this.toggleSelectedPlaylists.bind(this);
		this.toggleMultiFileExportMode = this.toggleMultiFileExportMode.bind(this);
	}

	componentDidMount() {

		var params = this.getHashParams();

		var state = params.state,
			storedState = localStorage.getItem(stateKey);

		if('access_token' in params) {
			this.setState({access_token: params.access_token}, () => {
				if (this.state.access_token && (state == null || state !== storedState)) {
					console.warn('There was an error during the authentication');
				}
				else {
					localStorage.removeItem(stateKey);
					if (this.state.access_token) {
						$.get('https://api.spotify.com/v1/me', {
							headers: {
							'Authorization': 'Bearer ' + this.state.access_token
							}
						})
						.then((response) => {
							this.setState({user: response.data, playlists: []});
							$.get('https://api.spotify.com/v1/me/playlists?limit=50', {
								headers: {
								'Authorization': 'Bearer ' + this.state.access_token
								}
							})
							.then((response) => {
								let playlists = response.data;
								for(let playlist of playlists.items) {
									playlist.byebyespotify_should_export = true;
								}
								this.setState({playlists: playlists});
							})
						})
					}
				}
			});
		}


	}

	componentWillUnmount() {

	}

	makeTrackCSVFromPlaylist(trackList, playlistName) {
		console.log('we got a tracklist here bobo');
		let csv = '';
		if(trackList.items.length) {
			trackList.items.forEach( (item, index) => {
				csv += this.sanitizeFieldForCSV(item.track.name)  + ',' + this.sanitizeFieldForCSV(item.track.artists[0].name) + ',' + this.sanitizeFieldForCSV(item.track.album.name);
				if(!this.state.multiFileExport) {
					csv += ',' + this.sanitizeFieldForCSV(playlistName);
				}
				if(index < trackList.items.length) {
					csv += '\r\n';
				}
			});
		}
		return csv;
	}

	// Takes a string and returns a string suitable for use in the CSV file,
	// adding quotes if the string contains a comma and escaping quotes if quotes were added.
	// See: http://stackoverflow.com/questions/769621/dealing-with-commas-in-a-csv-file
	sanitizeFieldForCSV(string) {
		if(string.includes(',')) {
			if(!string.includes('"')) {
				return '"' + string + '"';
			}
			return '"' + string.replace(/"/g, '\"') + '"';
		}
		return string;
	}

	getPlaylistDetails(playlist) {
		return $.get(playlist.href, {
			headers: {
			'Authorization': 'Bearer ' + this.state.access_token
			}
		})
		.then((response) => {
			if('data' in response && response.data.tracks.items.length) {
				playlist.trackList = response.data.tracks;
			}
		})
	}

	spotifyAuth() {
		let client_id = '0e5aaf3062d24668b96cbe8c6309aa36';
		let redirect_uri = 'http://localhost:8888/';

		let state = this.generateRandomString(16);

		localStorage.setItem(stateKey, state);
		let scope = 'user-read-private user-read-email playlist-read-collaborative';

		let url = 'https://accounts.spotify.com/authorize';
		url += '?response_type=token';
		url += '&client_id=' + encodeURIComponent(client_id);
		url += '&scope=' + encodeURIComponent(scope);
		url += '&redirect_uri=' + encodeURIComponent(redirect_uri);
		url += '&state=' + encodeURIComponent(state);

		window.location = url;
	}

	/**
	* Generates a random string containing numbers and letters
	* @param  {number} length The length of the string
	* @return {string} The generated string
	*/
	generateRandomString(length) {
		var text = '';
		var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

		for (var i = 0; i < length; i++) {
			text += possible.charAt(Math.floor(Math.random() * possible.length));
		}

		return text;
	}

	/**
	* Obtains parameters from the hash of the URL
	* @return Object
	*/
	getHashParams() {
		var hashParams = {};
		var e, r = /([^&;=]+)=?([^&;]*)/g,
		  q = window.location.hash.substring(1);
		while ( e = r.exec(q)) {
			hashParams[e[1]] = decodeURIComponent(e[2]);
		}

		return hashParams;
	}

	renderUserProfile() {
		if(this.state.user) {
			console.log('sherpin a derp', this.state);
			let { user } = this.state;
			return (
				<div>
					<h1>Hey, <img width="50" className="profile-picture" src={user.images[0].url} /> {user.display_name}</h1>
				</div>
			);
		}
	}

	downloadPlaylists(playlists) {
		console.log('gonna downloadPlaylists', playlists);
		if(Array.isArray(playlists) && playlists.length) {
			const promiseArray = Array.from(playlists, (playlist) => {
				return this.getPlaylistDetails(playlist);
			});

			Promise.all(promiseArray)
			.then(() => {
				console.log('got the tracks for all selected playlists, time to assemble CSVs');

				if(this.state.multiFileExport) {
					playlists.forEach((playlist) => {
						let csvFile = 'data:text/csv;charset=utf-8,' + 'title,artist,album\r\n' + this.makeTrackCSVFromPlaylist(playlist.trackList, playlist.name);
						console.log('csv contents', csvFile);
						this.triggerPlaylistDownload(playlist.name, csvFile);
					});
				}
				else {
					let csvFile = 'data:text/csv;charset=utf-8,' + 'title,artist,album,playlist\r\n';
					playlists.forEach((playlist) => {
						csvFile += this.makeTrackCSVFromPlaylist(playlist.trackList, playlist.name);
					});
					this.triggerPlaylistDownload('multi-file-playlist', csvFile);
				}
			});
		}
	}

	triggerPlaylistDownload(fileName, csvFile) {
		let encodedFile = encodeURI(csvFile);
		let link = document.createElement('a');
		link.setAttribute('href', encodedFile);
		link.setAttribute('download', fileName + '.csv');
		document.body.appendChild(link);
		link.click();
		document.body.removeChild(link);
	}

	exportSelectedPlaylists() {
		console.log('beginning playlist export, multi-file mode is', this.state.multiFileExport);
		let playlistsToExport = this.getCurrentSelectedPlaylists();
		this.downloadPlaylists(playlistsToExport);<commit_msg>-Comment out console logs -Better filename when exporting playlists as one file<commit_after>import React, { Component } from 'react';
import * as $ from 'axios';

const stateKey = 'spotify_auth_state';

export default class App extends Component {

	constructor(props) {
		super(props);
		this.state = {
			user: null,
			playlists: null,
			access_token: null,
			multiFileExport: false
		}
		this.spotifyAuth = this.spotifyAuth.bind(this);
		this.exportSelectedPlaylists = this.exportSelectedPlaylists.bind(this);
		this.toggleSelectedPlaylists = this.toggleSelectedPlaylists.bind(this);
		this.toggleMultiFileExportMode = this.toggleMultiFileExportMode.bind(this);
	}

	componentDidMount() {

		var params = this.getHashParams();

		var state = params.state,
			storedState = localStorage.getItem(stateKey);

		if('access_token' in params) {
			this.setState({access_token: params.access_token}, () => {
				if (this.state.access_token && (state == null || state !== storedState)) {
					console.warn('There was an error during the authentication');
				}
				else {
					localStorage.removeItem(stateKey);
					if (this.state.access_token) {
						$.get('https://api.spotify.com/v1/me', {
							headers: {
							'Authorization': 'Bearer ' + this.state.access_token
							}
						})
						.then((response) => {
							this.setState({user: response.data, playlists: []});
							$.get('https://api.spotify.com/v1/me/playlists?limit=50', {
								headers: {
								'Authorization': 'Bearer ' + this.state.access_token
								}
							})
							.then((response) => {
								let playlists = response.data;
								for(let playlist of playlists.items) {
									playlist.byebyespotify_should_export = true;
								}
								this.setState({playlists: playlists});
							})
						})
					}
				}
			});
		}


	}

	componentWillUnmount() {

	}

	makeTrackCSVFromPlaylist(trackList, playlistName) {
		//console.log('we got a tracklist here bobo');
		let csv = '';
		if(trackList.items.length) {
			trackList.items.forEach( (item, index) => {
				csv += this.sanitizeFieldForCSV(item.track.name)  + ',' + this.sanitizeFieldForCSV(item.track.artists[0].name) + ',' + this.sanitizeFieldForCSV(item.track.album.name);
				if(!this.state.multiFileExport) {
					csv += ',' + this.sanitizeFieldForCSV(playlistName);
				}
				if(index < trackList.items.length) {
					csv += '\r\n';
				}
			});
		}
		return csv;
	}

	// Takes a string and returns a string suitable for use in the CSV file,
	// adding quotes if the string contains a comma and escaping quotes if quotes were added.
	// See: http://stackoverflow.com/questions/769621/dealing-with-commas-in-a-csv-file
	sanitizeFieldForCSV(string) {
		if(string.includes(',')) {
			if(!string.includes('"')) {
				return '"' + string + '"';
			}
			return '"' + string.replace(/"/g, '\"') + '"';
		}
		return string;
	}

	getPlaylistDetails(playlist) {
		return $.get(playlist.href, {
			headers: {
			'Authorization': 'Bearer ' + this.state.access_token
			}
		})
		.then((response) => {
			if('data' in response && response.data.tracks.items.length) {
				playlist.trackList = response.data.tracks;
			}
		})
	}

	spotifyAuth() {
		let client_id = '0e5aaf3062d24668b96cbe8c6309aa36';
		let redirect_uri = 'http://localhost:8888/';

		let state = this.generateRandomString(16);

		localStorage.setItem(stateKey, state);
		let scope = 'user-read-private user-read-email playlist-read-collaborative';

		let url = 'https://accounts.spotify.com/authorize';
		url += '?response_type=token';
		url += '&client_id=' + encodeURIComponent(client_id);
		url += '&scope=' + encodeURIComponent(scope);
		url += '&redirect_uri=' + encodeURIComponent(redirect_uri);
		url += '&state=' + encodeURIComponent(state);

		window.location = url;
	}

	/**
	* Generates a random string containing numbers and letters
	* @param  {number} length The length of the string
	* @return {string} The generated string
	*/
	generateRandomString(length) {
		var text = '';
		var possible = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';

		for (var i = 0; i < length; i++) {
			text += possible.charAt(Math.floor(Math.random() * possible.length));
		}

		return text;
	}

	/**
	* Obtains parameters from the hash of the URL
	* @return Object
	*/
	getHashParams() {
		var hashParams = {};
		var e, r = /([^&;=]+)=?([^&;]*)/g,
		  q = window.location.hash.substring(1);
		while ( e = r.exec(q)) {
			hashParams[e[1]] = decodeURIComponent(e[2]);
		}

		return hashParams;
	}

	renderUserProfile() {
		if(this.state.user) {
			//console.log('sherpin a derp', this.state);
			let { user } = this.state;
			return (
				<div>
					<h1>Hey, <img width="50" className="profile-picture" src={user.images[0].url} /> {user.display_name}</h1>
				</div>
			);
		}
	}

	downloadPlaylists(playlists) {
		console.log('gonna downloadPlaylists', playlists);
		if(Array.isArray(playlists) && playlists.length) {
			const promiseArray = Array.from(playlists, (playlist) => {
				return this.getPlaylistDetails(playlist);
			});

			Promise.all(promiseArray)
			.then(() => {
				console.log('got the tracks for all selected playlists, time to assemble CSVs');

				if(this.state.multiFileExport) {
					playlists.forEach((playlist) => {
						let csvFile = 'data:text/csv;charset=utf-8,' + 'title,artist,album\r\n' + this.makeTrackCSVFromPlaylist(playlist.trackList, playlist.name);
						console.log('csv contents', csvFile);
						this.triggerPlaylistDownload(playlist.name, csvFile);
					});
				}
				else {
					const formattedDate = new Date().toLocaleString(false,{ year: 'numeric', month: 'long', day: 'numeric' }).replace(',', '').replace(/ /g, '-');
					let csvFile = 'data:text/csv;charset=utf-8,' + 'title,artist,album,playlist\r\n';
					playlists.forEach((playlist) => {
						csvFile += this.makeTrackCSVFromPlaylist(playlist.trackList, playlist.name);
					});
					this.triggerPlaylistDownload(this.state.user.uri + '_playlists_exported_' + formattedDate, csvFile);
				}
			});
		}
	}

	triggerPlaylistDownload(fileName, csvFile) {
		let encodedFile = encodeURI(csvFile);
		let link = document.createElement('a');
		link.setAttribute('href', encodedFile);
		link.setAttribute('download', fileName + '.csv');
		document.body.appendChild(link);
		link.click();
		document.body.removeChild(link);
	}

	exportSelectedPlaylists() {
		console.log('beginning playlist export, multi-file mode is', this.state.multiFileExport);
		let playlistsToExport = this.getCurrentSelectedPlaylists();
		this.downloadPlaylists(playlistsToExport);
{'fraction_non_alphanumeric': 0.15447975755691973, 'fraction_numerical': 0.00901390939466936, 'mean_word_length': 3.6112504478681475, 'pattern_counts': {'":': 0, '<': 17, '<?xml version=': 0, '>': 31, 'https://': 6, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '295502', 'n_tokens_mistral': 5165, 'n_tokens_neox': 4311, 'n_words': 769}