From 6fbb0e96dec4229779903b1bac14a00507c9d6fb Mon Sep 17 00:00:00 2001 From: killer069 <65385476+killer069@users.noreply.github.com> Date: Wed, 15 Dec 2021 13:11:16 +0530 Subject: [PATCH] Fixed Spotify Playlist and Album search issues --- play-dl/Spotify/classes.ts | 181 ++++--------------------------------- play-dl/Spotify/index.ts | 18 ++-- play-dl/index.ts | 7 +- 3 files changed, 30 insertions(+), 176 deletions(-) diff --git a/play-dl/Spotify/classes.ts b/play-dl/Spotify/classes.ts index cf7b354..3ab4bd9 100644 --- a/play-dl/Spotify/classes.ts +++ b/play-dl/Spotify/classes.ts @@ -215,14 +215,19 @@ export class SpotifyPlaylist { * @private */ private fetched_tracks: Map; + /** + * Boolean to tell whether it is a searched result or not. + */ + private readonly search : boolean /** * Constructor for Spotify Playlist Class * @param data JSON parsed data of playlist * @param spotifyData Data about sporify token for furhter fetching. */ - constructor(data: any, spotifyData: SpotifyDataOptions) { + constructor(data: any, spotifyData: SpotifyDataOptions, search : boolean) { this.name = data.name; this.type = 'playlist'; + this.search = search this.collaborative = data.collaborative; this.description = data.description; this.url = data.external_urls.spotify; @@ -235,7 +240,7 @@ export class SpotifyPlaylist { }; this.tracksCount = Number(data.tracks.total); const videos: SpotifyTrack[] = []; - data.tracks.items.forEach((v: any) => { + if(!this.search) data.tracks.items.forEach((v: any) => { if(v.track) videos.push(new SpotifyTrack(v.track)); }); this.fetched_tracks = new Map(); @@ -249,10 +254,11 @@ export class SpotifyPlaylist { * @returns Playlist Class. */ async fetch() { + if(this.search) return this; let fetching: number; if (this.tracksCount > 1000) fetching = 1000; else fetching = this.tracksCount; - if (fetching <= 100) return; + if (fetching <= 100) return this; const work = []; for (let i = 2; i <= Math.ceil(fetching / 100); i++) { work.push( @@ -325,6 +331,7 @@ export class SpotifyPlaylist { * Spotify Playlist total no of tracks that have been fetched so far. */ get total_tracks() { + if(this.search) return this.tracksCount; const page_number: number = this.total_pages; return (page_number - 1) * 100 + (this.fetched_tracks.get(`${page_number}`) as SpotifyTrack[]).length; } @@ -401,15 +408,20 @@ export class SpotifyAlbum { * @private */ private fetched_tracks: Map; + /** + * Boolean to tell whether it is a searched result or not. + */ + private readonly search : boolean /** * Constructor for Spotify Album Class * @param data Json parsed album data * @param spotifyData Spotify credentials */ - constructor(data: any, spotifyData: SpotifyDataOptions) { + constructor(data: any, spotifyData: SpotifyDataOptions, search : boolean) { this.name = data.name; this.type = 'album'; this.id = data.id; + this.search = search this.url = data.external_urls.spotify; this.thumbnail = data.images[0]; const artists: SpotifyArtists[] = []; @@ -426,7 +438,7 @@ export class SpotifyAlbum { this.release_date_precision = data.release_date_precision; this.tracksCount = data.total_tracks; const videos: SpotifyTrack[] = []; - data.tracks.items.forEach((v: any) => { + if(!this.search) data.tracks.items.forEach((v: any) => { videos.push(new SpotifyTrack(v)); }); this.fetched_tracks = new Map(); @@ -440,10 +452,11 @@ export class SpotifyAlbum { * @returns Album Class. */ async fetch() { + if(this.search) return this let fetching: number; if (this.tracksCount > 500) fetching = 500; else fetching = this.tracksCount; - if (fetching <= 50) return; + if (fetching <= 50) return this; const work = []; for (let i = 2; i <= Math.ceil(fetching / 50); i++) { work.push( @@ -516,165 +529,11 @@ export class SpotifyAlbum { * Spotify Album total no of tracks that have been fetched so far. */ get total_tracks() { + if(this.search) return this.tracksCount const page_number: number = this.total_pages; return (page_number - 1) * 100 + (this.fetched_tracks.get(`${page_number}`) as SpotifyTrack[]).length; } - toJSON(): AlbumJSON { - return { - name: this.name, - id: this.id, - type: this.type, - url: this.url, - thumbnail: this.thumbnail, - artists: this.artists, - copyrights: this.copyrights, - release_date: this.release_date, - release_date_precision: this.release_date_precision, - tracksCount: this.tracksCount - }; - } -} - -export class SpotifySearchPlaylist{ - /** - * Spotify Playlist Name - */ - name: string; - /** - * Spotify Class type. == "playlist" - */ - type: 'track' | 'playlist' | 'album'; - /** - * Spotify Playlist collaborative boolean. - */ - collaborative: boolean; - /** - * Spotify Playlist Description - */ - description: string; - /** - * Spotify Playlist URL - */ - url: string; - /** - * Spotify Playlist ID - */ - id: string; - /** - * Spotify Playlist Thumbnail Data - */ - thumbnail: SpotifyThumbnail; - /** - * Spotify Playlist Owner Artist data - */ - owner: SpotifyArtists; - /** - * Spotify Playlist total tracks Count - */ - tracksCount: number; - - constructor(data : any){ - this.name = data.name; - this.type = 'playlist'; - this.collaborative = data.collaborative; - this.description = data.description; - this.url = data.external_urls.spotify; - this.id = data.id; - this.thumbnail = data.images[0]; - this.owner = { - name: data.owner.display_name, - url: data.owner.external_urls.spotify, - id: data.owner.id - }; - this.tracksCount = Number(data.tracks.total); - } - - /** - * Converts Class to JSON - * @returns JSON data - */ - toJSON(): PlaylistJSON { - return { - name: this.name, - collaborative: this.collaborative, - description: this.description, - url: this.url, - id: this.id, - thumbnail: this.thumbnail, - owner: this.owner, - tracksCount: this.tracksCount - }; - } -} - -export class SpotifySearchAlbum{ - /** - * Spotify Album Name - */ - name: string; - /** - * Spotify Class type. == "album" - */ - type: 'track' | 'playlist' | 'album'; - /** - * Spotify Album url - */ - url: string; - /** - * Spotify Album id - */ - id: string; - /** - * Spotify Album Thumbnail data - */ - thumbnail: SpotifyThumbnail; - /** - * Spotify Album artists [ array ] - */ - artists: SpotifyArtists[]; - /** - * Spotify Album copyright data [ array ] - */ - copyrights: SpotifyCopyright[]; - /** - * Spotify Album Release date - */ - release_date: string; - /** - * Spotify Album Release Date **precise** - */ - release_date_precision: string; - /** - * Spotify Album total no of tracks - */ - tracksCount: number; - /** - * Spotify Album Spotify data - * - * @private - */ - constructor(data : any){ - this.name = data.name; - this.type = 'album'; - this.id = data.id; - this.url = data.external_urls.spotify; - this.thumbnail = data.images[0]; - const artists: SpotifyArtists[] = []; - data.artists.forEach((v: any) => { - artists.push({ - name: v.name, - id: v.id, - url: v.external_urls.spotify - }); - }); - this.artists = artists; - this.copyrights = data.copyrights; - this.release_date = data.release_date; - this.release_date_precision = data.release_date_precision; - this.tracksCount = data.total_tracks; - } - toJSON(): AlbumJSON { return { name: this.name, diff --git a/play-dl/Spotify/index.ts b/play-dl/Spotify/index.ts index edc509b..7ab93ea 100644 --- a/play-dl/Spotify/index.ts +++ b/play-dl/Spotify/index.ts @@ -1,5 +1,5 @@ import { request } from '../Request'; -import { SpotifyAlbum, SpotifyPlaylist, SpotifySearchAlbum, SpotifySearchPlaylist, SpotifyTrack } from './classes'; +import { SpotifyAlbum, SpotifyPlaylist, SpotifyTrack } from './classes'; import { existsSync, readFileSync, writeFileSync } from 'node:fs'; let spotifyData: SpotifyDataOptions; @@ -65,7 +65,7 @@ export async function spotify(url: string): Promise { return err; }); if (response instanceof Error) throw response; - return new SpotifyAlbum(JSON.parse(response), spotifyData); + return new SpotifyAlbum(JSON.parse(response), spotifyData, false); } else if (url.indexOf('playlist/') !== -1) { const playlistID = url.split('playlist/')[1].split('&')[0].split('?')[0]; const response = await request( @@ -79,7 +79,7 @@ export async function spotify(url: string): Promise { return err; }); if (response instanceof Error) throw response; - return new SpotifyPlaylist(JSON.parse(response), spotifyData); + return new SpotifyPlaylist(JSON.parse(response), spotifyData, false); } else throw new Error('URL is out of scope for play-dl.'); } /** @@ -161,10 +161,6 @@ export function is_expired(): boolean { * type for Spotify Classes */ export type Spotify = SpotifyAlbum | SpotifyPlaylist | SpotifyTrack; -/** - * type for Spotify Searched Classes - */ -export type SpotifySearch = SpotifyTrack | SpotifySearchPlaylist | SpotifySearchAlbum /** * Function for searching songs on Spotify * @param query searching query @@ -176,8 +172,8 @@ export async function sp_search( query: string, type: 'album' | 'playlist' | 'track', limit: number = 10 -): Promise { - const results: SpotifySearch[] = []; +): Promise { + const results: Spotify[] = []; if (!spotifyData) throw new Error('Spotify Data is missing\nDid you forgot to do authorization ?'); if (query.length === 0) throw new Error('Pass some query to search.'); if (limit > 50 || limit < 0) throw new Error(`You crossed limit range of Spotify [ 0 - 50 ]`); @@ -199,11 +195,11 @@ export async function sp_search( }); } else if (type === 'album') { json_data.albums.items.forEach((album: any) => { - results.push(new SpotifySearchAlbum(album)); + results.push(new SpotifyAlbum(album, spotifyData, true)); }); } else if (type === 'playlist') { json_data.playlists.items.forEach((playlist: any) => { - results.push(new SpotifySearchPlaylist(playlist)); + results.push(new SpotifyPlaylist(playlist, spotifyData, true)); }); } return results; diff --git a/play-dl/index.ts b/play-dl/index.ts index b028cee..ed91eeb 100644 --- a/play-dl/index.ts +++ b/play-dl/index.ts @@ -19,8 +19,7 @@ export { SpotifyAlbum, SpotifyPlaylist, SpotifyTrack, - Spotify, - SpotifySearch + Spotify } from './Spotify'; export { soundcloud, @@ -73,7 +72,7 @@ import { SoundCloud, Spotify } from '.'; -import { SpotifyAuthorize, SpotifySearch, sp_search } from './Spotify'; +import { SpotifyAuthorize, sp_search } from './Spotify'; import { check_id, so_search, stream as so_stream, stream_from_info as so_stream_info } from './SoundCloud'; import { stream as yt_stream, StreamOptions, stream_from_info as yt_stream_info } from './YouTube/stream'; import { SoundCloudPlaylist, SoundCloudTrack } from './SoundCloud/classes'; @@ -214,7 +213,7 @@ export async function search(query: string, options?: SearchOptions): Promise { +): Promise { if (!options.source) options.source = { youtube: 'video' }; query = encodeURIComponent(query); if (options.source.youtube) return await yt_search(query, { limit: options.limit, type: options.source.youtube });