diff --git a/cli.js b/cli.js index ab00e76..e1f7a7e 100755 --- a/cli.js +++ b/cli.js @@ -25,4 +25,4 @@ try { logFailure('Something went wrong!'); console.log(error); process.exit(1); -} \ No newline at end of file +} diff --git a/lib/api.js b/lib/api.js index 8754e83..01a1f44 100644 --- a/lib/api.js +++ b/lib/api.js @@ -8,16 +8,15 @@ import Constants from '../util/constants.js'; import { logInfo, logFailure } from '../util/log-helper.js'; const { - spotifyApi: { - clientId, - clientSecret, - }, + spotifyApi: { clientId, clientSecret }, } = Config; const { AUTH: { SCOPES: { - USERS_SAVED_PLAYLISTS, USERS_SAVED_TRACKS_ALBUMS, USERS_TOP_TRACKS, + USERS_SAVED_PLAYLISTS, + USERS_SAVED_TRACKS_ALBUMS, + USERS_TOP_TRACKS, }, STATE, REFRESH_ACCESS_TOKEN_SECONDS, @@ -52,7 +51,7 @@ Object.defineProperty(Array.prototype, 'chunk', { }); const verifyCredentials = async () => { - if (!nextTokenRefreshTime || (nextTokenRefreshTime < new Date())) { + if (!nextTokenRefreshTime || nextTokenRefreshTime < new Date()) { nextTokenRefreshTime = new Date(); nextTokenRefreshTime.setSeconds( nextTokenRefreshTime.getSeconds() + REFRESH_ACCESS_TOKEN_SECONDS, @@ -66,18 +65,14 @@ const checkCredentials = async () => { if (await spotifyApi.getRefreshToken()) { await refreshToken(); } else { - const { - inputs, - username, - password, - login, - } = cliInputs(); - - const requiresLogin = inputs.find(input => - input.type == INPUT_TYPES.SONG.SAVED_ALBUMS || - input.type == INPUT_TYPES.SONG.SAVED_PLAYLISTS || - input.type == INPUT_TYPES.SONG.SAVED_TRACKS || - input.type == INPUT_TYPES.EPISODE.SAVED_SHOWS, + const { inputs, username, password, login } = cliInputs(); + + const requiresLogin = inputs.find( + input => + input.type == INPUT_TYPES.SONG.SAVED_ALBUMS || + input.type == INPUT_TYPES.SONG.SAVED_PLAYLISTS || + input.type == INPUT_TYPES.SONG.SAVED_TRACKS || + input.type == INPUT_TYPES.EPISODE.SAVED_SHOWS, ); const requestingLogin = (username && password) || login; @@ -91,10 +86,7 @@ const checkCredentials = async () => { }; const requestAuthorizedTokens = async () => { - const { - username, - password, - } = cliInputs(); + const { username, password } = cliInputs(); const autoLogin = username.length > 0 && password.length > 0; const app = express(); let resolve; @@ -107,17 +99,11 @@ const requestAuthorizedTokens = async () => { }); const server = await app.listen(PORT); - const authURL = await spotifyApi.createAuthorizeURL( - scopes, - STATE, - autoLogin, - ); + const authURL = await spotifyApi.createAuthorizeURL(scopes, STATE, autoLogin); let browser = null; - logInfo( - 'Performing Spotify Auth Please Wait...', - ); + logInfo('Performing Spotify Auth Please Wait...'); if (autoLogin) { browser = await puppeteer.launch({ @@ -136,8 +122,8 @@ const requestAuthorizedTokens = async () => { await page.type('#login-password', password); await page.click('#login-button'); await page - .waitForSelector('#auth-accept, *[data-testid="auth-accept"]') - .then(e => e.click()); + .waitForSelector('#auth-accept, *[data-testid="auth-accept"]') + .then(e => e.click()); } catch (e) { logFailure(e.message); const screenshotPath = './failure.png'; @@ -158,9 +144,7 @@ const requestAuthorizedTokens = async () => { } const code = await getCode; - setTokens( - (await spotifyApi.authorizationCodeGrant(code)).body, - ); + setTokens((await spotifyApi.authorizationCodeGrant(code)).body); if (browser) { browser.close(); } @@ -195,7 +179,7 @@ const callSpotifyApi = async function (apiCall) { error = e; logInfo( `Got a spotify api error (${e})\n` + - `Timing out for 5 minutes x ${tries}`, + `Timing out for 5 minutes x ${tries}`, ); await new Promise(resolve => setTimeout(resolve, TIMEOUT_RETRY * 1000)); tries++; @@ -209,17 +193,16 @@ export async function extractTracks(trackIds) { let extractedTracks = []; const chunkedTracks = trackIds.chunk(20); for (let x = 0; x < chunkedTracks.length; x++) { - logInfo('extracting track set ' + - `${x + 1}/${chunkedTracks.length}`); + logInfo('extracting track set ' + `${x + 1}/${chunkedTracks.length}`); const tracks = await callSpotifyApi( async () => (await spotifyApi.getTracks(chunkedTracks[x])).body.tracks, ); extractedTracks.push(...tracks); } extractedTracks = extractedTracks.filter(x => x); - const audioFeatures = (await extractTrackAudioFeatures( - extractedTracks.map(track => track.id), - )).filter(x => x); + const audioFeatures = ( + await extractTrackAudioFeatures(extractedTracks.map(track => track.id)) + ).filter(x => x); return extractedTracks.map(track => parseTrack(track, audioFeatures)); } @@ -259,27 +242,25 @@ const parseEpisode = (episode, index = 0) => { export async function extractPlaylist(playlistId) { const playlistInfo = await callSpotifyApi( - async () => (await spotifyApi.getPlaylist( - playlistId, - { limit: 1 }, - )).body, + async () => (await spotifyApi.getPlaylist(playlistId, { limit: 1 })).body, ); const tracks = []; let playlistData; let offset = 0; do { playlistData = await callSpotifyApi( - async () => (await spotifyApi.getPlaylistTracks( - playlistId, - { limit: MAX_LIMIT_DEFAULT, offset: offset }, - )).body, + async () => + ( + await spotifyApi.getPlaylistTracks(playlistId, { + limit: MAX_LIMIT_DEFAULT, + offset: offset, + }) + ).body, ); if (!offset) { logInfo(`extracting ${playlistData.total} tracks`); } - tracks.push( - ...playlistData.items, - ); + tracks.push(...playlistData.items); offset += MAX_LIMIT_DEFAULT; } while (tracks.length < playlistData.total); const audioFeatures = await extractTrackAudioFeatures( @@ -295,20 +276,20 @@ export async function extractPlaylist(playlistId) { export async function extractAlbum(albumId) { const albumInfo = await callSpotifyApi( - async () => (await spotifyApi.getAlbum( - albumId, - { limit: 1 }, - )).body, + async () => (await spotifyApi.getAlbum(albumId, { limit: 1 })).body, ); const tracks = []; let offset = 0; let albumTracks; do { albumTracks = await callSpotifyApi( - async () => (await spotifyApi.getAlbumTracks( - albumId, - { limit: MAX_LIMIT_DEFAULT, offset: offset }, - )).body, + async () => + ( + await spotifyApi.getAlbumTracks(albumId, { + limit: MAX_LIMIT_DEFAULT, + offset: offset, + }) + ).body, ); if (!offset) { logInfo(`extracting ${albumTracks.total} tracks`); @@ -317,11 +298,9 @@ export async function extractAlbum(albumId) { offset += MAX_LIMIT_DEFAULT; } while (tracks.length < albumTracks.total); - const trackParsed = (await extractTracks( - tracks - .filter(track => track) - .map(track => track.id), - )).map(track => { + const trackParsed = ( + await extractTracks(tracks.filter(track => track).map(track => track.id)) + ).map(track => { track.artists = [albumInfo.artists[0].name, ...track.artists]; return track; }); @@ -349,10 +328,13 @@ export async function extractArtistAlbums(artistId) { let artistAlbums; do { artistAlbums = await callSpotifyApi( - async () => (await spotifyApi.getArtistAlbums( - artistId, - { limit: MAX_LIMIT_DEFAULT, offset: offset }, - )).body, + async () => + ( + await spotifyApi.getArtistAlbums(artistId, { + limit: MAX_LIMIT_DEFAULT, + offset: offset, + }) + ).body, ); if (!offset) { logInfo(`extracting ${artistAlbums.total} albums`); @@ -369,12 +351,12 @@ export async function extractEpisodes(episodeIds) { let episodesResult; const chunkedEpisodes = episodeIds.chunk(20); for (let x = 0; x < chunkedEpisodes.length; x++) { - logInfo('extracting episode set ' + - `${x + 1}/${chunkedEpisodes.length}`); + logInfo('extracting episode set ' + `${x + 1}/${chunkedEpisodes.length}`); episodesResult = await callSpotifyApi( - async () => (await spotifyApi.getEpisodes( - chunkedEpisodes[x], - )).body.episodes, + async () => + ( + await spotifyApi.getEpisodes(chunkedEpisodes[x]) + ).body.episodes, ); episodesResult = episodesResult.filter(episode => episode); episodes.push(...episodesResult); @@ -384,19 +366,20 @@ export async function extractEpisodes(episodeIds) { export async function extractShowEpisodes(showId) { const showInfo = await callSpotifyApi( - async () => (await spotifyApi.getShow( - showId, - )).body, + async () => (await spotifyApi.getShow(showId)).body, ); const episodes = []; let offset = 0; let showEpisodes; do { showEpisodes = await callSpotifyApi( - async () => (await spotifyApi.getShowEpisodes( - showId, - { limit: MAX_LIMIT_DEFAULT, offset: offset }, - )).body, + async () => + ( + await spotifyApi.getShowEpisodes(showId, { + limit: MAX_LIMIT_DEFAULT, + offset: offset, + }) + ).body, ); if (!offset) { logInfo(`extracting ${showEpisodes.total} episodes`); @@ -416,9 +399,13 @@ export async function extractSavedShows() { let savedShows; do { savedShows = await callSpotifyApi( - async () => (await spotifyApi.getMySavedShows( - { limit: MAX_LIMIT_DEFAULT, offset: offset }, - )).body, + async () => + ( + await spotifyApi.getMySavedShows({ + limit: MAX_LIMIT_DEFAULT, + offset: offset, + }) + ).body, ); if (!offset) { logInfo(`extracting ${savedShows.total} shows`); @@ -435,9 +422,13 @@ export async function extractSavedAlbums() { let savedAlbums; do { savedAlbums = await callSpotifyApi( - async () => (await spotifyApi.getMySavedAlbums( - { limit: MAX_LIMIT_DEFAULT, offset: offset }, - )).body, + async () => + ( + await spotifyApi.getMySavedAlbums({ + limit: MAX_LIMIT_DEFAULT, + offset: offset, + }) + ).body, ); if (!offset) { logInfo(`extracting ${savedAlbums.total} albums`); @@ -455,9 +446,13 @@ export async function extractSavedPlaylists() { let savedPlaylists; do { savedPlaylists = await callSpotifyApi( - async () => (await spotifyApi.getUserPlaylists( - { limit: MAX_LIMIT_DEFAULT, offset: offset }, - )).body, + async () => + ( + await spotifyApi.getUserPlaylists({ + limit: MAX_LIMIT_DEFAULT, + offset: offset, + }) + ).body, ); if (!offset) { logInfo(`extracting ${savedPlaylists.total} playlists`); @@ -475,16 +470,17 @@ export async function extractSavedTracks() { let savedTracks; do { savedTracks = await callSpotifyApi( - async () => (await spotifyApi.getMySavedTracks( - { limit: MAX_LIMIT_DEFAULT, offset: offset }, - )).body, - ); - tracks.push( - ...savedTracks.items.map(item => item.track), + async () => + ( + await spotifyApi.getMySavedTracks({ + limit: MAX_LIMIT_DEFAULT, + offset: offset, + }) + ).body, ); + tracks.push(...savedTracks.items.map(item => item.track)); offset += MAX_LIMIT_DEFAULT; - logInfo('extracting tracks ' + - `${tracks.length}/${savedTracks.total}`); + logInfo('extracting tracks ' + `${tracks.length}/${savedTracks.total}`); } while (tracks.length < savedTracks.total); const audioFeatures = await extractTrackAudioFeatures( tracks.map(track => track.id), @@ -493,21 +489,21 @@ export async function extractSavedTracks() { name: 'Saved Tracks', items: tracks .filter(track => track) - .map(track => parseTrack( - track, - audioFeatures, - )), + .map(track => parseTrack(track, audioFeatures)), }; } export async function extractTrackAudioFeatures(trackIds) { let audioFeatures = []; - for(let chunk of trackIds.chunk(MAX_LIMIT_DEFAULT)) { - audioFeatures.push(...(await callSpotifyApi( - async () => (await spotifyApi.getAudioFeaturesForTracks( - chunk, - )).body.audio_features, - ))); + for (let chunk of trackIds.chunk(MAX_LIMIT_DEFAULT)) { + audioFeatures.push( + ...(await callSpotifyApi( + async () => + ( + await spotifyApi.getAudioFeaturesForTracks(chunk) + ).body.audio_features, + )), + ); } return audioFeatures.filter(x => x); } diff --git a/lib/cache.js b/lib/cache.js index 29bbd7f..1759478 100644 --- a/lib/cache.js +++ b/lib/cache.js @@ -5,8 +5,7 @@ import { cliInputs } from './setup.js'; const getCacheFile = dir => { const { cacheFile } = cliInputs(); const cacheFileIsRelative = cacheFile[0] == '.'; - return cacheFileIsRelative ? - path.join(dir, cacheFile) : cacheFile; + return cacheFileIsRelative ? path.join(dir, cacheFile) : cacheFile; }; export function writeId(dir, id) { @@ -18,7 +17,8 @@ export function findId(id, dir) { const cacheFile = getCacheFile(dir); let cached = false; if (fs.existsSync(cacheFile)) { - cached = fs.readFileSync(cacheFile, 'utf-8') + cached = fs + .readFileSync(cacheFile, 'utf-8') .split('\n') .map(line => line.replace('spotify ', '')) .find(line => line == id); diff --git a/lib/downloader.js b/lib/downloader.js index 8e3e3a7..7ea8b97 100644 --- a/lib/downloader.js +++ b/lib/downloader.js @@ -7,7 +7,10 @@ import Config from '../config.js'; import { cliInputs } from './setup.js'; import Constants from '../util/constants.js'; import { - logStart, updateSpinner, logInfo, logSuccess, + logStart, + updateSpinner, + logInfo, + logSuccess, } from '../util/log-helper.js'; const { youtubeDLConfig, isTTY } = Config; @@ -23,26 +26,26 @@ const { MUSIC_OFF_TOPIC, }, }, - FFMPEG: { - ASET, - TIMEOUT_MINUTES, - }, + FFMPEG: { ASET, TIMEOUT_MINUTES }, } = Constants; const sponsorComplexFilter = async link => { - const videoID = (new URLSearchParams((new URL(link)).search)).get('v'); + const videoID = new URLSearchParams(new URL(link).search).get('v'); let segments = []; let complexFilter = null; try { - segments = (await sponsorBlock.getSegments( - videoID, - SPONSOR, - INTRO, - OUTRO, - INTERACTION, - SELF_PROMO, - MUSIC_OFF_TOPIC, - )).sort((a, b) => a.startTime - b.startTime) + segments = ( + await sponsorBlock.getSegments( + videoID, + SPONSOR, + INTRO, + OUTRO, + INTERACTION, + SELF_PROMO, + MUSIC_OFF_TOPIC, + ) + ) + .sort((a, b) => a.startTime - b.startTime) .reduce((acc, { startTime, endTime }) => { const previousSegment = acc[acc.length - 1]; // if segments overlap merge @@ -54,7 +57,7 @@ const sponsorComplexFilter = async link => { return acc; }, []); // we have to catch as it throws if none found - } catch (_) { } + } catch (_) {} const segmentLength = segments.length; if (segmentLength) { // 0 -> start1 , end1 -> start2, end2 @@ -64,10 +67,14 @@ const sponsorComplexFilter = async link => { const endString = `:end=${segment.startTime}`; return `[0:a]atrim=${startString}${endString},${ASET}[${i}a];`; }); - complexFilter.push(`[0:a]atrim=start=${segments[segmentLength - 1].endTime}` - + `,${ASET}[${segmentLength}a];`); - complexFilter.push(`${complexFilter.map((_, i) => `[${i}a]`).join('')}` + - `concat=n=${segmentLength + 1}:v=0:a=1[outa]`); + complexFilter.push( + `[0:a]atrim=start=${segments[segmentLength - 1].endTime}` + + `,${ASET}[${segmentLength}a];`, + ); + complexFilter.push( + `${complexFilter.map((_, i) => `[${i}a]`).join('')}` + + `concat=n=${segmentLength + 1}:v=0:a=1[outa]`, + ); complexFilter = complexFilter.join('\n'); } return complexFilter; @@ -77,7 +84,7 @@ const progressFunction = (_, downloaded, total) => { const downloadedMb = (downloaded / 1024 / 1024).toFixed(2); const toBeDownloadedMb = (total / 1024 / 1024).toFixed(2); const downloadText = `Downloaded ${downloadedMb}/${toBeDownloadedMb} MB`; - if (isTTY || (downloadedMb % 1 == 0 || toBeDownloadedMb == downloadedMb)) { + if (isTTY || downloadedMb % 1 == 0 || toBeDownloadedMb == downloadedMb) { updateSpinner(downloadText); } }; @@ -106,7 +113,7 @@ const getYoutubeDLConfig = () => { }; /** - * This function downloads the given youtube video + * This function downloads the given youtube video * in best audio format as mp3 file * * @param {array} youtubeLinks array of links of youtube videos @@ -115,7 +122,7 @@ const getYoutubeDLConfig = () => { const downloader = async (youtubeLinks, output) => { let attemptCount = 0; let downloadSuccess = false; - while ((attemptCount < youtubeLinks.length) && !downloadSuccess) { + while (attemptCount < youtubeLinks.length && !downloadSuccess) { const link = youtubeLinks[attemptCount]; logStart(`Trying youtube link (${link}) ${attemptCount + 1}...`); const complexFilter = await sponsorComplexFilter(link); @@ -125,9 +132,7 @@ const downloader = async (youtubeLinks, output) => { download.on('progress', progressFunction); const ffmpegCommand = ffmpeg({ timeout: TIMEOUT_MINUTES * 60 }); if (complexFilter) { - ffmpegCommand - .complexFilter(complexFilter) - .map('[outa]'); + ffmpegCommand.complexFilter(complexFilter).map('[outa]'); } ffmpegCommand .on('error', e => { diff --git a/lib/metadata.js b/lib/metadata.js index b3a30cc..172712e 100644 --- a/lib/metadata.js +++ b/lib/metadata.js @@ -4,9 +4,7 @@ import axios from 'axios'; import ffmpeg from 'fluent-ffmpeg'; import { logSuccess } from '../util/log-helper.js'; import Constants from '../util/constants.js'; -import { - logInfo, -} from '../util/log-helper.js'; +import { logInfo } from '../util/log-helper.js'; import { splitDates } from '../util/filters.js'; const downloadAndSaveCover = function (uri, filename) { return new Promise(async (resolve, reject) => { @@ -58,8 +56,8 @@ const mergeMetadata = async (output, songData) => { ); } const dateSplits = splitDates(songData.release_date); - const firstArtist = songData.artists && songData.artists.length > 0 ? - songData.artists[0] : ''; + const firstArtist = + songData.artists && songData.artists.length > 0 ? songData.artists[0] : ''; const metadata = { artist: firstArtist, originalArtist: firstArtist, diff --git a/lib/setup.js b/lib/setup.js index b075896..d0dc2c7 100644 --- a/lib/setup.js +++ b/lib/setup.js @@ -14,37 +14,32 @@ const ffmpegSetup = function (platform_name) { try { const ffmpeg_paths = execSync('where ffmpeg'); if (ffmpeg_paths.includes('Could not find file')) { - process.env.PATH = - path.resolve(__dirname, 'bin;') + process.env.PATH; + process.env.PATH = path.resolve(__dirname, 'bin;') + process.env.PATH; } break; } catch (err) { - logFailure( - 'Couldn\'t find ffmpeg. Please install https://ffmpeg.org', - ); + logFailure("Couldn't find ffmpeg. Please install https://ffmpeg.org"); } break; } case 'linux': case 'android': case 'darwin': - try { const ffmpeg_paths = execSync('which ffmpeg'); if (ffmpeg_paths == null) { - logFailure('ERROR: Cannot find ffmpeg! Install it first, \ - why don\'t you read README.md on git!'); + logFailure( + "ERROR: Cannot find ffmpeg! Install it first, \ + why don't you read README.md on git!" + ); process.exit(-1); - } - else { + } else { execSync('export FFMPEG_PATH=$(which ffmpeg)'); } break; } catch (error) { - logFailure( - 'Couldn\'t find ffmpeg. Please install https://ffmpeg.org', - ); + logFailure("Couldn't find ffmpeg. Please install https://ffmpeg.org"); } } }; @@ -60,10 +55,12 @@ export function startup() { export function cliInputs() { const loginRequired = (flags, _input) => { - if ((flags.savedAlbums || - flags.savedPlaylists || - flags.savedShows || - flags.savedSongs) && !Config.isTTY + if ( + (flags.savedAlbums || + flags.savedPlaylists || + flags.savedShows || + flags.savedSongs) && + !Config.isTTY ) { return true; } @@ -77,11 +74,7 @@ export function cliInputs() { const flags = { help: { alias: 'h', - helpText: [ - '--help or --h', - '* returns help', - 'eg. $ spotifydl --h', - ], + helpText: ['--help or --h', '* returns help', 'eg. $ spotifydl --h'], }, version: { alias: 'v', @@ -129,7 +122,8 @@ export function cliInputs() { type: 'string', default: flagsConfig.output, helpText: [ - '--output "" or --o ""', '-takes valid path argument', + '--output "" or --o ""', + '-takes valid path argument', 'eg. $ spotifydl --o ~/songs ', ], }, @@ -281,7 +275,7 @@ export function cliInputs() { ], }, exclusionFilters: { - alias: "ef", + alias: 'ef', default: flagsConfig.exclusionFilters, type: 'string', helpText: [ @@ -290,12 +284,15 @@ export function cliInputs() { '* each filter will be checked against the description and title if found the link will be ignored', 'eg. $ spotifydl --ef "live,concert"', ], - } + }, }; - const helpText = '\n' + Object - .values(flags) - .reduce((acc, flag) => `${acc}${flag.helpText.join('\n ')}\n\n`, ''); + const helpText = + '\n' + + Object.values(flags).reduce( + (acc, flag) => `${acc}${flag.helpText.join('\n ')}\n\n`, + '' + ); const cli = meow( ` @@ -318,7 +315,7 @@ export function cliInputs() { { importMeta: import.meta, flags: flags, - }, + } ); const { flags: inputFlags } = cli; @@ -340,22 +337,22 @@ export function cliInputs() { inputs.push({ type: Constants.INPUT_TYPES.SONG.SAVED_TRACKS, url: null }); } if (inputFlags.savedPlaylists) { - inputs.push( - { type: Constants.INPUT_TYPES.SONG.SAVED_PLAYLISTS, url: null }, - ); + inputs.push({ + type: Constants.INPUT_TYPES.SONG.SAVED_PLAYLISTS, + url: null, + }); } if (inputFlags.savedShows) { - inputs.push( - { type: Constants.INPUT_TYPES.EPISODE.SAVED_SHOWS, url: null }, - ); + inputs.push({ type: Constants.INPUT_TYPES.EPISODE.SAVED_SHOWS, url: null }); } if (!inputs.length) { - console.log('No spotify url provided for scaping, See spotifydl --help for instructions'); + console.log( + 'No spotify url provided for scaping, See spotifydl --help for instructions' + ); process.exit(1); } - return { inputs: inputs, extraSearch: inputFlags.extraSearch, @@ -365,11 +362,11 @@ export function cliInputs() { downloadReport: inputFlags.downloadReport, outputOnly: inputFlags.outputOnly, searchFormat: inputFlags.searchFormat, - exclusionFilters: inputFlags.exclusionFilters.split(",").filter(x => x), + exclusionFilters: inputFlags.exclusionFilters.split(',').filter(x => x), login: inputFlags.login, username: inputFlags.username, password: inputFlags.password, downloadLyrics: inputFlags.downloadLyrics, outputFormat: inputFlags.outputFormat, }; -} \ No newline at end of file +} diff --git a/lib/subtitle-downloader.js b/lib/subtitle-downloader.js index 997577a..3e51f14 100644 --- a/lib/subtitle-downloader.js +++ b/lib/subtitle-downloader.js @@ -1,7 +1,5 @@ import Genius from 'genius-lyrics'; -import { - logInfo, -} from '../util/log-helper.js'; +import { logInfo } from '../util/log-helper.js'; const downloadSubtitles = async (itemName, artistName) => { const Client = new Genius.Client(); diff --git a/util/constants.js b/util/constants.js index c9008fb..be844e1 100644 --- a/util/constants.js +++ b/util/constants.js @@ -52,9 +52,10 @@ export default { YOUTUBE_SEARCH: { // this roughly equates to a max of 30mb MAX_MINUTES: 15, - GENERIC_IMAGE: 'https://lh3.googleusercontent.com/z6Sl4j9zQ88oUKN' + + GENERIC_IMAGE: + 'https://lh3.googleusercontent.com/z6Sl4j9zQ88oUKN' + 'y0G3PAMiVwy8DzQLh_ygyvBXv0zVNUZ_wQPN_n7EAR2By3dhoUpX7kTpaHjRP' + 'ni1MHwKpaBJbpNqdEsHZsH4q', VALID_CONTEXTS: ['itemName', 'albumName', 'artistName'], }, -}; \ No newline at end of file +}; diff --git a/util/filters.js b/util/filters.js index 1f35ac9..97a2d36 100644 --- a/util/filters.js +++ b/util/filters.js @@ -13,4 +13,4 @@ export function splitDates(dateString) { month: dateSplits && dateSplits.length > 1 ? dateSplits[1] : '', day: dateSplits && dateSplits.length > 2 ? dateSplits[2] : '', }; -} \ No newline at end of file +} diff --git a/util/get-link.js b/util/get-link.js index a5ecdca..346bc7a 100644 --- a/util/get-link.js +++ b/util/get-link.js @@ -15,7 +15,7 @@ const search = promisify(YoutubeSearch); * This function does the actual api calls to youtube * * @param {String} searchTerms string to search on youtube with - * @param {String} type the type of item being searched + * @param {String} type the type of item being searched * @param {String[]} exclusionFilters exclusion texts for description, title * @returns {String[]} youtube links */ @@ -24,28 +24,32 @@ const findLinks = async (searchTerms, type, exclusionFilters) => { const result = await search(searchTerms); const isSong = Object.values(SONG).includes(type); return result.videos - .filter(video => - !exclusionFilters || - !( - exclusionFilters.some( - exclusionFilter => video.title.includes(exclusionFilter), - ) || - exclusionFilters.some( - exclusionFilter => video.description.includes(exclusionFilter), - ) - ), + .filter( + video => + !exclusionFilters || + !( + exclusionFilters.some(exclusionFilter => + video.title.includes(exclusionFilter), + ) || + exclusionFilters.some(exclusionFilter => + video.description.includes(exclusionFilter), + ) + ), + ) + .filter( + video => + (!isSong || video.seconds < MAX_MINUTES * 60) && video.seconds > 0, ) - .filter(video => ( - (!isSong || (video.seconds < (MAX_MINUTES * 60))) && - (video.seconds > 0) - )) .slice(0, 10) - .map(video => (video.url.includes('https://youtube.com')) ? - video.url : 'https://youtube.com' + video.url); + .map(video => + video.url.includes('https://youtube.com') + ? video.url + : 'https://youtube.com' + video.url, + ); }; /** - * This function searches youtube for given songname + * This function searches youtube for given songname * and returns the link of topmost result * * @param {String} itemName name of song @@ -87,7 +91,9 @@ const getLinks = async ({ } if (!links.length) { links = await findLinks( - `${artistName} - ${itemName}${extraSearch}`, type, exclusionFilters, + `${artistName} - ${itemName}${extraSearch}`, + type, + exclusionFilters, ); } } diff --git a/util/get-songdata.js b/util/get-songdata.js index 7c8396c..f8e2dfb 100644 --- a/util/get-songdata.js +++ b/util/get-songdata.js @@ -1,7 +1,15 @@ import { - extractTracks, extractAlbum, extractArtist, extractArtistAlbums, - extractPlaylist, extractEpisodes, extractShowEpisodes, extractSavedShows, - extractSavedAlbums, extractSavedPlaylists, extractSavedTracks, + extractTracks, + extractAlbum, + extractArtist, + extractArtistAlbums, + extractPlaylist, + extractEpisodes, + extractShowEpisodes, + extractSavedShows, + extractSavedAlbums, + extractSavedPlaylists, + extractSavedTracks, } from '../lib/api.js'; export async function getTrack(url) { @@ -18,9 +26,7 @@ export async function getArtist(url) { export async function getArtistAlbums(url) { const artistResult = await getArtist(url); - const albumsResult = await extractArtistAlbums( - artistResult.id, - ); + const albumsResult = await extractArtistAlbums(artistResult.id); const albumIds = albumsResult.map(album => album.id); let albumInfos = []; for (let x = 0; x < albumIds.length; x++) { diff --git a/util/runner.js b/util/runner.js index 2292e7c..25ba040 100644 --- a/util/runner.js +++ b/util/runner.js @@ -8,9 +8,16 @@ import { writeId, findId } from '../lib/cache.js'; import mergeMetadata from '../lib/metadata.js'; import { cliInputs } from '../lib/setup.js'; import { - getTrack, getPlaylist, getArtistAlbums, - getEpisode, getShowEpisodes, getSavedShows, - getSavedAlbums, getSavedPlaylists, getSavedTracks, getAlbum, + getTrack, + getPlaylist, + getArtistAlbums, + getEpisode, + getShowEpisodes, + getSavedShows, + getSavedAlbums, + getSavedPlaylists, + getSavedTracks, + getAlbum, } from './get-songdata.js'; import { logSuccess, logInfo, logFailure } from './log-helper.js'; import downloadSubtitles from '../lib/subtitle-downloader.js'; @@ -51,10 +58,10 @@ const downloadList = async list => { let currentCount = 0; for (const nextItem of list.items) { currentCount++; - const itemId = nextItem.id; - const itemName = nextItem.name; - const albumName = nextItem.album_name; - const artistName = nextItem.artists[0]; + const itemId = nextItem.id; + const itemName = nextItem.name; + const albumName = nextItem.album_name; + const artistName = nextItem.artists[0]; const fullItemPath = itemOutputPath(itemName, albumName, artistName); const itemDir = fullItemPath.substr(0, fullItemPath.lastIndexOf('/')); const cached = findId(nextItem.id, itemDir); @@ -75,17 +82,17 @@ const downloadList = async list => { nextItem.lyrics = await downloadSubtitles(itemName, artistName); } - const ytLinks = nextItem.URL ? [nextItem.URL] : await getLinks( - { - itemName, - albumName, - artistName, - extraSearch, - searchFormat, - type: list.type, - exclusionFilters, - }, - ); + const ytLinks = nextItem.URL + ? [nextItem.URL] + : await getLinks({ + itemName, + albumName, + artistName, + extraSearch, + searchFormat, + type: list.type, + exclusionFilters, + }); const outputFilePath = path.resolve(fullItemPath); @@ -147,9 +154,7 @@ const run = async () => { case INPUT_TYPES.SONG.SONG: { const track = await getTrack(URL); lists.push({ - items: [ - track, - ], + items: [track], name: `${track.name} ${track.artists[0]}`, type: input.type, }); @@ -169,26 +174,24 @@ const run = async () => { } case INPUT_TYPES.SONG.ARTIST: { const artistAlbumInfos = await getArtistAlbums(URL); - lists.push(...artistAlbumInfos.map(list => { - list.type = input.type; - return list; - })); + lists.push( + ...artistAlbumInfos.map(list => { + list.type = input.type; + return list; + }), + ); break; } case INPUT_TYPES.EPISODE.EPISODE: { const episode = await getEpisode(URL); if (episode) { lists.push({ - items: [ - episode, - ], + items: [episode], name: `${episode.name} ${episode.album_name}`, type: input.type, }); } else { - logFailure( - 'Failed to find episode, you may need to use auth', - ); + logFailure('Failed to find episode, you may need to use auth'); } break; @@ -201,26 +204,32 @@ const run = async () => { } case INPUT_TYPES.EPISODE.SAVED_SHOWS: { const savedShowsInfo = await getSavedShows(); - lists.push(...savedShowsInfo.map(list => { - list.type = input.type; - return list; - })); + lists.push( + ...savedShowsInfo.map(list => { + list.type = input.type; + return list; + }), + ); break; } case INPUT_TYPES.SONG.SAVED_ALBUMS: { const savedAlbumsInfo = await getSavedAlbums(); - lists.push(...savedAlbumsInfo.map(list => { - list.type = input.type; - return list; - })); + lists.push( + ...savedAlbumsInfo.map(list => { + list.type = input.type; + return list; + }), + ); break; } case INPUT_TYPES.SONG.SAVED_PLAYLISTS: { const savedPlaylistsInfo = await getSavedPlaylists(); - lists.push(...savedPlaylistsInfo.map(list => { - list.type = input.type; - return list; - })); + lists.push( + ...savedPlaylistsInfo.map(list => { + list.type = input.type; + return list; + }), + ); break; } case INPUT_TYPES.SONG.SAVED_TRACKS: { @@ -249,8 +258,10 @@ const run = async () => { break; } default: { - throw new Error(`Invalid URL type (${input.type}), ` + - 'Please visit github and make a request to support this type'); + throw new Error( + `Invalid URL type (${input.type}), ` + + 'Please visit github and make a request to support this type', + ); } } @@ -266,4 +277,4 @@ const run = async () => { logSuccess('Finished!'); }; -export default run; \ No newline at end of file +export default run; diff --git a/util/url-parser.js b/util/url-parser.js index da2485e..e4fd220 100644 --- a/util/url-parser.js +++ b/util/url-parser.js @@ -1,26 +1,19 @@ export default inputUrl => { if (inputUrl.includes('youtube')) { return 'youtube'; - } - else if (inputUrl.includes('/track/')) { + } else if (inputUrl.includes('/track/')) { return 'song'; - } - else if (inputUrl.includes('/playlist/')) { + } else if (inputUrl.includes('/playlist/')) { return 'playlist'; - } - else if (inputUrl.includes('/album/')) { + } else if (inputUrl.includes('/album/')) { return 'album'; - } - else if (inputUrl.includes('/artist/')) { + } else if (inputUrl.includes('/artist/')) { return 'artist'; - } - else if (inputUrl.includes('/show/')) { + } else if (inputUrl.includes('/show/')) { return 'show'; - } - else if (inputUrl.includes('/episode/')) { + } else if (inputUrl.includes('/episode/')) { return 'episode'; - } - else { + } else { return new Error('Invalid spotify URL'); } -}; \ No newline at end of file +}; diff --git a/util/version-checker.js b/util/version-checker.js index 384dd15..5a52a4c 100644 --- a/util/version-checker.js +++ b/util/version-checker.js @@ -2,21 +2,22 @@ import axios from 'axios'; import meow from 'meow'; const checkVersion = async () => { - const res = - await axios.default( - 'https://api.github.com/repos/SwapnilSoni1999/spotify-dl/tags', - ); + const res = await axios.default( + 'https://api.github.com/repos/SwapnilSoni1999/spotify-dl/tags' + ); const latestVersion = res.data[0].name; - const pkg = meow('', { importMeta: import.meta }).pkg + const pkg = meow('', { importMeta: import.meta }).pkg; if (pkg.version !== latestVersion) { - console.log([ - '\n========Update Available========', - 'Use npm install -g spotify-dl', - 'to update the package.', - '================================\n', - ].join('\n')); + console.log( + [ + '\n========Update Available========', + 'Use npm install -g spotify-dl', + 'to update the package.', + '================================\n', + ].join('\n') + ); } }; -export default checkVersion; \ No newline at end of file +export default checkVersion;