mirror of
https://gitlab.com/deeplydrumming/DeemixFix.git
synced 2026-01-15 08:22:59 -03:00
Main
This commit is contained in:
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"env": {
|
|
||||||
"commonjs": true,
|
|
||||||
"es2021": true,
|
|
||||||
"node": true
|
|
||||||
},
|
|
||||||
"extends": "eslint:recommended",
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 12
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,49 +1,49 @@
|
|||||||
const got = require('got')
|
const got = require('got')
|
||||||
const {CookieJar} = require('tough-cookie')
|
const { CookieJar } = require('tough-cookie')
|
||||||
const {_md5} = require('./crypto.js')
|
const { _md5 } = require('./crypto.js')
|
||||||
const { USER_AGENT_HEADER } = require('./index.js')
|
const { USER_AGENT_HEADER } = require('./index.js')
|
||||||
|
|
||||||
const CLIENT_ID = "172365"
|
const CLIENT_ID = '172365'
|
||||||
const CLIENT_SECRET = "fb0bec7ccc063dab0417eb7b0d847f34"
|
const CLIENT_SECRET = 'fb0bec7ccc063dab0417eb7b0d847f34'
|
||||||
|
|
||||||
async function getAccessToken(email, password){
|
async function getAccessToken (email, password) {
|
||||||
let accessToken = null
|
let accessToken = null
|
||||||
password = _md5(password, 'utf8')
|
password = _md5(password, 'utf8')
|
||||||
const hash = _md5([CLIENT_ID, email, password, CLIENT_SECRET].join(''), 'utf8')
|
const hash = _md5([CLIENT_ID, email, password, CLIENT_SECRET].join(''), 'utf8')
|
||||||
try {
|
try {
|
||||||
let response = await got.get("https://api.deezer.com/auth/token",{
|
const response = await got.get('https://api.deezer.com/auth/token', {
|
||||||
searchParams: {
|
searchParams: {
|
||||||
app_id: CLIENT_ID,
|
app_id: CLIENT_ID,
|
||||||
login: email,
|
login: email,
|
||||||
password: password,
|
password,
|
||||||
hash
|
hash
|
||||||
},
|
},
|
||||||
https: {rejectUnauthorized: false},
|
https: { rejectUnauthorized: false },
|
||||||
headers: {"User-Agent": USER_AGENT_HEADER}
|
headers: { 'User-Agent': USER_AGENT_HEADER }
|
||||||
}).json()
|
}).json()
|
||||||
accessToken = response.access_token
|
accessToken = response.access_token
|
||||||
if (accessToken == "undefined") accessToken = null
|
if (accessToken === 'undefined') accessToken = null
|
||||||
} catch { /*empty*/ }
|
} catch { /* empty */ }
|
||||||
return accessToken
|
return accessToken
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getArlFromAccessToken(accessToken){
|
async function getArlFromAccessToken (accessToken) {
|
||||||
if (!accessToken) return null
|
if (!accessToken) return null
|
||||||
let arl = null
|
let arl = null
|
||||||
let cookieJar = new CookieJar()
|
const cookieJar = new CookieJar()
|
||||||
try {
|
try {
|
||||||
await got.get("https://api.deezer.com/platform/generic/track/3135556", {
|
await got.get('https://api.deezer.com/platform/generic/track/3135556', {
|
||||||
headers: {"Authorization": `Bearer ${accessToken}`, "User-Agent": USER_AGENT_HEADER},
|
headers: { Authorization: `Bearer ${accessToken}`, 'User-Agent': USER_AGENT_HEADER },
|
||||||
https: {rejectUnauthorized: false},
|
https: { rejectUnauthorized: false },
|
||||||
cookieJar
|
cookieJar
|
||||||
})
|
})
|
||||||
let response = await got.get('https://www.deezer.com/ajax/gw-light.php?method=user.getArl&input=3&api_version=1.0&api_token=null', {
|
const response = await got.get('https://www.deezer.com/ajax/gw-light.php?method=user.getArl&input=3&api_version=1.0&api_token=null', {
|
||||||
headers: {"User-Agent": USER_AGENT_HEADER},
|
headers: { 'User-Agent': USER_AGENT_HEADER },
|
||||||
https: {rejectUnauthorized: false},
|
https: { rejectUnauthorized: false },
|
||||||
cookieJar
|
cookieJar
|
||||||
}).json()
|
}).json()
|
||||||
arl = response.results
|
arl = response.results
|
||||||
} catch { /*empty*/ }
|
} catch { /* empty */ }
|
||||||
return arl
|
return arl
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,32 +1,32 @@
|
|||||||
const stream = require('stream')
|
const stream = require('stream')
|
||||||
const {promisify} = require('util')
|
const { promisify } = require('util')
|
||||||
const pipeline = promisify(stream.pipeline)
|
const pipeline = promisify(stream.pipeline)
|
||||||
const { accessSync, constants } = require('fs')
|
const { accessSync, constants } = require('fs')
|
||||||
const { ErrorMessages } = require('../errors.js')
|
const { ErrorMessages } = require('../errors.js')
|
||||||
|
|
||||||
const USER_AGENT_HEADER = "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36"
|
const USER_AGENT_HEADER = 'Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.130 Safari/537.36'
|
||||||
|
|
||||||
function canWrite(path){
|
function canWrite (path) {
|
||||||
try{
|
try {
|
||||||
accessSync(path, constants.R_OK | constants.W_OK)
|
accessSync(path, constants.R_OK | constants.W_OK)
|
||||||
}catch{
|
} catch {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateReplayGainString(trackGain){
|
function generateReplayGainString (trackGain) {
|
||||||
return `${Math.round((parseFloat(trackGain) + 18.4)*-100)/100} dB`
|
return `${Math.round((parseFloat(trackGain) + 18.4) * -100) / 100} dB`
|
||||||
}
|
}
|
||||||
|
|
||||||
function changeCase(txt, type){
|
function changeCase (txt, type) {
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case 'lower': return txt.toLowerCase()
|
case 'lower': return txt.toLowerCase()
|
||||||
case 'upper': return txt.toUpperCase()
|
case 'upper': return txt.toUpperCase()
|
||||||
case 'start':
|
case 'start':
|
||||||
txt = txt.trim().split(" ")
|
txt = txt.trim().split(' ')
|
||||||
for (let i = 0; i < txt.length; i++) {
|
for (let i = 0; i < txt.length; i++) {
|
||||||
if (['(', '{', '[', "'", '"'].some(bracket => ( txt[i].length > 1 && txt[i].startsWith(bracket) ) )) {
|
if (['(', '{', '[', "'", '"'].some(bracket => (txt[i].length > 1 && txt[i].startsWith(bracket)))) {
|
||||||
txt[i] = txt[i][0] + txt[i][1].toUpperCase() + txt[i].substr(2).toLowerCase()
|
txt[i] = txt[i][0] + txt[i][1].toUpperCase() + txt[i].substr(2).toLowerCase()
|
||||||
} else if (txt[i].length > 1) {
|
} else if (txt[i].length > 1) {
|
||||||
txt[i] = txt[i][0].toUpperCase() + txt[i].substr(1).toLowerCase()
|
txt[i] = txt[i][0].toUpperCase() + txt[i].substr(1).toLowerCase()
|
||||||
@@ -34,58 +34,56 @@ function changeCase(txt, type){
|
|||||||
txt[i] = txt[i][0].toUpperCase()
|
txt[i] = txt[i][0].toUpperCase()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return txt.join(" ")
|
return txt.join(' ')
|
||||||
case 'sentence': return txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase()
|
case 'sentence': return txt.charAt(0).toUpperCase() + txt.slice(1).toLowerCase()
|
||||||
default: return txt
|
default: return txt
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeFeatures(title){
|
function removeFeatures (title) {
|
||||||
let clean = title
|
let clean = title
|
||||||
let found = false
|
let found = false
|
||||||
let pos
|
let pos
|
||||||
if (clean.search(/[\s(]\(?\s?feat\.?\s/gi) != -1){
|
if (clean.search(/[\s(]\(?\s?feat\.?\s/gi) !== -1) {
|
||||||
pos = clean.search(/[\s(]\(?\s?feat\.?\s/gi)
|
pos = clean.search(/[\s(]\(?\s?feat\.?\s/gi)
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
if (clean.search(/[\s(]\(?\s?ft\.?\s/gi) != -1){
|
if (clean.search(/[\s(]\(?\s?ft\.?\s/gi) !== -1) {
|
||||||
pos = clean.search(/[\s(]\(?\s?ft\.?\s/gi)
|
pos = clean.search(/[\s(]\(?\s?ft\.?\s/gi)
|
||||||
found = true
|
found = true
|
||||||
}
|
}
|
||||||
const openBracket = clean[pos] == '(' || clean[pos+1] == '('
|
const openBracket = clean[pos] === '(' || clean[pos + 1] === '('
|
||||||
const otherBracket = clean.indexOf('(', pos+2)
|
const otherBracket = clean.indexOf('(', pos + 2)
|
||||||
if (found) {
|
if (found) {
|
||||||
let tempTrack = clean.slice(0, pos)
|
let tempTrack = clean.slice(0, pos)
|
||||||
if (clean.includes(')') && openBracket)
|
if (clean.includes(')') && openBracket) { tempTrack += clean.slice(clean.indexOf(')', pos + 2) + 1) }
|
||||||
tempTrack += clean.slice(clean.indexOf(')', pos+2)+1)
|
if (!openBracket && otherBracket !== -1) { tempTrack += ` ${clean.slice(otherBracket)}` }
|
||||||
if (!openBracket && otherBracket != -1)
|
|
||||||
tempTrack += ` ${clean.slice(otherBracket)}`
|
|
||||||
clean = tempTrack.trim()
|
clean = tempTrack.trim()
|
||||||
clean = clean.replace(/\s\s+/g, ' ') // remove extra spaces
|
clean = clean.replace(/\s\s+/g, ' ') // remove extra spaces
|
||||||
}
|
}
|
||||||
return clean
|
return clean
|
||||||
}
|
}
|
||||||
|
|
||||||
function andCommaConcat(lst){
|
function andCommaConcat (lst) {
|
||||||
const tot = lst.length
|
const tot = lst.length
|
||||||
let result = ""
|
let result = ''
|
||||||
lst.forEach((art, i) => {
|
lst.forEach((art, i) => {
|
||||||
result += art
|
result += art
|
||||||
if (tot != i+1){
|
if (tot !== i + 1) {
|
||||||
if (tot - 1 == i+1){
|
if (tot - 1 === i + 1) {
|
||||||
result += " & "
|
result += ' & '
|
||||||
} else {
|
} else {
|
||||||
result += ", "
|
result += ', '
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
function uniqueArray(arr){
|
function uniqueArray (arr) {
|
||||||
arr.forEach((namePrinc, iPrinc) => {
|
arr.forEach((namePrinc, iPrinc) => {
|
||||||
arr.forEach((nameRest, iRest) => {
|
arr.forEach((nameRest, iRest) => {
|
||||||
if (iPrinc != iRest && nameRest.toLowerCase().includes(namePrinc.toLowerCase())){
|
if (iPrinc !== iRest && nameRest.toLowerCase().includes(namePrinc.toLowerCase())) {
|
||||||
arr.splice(iRest, 1)
|
arr.splice(iRest, 1)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -93,13 +91,13 @@ function uniqueArray(arr){
|
|||||||
return arr
|
return arr
|
||||||
}
|
}
|
||||||
|
|
||||||
function shellEscape(s){
|
function shellEscape (s) {
|
||||||
if (typeof s !== 'string') return ''
|
if (typeof s !== 'string') return ''
|
||||||
if (!(/[^\w@%+=:,./-]/g.test(s))) return s
|
if (!(/[^\w@%+=:,./-]/g.test(s))) return s
|
||||||
return "'" + s.replaceAll("'", "'\"'\"'") + "'"
|
return "'" + s.replaceAll("'", "'\"'\"'") + "'"
|
||||||
}
|
}
|
||||||
|
|
||||||
function removeDuplicateArtists(artist, artists){
|
function removeDuplicateArtists (artist, artists) {
|
||||||
artists = uniqueArray(artists)
|
artists = uniqueArray(artists)
|
||||||
Object.keys(artist).forEach((role) => {
|
Object.keys(artist).forEach((role) => {
|
||||||
artist[role] = uniqueArray(artist[role])
|
artist[role] = uniqueArray(artist[role])
|
||||||
@@ -107,55 +105,55 @@ function removeDuplicateArtists(artist, artists){
|
|||||||
return [artist, artists]
|
return [artist, artists]
|
||||||
}
|
}
|
||||||
|
|
||||||
function formatListener(key, data){
|
function formatListener (key, data) {
|
||||||
let message = ""
|
let message = ''
|
||||||
switch (key) {
|
switch (key) {
|
||||||
case "startAddingArtist": return `Started gathering ${data.name}'s albums (${data.id})`
|
case 'startAddingArtist': return `Started gathering ${data.name}'s albums (${data.id})`
|
||||||
case "finishAddingArtist": return `Finished gathering ${data.name}'s albums (${data.id})`
|
case 'finishAddingArtist': return `Finished gathering ${data.name}'s albums (${data.id})`
|
||||||
case "updateQueue":
|
case 'updateQueue':
|
||||||
message = `[${data['uuid']}]`
|
message = `[${data.uuid}]`
|
||||||
if (data.downloaded) message += ` Completed download of ${data.downloadPath.slice(data.extrasPath.length+1)}`
|
if (data.downloaded) message += ` Completed download of ${data.downloadPath.slice(data.extrasPath.length + 1)}`
|
||||||
if (data.failed) message += ` ${data.data.artist} - ${data.data.title} :: ${data.error}`
|
if (data.failed) message += ` ${data.data.artist} - ${data.data.title} :: ${data.error}`
|
||||||
if (data.progress) message += ` Download at ${data.progress}%`
|
if (data.progress) message += ` Download at ${data.progress}%`
|
||||||
if (data.conversion) message += ` Conversion at ${data.conversion}%`
|
if (data.conversion) message += ` Conversion at ${data.conversion}%`
|
||||||
return message
|
return message
|
||||||
case "downloadInfo":
|
case 'downloadInfo':
|
||||||
message = data.state
|
message = data.state
|
||||||
switch (data.state) {
|
switch (data.state) {
|
||||||
case "getTags": message = "Getting tags."; break;
|
case 'getTags': message = 'Getting tags.'; break
|
||||||
case "gotTags": message = "Tags got."; break;
|
case 'gotTags': message = 'Tags got.'; break
|
||||||
case "getBitrate": message = "Getting download URL."; break;
|
case 'getBitrate': message = 'Getting download URL.'; break
|
||||||
case "bitrateFallback": message = "Desired bitrate not found, falling back to lower bitrate."; break;
|
case 'bitrateFallback': message = 'Desired bitrate not found, falling back to lower bitrate.'; break
|
||||||
case "searchFallback": message = "This track has been searched for, result might not be 100% exact."; break;
|
case 'searchFallback': message = 'This track has been searched for, result might not be 100% exact.'; break
|
||||||
case "gotBitrate": message = "Download URL got."; break;
|
case 'gotBitrate': message = 'Download URL got.'; break
|
||||||
case "getAlbumArt": message = "Downloading album art."; break;
|
case 'getAlbumArt': message = 'Downloading album art.'; break
|
||||||
case "gotAlbumArt": message = "Album art downloaded."; break;
|
case 'gotAlbumArt': message = 'Album art downloaded.'; break
|
||||||
case "downloading":
|
case 'downloading':
|
||||||
message = "Downloading track.";
|
message = 'Downloading track.'
|
||||||
if (data.alreadyStarted) message += ` Recovering download from ${data.value}.`
|
if (data.alreadyStarted) message += ` Recovering download from ${data.value}.`
|
||||||
else message += ` Downloading ${data.value} bytes.`
|
else message += ` Downloading ${data.value} bytes.`
|
||||||
break;
|
break
|
||||||
case "downloadTimeout": message = "Deezer timedout when downloading track, retrying..."; break;
|
case 'downloadTimeout': message = 'Deezer timedout when downloading track, retrying...'; break
|
||||||
case "downloaded": message = "Track downloaded."; break;
|
case 'downloaded': message = 'Track downloaded.'; break
|
||||||
case "alreadyDownloaded": message = "Track already downloaded."; break;
|
case 'alreadyDownloaded': message = 'Track already downloaded.'; break
|
||||||
case "tagging": message = "Tagging track."; break;
|
case 'tagging': message = 'Tagging track.'; break
|
||||||
case "tagged": message = "Track tagged."; break;
|
case 'tagged': message = 'Track tagged.'; break
|
||||||
case "stderr": return `ExecuteCommand Error: ${data.data.stderr}`
|
case 'stderr': return `ExecuteCommand Error: ${data.data.stderr}`
|
||||||
case "stdout": return `ExecuteCommand Output: ${data.data.stdout}`
|
case 'stdout': return `ExecuteCommand Output: ${data.data.stdout}`
|
||||||
}
|
}
|
||||||
return `[${data.uuid}] ${data.data.artist} - ${data.data.title} :: ${message}`
|
return `[${data.uuid}] ${data.data.artist} - ${data.data.title} :: ${message}`
|
||||||
case "downloadWarn":
|
case 'downloadWarn':
|
||||||
message = `[${data.uuid}] ${data.data.artist} - ${data.data.title} :: ${ErrorMessages[data.state]} `
|
message = `[${data.uuid}] ${data.data.artist} - ${data.data.title} :: ${ErrorMessages[data.state]} `
|
||||||
switch (data.solution) {
|
switch (data.solution) {
|
||||||
case 'fallback': message += "Using fallback id."; break;
|
case 'fallback': message += 'Using fallback id.'; break
|
||||||
case 'search': message += "Searching for alternative."; break;
|
case 'search': message += 'Searching for alternative.'; break
|
||||||
}
|
}
|
||||||
return message
|
return message
|
||||||
case "currentItemCancelled": return `Current item cancelled (${data})`
|
case 'currentItemCancelled': return `Current item cancelled (${data})`
|
||||||
case "removedFromQueue": return `[${data}] Removed from the queue`
|
case 'removedFromQueue': return `[${data}] Removed from the queue`
|
||||||
case "finishDownload": return `[${data}] Finished downloading`
|
case 'finishDownload': return `[${data}] Finished downloading`
|
||||||
case "startConversion": return `[${data}] Started converting`
|
case 'startConversion': return `[${data}] Started converting`
|
||||||
case "finishConversion": return `[${data.uuid}] Finished converting`
|
case 'finishConversion': return `[${data.uuid}] Finished converting`
|
||||||
default: return message
|
default: return message
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,80 +3,80 @@ const { homedir } = require('os')
|
|||||||
const fs = require('fs')
|
const fs = require('fs')
|
||||||
const { canWrite } = require('./index.js')
|
const { canWrite } = require('./index.js')
|
||||||
|
|
||||||
let homedata = homedir()
|
const homedata = homedir()
|
||||||
let userdata = ""
|
let userdata = ''
|
||||||
let musicdata = ""
|
let musicdata = ''
|
||||||
|
|
||||||
function checkPath(path){
|
function checkPath (path) {
|
||||||
if (path === "") return ""
|
if (path === '') return ''
|
||||||
if (!fs.existsSync(path)) return ""
|
if (!fs.existsSync(path)) return ''
|
||||||
if (!canWrite(path)) return ""
|
if (!canWrite(path)) return ''
|
||||||
return path
|
return path
|
||||||
}
|
}
|
||||||
|
|
||||||
function getConfigFolder(){
|
function getConfigFolder () {
|
||||||
if (userdata != "") return userdata
|
if (userdata !== '') return userdata
|
||||||
if (process.env.XDG_CONFIG_HOME && userdata === ""){
|
if (process.env.XDG_CONFIG_HOME && userdata === '') {
|
||||||
userdata = `${process.env.XDG_CONFIG_HOME}${sep}`
|
userdata = `${process.env.XDG_CONFIG_HOME}${sep}`
|
||||||
userdata = checkPath(userdata)
|
userdata = checkPath(userdata)
|
||||||
}
|
}
|
||||||
if (process.env.APPDATA && userdata === ""){
|
if (process.env.APPDATA && userdata === '') {
|
||||||
userdata = `${process.env.APPDATA}${sep}`
|
userdata = `${process.env.APPDATA}${sep}`
|
||||||
userdata = checkPath(userdata)
|
userdata = checkPath(userdata)
|
||||||
}
|
}
|
||||||
if (process.platform == "darwin" && userdata === ""){
|
if (process.platform === 'darwin' && userdata === '') {
|
||||||
userdata = `${homedata}/Library/Application Support/`
|
userdata = `${homedata}/Library/Application Support/`
|
||||||
userdata = checkPath(userdata)
|
userdata = checkPath(userdata)
|
||||||
}
|
}
|
||||||
if (userdata === ""){
|
if (userdata === '') {
|
||||||
userdata = `${homedata}${sep}.config${sep}`
|
userdata = `${homedata}${sep}.config${sep}`
|
||||||
userdata = checkPath(userdata)
|
userdata = checkPath(userdata)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (userdata === "") userdata = `${process.cwd()}${sep}config${sep}`
|
if (userdata === '') userdata = `${process.cwd()}${sep}config${sep}`
|
||||||
else userdata += `deemix${sep}`
|
else userdata += `deemix${sep}`
|
||||||
|
|
||||||
if (process.env.DEEMIX_DATA_DIR) userdata = process.env.DEEMIX_DATA_DIR
|
if (process.env.DEEMIX_DATA_DIR) userdata = process.env.DEEMIX_DATA_DIR
|
||||||
return userdata
|
return userdata
|
||||||
}
|
}
|
||||||
|
|
||||||
function getMusicFolder(){
|
function getMusicFolder () {
|
||||||
if (musicdata != "") return musicdata
|
if (musicdata !== '') return musicdata
|
||||||
if (process.env.XDG_MUSIC_DIR && musicdata === ""){
|
if (process.env.XDG_MUSIC_DIR && musicdata === '') {
|
||||||
musicdata = `${process.env.XDG_MUSIC_DIR}${sep}`
|
musicdata = `${process.env.XDG_MUSIC_DIR}${sep}`
|
||||||
musicdata = checkPath(musicdata)
|
musicdata = checkPath(musicdata)
|
||||||
}
|
}
|
||||||
if (fs.existsSync(`${homedata}${sep}.config${sep}user-dirs.dirs`)){
|
if (fs.existsSync(`${homedata}${sep}.config${sep}user-dirs.dirs`)) {
|
||||||
const userDirs = fs.readFileSync(`${homedata}${sep}.config${sep}user-dirs.dirs`).toString()
|
const userDirs = fs.readFileSync(`${homedata}${sep}.config${sep}user-dirs.dirs`).toString()
|
||||||
musicdata = userDirs.match(/XDG_MUSIC_DIR="(.*)"/)[1]
|
musicdata = userDirs.match(/XDG_MUSIC_DIR="(.*)"/)[1]
|
||||||
musicdata = musicdata.replace(/\$([A-Z_]+[A-Z0-9_]*)/ig, (_, envName) => process.env[envName])
|
musicdata = musicdata.replace(/\$([A-Z_]+[A-Z0-9_]*)/ig, (_, envName) => process.env[envName])
|
||||||
musicdata += sep
|
musicdata += sep
|
||||||
musicdata = checkPath(musicdata)
|
musicdata = checkPath(musicdata)
|
||||||
}
|
}
|
||||||
if (process.platform == 'win32' && musicdata === ""){
|
if (process.platform === 'win32' && musicdata === '') {
|
||||||
try {
|
try {
|
||||||
const { execSync } = require('child_process')
|
const { execSync } = require('child_process')
|
||||||
const musicKeys = ["My Music", "{4BD8D571-6D19-48D3-BE97-422220080E43}"]
|
const musicKeys = ['My Music', '{4BD8D571-6D19-48D3-BE97-422220080E43}']
|
||||||
let regData = execSync('reg.exe query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"').toString().split('\r\n')
|
const regData = execSync('reg.exe query "HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\Shell Folders"').toString().split('\r\n')
|
||||||
for (let i = 0; i < regData.length; i++){
|
for (let i = 0; i < regData.length; i++) {
|
||||||
let line = regData[i]
|
let line = regData[i]
|
||||||
if (line === "") continue
|
if (line === '') continue
|
||||||
if (i == 1) continue
|
if (i === 1) continue
|
||||||
line = line.split(' ')
|
line = line.split(' ')
|
||||||
if (musicKeys.includes(line[1])){
|
if (musicKeys.includes(line[1])) {
|
||||||
musicdata = line[3] + sep
|
musicdata = line[3] + sep
|
||||||
break;
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
musicdata = checkPath(musicdata)
|
musicdata = checkPath(musicdata)
|
||||||
} catch {/* empty */}
|
} catch { /* empty */ }
|
||||||
}
|
}
|
||||||
if (musicdata === ""){
|
if (musicdata === '') {
|
||||||
musicdata = `${homedata}${sep}Music${sep}`
|
musicdata = `${homedata}${sep}Music${sep}`
|
||||||
musicdata = checkPath(musicdata)
|
musicdata = checkPath(musicdata)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (musicdata === "") musicdata = `${process.cwd()}${sep}music${sep}`
|
if (musicdata === '') musicdata = `${process.cwd()}${sep}music${sep}`
|
||||||
else musicdata += `deemix Music${sep}`
|
else musicdata += `deemix Music${sep}`
|
||||||
|
|
||||||
if (process.env.DEEMIX_MUSIC_DIR) musicdata = process.env.DEEMIX_MUSIC_DIR
|
if (process.env.DEEMIX_MUSIC_DIR) musicdata = process.env.DEEMIX_MUSIC_DIR
|
||||||
|
|||||||
@@ -2,26 +2,26 @@ const { TrackFormats } = require('deezer-js')
|
|||||||
const { Date: dzDate } = require('../types/Date.js')
|
const { Date: dzDate } = require('../types/Date.js')
|
||||||
|
|
||||||
const bitrateLabels = {
|
const bitrateLabels = {
|
||||||
[TrackFormats.MP4_RA3]: "360 HQ",
|
[TrackFormats.MP4_RA3]: '360 HQ',
|
||||||
[TrackFormats.MP4_RA2]: "360 MQ",
|
[TrackFormats.MP4_RA2]: '360 MQ',
|
||||||
[TrackFormats.MP4_RA1]: "360 LQ",
|
[TrackFormats.MP4_RA1]: '360 LQ',
|
||||||
[TrackFormats.FLAC] : "FLAC",
|
[TrackFormats.FLAC]: 'FLAC',
|
||||||
[TrackFormats.MP3_320]: "320",
|
[TrackFormats.MP3_320]: '320',
|
||||||
[TrackFormats.MP3_128]: "128",
|
[TrackFormats.MP3_128]: '128',
|
||||||
[TrackFormats.DEFAULT]: "128",
|
[TrackFormats.DEFAULT]: '128',
|
||||||
[TrackFormats.LOCAL] : "MP3"
|
[TrackFormats.LOCAL]: 'MP3'
|
||||||
}
|
}
|
||||||
|
|
||||||
function fixName(txt, char='_'){
|
function fixName (txt, char = '_') {
|
||||||
txt = txt+""
|
txt = txt + ''
|
||||||
txt = txt.replace(/[\0/\\:*?"<>|]/g, char)
|
txt = txt.replace(/[\0/\\:*?"<>|]/g, char)
|
||||||
return txt.normalize('NFC')
|
return txt.normalize('NFC')
|
||||||
}
|
}
|
||||||
|
|
||||||
function fixLongName(name){
|
function fixLongName (name) {
|
||||||
if (name.includes('/')){
|
if (name.includes('/')) {
|
||||||
let sepName = name.split('/')
|
const sepName = name.split('/')
|
||||||
name = ""
|
name = ''
|
||||||
sepName.forEach((txt) => {
|
sepName.forEach((txt) => {
|
||||||
txt = fixLongName(txt)
|
txt = fixLongName(txt)
|
||||||
name += `${txt}/`
|
name += `${txt}/`
|
||||||
@@ -33,37 +33,37 @@ function fixLongName(name){
|
|||||||
return name
|
return name
|
||||||
}
|
}
|
||||||
|
|
||||||
function antiDot(str){
|
function antiDot (str) {
|
||||||
while(str[str.length-1] == "." || str[str.length-1] == " " || str[str.length-1] == "\n"){
|
while (str[str.length - 1] === '.' || str[str.length - 1] === ' ' || str[str.length - 1] === '\n') {
|
||||||
str = str.slice(0,-1)
|
str = str.slice(0, -1)
|
||||||
}
|
|
||||||
if(str.length < 1){
|
|
||||||
str = "dot"
|
|
||||||
}
|
|
||||||
return str
|
|
||||||
}
|
|
||||||
|
|
||||||
function pad(num, max_val, settings) {
|
|
||||||
let paddingSize;
|
|
||||||
if (parseInt(settings.paddingSize) == 0) {
|
|
||||||
paddingSize = (max_val+"").length
|
|
||||||
} else{
|
|
||||||
paddingSize = ((10 ** (parseInt(settings.paddingSize) - 1))+"").length
|
|
||||||
}
|
}
|
||||||
if (settings.padSingleDigit && paddingSize == 1) paddingSize = 2
|
if (str.length < 1) {
|
||||||
|
str = 'dot'
|
||||||
if (settings.padTracks) return (num+"").padStart(paddingSize, "0")
|
}
|
||||||
return (num+"")
|
return str
|
||||||
}
|
}
|
||||||
|
|
||||||
function generatePath(track, downloadObject, settings){
|
function pad (num, max_val, settings) {
|
||||||
let filenameTemplate = "%artist% - %title%";
|
let paddingSize
|
||||||
|
if (parseInt(settings.paddingSize) === 0) {
|
||||||
|
paddingSize = (max_val + '').length
|
||||||
|
} else {
|
||||||
|
paddingSize = ((10 ** (parseInt(settings.paddingSize) - 1)) + '').length
|
||||||
|
}
|
||||||
|
if (settings.padSingleDigit && paddingSize === 1) paddingSize = 2
|
||||||
|
|
||||||
|
if (settings.padTracks) return (num + '').padStart(paddingSize, '0')
|
||||||
|
return (num + '')
|
||||||
|
}
|
||||||
|
|
||||||
|
function generatePath (track, downloadObject, settings) {
|
||||||
|
let filenameTemplate = '%artist% - %title%'
|
||||||
let singleTrack = false
|
let singleTrack = false
|
||||||
if (downloadObject.type === "track"){
|
if (downloadObject.type === 'track') {
|
||||||
if (settings.createSingleFolder) filenameTemplate = settings.albumTracknameTemplate
|
if (settings.createSingleFolder) filenameTemplate = settings.albumTracknameTemplate
|
||||||
else filenameTemplate = settings.tracknameTemplate
|
else filenameTemplate = settings.tracknameTemplate
|
||||||
singleTrack = true
|
singleTrack = true
|
||||||
} else if (downloadObject.type === "album") {
|
} else if (downloadObject.type === 'album') {
|
||||||
filenameTemplate = settings.albumTracknameTemplate
|
filenameTemplate = settings.albumTracknameTemplate
|
||||||
} else {
|
} else {
|
||||||
filenameTemplate = settings.playlistTracknameTemplate
|
filenameTemplate = settings.playlistTracknameTemplate
|
||||||
@@ -72,31 +72,28 @@ function generatePath(track, downloadObject, settings){
|
|||||||
let filename = generateTrackName(filenameTemplate, track, settings)
|
let filename = generateTrackName(filenameTemplate, track, settings)
|
||||||
let filepath, artistPath, coverPath, extrasPath
|
let filepath, artistPath, coverPath, extrasPath
|
||||||
|
|
||||||
filepath = settings.downloadLocation || "."
|
filepath = settings.downloadLocation || '.'
|
||||||
|
|
||||||
if (settings.createPlaylistFolder && track.playlist && !settings.tags.savePlaylistAsCompilation)
|
if (settings.createPlaylistFolder && track.playlist && !settings.tags.savePlaylistAsCompilation) { filepath += `/${generatePlaylistName(settings.playlistNameTemplate, track.playlist, settings)}` }
|
||||||
filepath += `/${generatePlaylistName(settings.playlistNameTemplate, track.playlist, settings)}`
|
|
||||||
|
|
||||||
if (track.playlist && !settings.tags.savePlaylistAsCompilation)
|
if (track.playlist && !settings.tags.savePlaylistAsCompilation) { extrasPath = filepath }
|
||||||
extrasPath = filepath
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
(settings.createArtistFolder && !track.playlist) ||
|
(settings.createArtistFolder && !track.playlist) ||
|
||||||
(settings.createArtistFolder && track.playlist && settings.tags.savePlaylistAsCompilation) ||
|
(settings.createArtistFolder && track.playlist && settings.tags.savePlaylistAsCompilation) ||
|
||||||
(settings.createArtistFolder && track.playlist && settings.createStructurePlaylist)
|
(settings.createArtistFolder && track.playlist && settings.createStructurePlaylist)
|
||||||
){
|
) {
|
||||||
filepath += `/${generateArtistName(settings.artistNameTemplate, track.album.mainArtist, settings, track.album.rootArtist)}`
|
filepath += `/${generateArtistName(settings.artistNameTemplate, track.album.mainArtist, settings, track.album.rootArtist)}`
|
||||||
artistPath = filepath
|
artistPath = filepath
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
if (settings.createAlbumFolder &&
|
if (settings.createAlbumFolder &&
|
||||||
(!singleTrack || singleTrack && settings.createSingleFolder) &&
|
(!singleTrack || (singleTrack && settings.createSingleFolder)) &&
|
||||||
(!track.playlist ||
|
(!track.playlist ||
|
||||||
(track.playlist && settings.tags.savePlaylistAsCompilation) ||
|
(track.playlist && settings.tags.savePlaylistAsCompilation) ||
|
||||||
(track.playlist && settings.createStructurePlaylist)
|
(track.playlist && settings.createStructurePlaylist)
|
||||||
)
|
)
|
||||||
){
|
) {
|
||||||
filepath += `/${generateAlbumName(settings.albumNameTemplate, track.album, settings, track.playlist)}`
|
filepath += `/${generateAlbumName(settings.albumNameTemplate, track.album, settings, track.playlist)}`
|
||||||
coverPath = filepath
|
coverPath = filepath
|
||||||
}
|
}
|
||||||
@@ -107,18 +104,15 @@ function generatePath(track, downloadObject, settings){
|
|||||||
parseInt(track.album.discTotal) > 1 && (
|
parseInt(track.album.discTotal) > 1 && (
|
||||||
(settings.createAlbumFolder && settings.createCDFolder) &&
|
(settings.createAlbumFolder && settings.createCDFolder) &&
|
||||||
(!singleTrack || (singleTrack && settings.createSingleFolder)) &&
|
(!singleTrack || (singleTrack && settings.createSingleFolder)) &&
|
||||||
(!track.playlist ||
|
((!track.playlist || (track.playlist && settings.tags.savePlaylistAsCompilation)) || (track.playlist && settings.createStructurePlaylist))
|
||||||
(track.playlist && settings.tags.savePlaylistAsCompilation)) ||
|
|
||||||
(track.playlist && settings.createStructurePlaylist)
|
|
||||||
)
|
)
|
||||||
)
|
) { filepath += `/CD${track.discNumber}` }
|
||||||
filepath += `/CD${track.discNumber}`
|
|
||||||
|
|
||||||
// Remove Subfolders from filename and add it to filepath
|
// Remove Subfolders from filename and add it to filepath
|
||||||
if (filename.includes('/')){
|
if (filename.includes('/')) {
|
||||||
let tempPath = filename.slice(0, filename.indexOf('/'))
|
const tempPath = filename.slice(0, filename.indexOf('/'))
|
||||||
filepath += `/${tempPath}`
|
filepath += `/${tempPath}`
|
||||||
filename = filename.slice(tempPath.length+1)
|
filename = filename.slice(tempPath.length + 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
return {
|
return {
|
||||||
@@ -130,121 +124,121 @@ function generatePath(track, downloadObject, settings){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateTrackName(filename, track, settings){
|
function generateTrackName (filename, track, settings) {
|
||||||
let c = settings.illegalCharacterReplacer
|
const c = settings.illegalCharacterReplacer
|
||||||
filename = filename.replaceAll("%title%", fixName(track.title, c))
|
filename = filename.replaceAll('%title%', fixName(track.title, c))
|
||||||
filename = filename.replaceAll("%artist%", fixName(track.mainArtist.name, c))
|
filename = filename.replaceAll('%artist%', fixName(track.mainArtist.name, c))
|
||||||
filename = filename.replaceAll("%artists%", fixName(track.artists.join(", "), c))
|
filename = filename.replaceAll('%artists%', fixName(track.artists.join(', '), c))
|
||||||
filename = filename.replaceAll("%tagsartists%", fixName(track.artistsString, c))
|
filename = filename.replaceAll('%tagsartists%', fixName(track.artistsString, c))
|
||||||
filename = filename.replaceAll("%allartists%", fixName(track.fullArtistsString, c))
|
filename = filename.replaceAll('%allartists%', fixName(track.fullArtistsString, c))
|
||||||
filename = filename.replaceAll("%mainartists%", fixName(track.mainArtistsString, c))
|
filename = filename.replaceAll('%mainartists%', fixName(track.mainArtistsString, c))
|
||||||
if (track.featArtistsString) filename = filename.replaceAll("%featartists%", fixName('('+track.featArtistsString+')', c))
|
if (track.featArtistsString) filename = filename.replaceAll('%featartists%', fixName('(' + track.featArtistsString + ')', c))
|
||||||
else filename = filename.replaceAll(" %featartists%", '').replaceAll("%featartists%", '')
|
else filename = filename.replaceAll(' %featartists%', '').replaceAll('%featartists%', '')
|
||||||
filename = filename.replaceAll("%album%", fixName(track.album.title, c))
|
filename = filename.replaceAll('%album%', fixName(track.album.title, c))
|
||||||
filename = filename.replaceAll("%albumartist%", fixName(track.album.mainArtist.name, c))
|
filename = filename.replaceAll('%albumartist%', fixName(track.album.mainArtist.name, c))
|
||||||
filename = filename.replaceAll("%tracknumber%", pad(track.trackNumber, track.album.trackTotal, settings))
|
filename = filename.replaceAll('%tracknumber%', pad(track.trackNumber, track.album.trackTotal, settings))
|
||||||
filename = filename.replaceAll("%tracktotal%", track.album.trackTotal)
|
filename = filename.replaceAll('%tracktotal%', track.album.trackTotal)
|
||||||
filename = filename.replaceAll("%discnumber%", track.discNumber)
|
filename = filename.replaceAll('%discnumber%', track.discNumber)
|
||||||
filename = filename.replaceAll("%disctotal%", track.album.discTotal)
|
filename = filename.replaceAll('%disctotal%', track.album.discTotal)
|
||||||
if (track.album.genre.length) filename = filename.replaceAll("%genre%", fixName(track.album.genre[0], c))
|
if (track.album.genre.length) filename = filename.replaceAll('%genre%', fixName(track.album.genre[0], c))
|
||||||
else filename = filename.replaceAll("%genre%", "Unknown")
|
else filename = filename.replaceAll('%genre%', 'Unknown')
|
||||||
filename = filename.replaceAll("%year%", track.date.year)
|
filename = filename.replaceAll('%year%', track.date.year)
|
||||||
filename = filename.replaceAll("%date%", track.dateString)
|
filename = filename.replaceAll('%date%', track.dateString)
|
||||||
filename = filename.replaceAll("%bpm%", track.bpm)
|
filename = filename.replaceAll('%bpm%', track.bpm)
|
||||||
filename = filename.replaceAll("%label%", fixName(track.album.label, c))
|
filename = filename.replaceAll('%label%', fixName(track.album.label, c))
|
||||||
filename = filename.replaceAll("%isrc%", track.ISRC)
|
filename = filename.replaceAll('%isrc%', track.ISRC)
|
||||||
filename = filename.replaceAll("%upc%", track.album.barcode)
|
filename = filename.replaceAll('%upc%', track.album.barcode)
|
||||||
if (track.explicit) filename = filename.replaceAll("%explicit%", "(Explicit)")
|
if (track.explicit) filename = filename.replaceAll('%explicit%', '(Explicit)')
|
||||||
else filename = filename.replaceAll(" %explicit%", "").replaceAll("%explicit%", "")
|
else filename = filename.replaceAll(' %explicit%', '').replaceAll('%explicit%', '')
|
||||||
|
|
||||||
filename = filename.replaceAll("%track_id%", track.id)
|
filename = filename.replaceAll('%track_id%', track.id)
|
||||||
filename = filename.replaceAll("%album_id%", track.album.id)
|
filename = filename.replaceAll('%album_id%', track.album.id)
|
||||||
filename = filename.replaceAll("%artist_id%", track.mainArtist.id)
|
filename = filename.replaceAll('%artist_id%', track.mainArtist.id)
|
||||||
if (track.playlist){
|
if (track.playlist) {
|
||||||
filename = filename.replaceAll("%playlist_id%", track.playlist.playlistID)
|
filename = filename.replaceAll('%playlist_id%', track.playlist.playlistID)
|
||||||
filename = filename.replaceAll("%position%", pad(track.position, track.playlist.trackTotal, settings))
|
filename = filename.replaceAll('%position%', pad(track.position, track.playlist.trackTotal, settings))
|
||||||
} else {
|
} else {
|
||||||
filename = filename.replaceAll("%playlist_id%", '')
|
filename = filename.replaceAll('%playlist_id%', '')
|
||||||
filename = filename.replaceAll("%position%", pad(track.trackNumber, track.album.trackTotal, settings))
|
filename = filename.replaceAll('%position%', pad(track.trackNumber, track.album.trackTotal, settings))
|
||||||
}
|
}
|
||||||
filename = filename.replaceAll('\\', '/')
|
filename = filename.replaceAll('\\', '/')
|
||||||
return antiDot(fixLongName(filename))
|
return antiDot(fixLongName(filename))
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateAlbumName(foldername, album, settings, playlist){
|
function generateAlbumName (foldername, album, settings, playlist) {
|
||||||
let c = settings.illegalCharacterReplacer
|
const c = settings.illegalCharacterReplacer
|
||||||
if (playlist && settings.tags.savePlaylistAsCompilation){
|
if (playlist && settings.tags.savePlaylistAsCompilation) {
|
||||||
foldername = foldername.replaceAll("%album_id%", "pl_" + playlist.playlistID)
|
foldername = foldername.replaceAll('%album_id%', 'pl_' + playlist.playlistID)
|
||||||
foldername = foldername.replaceAll("%genre%", "Compile")
|
foldername = foldername.replaceAll('%genre%', 'Compile')
|
||||||
} else {
|
} else {
|
||||||
foldername = foldername.replaceAll("%album_id%", album.id)
|
foldername = foldername.replaceAll('%album_id%', album.id)
|
||||||
if (album.genre.length) foldername = foldername.replaceAll("%genre%", fixName(album.genre[0], c))
|
if (album.genre.length) foldername = foldername.replaceAll('%genre%', fixName(album.genre[0], c))
|
||||||
else foldername = foldername.replaceAll("%genre%", "Unknown")
|
else foldername = foldername.replaceAll('%genre%', 'Unknown')
|
||||||
}
|
}
|
||||||
foldername = foldername.replaceAll("%album%", fixName(album.title, c))
|
foldername = foldername.replaceAll('%album%', fixName(album.title, c))
|
||||||
foldername = foldername.replaceAll("%artist%", fixName(album.mainArtist.name, c))
|
foldername = foldername.replaceAll('%artist%', fixName(album.mainArtist.name, c))
|
||||||
foldername = foldername.replaceAll("%artists%", fixName(album.artists.join(", "), c))
|
foldername = foldername.replaceAll('%artists%', fixName(album.artists.join(', '), c))
|
||||||
foldername = foldername.replaceAll("%artist_id%", album.mainArtist.id)
|
foldername = foldername.replaceAll('%artist_id%', album.mainArtist.id)
|
||||||
if (album.rootArtist){
|
if (album.rootArtist) {
|
||||||
foldername = foldername.replaceAll("%root_artist%", fixName(album.rootArtist.name, c))
|
foldername = foldername.replaceAll('%root_artist%', fixName(album.rootArtist.name, c))
|
||||||
foldername = foldername.replaceAll("%root_artist_id%", album.rootArtist.id)
|
foldername = foldername.replaceAll('%root_artist_id%', album.rootArtist.id)
|
||||||
} else {
|
} else {
|
||||||
foldername = foldername.replaceAll("%root_artist%", fixName(album.mainArtist.name, c))
|
foldername = foldername.replaceAll('%root_artist%', fixName(album.mainArtist.name, c))
|
||||||
foldername = foldername.replaceAll("%root_artist_id%", album.mainArtist.id)
|
foldername = foldername.replaceAll('%root_artist_id%', album.mainArtist.id)
|
||||||
}
|
}
|
||||||
foldername = foldername.replaceAll("%tracktotal%", album.trackTotal)
|
foldername = foldername.replaceAll('%tracktotal%', album.trackTotal)
|
||||||
foldername = foldername.replaceAll("%disctotal%", album.discTotal)
|
foldername = foldername.replaceAll('%disctotal%', album.discTotal)
|
||||||
foldername = foldername.replaceAll("%type%", fixName(album.recordType.charAt(0).toUpperCase() + album.recordType.slice(1), c))
|
foldername = foldername.replaceAll('%type%', fixName(album.recordType.charAt(0).toUpperCase() + album.recordType.slice(1), c))
|
||||||
foldername = foldername.replaceAll("%upc%", album.barcode)
|
foldername = foldername.replaceAll('%upc%', album.barcode)
|
||||||
foldername = foldername.replaceAll("%explicit%", album.explicit ? "(Explicit)" : "")
|
foldername = foldername.replaceAll('%explicit%', album.explicit ? '(Explicit)' : '')
|
||||||
foldername = foldername.replaceAll("%label%", fixName(album.label, c))
|
foldername = foldername.replaceAll('%label%', fixName(album.label, c))
|
||||||
foldername = foldername.replaceAll("%year%", album.date.year)
|
foldername = foldername.replaceAll('%year%', album.date.year)
|
||||||
foldername = foldername.replaceAll("%date%", album.dateString)
|
foldername = foldername.replaceAll('%date%', album.dateString)
|
||||||
foldername = foldername.replaceAll("%bitrate%", bitrateLabels[parseInt(album.bitrate)])
|
foldername = foldername.replaceAll('%bitrate%', bitrateLabels[parseInt(album.bitrate)])
|
||||||
|
|
||||||
foldername = foldername.replaceAll('\\', '/')
|
foldername = foldername.replaceAll('\\', '/')
|
||||||
return antiDot(fixLongName(foldername))
|
return antiDot(fixLongName(foldername))
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateArtistName(foldername, artist, settings, rootArtist){
|
function generateArtistName (foldername, artist, settings, rootArtist) {
|
||||||
let c = settings['illegalCharacterReplacer']
|
const c = settings.illegalCharacterReplacer
|
||||||
foldername = foldername.replaceAll("%artist%", fixName(artist.name, c))
|
foldername = foldername.replaceAll('%artist%', fixName(artist.name, c))
|
||||||
foldername = foldername.replaceAll("%artist_id%", artist.id)
|
foldername = foldername.replaceAll('%artist_id%', artist.id)
|
||||||
if (rootArtist){
|
if (rootArtist) {
|
||||||
foldername = foldername.replaceAll("%root_artist%", fixName(rootArtist.name, c))
|
foldername = foldername.replaceAll('%root_artist%', fixName(rootArtist.name, c))
|
||||||
foldername = foldername.replaceAll("%root_artist_id%", rootArtist.id)
|
foldername = foldername.replaceAll('%root_artist_id%', rootArtist.id)
|
||||||
} else {
|
} else {
|
||||||
foldername = foldername.replaceAll("%root_artist%", fixName(artist.name, c))
|
foldername = foldername.replaceAll('%root_artist%', fixName(artist.name, c))
|
||||||
foldername = foldername.replaceAll("%root_artist_id%", artist.id)
|
foldername = foldername.replaceAll('%root_artist_id%', artist.id)
|
||||||
}
|
}
|
||||||
foldername = foldername.replaceAll('\\', '/')
|
foldername = foldername.replaceAll('\\', '/')
|
||||||
return antiDot(fixLongName(foldername))
|
return antiDot(fixLongName(foldername))
|
||||||
}
|
}
|
||||||
|
|
||||||
function generatePlaylistName(foldername, playlist, settings){
|
function generatePlaylistName (foldername, playlist, settings) {
|
||||||
let c = settings['illegalCharacterReplacer']
|
const c = settings.illegalCharacterReplacer
|
||||||
let today = new Date()
|
const today = new Date()
|
||||||
let today_dz = new dzDate(String(today.getDate()).padStart(2, '0'), String(today.getMonth()+1).padStart(2, '0'), String(today.getFullYear()))
|
const today_dz = new dzDate(String(today.getDate()).padStart(2, '0'), String(today.getMonth() + 1).padStart(2, '0'), String(today.getFullYear()))
|
||||||
foldername = foldername.replaceAll("%playlist%", fixName(playlist.title, c))
|
foldername = foldername.replaceAll('%playlist%', fixName(playlist.title, c))
|
||||||
foldername = foldername.replaceAll("%playlist_id%", fixName(playlist.playlistID, c))
|
foldername = foldername.replaceAll('%playlist_id%', fixName(playlist.playlistID, c))
|
||||||
foldername = foldername.replaceAll("%owner%", fixName(playlist.owner['name'], c))
|
foldername = foldername.replaceAll('%owner%', fixName(playlist.owner.name, c))
|
||||||
foldername = foldername.replaceAll("%owner_id%", playlist.owner['id'])
|
foldername = foldername.replaceAll('%owner_id%', playlist.owner.id)
|
||||||
foldername = foldername.replaceAll("%year%", playlist.date.year)
|
foldername = foldername.replaceAll('%year%', playlist.date.year)
|
||||||
foldername = foldername.replaceAll("%date%", playlist.dateString)
|
foldername = foldername.replaceAll('%date%', playlist.dateString)
|
||||||
foldername = foldername.replaceAll("%explicit%", playlist.explicit ? "(Explicit)" : "")
|
foldername = foldername.replaceAll('%explicit%', playlist.explicit ? '(Explicit)' : '')
|
||||||
foldername = foldername.replaceAll("%today%", today_dz.format(settings['dateFormat']))
|
foldername = foldername.replaceAll('%today%', today_dz.format(settings.dateFormat))
|
||||||
foldername = foldername.replaceAll('\\', '/')
|
foldername = foldername.replaceAll('\\', '/')
|
||||||
return antiDot(fixLongName(foldername))
|
return antiDot(fixLongName(foldername))
|
||||||
}
|
}
|
||||||
|
|
||||||
function generateDownloadObjectName(foldername, queueItem, settings){
|
function generateDownloadObjectName (foldername, queueItem, settings) {
|
||||||
let c = settings['illegalCharacterReplacer']
|
const c = settings.illegalCharacterReplacer
|
||||||
foldername = foldername.replaceAll("%title%", fixName(queueItem.title, c))
|
foldername = foldername.replaceAll('%title%', fixName(queueItem.title, c))
|
||||||
foldername = foldername.replaceAll("%artist%", fixName(queueItem.artist, c))
|
foldername = foldername.replaceAll('%artist%', fixName(queueItem.artist, c))
|
||||||
foldername = foldername.replaceAll("%size%", queueItem.size)
|
foldername = foldername.replaceAll('%size%', queueItem.size)
|
||||||
foldername = foldername.replaceAll("%type%", fixName(queueItem.type, c))
|
foldername = foldername.replaceAll('%type%', fixName(queueItem.type, c))
|
||||||
foldername = foldername.replaceAll("%id%", fixName(queueItem.id, c))
|
foldername = foldername.replaceAll('%id%', fixName(queueItem.id, c))
|
||||||
foldername = foldername.replaceAll("%bitrate%", bitrateLabels[parseInt(queueItem.bitrate)])
|
foldername = foldername.replaceAll('%bitrate%', bitrateLabels[parseInt(queueItem.bitrate)])
|
||||||
foldername = foldername.replaceAll('\\', '/').replace('/', c)
|
foldername = foldername.replaceAll('\\', '/').replace('/', c)
|
||||||
return antiDot(fixLongName(foldername))
|
return antiDot(fixLongName(foldername))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "deemix",
|
"name": "deemix",
|
||||||
"version": "3.6.17",
|
"version": "3.6.20",
|
||||||
"description": "a barebones deezer downloader library",
|
"description": "a barebones deezer downloader library",
|
||||||
"main": "deemix/index.js",
|
"main": "deemix/index.js",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
@@ -22,8 +22,5 @@
|
|||||||
"metaflac-js2": "^1.0.8",
|
"metaflac-js2": "^1.0.8",
|
||||||
"spotify-web-api-node": "../spotify-web-api-node",
|
"spotify-web-api-node": "../spotify-web-api-node",
|
||||||
"tough-cookie": "^4.0.0"
|
"tough-cookie": "^4.0.0"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"eslint": "^9.7.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"env": {
|
|
||||||
"commonjs": true,
|
|
||||||
"es2021": true,
|
|
||||||
"node": true
|
|
||||||
},
|
|
||||||
"extends": "eslint:recommended",
|
|
||||||
"parserOptions": {
|
|
||||||
"ecmaVersion": 12
|
|
||||||
},
|
|
||||||
"rules": {
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -15,8 +15,5 @@
|
|||||||
"dependencies": {
|
"dependencies": {
|
||||||
"got": "11.8.2",
|
"got": "11.8.2",
|
||||||
"tough-cookie": "^4.0.0"
|
"tough-cookie": "^4.0.0"
|
||||||
},
|
|
||||||
"devDependencies": {
|
|
||||||
"eslint": "^7.23.0"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1 +1 @@
|
|||||||
2024.7.31-r258.711fcec286
|
2024.8.2-r263.9ddd7fea0e
|
||||||
@@ -1 +0,0 @@
|
|||||||
dist/
|
|
||||||
@@ -1,16 +0,0 @@
|
|||||||
---
|
|
||||||
extends:
|
|
||||||
- "@nuxtjs"
|
|
||||||
- plugin:prettier/recommended
|
|
||||||
plugins:
|
|
||||||
- "@typescript-eslint"
|
|
||||||
parserOptions:
|
|
||||||
parser: "@typescript-eslint/parser"
|
|
||||||
rules:
|
|
||||||
"@typescript-eslint/no-unused-vars":
|
|
||||||
- error
|
|
||||||
- args: all
|
|
||||||
argsIgnorePattern: ^_
|
|
||||||
no-unused-vars: off
|
|
||||||
no-console: off
|
|
||||||
camelcase: off
|
|
||||||
@@ -1,8 +0,0 @@
|
|||||||
tabWidth: 2
|
|
||||||
printWidth: 120
|
|
||||||
useTabs: true
|
|
||||||
semi: false
|
|
||||||
singleQuote: true
|
|
||||||
bracketSpacing: true
|
|
||||||
arrowParens: avoid
|
|
||||||
trailingComma: none
|
|
||||||
@@ -6,10 +6,7 @@
|
|||||||
"start": "node dist/app.js",
|
"start": "node dist/app.js",
|
||||||
"build": "webpack --env production",
|
"build": "webpack --env production",
|
||||||
"sourcemap": "webpack --env production sourcemap",
|
"sourcemap": "webpack --env production sourcemap",
|
||||||
"prewatch": "pnpm lint-build",
|
|
||||||
"watch": "webpack --watch",
|
"watch": "webpack --watch",
|
||||||
"lint": "eslint \"./{src, tests}/**\" --fix",
|
|
||||||
"lint-build": "eslint \"./src/**\" --fix",
|
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test-watch": "jest --watch"
|
"test-watch": "jest --watch"
|
||||||
},
|
},
|
||||||
@@ -66,13 +63,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "29.5.12",
|
"@types/jest": "29.5.12",
|
||||||
"@types/supertest": "6.0.2",
|
"@types/supertest": "6.0.2",
|
||||||
"@typescript-eslint/eslint-plugin": "4.21.0",
|
|
||||||
"@typescript-eslint/parser": "4.21.0",
|
|
||||||
"eslint": "7.23.0",
|
|
||||||
"eslint-config-prettier": "^8.1.0",
|
|
||||||
"eslint-plugin-prettier": "^3.3.1",
|
|
||||||
"jest": "26.6.3",
|
"jest": "26.6.3",
|
||||||
"prettier": "2.2.1",
|
|
||||||
"supertest": "6.1.3",
|
"supertest": "6.1.3",
|
||||||
"ts-jest": "26.5.4",
|
"ts-jest": "26.5.4",
|
||||||
"ts-node": "9.1.1",
|
"ts-node": "9.1.1",
|
||||||
|
|||||||
@@ -21,7 +21,7 @@ export function loadLoginCredentials() {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
loginData = JSON.parse(fs.readFileSync(configFolder + 'login.json').toString())
|
loginData = JSON.parse(fs.readFileSync(configFolder + 'login.json').toString())
|
||||||
} catch (e) {
|
} catch (e:any) {
|
||||||
if (e.name === 'SyntaxError') resetLoginCredentials()
|
if (e.name === 'SyntaxError') resetLoginCredentials()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ const handler: ApiHandler['handler'] = async (req, res) => {
|
|||||||
let results
|
let results
|
||||||
try {
|
try {
|
||||||
results = await dz.gw.search(term)
|
results = await dz.gw.search(term)
|
||||||
} catch (e) {
|
} catch (e:any) {
|
||||||
results = { ...emptyResult }
|
results = { ...emptyResult }
|
||||||
results.QUERY = term
|
results.QUERY = term
|
||||||
results.ERROR = e.message
|
results.ERROR = e.message
|
||||||
|
|||||||
@@ -47,7 +47,7 @@ const handler: ApiHandler['handler'] = async (req, res) => {
|
|||||||
data = await dz.api.search(term, { limit: nb, index: start })
|
data = await dz.api.search(term, { limit: nb, index: start })
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (e:any) {
|
||||||
data = { ...emptyResult }
|
data = { ...emptyResult }
|
||||||
data.error = e.message
|
data.error = e.message
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,7 @@ const handler: ApiHandler['handler'] = async (req, res) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
obj = await deemix.addToQueue(dz, url, bitrate)
|
obj = await deemix.addToQueue(dz, url, bitrate)
|
||||||
} catch (e) {
|
} catch (e:any) {
|
||||||
res.send({ result: false, errid: e.name, data: { url, bitrate } })
|
res.send({ result: false, errid: e.name, data: { url, bitrate } })
|
||||||
switch (e.name) {
|
switch (e.name) {
|
||||||
case 'NotLoggedIn':
|
case 'NotLoggedIn':
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ const handler: ApiHandler['handler'] = async (req, res) => {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
obj = await deemix.addToQueue(dz, [url], bitrate, true)
|
obj = await deemix.addToQueue(dz, [url], bitrate, true)
|
||||||
} catch (e) {
|
} catch (e:any) {
|
||||||
res.send({ result: false, errid: e.name, data: { url, bitrate } })
|
res.send({ result: false, errid: e.name, data: { url, bitrate } })
|
||||||
switch (e.name) {
|
switch (e.name) {
|
||||||
case 'NotLoggedIn':
|
case 'NotLoggedIn':
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "spotify-web-api-node",
|
"name": "spotify-web-api-node",
|
||||||
"version": "5.0.3",
|
"version": "5.0.4",
|
||||||
"homepage": "https://github.com/thelinmichael/spotify-web-api-node",
|
"homepage": "https://github.com/thelinmichael/spotify-web-api-node",
|
||||||
"description": "A Node.js wrapper for Spotify's Web API",
|
"description": "A Node.js wrapper for Spotify's Web API",
|
||||||
"main": "./src/server.js",
|
"main": "./src/server.js",
|
||||||
@@ -29,12 +29,6 @@
|
|||||||
"verbose": true,
|
"verbose": true,
|
||||||
"testURL": "http://localhost/"
|
"testURL": "http://localhost/"
|
||||||
},
|
},
|
||||||
"lint-staged": {
|
|
||||||
"*.{js,json,css,md}": [
|
|
||||||
"prettier --single-quote --write",
|
|
||||||
"git add"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"superagent": "^6.1.0"
|
"superagent": "^6.1.0"
|
||||||
},
|
},
|
||||||
@@ -42,8 +36,6 @@
|
|||||||
"coveralls": "^3.1.0",
|
"coveralls": "^3.1.0",
|
||||||
"husky": "^4.3.0",
|
"husky": "^4.3.0",
|
||||||
"jest": "^26.6.3",
|
"jest": "^26.6.3",
|
||||||
"lint-staged": "^10.4.0",
|
|
||||||
"prettier": "^2.1.2",
|
|
||||||
"sinon": "^9.0.3",
|
"sinon": "^9.0.3",
|
||||||
"canvas": "^2.6.1",
|
"canvas": "^2.6.1",
|
||||||
"bufferutil": "^4.0.1",
|
"bufferutil": "^4.0.1",
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
'use strict'
|
'use strict'
|
||||||
|
|
||||||
const AuthenticationRequest = require('./authentication-request')
|
|
||||||
const WebApiRequest = require('./webapi-request')
|
const WebApiRequest = require('./webapi-request')
|
||||||
const HttpManager = require('./http-manager')
|
const HttpManager = require('./http-manager')
|
||||||
|
|
||||||
@@ -91,19 +90,11 @@ SpotifyWebApi.prototype = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
_getCredential: function (credentialKey) {
|
_getCredential: function (credentialKey) {
|
||||||
if (!this._credentials) {
|
return this._credentials[credentialKey]
|
||||||
|
|
||||||
} else {
|
|
||||||
return this._credentials[credentialKey]
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
_resetCredential: function (credentialKey) {
|
_resetCredential: function (credentialKey) {
|
||||||
if (!this._credentials) {
|
this._credentials[credentialKey] = null
|
||||||
|
|
||||||
} else {
|
|
||||||
this._credentials[credentialKey] = null
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,17 +0,0 @@
|
|||||||
---
|
|
||||||
extends:
|
|
||||||
- "@nuxtjs"
|
|
||||||
- plugin:prettier/recommended
|
|
||||||
plugins:
|
|
||||||
- "@typescript-eslint"
|
|
||||||
parserOptions:
|
|
||||||
parser: "@typescript-eslint/parser"
|
|
||||||
rules:
|
|
||||||
"@typescript-eslint/no-unused-vars":
|
|
||||||
- error
|
|
||||||
- args: all
|
|
||||||
argsIgnorePattern: ^_
|
|
||||||
no-unused-vars: off
|
|
||||||
no-console: off
|
|
||||||
camelcase: off
|
|
||||||
vue/no-v-html: off
|
|
||||||
@@ -1,10 +0,0 @@
|
|||||||
---
|
|
||||||
useTabs: true
|
|
||||||
tabWidth: 2
|
|
||||||
semi: false
|
|
||||||
singleQuote: true
|
|
||||||
bracketSpacing: true
|
|
||||||
trailingComma: none
|
|
||||||
printWidth: 120
|
|
||||||
arrowParens: avoid
|
|
||||||
vueIndentScriptAndStyle: false
|
|
||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "deemix-webui",
|
"name": "deemix-webui",
|
||||||
"version": "1.9.6",
|
"version": "1.9.7",
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"clean": "rimraf public/js/bundle.js public/js/bundle.temp.js public/js/bundle.js.map",
|
"clean": "rimraf public/js/bundle.js public/js/bundle.temp.js public/js/bundle.js.map",
|
||||||
"clean-temp": "rimraf public/js/bundle.temp.js",
|
"clean-temp": "rimraf public/js/bundle.temp.js",
|
||||||
@@ -11,8 +11,6 @@
|
|||||||
"watch:server": "pnpm -C ../server watch",
|
"watch:server": "pnpm -C ../server watch",
|
||||||
"watch:js": "rollup -c -w",
|
"watch:js": "rollup -c -w",
|
||||||
"dev": "npm-run-all --parallel watch:server watch:js",
|
"dev": "npm-run-all --parallel watch:server watch:js",
|
||||||
"lint": "eslint src/**/*.{js,vue,mjs} --fix",
|
|
||||||
"lint-tests": "eslint src/**/*.js --fix",
|
|
||||||
"test": "jest",
|
"test": "jest",
|
||||||
"test-watch": "jest --watch",
|
"test-watch": "jest --watch",
|
||||||
"testlang": "node ./tests/testlang.js"
|
"testlang": "node ./tests/testlang.js"
|
||||||
@@ -24,7 +22,7 @@
|
|||||||
"@rollup/plugin-replace": "3.0.0",
|
"@rollup/plugin-replace": "3.0.0",
|
||||||
"@vue/composition-api": "1.0.6",
|
"@vue/composition-api": "1.0.6",
|
||||||
"esbuild": "0.12.19",
|
"esbuild": "0.12.19",
|
||||||
"flag-icon-css": "3.5.0",
|
"flag-icon-css": "4.1.7",
|
||||||
"lodash-es": "4.17.21",
|
"lodash-es": "4.17.21",
|
||||||
"postcss": "8.4.39",
|
"postcss": "8.4.39",
|
||||||
"rollup": "2.56.1",
|
"rollup": "2.56.1",
|
||||||
@@ -43,18 +41,11 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@babel/core": "7.24.9",
|
"@babel/core": "7.24.9",
|
||||||
"@babel/plugin-transform-modules-commonjs": "7.24.8",
|
"@babel/plugin-transform-modules-commonjs": "7.24.8",
|
||||||
"@nuxtjs/eslint-config": "6.0.1",
|
|
||||||
"@types/jest": "26.0.24",
|
"@types/jest": "26.0.24",
|
||||||
"@types/node": "14.14.37",
|
"@types/node": "14.14.37",
|
||||||
"@typescript-eslint/eslint-plugin": "4.29.0",
|
|
||||||
"@typescript-eslint/parser": "4.29.0",
|
|
||||||
"babel-jest": "27.0.6",
|
"babel-jest": "27.0.6",
|
||||||
"eslint": "7.32.0",
|
|
||||||
"eslint-config-prettier": "8.3.0",
|
|
||||||
"eslint-plugin-prettier": "3.4.0",
|
|
||||||
"jest": "27.0.6",
|
"jest": "27.0.6",
|
||||||
"npm-run-all": "^4.1.5",
|
"npm-run-all": "^4.1.5",
|
||||||
"prettier": "2.3.2",
|
|
||||||
"rimraf": "3.0.2",
|
"rimraf": "3.0.2",
|
||||||
"typescript": "4.3.5",
|
"typescript": "4.3.5",
|
||||||
"vue-template-compiler": "2.6.14"
|
"vue-template-compiler": "2.6.14"
|
||||||
|
|||||||
@@ -37,6 +37,11 @@
|
|||||||
|
|
||||||
<h2>Changelog</h2>
|
<h2>Changelog</h2>
|
||||||
<ul class="no-dots" style="font-size: 15px;">
|
<ul class="no-dots" style="font-size: 15px;">
|
||||||
|
<h3>02/08/2024</h3>
|
||||||
|
- Removed outdated linters and formatters<br>
|
||||||
|
- Few fixes in API ts types<br>
|
||||||
|
- Removed Spotify UserName requirement and instructions from settings<br>
|
||||||
|
<br>
|
||||||
<h3>31/07/2024</h3>
|
<h3>31/07/2024</h3>
|
||||||
- Reverted to spotify-web-api-node<br>
|
- Reverted to spotify-web-api-node<br>
|
||||||
- Fixed (again) the Buffer method in spotify-web-api-node<br>
|
- Fixed (again) the Buffer method in spotify-web-api-node<br>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div id="home_tab">
|
<div id="home_tab">
|
||||||
<h1 class="mb-8 text-5xl">{{ $t('globals.welcome') }}</h1>
|
<h1 class="mb-8 text-5xl">{{ $t('globals.welcome') }}</h1>
|
||||||
Version published 31/07/2024, see About section for changelog.
|
Version published 02/08/2024, see About section for changelog.
|
||||||
<section v-if="!isLoggedIn" ref="notLogged" class="py-6 border-0 border-t border-solid border-grayscale-500">
|
<section v-if="!isLoggedIn" ref="notLogged" class="py-6 border-0 border-t border-solid border-grayscale-500">
|
||||||
<p id="home_not_logged_text" class="mb-4">{{ $t('home.needTologin') }}</p>
|
<p id="home_not_logged_text" class="mb-4">{{ $t('home.needTologin') }}</p>
|
||||||
<router-link custom v-slot="{ navigate }" class="btn btn-primary" name="button" :to="{ name: 'Settings' }">
|
<router-link custom v-slot="{ navigate }" class="btn btn-primary" name="button" :to="{ name: 'Settings' }">
|
||||||
|
|||||||
@@ -28,12 +28,12 @@
|
|||||||
</p>
|
</p>
|
||||||
<p class="mb-4 text-base">{{ $t('settings.spotify.howTo.clientSecretQuestion.step5') }}</p>
|
<p class="mb-4 text-base">{{ $t('settings.spotify.howTo.clientSecretQuestion.step5') }}</p>
|
||||||
|
|
||||||
<h2 class="mt-6 text-3xl">{{ $t('settings.spotify.howTo.usernameQuestion.title') }}</h2>
|
<!-- <h2 class="mt-6 text-3xl">{{ $t('settings.spotify.howTo.usernameQuestion.title') }}</h2>
|
||||||
<i18n path="settings.spotify.howTo.usernameQuestion.step1.text" tag="p" class="mb-4 text-base">
|
<i18n path="settings.spotify.howTo.usernameQuestion.step1.text" tag="p" class="mb-4 text-base">
|
||||||
<template #overviewPage>
|
<template #overviewPage>
|
||||||
<a href="https://www.spotify.com/it/account/overview/" target="_blank">{{ $t('settings.spotify.howTo.usernameQuestion.step1.overviewPage') }}</a>
|
<a href="https://www.spotify.com/it/account/overview/" target="_blank">{{ $t('settings.spotify.howTo.usernameQuestion.step1.overviewPage') }}</a>
|
||||||
</template>
|
</template>
|
||||||
</i18n>
|
</i18n> -->
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
|
|||||||
@@ -711,10 +711,10 @@
|
|||||||
<input v-model="spotifyFeatures.clientSecret" type="password" />
|
<input v-model="spotifyFeatures.clientSecret" type="password" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="input-group">
|
<!-- <div class="input-group">
|
||||||
<p class="input-group-text">{{ $t('settings.spotify.username') }}</p>
|
<p class="input-group-text">{{ $t('settings.spotify.username') }}</p>
|
||||||
<input v-model="spotifyUser" type="text" />
|
<input v-model="spotifyUser" type="text" />
|
||||||
</div>
|
</div> -->
|
||||||
|
|
||||||
<label class="with-checkbox">
|
<label class="with-checkbox">
|
||||||
<input v-model="spotifyFeatures.fallbackSearch" type="checkbox" />
|
<input v-model="spotifyFeatures.fallbackSearch" type="checkbox" />
|
||||||
|
|||||||
Reference in New Issue
Block a user