Made library work

This commit is contained in:
RemixDev 2021-03-13 13:18:22 +01:00
parent f2ac5665e6
commit 8528617e07
6 changed files with 306 additions and 261 deletions

View file

@ -1,21 +1,21 @@
const got = require('got') const got = require('got')
// Possible values for order parameter in search // Possible values for order parameter in search
export const SearchOrder = { const SearchOrder = {
RANKING : "RANKING" RANKING : "RANKING",
TRACK_ASC : "TRACK_ASC" TRACK_ASC : "TRACK_ASC",
TRACK_DESC : "TRACK_DESC" TRACK_DESC : "TRACK_DESC",
ARTIST_ASC : "ARTIST_ASC" ARTIST_ASC : "ARTIST_ASC",
ARTIST_DESC : "ARTIST_DESC" ARTIST_DESC : "ARTIST_DESC",
ALBUM_ASC : "ALBUM_ASC" ALBUM_ASC : "ALBUM_ASC",
ALBUM_DESC : "ALBUM_DESC" ALBUM_DESC : "ALBUM_DESC",
RATING_ASC : "RATING_ASC" RATING_ASC : "RATING_ASC",
RATING_DESC : "RATING_DESC" RATING_DESC : "RATING_DESC",
DURATION_ASC : "DURATION_ASC" DURATION_ASC : "DURATION_ASC",
DURATION_DESC : "DURATION_DESC" DURATION_DESC : "DURATION_DESC"
} }
export class API{ class API{
constructor(cookie_jar, headers){ constructor(cookie_jar, headers){
this.http_headers = headers this.http_headers = headers
this.cookie_jar = cookie_jar this.cookie_jar = cookie_jar
@ -24,15 +24,17 @@ export class API{
async api_call(method, args){ async api_call(method, args){
if (typeof args == "undefined") args = {} if (typeof args == "undefined") args = {}
if this.access_token: args.access_token = this.access_token if (this.access_token) args.access_token = this.access_token
let result_json;
try { try {
const result_json = await got.get("https://api.deezer.com/" + method, { result_json = await got.get("https://api.deezer.com/" + method, {
searchParams: args, searchParams: args,
cookieJar: this.cookie_jar, cookieJar: this.cookie_jar,
headers: this.http_headers, headers: this.http_headers,
timeout: 30000 timeout: 30000
}).json() }).json()
} catch (error) { } catch (e) {
console.log(e)
await new Promise(r => setTimeout(r, 2000)) // sleep(2000ms) await new Promise(r => setTimeout(r, 2000)) // sleep(2000ms)
return await this.api_call(method, args) return await this.api_call(method, args)
} }
@ -51,177 +53,177 @@ export class API{
if (result_json.error.code == 800) throw new DataException(`DataException: ${method} ${result_json.error.message || ""}`) if (result_json.error.code == 800) throw new DataException(`DataException: ${method} ${result_json.error.message || ""}`)
if (result_json.error.code == 901) throw new IndividualAccountChangedNotAllowedException(`IndividualAccountChangedNotAllowedException: ${method} ${result_json.error.message || ""}`) if (result_json.error.code == 901) throw new IndividualAccountChangedNotAllowedException(`IndividualAccountChangedNotAllowedException: ${method} ${result_json.error.message || ""}`)
} }
throw APIError(result_json.error)) throw APIError(result_json.error)
} }
return result_json return result_json
} }
async get_album(album_id){ get_album(album_id){
return await this.api_call(`album/${album_id}`) return this.api_call(`album/${album_id}`)
} }
async get_album_by_UPC(upc){ get_album_by_UPC(upc){
return await this.get_album(`upc:${upc}`) return this.get_album(`upc:${upc}`)
} }
async get_album_comments(album_id, index=0, limit=10){ get_album_comments(album_id, index=0, limit=10){
return await this.api_call(`album/${album_id}/comments`, {index, limit}) return this.api_call(`album/${album_id}/comments`, {index, limit})
} }
async get_album_fans(album_id, index=0, limit=100){ get_album_fans(album_id, index=0, limit=100){
return await this.api_call(`album/${album_id}/fans`, {index, limit}) return this.api_call(`album/${album_id}/fans`, {index, limit})
} }
async get_album_tracks(album_id, index=0, limit=-1){ get_album_tracks(album_id, index=0, limit=-1){
return await this.api_call(`album/${album_id}/tracks`, {index, limit}) return this.api_call(`album/${album_id}/tracks`, {index, limit})
} }
async get_artist(artist_id){ get_artist(artist_id){
return await this.api_call(`artist/${artist_id}`) return this.api_call(`artist/${artist_id}`)
} }
async get_artist_top(artist_id, index=0, limit=10){ get_artist_top(artist_id, index=0, limit=10){
return await this.api_call(`artist/${artist_id}/top`, {index, limit}) return this.api_call(`artist/${artist_id}/top`, {index, limit})
} }
async get_artist_albums(artist_id, index=0, limit=-1){ get_artist_albums(artist_id, index=0, limit=-1){
return await this.api_call(`artist/${artist_id}/albums`, {index, limit}) return this.api_call(`artist/${artist_id}/albums`, {index, limit})
} }
async get_artist_comments(artist_id, index=0, limit=10){ get_artist_comments(artist_id, index=0, limit=10){
return await this.api_call(`artist/${artist_id}/comments`, {index, limit}) return this.api_call(`artist/${artist_id}/comments`, {index, limit})
} }
async get_artist_fans(artist_id, index=0, limit=100){ get_artist_fans(artist_id, index=0, limit=100){
return await this.api_call(`artist/${artist_id}/fans`, {index, limit}) return this.api_call(`artist/${artist_id}/fans`, {index, limit})
} }
async get_artist_related(artist_id, index=0, limit=20){ get_artist_related(artist_id, index=0, limit=20){
return await this.api_call(`artist/${artist_id}/related`, {index, limit}) return this.api_call(`artist/${artist_id}/related`, {index, limit})
} }
async get_artist_radio(artist_id, index=0, limit=25){ get_artist_radio(artist_id, index=0, limit=25){
return await this.api_call(`artist/${artist_id}/radio`, {index, limit}) return this.api_call(`artist/${artist_id}/radio`, {index, limit})
} }
async get_artist_playlists(artist_id, index=0, limit=-1){ get_artist_playlists(artist_id, index=0, limit=-1){
return await this.api_call(`artist/${artist_id}/playlists`, {index, limit}) return this.api_call(`artist/${artist_id}/playlists`, {index, limit})
} }
async get_chart(genre_id=0, index=0, limit=10){ get_chart(genre_id=0, index=0, limit=10){
return await this.api_call(`chart/${genre_id}`, {index, limit}) return this.api_call(`chart/${genre_id}`, {index, limit})
} }
async get_chart_tracks(genre_id=0, index=0, limit=10){ get_chart_tracks(genre_id=0, index=0, limit=10){
return await this.api_call(`chart/${genre_id}/tracks`, {index, limit}) return this.api_call(`chart/${genre_id}/tracks`, {index, limit})
} }
async get_chart_albums(genre_id=0, index=0, limit=10){ get_chart_albums(genre_id=0, index=0, limit=10){
return await this.api_call(`chart/${genre_id}/albums`, {index, limit}) return this.api_call(`chart/${genre_id}/albums`, {index, limit})
} }
async get_chart_artists(genre_id=0, index=0, limit=10){ get_chart_artists(genre_id=0, index=0, limit=10){
return await this.api_call(`chart/${genre_id}/artists`, {index, limit}) return this.api_call(`chart/${genre_id}/artists`, {index, limit})
} }
async get_chart_playlists(genre_id=0, index=0, limit=10){ get_chart_playlists(genre_id=0, index=0, limit=10){
return await this.api_call(`chart/${genre_id}/playlists`, {index, limit}) return this.api_call(`chart/${genre_id}/playlists`, {index, limit})
} }
async get_chart_podcasts(genre_id=0, index=0, limit=10){ get_chart_podcasts(genre_id=0, index=0, limit=10){
return await this.api_call(`chart/${genre_id}/podcasts`, {index, limit}) return this.api_call(`chart/${genre_id}/podcasts`, {index, limit})
} }
async get_comment(comment_id){ get_comment(comment_id){
return await this.api_call(`comment/${comment_id}`) return this.api_call(`comment/${comment_id}`)
} }
async get_editorials(index=0, limit=10){ get_editorials(index=0, limit=10){
return await this.api_call('editorial', {index, limit}) return this.api_call('editorial', {index, limit})
} }
async get_editorial(genre_id=0){ get_editorial(genre_id=0){
return await this.api_call(`editorial/${genre_id}`) return this.api_call(`editorial/${genre_id}`)
} }
async get_editorial_selection(genre_id=0, index=0, limit=10){ get_editorial_selection(genre_id=0, index=0, limit=10){
return await this.api_call(`editorial/${genre_id}/selection`, {index, limit}) return this.api_call(`editorial/${genre_id}/selection`, {index, limit})
} }
async get_editorial_charts(genre_id=0, index=0, limit=10){ get_editorial_charts(genre_id=0, index=0, limit=10){
return await this.api_call(`editorial/${genre_id}/charts`, {index, limit}) return this.api_call(`editorial/${genre_id}/charts`, {index, limit})
} }
async get_editorial_releases(genre_id=0, index=0, limit=10){ get_editorial_releases(genre_id=0, index=0, limit=10){
return await this.api_call(`editorial/${genre_id}/releases`, {index, limit}) return this.api_call(`editorial/${genre_id}/releases`, {index, limit})
} }
async get_genres(index=0, limit=10){ get_genres(index=0, limit=10){
return await this.api_call('genre', {index, limit}) return this.api_call('genre', {index, limit})
} }
async get_genre(genre_id=0){ get_genre(genre_id=0){
return await this.api_call(`genre/${genre_id}`) return this.api_call(`genre/${genre_id}`)
} }
async get_genre_artists(genre_id=0, index=0, limit=10){ get_genre_artists(genre_id=0, index=0, limit=10){
return await this.api_call(`genre/${genre_id}/artists`, {index, limit}) return this.api_call(`genre/${genre_id}/artists`, {index, limit})
} }
async get_genre_radios( genre_id=0, index=0, limit=10){ get_genre_radios( genre_id=0, index=0, limit=10){
return await this.api_call(`genre/${genre_id}/radios`, {index, limit}) return this.api_call(`genre/${genre_id}/radios`, {index, limit})
} }
async get_infos(){ get_infos(){
return await this.api_call('infos') return this.api_call('infos')
} }
async get_options(){ get_options(){
return await this.api_call('options') return this.api_call('options')
} }
async get_playlist(playlist_id){ get_playlist(playlist_id){
return await this.api_call(`playlist/${playlist_id}`) return this.api_call(`playlist/${playlist_id}`)
} }
async get_playlist_comments(album_id, index=0, limit=10){ get_playlist_comments(album_id, index=0, limit=10){
return await this.api_call(`playlist/${album_id}/comments`, {index, limit}) return this.api_call(`playlist/${album_id}/comments`, {index, limit})
} }
async get_playlist_fans(album_id, index=0, limit=100){ get_playlist_fans(album_id, index=0, limit=100){
return await this.api_call(`playlist/${album_id}/fans`, {index, limit}) return this.api_call(`playlist/${album_id}/fans`, {index, limit})
} }
async get_playlist_tracks(album_id, index=0, limit=-1){ get_playlist_tracks(album_id, index=0, limit=-1){
return await this.api_call(`playlist/${album_id}/tracks`, {index, limit}) return this.api_call(`playlist/${album_id}/tracks`, {index, limit})
} }
async get_playlist_radio(album_id, index=0, limit=100){ get_playlist_radio(album_id, index=0, limit=100){
return await this.api_call(`playlist/${album_id}/radio`, {index, limit}) return this.api_call(`playlist/${album_id}/radio`, {index, limit})
} }
async get_radios(index=0, limit=10){ get_radios(index=0, limit=10){
return await this.api_call('radio', {index, limit}) return this.api_call('radio', {index, limit})
} }
async get_radios_genres(index=0, limit=25){ get_radios_genres(index=0, limit=25){
return await this.api_call('radio/genres', {index, limit}) return this.api_call('radio/genres', {index, limit})
} }
async get_radios_top(index=0, limit=50){ get_radios_top(index=0, limit=50){
return await this.api_call('radio/top', {index, limit}) return this.api_call('radio/top', {index, limit})
} }
async get_radios_lists(index=0, limit=25){ get_radios_lists(index=0, limit=25){
return await this.api_call('radio/lists', {index, limit}) return this.api_call('radio/lists', {index, limit})
} }
async get_radio(radio_id){ get_radio(radio_id){
return await this.api_call(`radio/${radio_id}`) return this.api_call(`radio/${radio_id}`)
} }
async get_radio_tracks(radio_id, index=0, limit=40){ get_radio_tracks(radio_id, index=0, limit=40){
return await this.api_call(`radio/${radio_id}/tracks`, {index, limit}) return this.api_call(`radio/${radio_id}/tracks`, {index, limit})
} }
_generate_search_advanced_query(artist="", album="", track="", label="", dur_min=0, dur_max=0, bpm_min=0, bpm_max=0){ _generate_search_advanced_query(artist="", album="", track="", label="", dur_min=0, dur_max=0, bpm_min=0, bpm_max=0){
@ -244,92 +246,92 @@ export class API{
return args return args
} }
async search(query, strict=false, order, index=0, limit=25){ search(query, strict=false, order, index=0, limit=25){
const args = this._generate_search_args(query, strict, order, index, limit) const args = this._generate_search_args(query, strict, order, index, limit)
return await this.api_call('search', args) return this.api_call('search', args)
} }
async advanced_search(artist="", album="", track="", label="", dur_min=0, dur_max=0, bpm_min=0, bpm_max=0, strict=false, order, index=0, limit=25){ advanced_search(artist="", album="", track="", label="", dur_min=0, dur_max=0, bpm_min=0, bpm_max=0, strict=false, order, index=0, limit=25){
const query = this._generate_search_advanced_query(artist, album, track, label, dur_min, dur_max, bpm_min, bpm_max) const query = this._generate_search_advanced_query(artist, album, track, label, dur_min, dur_max, bpm_min, bpm_max)
return await this.search(query, strict, order, index, limit) return this.search(query, strict, order, index, limit)
} }
async search_album(query, strict=false, order, index=0, limit=25){ search_album(query, strict=false, order, index=0, limit=25){
const args = this._generate_search_args(query, strict, order, index, limit) const args = this._generate_search_args(query, strict, order, index, limit)
return await this.api_call('search/album', args) return this.api_call('search/album', args)
} }
async search_artist(query, strict=false, order, index=0, limit=25){ search_artist(query, strict=false, order, index=0, limit=25){
const args = this._generate_search_args(query, strict, order, index, limit) const args = this._generate_search_args(query, strict, order, index, limit)
return await this.api_call('search/artist', args) return this.api_call('search/artist', args)
} }
async search_playlist(query, strict=false, order, index=0, limit=25){ search_playlist(query, strict=false, order, index=0, limit=25){
const args = this._generate_search_args(query, strict, order, index, limit) const args = this._generate_search_args(query, strict, order, index, limit)
return await this.api_call('search/playlist', args) return this.api_call('search/playlist', args)
} }
async search_radio(query, strict=false, order, index=0, limit=25){ search_radio(query, strict=false, order, index=0, limit=25){
const args = this._generate_search_args(query, strict, order, index, limit) const args = this._generate_search_args(query, strict, order, index, limit)
return await this.api_call('search/radio', args) return this.api_call('search/radio', args)
} }
async search_track(query, strict=false, order, index=0, limit=25){ search_track(query, strict=false, order, index=0, limit=25){
const args = this._generate_search_args(query, strict, order, index, limit) const args = this._generate_search_args(query, strict, order, index, limit)
return await this.api_call('search/track', args) return this.api_call('search/track', args)
} }
async search_user(query, strict=false, order, index=0, limit=25){ search_user(query, strict=false, order, index=0, limit=25){
const args = this._generate_search_args(query, strict, order, index, limit) const args = this._generate_search_args(query, strict, order, index, limit)
return await this.api_call('search/user', args) return this.api_call('search/user', args)
} }
async get_track(song_id){ get_track(song_id){
return await this.api_call(`track/${song_id}`) return this.api_call(`track/${song_id}`)
} }
async get_track_by_ISRC(isrc){ get_track_by_ISRC(isrc){
return await this.get_track(`isrc:${isrc}`) return this.get_track(`isrc:${isrc}`)
} }
async get_user(user_id){ get_user(user_id){
return await this.api_call(`user/${user_id}`) return this.api_call(`user/${user_id}`)
} }
async get_user_albums(user_id, index=0, limit=25){ get_user_albums(user_id, index=0, limit=25){
return await this.api_call(`user/${user_id}/albums`, {index, limit}) return this.api_call(`user/${user_id}/albums`, {index, limit})
} }
async get_user_artists(user_id, index=0, limit=25){ get_user_artists(user_id, index=0, limit=25){
return await this.api_call(`user/${user_id}/artists`, {index, limit}) return this.api_call(`user/${user_id}/artists`, {index, limit})
} }
async get_user_artists(user_id, index=0, limit=25){ get_user_artists(user_id, index=0, limit=25){
return await this.api_call(`user/${user_id}/artists`, {index, limit}) return this.api_call(`user/${user_id}/artists`, {index, limit})
} }
async get_user_flow(user_id, index=0, limit=25){ get_user_flow(user_id, index=0, limit=25){
return await this.api_call(`user/${user_id}/flow`, {index, limit}) return this.api_call(`user/${user_id}/flow`, {index, limit})
} }
async get_user_following(user_id, index=0, limit=25){ get_user_following(user_id, index=0, limit=25){
return await this.api_call(`user/${user_id}/followings`, {index, limit}) return this.api_call(`user/${user_id}/followings`, {index, limit})
} }
async get_user_followers(user_id, index=0, limit=25){ get_user_followers(user_id, index=0, limit=25){
return await this.api_call(`user/${user_id}/followers`, {index, limit}) return this.api_call(`user/${user_id}/followers`, {index, limit})
} }
async get_user_playlists(user_id, index=0, limit=25){ get_user_playlists(user_id, index=0, limit=25){
return await this.api_call(`user/${user_id}/playlists`, {index, limit}) return this.api_call(`user/${user_id}/playlists`, {index, limit})
} }
async get_user_radios(user_id, index=0, limit=25){ get_user_radios(user_id, index=0, limit=25){
return await this.api_call(`user/${user_id}/radios`, {index, limit}) return this.api_call(`user/${user_id}/radios`, {index, limit})
} }
async get_user_tracks(user_id, index=0, limit=25){ get_user_tracks(user_id, index=0, limit=25){
return await this.api_call(`user/${user_id}/tracks`, {index, limit}) return this.api_call(`user/${user_id}/tracks`, {index, limit})
} }
// Extra calls // Extra calls
@ -367,57 +369,71 @@ export class API{
} }
// Base class for Deezer exceptions // Base class for Deezer exceptions
export class APIError extends Error { class APIError extends Error {
constructor(message) { constructor(message) {
super(message); super(message);
this.name = "APIError"; this.name = "APIError";
} }
} }
export class ItemsLimitExceededException extends APIError { class ItemsLimitExceededException extends APIError {
constructor(message) { constructor(message) {
super(message); super(message);
this.name = "ItemsLimitExceededException"; this.name = "ItemsLimitExceededException";
} }
} }
export class PermissionException extends APIError { class PermissionException extends APIError {
constructor(message) { constructor(message) {
super(message); super(message);
this.name = "PermissionException"; this.name = "PermissionException";
} }
} }
export class InvalidTokenException extends APIError { class InvalidTokenException extends APIError {
constructor(message) { constructor(message) {
super(message); super(message);
this.name = "InvalidTokenException"; this.name = "InvalidTokenException";
} }
} }
export class WrongParameterException extends APIError { class WrongParameterException extends APIError {
constructor(message) { constructor(message) {
super(message); super(message);
this.name = "WrongParameterException"; this.name = "WrongParameterException";
} }
} }
export class MissingParameterException extends APIError { class MissingParameterException extends APIError {
constructor(message) { constructor(message) {
super(message); super(message);
this.name = "MissingParameterException"; this.name = "MissingParameterException";
} }
} }
export class InvalidQueryException extends APIError { class InvalidQueryException extends APIError {
constructor(message) { constructor(message) {
super(message); super(message);
this.name = "InvalidQueryException"; this.name = "InvalidQueryException";
} }
} }
export class DataException extends APIError { class DataException extends APIError {
constructor(message) { constructor(message) {
super(message); super(message);
this.name = "DataException"; this.name = "DataException";
} }
} }
export class IndividualAccountChangedNotAllowedException extends APIError { class IndividualAccountChangedNotAllowedException extends APIError {
constructor(message) { constructor(message) {
super(message); super(message);
this.name = "IndividualAccountChangedNotAllowedException"; this.name = "IndividualAccountChangedNotAllowedException";
} }
} }
module.exports = {
SearchOrder,
API,
APIError,
ItemsLimitExceededException,
PermissionException,
InvalidTokenException,
WrongParameterException,
MissingParameterException,
InvalidQueryException,
DataException,
IndividualAccountChangedNotAllowedException
}

View file

@ -2,25 +2,25 @@ const got = require('got')
const {map_artist_album, map_user_track, map_user_artist, map_user_album, map_user_playlist} = require('./utils.js') const {map_artist_album, map_user_track, map_user_artist, map_user_album, map_user_playlist} = require('./utils.js')
// Explicit Content Lyrics // Explicit Content Lyrics
export const LyricsStatus = { const LyricsStatus = {
NOT_EXPLICIT: 0 // Not Explicit NOT_EXPLICIT: 0, // Not Explicit
EXPLICIT: 1 // Explicit EXPLICIT: 1, // Explicit
UNKNOWN: 2 // Unknown UNKNOWN: 2, // Unknown
EDITED: 3 // Edited EDITED: 3, // Edited
PARTIALLY_EXPLICIT: 4 // Partially Explicit (Album "lyrics" only) PARTIALLY_EXPLICIT: 4, // Partially Explicit (Album "lyrics" only)
PARTIALLY_UNKNOWN: 5 // Partially Unknown (Album "lyrics" only) PARTIALLY_UNKNOWN: 5, // Partially Unknown (Album "lyrics" only)
NO_ADVICE: 6 // No Advice Available NO_ADVICE: 6, // No Advice Available
PARTIALLY_NO_ADVICE: 7 // Partially No Advice Available (Album "lyrics" only) PARTIALLY_NO_ADVICE: 7 // Partially No Advice Available (Album "lyrics" only)
} }
export const PlaylistStatus = { const PlaylistStatus = {
PUBLIC: 0 PUBLIC: 0,
PRIVATE: 1 PRIVATE: 1,
COLLABORATIVE: 2 COLLABORATIVE: 2,
} }
export const EMPTY_TRACK_OBJ = { const EMPTY_TRACK_OBJ = {
SNG_ID: 0, SNG_ID: 0,
SNG_TITLE: '', SNG_TITLE: '',
DURATION: 0, DURATION: 0,
@ -33,7 +33,7 @@ export const EMPTY_TRACK_OBJ = {
ART_NAME: "" ART_NAME: ""
} }
export class GW{ class GW{
constructor(cookie_jar, headers){ constructor(cookie_jar, headers){
this.http_headers = headers this.http_headers = headers
this.cookie_jar = cookie_jar this.cookie_jar = cookie_jar
@ -42,27 +42,28 @@ export class GW{
async api_call(method, args, params){ async api_call(method, args, params){
if (typeof args == "unasyncined") args = {} if (typeof args == "unasyncined") args = {}
if (typeof params == "unasyncined") params = {} if (typeof params == "unasyncined") params = {}
p = { let p = {
api_version: "1.0", api_version: "1.0",
api_token: method == 'deezer.getUserData' ? 'null' : this._get_token(), api_token: method == 'deezer.getUserData' ? 'null' : await this._get_token(),
input: '3', input: '3',
method: method, method: method,
..params ...params
} }
let result_json
try{ try{
const result_json = await got.get("http://www.deezer.com/ajax/gw-light.php", { result_json = await got.post("http://www.deezer.com/ajax/gw-light.php", {
searchParams: p, searchParams: p,
json: args, json: args,
cookieJar: this.cookie_jar, cookieJar: this.cookie_jar,
headers: this.http_headers, headers: this.http_headers,
timeout: 30000 timeout: 30000
}).json() }).json()
}catch{ }catch (e){
console.log(e)
await new Promise(r => setTimeout(r, 2000)) // sleep(2000ms) await new Promise(r => setTimeout(r, 2000)) // sleep(2000ms)
return await this.api_call(method, args, params) return await this.api_call(method, args, params)
} }
if (result_json.error.length): if (result_json.error.length) throw new GWAPIError(result_json.error)
throw new GWAPIError(result_json.error)
return result_json.results return result_json.results
} }
@ -71,28 +72,28 @@ export class GW{
return token_data.checkForm return token_data.checkForm
} }
async get_user_data(){ get_user_data(){
return await this.api_call('deezer.getUserData') return this.api_call('deezer.getUserData')
} }
async get_user_profile_page(user_id, tab, limit=10){ get_user_profile_page(user_id, tab, limit=10){
return await this.api_call('deezer.pageProfile', {user_id, tab, nb: limit}) return this.api_call('deezer.pageProfile', {user_id, tab, nb: limit})
} }
async get_child_accounts(){ get_child_accounts(){
return await this.api_call('deezer.getChildAccounts') return this.api_call('deezer.getChildAccounts')
} }
async get_track(sng_id){ get_track(sng_id){
return await this.api_call('song.getData', {sng_id}) return this.api_call('song.getData', {sng_id})
} }
async get_track_page(sng_id){ get_track_page(sng_id){
return await this.api_call('deezer.pageTrack', {sng_id}) return this.api_call('deezer.pageTrack', {sng_id})
} }
async get_track_lyrics(sng_id){ get_track_lyrics(sng_id){
return await this.api_call('song.getLyrics', {sng_id}) return this.api_call('song.getLyrics', {sng_id})
} }
async get_tracks_gw(sng_ids){ async get_tracks_gw(sng_ids){
@ -110,12 +111,12 @@ export class GW{
return tracks_array return tracks_array
} }
async get_album(alb_id){ get_album(alb_id){
return await this.api_call('album.getData', {alb_id}) return this.api_call('album.getData', {alb_id})
} }
async get_album_page(alb_id){ get_album_page(alb_id){
return await this.api_call('deezer.pageAlbum', { return this.api_call('deezer.pageAlbum', {
alb_id, alb_id,
lang: 'en', lang: 'en',
header: True, header: True,
@ -134,11 +135,11 @@ export class GW{
return tracks_array return tracks_array
} }
async get_artist(art_id){ get_artist(art_id){
return await this.api_call('artist.getData', {art_id}) return this.api_call('artist.getData', {art_id})
} }
async get_artist_page(art_id){ get_artist_page(art_id){
return this.api_call('deezer.pageArtist', { return this.api_call('deezer.pageArtist', {
art_id, art_id,
lang: 'en', lang: 'en',
@ -157,8 +158,8 @@ export class GW{
return tracks_array return tracks_array
} }
async get_artist_discography(art_id, index=0, limit=25){ get_artist_discography(art_id, index=0, limit=25){
return await this.api_call('album.getDiscography', { return this.api_call('album.getDiscography', {
art_id, art_id,
discography_mode:"all", discography_mode:"all",
nb: limit, nb: limit,
@ -167,12 +168,12 @@ export class GW{
}) })
} }
async get_playlist(playlist_id){ get_playlist(playlist_id){
return await this.api_call('playlist.getData', {playlist_id}) return this.api_call('playlist.getData', {playlist_id})
} }
async get_playlist_page(playlist_id){ get_playlist_page(playlist_id){
return await this.api_call('deezer.pagePlaylist', { return this.api_call('deezer.pagePlaylist', {
playlist_id, playlist_id,
lang: 'en', lang: 'en',
header: True, header: True,
@ -190,12 +191,12 @@ export class GW{
return tracks_array return tracks_array
} }
async create_playlist(title, status=PlaylistStatus.PUBLIC, description, songs=[]){ create_playlist(title, status=PlaylistStatus.PUBLIC, description, songs=[]){
newSongs = [] newSongs = []
songs.forEach(song => { songs.forEach(song => {
newSongs.push([song, 0]) newSongs.push([song, 0])
}); });
return await this.api_call('playlist.create', { return this.api_call('playlist.create', {
title, title,
status, status,
description, description,
@ -203,12 +204,12 @@ export class GW{
}) })
} }
async edit_playlist(playlist_id, title, status, description, songs=[]){ edit_playlist(playlist_id, title, status, description, songs=[]){
newSongs = [] newSongs = []
songs.forEach(song => { songs.forEach(song => {
newSongs.push([song, 0]) newSongs.push([song, 0])
}); });
return await this.api_call('playlist.update', { return this.api_call('playlist.update', {
playlist_id, playlist_id,
title, title,
status, status,
@ -217,74 +218,74 @@ export class GW{
}) })
} }
async add_songs_to_playlist(playlist_id, songs, offset=-1){ add_songs_to_playlist(playlist_id, songs, offset=-1){
newSongs = [] newSongs = []
songs.forEach(song => { songs.forEach(song => {
newSongs.push([song, 0]) newSongs.push([song, 0])
}); });
return await this.api_call('playlist.addSongs', { return this.api_call('playlist.addSongs', {
playlist_id, playlist_id,
songs: newSongs, songs: newSongs,
offset offset
}) })
} }
async add_song_to_playlist(playlist_id, sng_id, offset=-1){ add_song_to_playlist(playlist_id, sng_id, offset=-1){
return await this.add_songs_to_playlist(playlist_id, [sng_id], offset) return this.add_songs_to_playlist(playlist_id, [sng_id], offset)
} }
async remove_songs_from_playlist(playlist_id, songs){ remove_songs_from_playlist(playlist_id, songs){
newSongs = [] newSongs = []
songs.forEach(song => { songs.forEach(song => {
newSongs.push([song, 0]) newSongs.push([song, 0])
}); });
return await this.api_call('playlist.deleteSongs', { return this.api_call('playlist.deleteSongs', {
playlist_id, playlist_id,
songs: newSongs songs: newSongs
}) })
} }
async remove_song_from_playlist(playlist_id, sng_id){ remove_song_from_playlist(playlist_id, sng_id){
return await this.remove_songs_from_playlist(playlist_id, [sng_id]) return this.remove_songs_from_playlist(playlist_id, [sng_id])
} }
async delete_playlist(playlist_id){ delete_playlist(playlist_id){
return await this.api_call('playlist.delete', {playlist_id}) return this.api_call('playlist.delete', {playlist_id})
} }
async add_song_to_favorites(sng_id){ add_song_to_favorites(sng_id){
return await this.gw_api_call('favorite_song.add', {sng_id}) return this.gw_api_call('favorite_song.add', {sng_id})
} }
async remove_song_from_favorites(sng_id){ remove_song_from_favorites(sng_id){
return await this.gw_api_call('favorite_song.remove', {sng_id}) return this.gw_api_call('favorite_song.remove', {sng_id})
} }
async add_album_to_favorites(alb_id){ add_album_to_favorites(alb_id){
return await this.gw_api_call('album.addFavorite', {alb_id}) return this.gw_api_call('album.addFavorite', {alb_id})
} }
async remove_album_from_favorites(alb_id){ remove_album_from_favorites(alb_id){
return await this.gw_api_call('album.deleteFavorite', {alb_id}) return this.gw_api_call('album.deleteFavorite', {alb_id})
} }
async add_artist_to_favorites(art_id){ add_artist_to_favorites(art_id){
return await this.gw_api_call('artist.addFavorite', {art_id}) return this.gw_api_call('artist.addFavorite', {art_id})
} }
async remove_artist_from_favorites(art_id){ remove_artist_from_favorites(art_id){
return await this.gw_api_call('artist.deleteFavorite', {art_id}) return this.gw_api_call('artist.deleteFavorite', {art_id})
} }
async add_playlist_to_favorites(playlist_id){ add_playlist_to_favorites(playlist_id){
return await this.gw_api_call('playlist.addFavorite', {PARENT_PLAYLIST_ID: playlist_id}) return this.gw_api_call('playlist.addFavorite', {PARENT_PLAYLIST_ID: playlist_id})
} }
async remove_playlist_from_favorites(playlist_id){ remove_playlist_from_favorites(playlist_id){
return await this.gw_api_call('playlist.deleteFavorite', {PLAYLIST_ID: playlist_id}) return this.gw_api_call('playlist.deleteFavorite', {PLAYLIST_ID: playlist_id})
} }
async get_page(page){ get_page(page){
let params = { let params = {
gateway_input: JSON.stringify({ gateway_input: JSON.stringify({
PAGE: page, PAGE: page,
@ -294,18 +295,18 @@ export class GW{
'channel', 'channel',
'album' 'album'
], ],
horizontal-grid: [ 'horizontal-grid': [
'album' 'album'
], ],
}, },
LANG: 'en' LANG: 'en'
}) })
} }
return await this.api_call('page.get', params=params) return this.api_call('page.get', params=params)
} }
async search(query, index=0, limit=10, suggest=true, artist_suggest=true, top_tracks=true){ search(query, index=0, limit=10, suggest=true, artist_suggest=true, top_tracks=true){
return await this.api_call('deezer.pageSearch', { return this.api_call('deezer.pageSearch', {
query, query,
start: index, start: index,
nb: limit, nb: limit,
@ -315,8 +316,8 @@ export class GW{
}) })
} }
async search_music(query, type, index=0, limit=10){ search_music(query, type, index=0, limit=10){
return await this.api_call('search.music', { return this.api_call('search.music', {
query, query,
filter: "ALL", filter: "ALL",
output: type, output: type,
@ -354,7 +355,7 @@ export class GW{
if (release.ROLE_ID == 5) { // Handle albums where the artist is featured if (release.ROLE_ID == 5) { // Handle albums where the artist is featured
if (!result.featured) result.featured = [] if (!result.featured) result.featured = []
result.featured.push(obj) result.featured.push(obj)
} else if release.ROLE_ID == 0 { // Handle "more" albums } else if (release.ROLE_ID == 0) { // Handle "more" albums
if (!result.more) result.more = [] if (!result.more) result.more = []
result.more.push(obj) result.more.push(obj)
result.all.push(obj) result.all.push(obj)
@ -421,9 +422,17 @@ export class GW{
} }
// Base class for Deezer exceptions // Base class for Deezer exceptions
export class GWAPIError extends Error { class GWAPIError extends Error {
constructor(message) { constructor(message) {
super(message); super(message);
this.name = "APIError"; this.name = "APIError";
} }
} }
module.exports = {
LyricsStatus,
PlaylistStatus,
EMPTY_TRACK_OBJ,
GW,
GWAPIError
}

View file

@ -4,18 +4,18 @@ const { API } = require('./api.js')
const { GW } = require('./gw.js') const { GW } = require('./gw.js')
// Number associtation for formats // Number associtation for formats
export const TrackFormats = { const TrackFormats = {
FLAC : 9 FLAC : 9,
MP3_320 : 3 MP3_320 : 3,
MP3_128 : 1 MP3_128 : 1,
MP4_RA3 : 15 MP4_RA3 : 15,
MP4_RA2 : 14 MP4_RA2 : 14,
MP4_RA1 : 13 MP4_RA1 : 13,
DEFAULT : 8 DEFAULT : 8,
LOCAL : 0 LOCAL : 0,
} }
export class Deezer{ class Deezer{
constructor(accept_language=""){ constructor(accept_language=""){
this.http_headers = { this.http_headers = {
"User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36", "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36",
@ -74,14 +74,16 @@ export class Deezer{
async login_via_arl(arl, child=0){ async login_via_arl(arl, child=0){
arl = arl.trim() arl = arl.trim()
// TODO: Check how to do this
let cookie_obj = Cookie({ // Create cookie
let cookie_obj = new Cookie({
key: 'arl', key: 'arl',
value: arl, value: arl,
domain: '.deezer.com',
path: "/", path: "/",
httpOnly: true httpOnly: true
}) })
this.cookie_jar.setCookie(cookie_obj, '.deezer.com') await this.cookie_jar.setCookie(cookie_obj.toString(), "https://www.deezer.com")
let user_data = await this.gw.get_user_data() let user_data = await this.gw.get_user_data()
// Check if user logged in // Check if user logged in
@ -108,7 +110,7 @@ export class Deezer{
}) })
}) })
} else { } else {
this.childs.append({ this.childs.push({
'id': user_data.USER.USER_ID, 'id': user_data.USER.USER_ID,
'name': user_data.USER.BLOG_NAME, 'name': user_data.USER.BLOG_NAME,
'picture': user_data.USER.USER_PICTURE || "" 'picture': user_data.USER.USER_PICTURE || ""
@ -125,3 +127,11 @@ export class Deezer{
} }
} }
module.exports = {
TrackFormats,
Deezer,
api: {...require('./api.js')},
gw: {...require('./gw.js')},
utils: {...require('./utils.js')}
}

View file

@ -1,7 +1,7 @@
const RELEASE_TYPE = ["single", "album", "compile", "ep", "bundle"] const RELEASE_TYPE = ["single", "album", "compile", "ep", "bundle"]
// maps gw-light api user/tracks to standard api // maps gw-light api user/tracks to standard api
export function map_user_track(track){ function map_user_track(track){
return { return {
id: track.SNG_ID, id: track.SNG_ID,
title: track.SNG_TITLE, title: track.SNG_TITLE,
@ -39,7 +39,7 @@ export function map_user_track(track){
} }
// maps gw-light api user/artists to standard api // maps gw-light api user/artists to standard api
export function map_user_artist(artist){ function map_user_artist(artist){
return { return {
id: artist.ART_ID, id: artist.ART_ID,
name: artist.ART_NAME, name: artist.ART_NAME,
@ -57,7 +57,7 @@ export function map_user_artist(artist){
// maps gw-light api user/albums to standard api // maps gw-light api user/albums to standard api
export function map_user_album(album){ function map_user_album(album){
return { return {
id: album.ALB_ID, id: album.ALB_ID,
title: album.ALB_TITLE, title: album.ALB_TITLE,
@ -81,7 +81,7 @@ export function map_user_album(album){
// maps gw-light api user/playlists to standard api // maps gw-light api user/playlists to standard api
export function map_user_playlist(playlist, default_user_name=""){ function map_user_playlist(playlist, default_user_name=""){
return { return {
id: playlist.PLAYLIST_ID, id: playlist.PLAYLIST_ID,
title: playlist.TITLE, title: playlist.TITLE,
@ -105,7 +105,7 @@ export function map_user_playlist(playlist, default_user_name=""){
// maps gw-light api albums to standard api // maps gw-light api albums to standard api
export function map_album(album){ function map_album(album){
return { return {
id: album.ALB_ID, id: album.ALB_ID,
title: album.ALB_TITLE, title: album.ALB_TITLE,
@ -144,7 +144,7 @@ export function map_album(album){
// maps gw-light api artist/albums to standard api // maps gw-light api artist/albums to standard api
export function map_artist_album(album){ function map_artist_album(album){
return { return {
id: album.ALB_ID, id: album.ALB_ID,
title: album.ALB_TITLE, title: album.ALB_TITLE,
@ -169,7 +169,7 @@ export function map_artist_album(album){
// maps gw-light api playlists to standard api // maps gw-light api playlists to standard api
export function map_playlist(playlist){ function map_playlist(playlist){
return { return {
id: playlist.PLAYLIST_ID, id: playlist.PLAYLIST_ID,
title: playlist.TITLE, title: playlist.TITLE,
@ -200,9 +200,8 @@ export function map_playlist(playlist){
} }
} }
// Cleanup terms that can hurt search results // Cleanup terms that can hurt search results
export function clean_search_query(term){ function clean_search_query(term){
term = term.replaceAll(/ feat[\.]? /g, " ") term = term.replaceAll(/ feat[\.]? /g, " ")
term = term.replaceAll(/ ft[\.]? /g, " ") term = term.replaceAll(/ ft[\.]? /g, " ")
term = term.replaceAll(/\(feat[\.]? /g, " ") term = term.replaceAll(/\(feat[\.]? /g, " ")
@ -210,3 +209,14 @@ export function clean_search_query(term){
term = term.replace(' & ', " ").replace('', "-").replace('—', "-") term = term.replace(' & ', " ").replace('', "-").replace('—', "-")
return term return term
} }
module.exports = {
map_user_track,
map_user_artist,
map_user_album,
map_user_playlist,
map_album,
map_artist_album,
map_playlist,
clean_search_query
}

4
package-lock.json generated
View file

@ -1,11 +1,11 @@
{ {
"name": "deezer-js", "name": "deezer-js",
"version": "1.0.0", "version": "0.0.2",
"lockfileVersion": 2, "lockfileVersion": 2,
"requires": true, "requires": true,
"packages": { "packages": {
"": { "": {
"version": "1.0.0", "version": "0.0.2",
"license": "GPL-3.0-or-later", "license": "GPL-3.0-or-later",
"dependencies": { "dependencies": {
"got": "^11.8.2", "got": "^11.8.2",

View file

@ -1,6 +1,6 @@
{ {
"name": "deezer-js", "name": "deezer-js",
"version": "0.0.1", "version": "0.0.2",
"description": "A wrapper for all Deezer's APIs", "description": "A wrapper for all Deezer's APIs",
"main": "deezer/index.js", "main": "deezer/index.js",
"scripts": { "scripts": {
@ -8,7 +8,7 @@
}, },
"repository": { "repository": {
"type": "git", "type": "git",
"url": "https://git.rip/RemixDev/deezer-js" "url": "https://gitlab.com/RemixDev/deezer-js"
}, },
"author": "RemixDev", "author": "RemixDev",
"license": "GPL-3.0-or-later", "license": "GPL-3.0-or-later",