From 9309792bbd674a14e167ebbface1108e539f8c31 Mon Sep 17 00:00:00 2001 From: Sayem Chowdhury Date: Wed, 24 Mar 2021 01:16:55 +0600 Subject: [PATCH] parse info --- package.json | 1 + src/converter/index.ts | 1 + src/converter/parse.ts | 168 +++++++++++++++++++++++++++++++++++++++++ yarn.lock | 5 ++ 4 files changed, 175 insertions(+) create mode 100644 src/converter/parse.ts diff --git a/package.json b/package.json index 548840b..ad0730a 100644 --- a/package.json +++ b/package.json @@ -19,6 +19,7 @@ "delay": "^5.0.0", "node-html-parser": "^3.1.0", "p-queue": "^6.6.2", + "spotify-uri": "^2.1.0", "spotify-web-api-node": "^5.0.2" }, "devDependencies": { diff --git a/src/converter/index.ts b/src/converter/index.ts index 4e65706..987c19b 100644 --- a/src/converter/index.ts +++ b/src/converter/index.ts @@ -1,3 +1,4 @@ +export * from './parse'; export * from './deezer'; export * as tidal from './tidal'; export * as spotify from './spotify'; diff --git a/src/converter/parse.ts b/src/converter/parse.ts new file mode 100644 index 0000000..c25d1c1 --- /dev/null +++ b/src/converter/parse.ts @@ -0,0 +1,168 @@ +import { + getAlbumInfo, + getAlbumTracks, + getArtistInfo, + getDiscography, + getPlaylistInfo, + getPlaylistTracks, + getTrackInfo, +} from '../'; +import spotifyUri from 'spotify-uri'; +import * as spotify from './spotify'; +import * as tidal from './tidal'; +import {isrc2deezer, upc2deezer} from './deezer'; +import PQueue from 'p-queue'; +import type {albumType, trackType} from '../types'; + +type linkType = 'track' | 'album' | 'artist' | 'playlist'; + +type urlPartsType = { + id: string; + type: + | 'track' + | 'album' + | 'audiobook' + | 'artist' + | 'playlist' + | 'spotify-track' + | 'spotify-album' + | 'spotify-playlist' + | 'spotify-artist' + | 'tidal-track' + | 'tidal-album' + | 'tidal-playlist' + | 'tidal-artist'; +}; + +const queue = new PQueue({concurrency: 10}); + +const getUrlParts = async (url: string): Promise => { + if (url.startsWith('spotify:')) { + const spotify = url.split(':'); + url = 'https://open.spotify.com/' + spotify[1] + '/' + spotify[2]; + } + + const site = url.match(/deezer|spotify|tidal/); + if (!site) { + throw new Error('Unknown URL: ' + url); + } + + switch (site[0]) { + case 'deezer': + const deezerUrlParts = url.split(/\/(\w+)\/(\d+)/); + return {type: deezerUrlParts[1] as any, id: deezerUrlParts[2]}; + case 'spotify': + const spotifyUrlParts = spotifyUri.parse(url); + await spotify.setSpotifyAnonymousToken(); + return {type: ('spotify-' + spotifyUrlParts.type) as any, id: (spotifyUrlParts as any).id}; + case 'tidal': + const tidalUrlParts = url.split(/\/(\w+)\/(\d+|\w+-\w+-\w+-\w+-\w+)/); + return {type: ('tidal-' + tidalUrlParts[1]) as any, id: tidalUrlParts[2]}; + default: + return null; + } +}; + +/** + * Deezer, Spotify or Tidal links only + * @param {String} url + */ +export const parseInfo = async (url: string) => { + let info = await getUrlParts(url); + if (!info) { + return null; + } else if (!info.id) { + throw new Error('Unable to parse id'); + } + + let linktype: linkType = 'track'; + let linkinfo: trackType | albumType | {} = {}; + let tracks: trackType[] = []; + + switch (info.type) { + case 'track': + tracks.push(await getTrackInfo(info.id)); + break; + + case 'album': + case 'audiobook': + linkinfo = await getAlbumInfo(info.id); + linktype = 'album'; + const albumTracks = await getAlbumTracks(info.id); + tracks = albumTracks.data; + break; + + case 'playlist': + linkinfo = await getPlaylistInfo(info.id); + linktype = 'playlist'; + const playlistTracks = await getPlaylistTracks(info.id); + tracks = playlistTracks.data; + break; + + case 'artist': + linkinfo = await getArtistInfo(info.id); + linktype = 'artist'; + const artistAlbums = await getDiscography(info.id); + await queue.addAll( + artistAlbums.data.map((album) => { + return async () => { + const albumTracks = await getAlbumTracks(album.ALB_ID); + tracks = [...tracks, ...albumTracks.data]; + }; + }), + ); + + case 'spotify-track': + tracks.push(await spotify.track2deezer(info.id)); + break; + + case 'spotify-album': + const [spotifyAlbumInfo, spotifyTracks] = await spotify.album2deezer(info.id); + tracks = spotifyTracks; + linkinfo = spotifyAlbumInfo; + linktype = 'album'; + break; + + case 'spotify-playlist': + const [spotifyPlaylistInfo, spotifyPlaylistTracks] = await spotify.playlist2Deezer(info.id); + tracks = spotifyPlaylistTracks; + linkinfo = spotifyPlaylistInfo; + linktype = 'playlist'; + break; + + case 'spotify-artist': + tracks = await spotify.artist2Deezer(info.id); + linktype = 'artist'; + break; + + case 'tidal-track': + const tidalTrack = await tidal.getTrack(info.id); + tracks.push(await isrc2deezer(tidalTrack.title, tidalTrack.isrc)); + break; + + case 'tidal-album': + const tidalAlbum = await tidal.getAlbum(info.id); + const [tidalAlbumInfo, tidalAlbumTracks] = await upc2deezer(tidalAlbum.title, tidalAlbum.upc); + tracks = tidalAlbumTracks; + linkinfo = tidalAlbumInfo; + linktype = 'album'; + break; + + case 'tidal-playlist': + const [tidalPlaylistInfo, tidalPlaylistTracks] = await tidal.playlist2Deezer(info.id); + tracks = tidalPlaylistTracks; + linkinfo = tidalPlaylistInfo; + linktype = 'playlist'; + break; + + case 'tidal-artist': + tracks = await tidal.artist2Deezer(info.id); + linktype = 'artist'; + break; + + default: + throw new Error('Unknown type: ' + info.type); + } + + return {info, linktype, linkinfo, tracks}; +}; diff --git a/yarn.lock b/yarn.lock index a2b8120..60025b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2285,6 +2285,11 @@ spdx-license-ids@^3.0.0: resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-3.0.7.tgz#e9c18a410e5ed7e12442a549fbd8afa767038d65" integrity sha512-U+MTEOO0AiDzxwFvoa4JVnMV6mZlJKk2sBLt90s7G0Gd0Mlknc7kxEn3nuDPNZRta7O2uy8oLcZLVT+4sqNZHQ== +spotify-uri@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/spotify-uri/-/spotify-uri-2.1.0.tgz#1e0428536bd616e90e086d74167310fa23465f6b" + integrity sha512-+QjB/9zRsbGB+2oOPK6K4jidLEWbsY43mov84vEj66dNj0aqqz6ul6VbxfUDlklOqgL4kVLFC/Yhr01PcXlJbQ== + spotify-web-api-node@^5.0.2: version "5.0.2" resolved "https://registry.yarnpkg.com/spotify-web-api-node/-/spotify-web-api-node-5.0.2.tgz#683669b3ccc046a5a357300f151df93a2b3539fe"