lx-music-desktop/src/renderer/utils/music/kw/util.js
2022-03-14 15:37:44 +08:00

159 lines
4.4 KiB
JavaScript

import { httpGet, httpFetch } from '../../request'
import { rendererInvoke, NAMES } from '@common/ipc'
const kw_token = {
token: null,
isGetingToken: false,
}
const translationMap = {
"{'": '{"',
"'}\n": '"}',
"'}": '"}',
"':'": '":"',
"','": '","',
"':{'": '":{"',
"':['": '":["',
"'}],'": '"}],"',
"':[{'": '":[{"',
"'},'": '"},"',
"'},{'": '"},{"',
"':[],'": '":[],"',
"':{},'": '":{},"',
}
export const objStr2JSON = str => {
return JSON.parse(str.replace(/(^{'|'}\n$|'}$|':'|','|':\[{'|'}\],'|':{'|'},'|'},{'|':\['|':\[\],'|':{},')/g, s => translationMap[s]))
}
export const formatSinger = rawData => rawData.replace(/&/g, '、')
export const matchToken = headers => {
try {
return headers['set-cookie'][0].match(/kw_token=(\w+)/)[1]
} catch (err) {
return null
}
}
const wait = time => new Promise(resolve => setTimeout(() => resolve(), time))
export const getToken = (retryNum = 0) => new Promise((resolve, reject) => {
if (retryNum > 2) return Promise.reject(new Error('try max num'))
if (kw_token.isGetingToken) return wait(1000).then(() => getToken(retryNum).then(token => resolve(token)))
if (kw_token.token) return resolve(kw_token.token)
kw_token.isGetingToken = true
httpGet('http://www.kuwo.cn/', (err, resp) => {
kw_token.isGetingToken = false
if (err) return getToken(++retryNum)
if (resp.statusCode != 200) return reject(new Error('获取失败'))
const token = kw_token.token = matchToken(resp.headers)
resolve(token)
})
})
export const decodeLyric = base64Data => rendererInvoke(NAMES.mainWindow.handle_kw_decode_lyric, base64Data)
export const tokenRequest = async(url, options = {}) => {
let token = kw_token.token
if (!token) token = await getToken()
if (!options.headers) {
options.headers = {
Referer: 'http://www.kuwo.cn/',
csrf: token,
cookie: 'kw_token=' + token,
}
}
const requestObj = httpFetch(url, options)
requestObj.promise = requestObj.promise.then(resp => {
// console.log(resp)
if (resp.statusCode == 200) {
kw_token.token = matchToken(resp.headers)
}
return resp
})
return requestObj
}
export const lrcTools = {
rxps: {
wordLine: /^(\[\d{1,2}:.*\d{1,4}\])\s*(\S+(?:\s+\S+)*)?\s*/,
tagLine: /\[(ver|ti|ar|al|by|kuwo):\s*(\S+(?:\s+\S+)*)\s*\]/,
wordTimeAll: /<(-?\d+),(-?\d+)(?:,-?\d+)?>/g,
wordTime: /<(-?\d+),(-?\d+)(?:,-?\d+)?>/,
},
offset: 1,
offset2: 1,
isOK: false,
lines: [],
tags: [],
getWordInfo(str, str2) {
const offset = parseInt(str)
const offset2 = parseInt(str2)
const startTime = Math.floor((offset + offset2) / (this.offset * 2))
const timeLength = Math.floor((offset - offset2) / (this.offset2 * 2))
return {
startTime,
timeLength,
}
},
parseLine(line) {
if (line.length < 6) return
let result = this.rxps.wordLine.exec(line)
if (result) {
const time = result[1]
let words = result[2]
if (words == null) {
words = ''
}
const wordTimes = words.match(this.rxps.wordTimeAll)
if (!wordTimes) return
// console.log(wordTimes)
for (const timeStr of wordTimes) {
const result = this.rxps.wordTime.exec(timeStr)
const wordInfo = this.getWordInfo(result[1], result[2])
words = words.replace(timeStr, `<${wordInfo.startTime},${wordInfo.timeLength}>`)
}
this.lines.push(time + words)
return
}
result = this.rxps.tagLine.exec(line)
if (!result) return
if (result[1] == 'kuwo') {
let content = result[2]
if (content != null && content.includes('][')) {
content = content.substring(0, content.indexOf(']['))
}
const valueOf = parseInt(content, 8)
this.offset = Math.floor(valueOf / 10)
this.offset2 = Math.floor(valueOf % 10)
if (this.offset == 0 || Number.isNaN(this.offset) || this.offset2 == 0 || Number.isNaN(this.offset2)) {
this.isOK = false
}
} else {
this.tags.push(line)
}
},
parse(lrc) {
// console.log(lrc)
const lines = lrc.split(/\r\n|\r|\n/)
const tools = Object.create(this)
tools.isOK = true
tools.offset = 1
tools.offset2 = 1
tools.lines = []
tools.tags = []
for (const line of lines) {
if (!tools.isOK) return ''
tools.parseLine(line)
}
if (!tools.lines.length) return ''
let lrcs = tools.lines.join('\n')
if (tools.tags.length) lrcs = `${tools.tags.join('\n')}\n${lrcs}`
return lrcs
},
}