From 4ee0cedb8f978fb96c05571341369fe1a2ae9ed6 Mon Sep 17 00:00:00 2001 From: Lachie Underhill Date: Wed, 30 Oct 2024 16:45:20 +1000 Subject: [PATCH] fix(cli): portable config not creating folder correctly --- .changeset/soft-snakes-travel.md | 5 +++++ cli/.gitignore | 1 + cli/src/download.ts | 13 +++++++++++++ cli/src/login.ts | 27 +++++++++++++++++---------- cli/src/main.ts | 15 +++++++++++---- deemix/src/errors.ts | 9 +++++++++ deemix/src/plugins/spotify.ts | 13 +++++++++---- 7 files changed, 65 insertions(+), 18 deletions(-) create mode 100644 .changeset/soft-snakes-travel.md create mode 100644 cli/.gitignore diff --git a/.changeset/soft-snakes-travel.md b/.changeset/soft-snakes-travel.md new file mode 100644 index 00000000..d91ce554 --- /dev/null +++ b/.changeset/soft-snakes-travel.md @@ -0,0 +1,5 @@ +--- +"deemix-cli": minor +--- + +Correctly create portable config diff --git a/cli/.gitignore b/cli/.gitignore new file mode 100644 index 00000000..f733c4b5 --- /dev/null +++ b/cli/.gitignore @@ -0,0 +1 @@ +config/ diff --git a/cli/src/download.ts b/cli/src/download.ts index ebb1ae71..c628732e 100644 --- a/cli/src/download.ts +++ b/cli/src/download.ts @@ -8,6 +8,7 @@ import { type Settings, } from "deemix"; import { TrackFormats, type Deezer } from "deezer-sdk"; +import { configFolder } from "./main"; const listener: Listener = { send: (key: string, data?: unknown) => { @@ -35,12 +36,24 @@ export const downloadLinks = async ( { spotify: spotifyPlugin }, listener ); + if (Array.isArray(downloadObject)) { downloadObjects.concat(downloadObject); } else { downloadObjects.push(downloadObject); } } catch (e) { + if (e instanceof Error && e.name === "PluginNotEnabledError") { + console.warn( + `Populate Spotify app credentials to download Spotify links:\n\t${configFolder}spotify/config.json\n` + ); + console.log( + "Documentation: https://developer.spotify.com/documentation/web-api/tutorials/getting-started#create-an-app" + ); + + continue; + } + if (e instanceof Error) { console.error(e); } diff --git a/cli/src/login.ts b/cli/src/login.ts index 277f6ea6..e6930095 100644 --- a/cli/src/login.ts +++ b/cli/src/login.ts @@ -1,5 +1,5 @@ import type { Deezer } from "deezer-sdk"; -import { existsSync, readFileSync, writeFileSync } from "fs"; +import { existsSync, readFileSync, rmSync, writeFileSync } from "fs"; import readline from "node:readline/promises"; import path from "path"; @@ -8,16 +8,23 @@ export const deezerLogin = async (dz: Deezer, configFolder: string) => { if (existsSync(arlFileLocation)) { const arl = readFileSync(arlFileLocation).toString().trim(); - await dz.loginViaArl(arl); - } else { - const rl = readline.createInterface({ - input: process.stdin, - output: process.stdout, - }); - const arl = await rl.question("Enter your ARL: "); - await dz.loginViaArl(arl); - writeFileSync(arlFileLocation, arl); + const loggedIn = await dz.loginViaArl(arl); + + if (loggedIn) { + return true; + } + + // If the ARL is invalid, remove it + rmSync(arlFileLocation); } + const rl = readline.createInterface({ + input: process.stdin, + output: process.stdout, + }); + const arl = await rl.question("Enter your ARL: "); + await dz.loginViaArl(arl); + writeFileSync(arlFileLocation, arl); + return dz.loggedIn; }; diff --git a/cli/src/main.ts b/cli/src/main.ts index 148ae2fe..14cb07f9 100644 --- a/cli/src/main.ts +++ b/cli/src/main.ts @@ -1,7 +1,7 @@ import { Command } from "commander"; import { loadSettings, SpotifyPlugin, utils } from "deemix"; import { Deezer, setDeezerCacheDir } from "deezer-sdk"; -import path from "path"; +import path, { sep } from "path"; import packageJson from "../package.json" with { type: "json" }; import { parseBitrate } from "./bitrate"; import { downloadLinks } from "./download"; @@ -17,7 +17,10 @@ program .version(packageJson.version) .argument("", "The URL of the track or playlist") .option("-p, --path ", "Downloads in the given folder") - .option("-b, --bitrate ", "Overrides the default bitrate selected") + .option( + "-b, --bitrate ", + "Overrides the default bitrate selected - 128, 320, flac" + ) .option( "--portable", "Creates the config folder in the same directory where the script is launched" @@ -26,10 +29,10 @@ program const { portable } = program.opts(); -let configFolder: string; +export let configFolder: string; if (portable) { - configFolder = path.join(process.cwd(), "config"); + configFolder = path.join(process.cwd(), `config${sep}`); } else { configFolder = getConfigFolder(); } @@ -53,8 +56,12 @@ const loginAndDownload = async () => { const urls = program.args; await downloadLinks(dz, urls, settings, spotifyPlugin); + + process.exit(0); } else { console.error("Not logged in"); + + process.exit(1); } }; diff --git a/deemix/src/errors.ts b/deemix/src/errors.ts index 621fd6f3..abe84901 100644 --- a/deemix/src/errors.ts +++ b/deemix/src/errors.ts @@ -90,6 +90,15 @@ export class DownloadError extends DeemixError { } } +export class PluginNotEnabledError extends DeemixError { + constructor(pluginName: string) { + const message = `${pluginName} plugin not enabled`; + super(message); + + this.name = "PluginNotEnabledError"; + } +} + export const ErrorMessages = { notOnDeezer: "Track not available on Deezer!", notEncoded: "Track not yet encoded!", diff --git a/deemix/src/plugins/spotify.ts b/deemix/src/plugins/spotify.ts index d56a0001..bb390821 100644 --- a/deemix/src/plugins/spotify.ts +++ b/deemix/src/plugins/spotify.ts @@ -1,7 +1,12 @@ import { Collection, Convertable } from "@/download-objects/Collection.js"; import { generateAlbumItem } from "@/download-objects/generateAlbumItem.js"; import { generateTrackItem } from "@/download-objects/generateTrackItem.js"; -import { AlbumNotOnDeezer, InvalidID, TrackNotOnDeezer } from "@/errors.js"; +import { + AlbumNotOnDeezer, + InvalidID, + PluginNotEnabledError, + TrackNotOnDeezer, +} from "@/errors.js"; import { type Settings } from "@/types/Settings.js"; import { getConfigFolder } from "@/utils/localpaths.js"; import { @@ -162,7 +167,7 @@ export default class SpotifyPlugin extends BasePlugin { } async generatePlaylistItem(dz: Deezer, link_id: string, bitrate: number) { - if (!this.enabled) throw new Error("Spotify plugin not enabled"); + if (!this.enabled) throw new PluginNotEnabledError("Spotify"); const spotifyPlaylist = await this.sp.playlists.getPlaylist(link_id); @@ -217,7 +222,7 @@ export default class SpotifyPlugin extends BasePlugin { } async getTrack(track_id: string, spotifyTrack?: SpotifyTrack) { - if (!this.enabled) throw new Error("Spotify plugin not enabled"); + if (!this.enabled) throw new PluginNotEnabledError("Spotify"); const cachedTrack = { isrc: null, @@ -247,7 +252,7 @@ export default class SpotifyPlugin extends BasePlugin { } async getAlbum(album_id: string, spotifyAlbum = null) { - if (!this.enabled) throw new Error("Spotify plugin not enabled"); + if (!this.enabled) throw new PluginNotEnabledError("Spotify"); const cachedAlbum = { upc: null, data: null,