2023-07-27 14:18:52 +08:00

245 lines
6.8 KiB
JavaScript

/**
*
* @param {String} prefix
* @returns {String}
*/
String.prototype.removePrefix = function (prefix) {
if (this.match('^' + prefix + '.*$')) {
return this.substring(prefix.length)
} else {
return this.toString()
}
}
/**
*
* @param {String} suffix
* @returns {String}
*/
String.prototype.removeSuffix = function (suffix) {
if (this.match('^.*' + suffix + '$')) {
return this.substring(0, prefix.length)
} else {
return this.toString()
}
}
function logOut(...any) {
console.log(...any);
}
/**
* @param commandLine{String}
*/
function convert(commandLine) {
cleanInfoBox()
const args = {
prefix: "",
/**
* @type {String[]}
*/
options: [
]
}
/**
* @type {String[]}
*/
let firstArgPos = commandLine.indexOf(' ', commandLine.indexOf('N_M3U8DL-CLI'))
args.prefix = commandLine.substring(0, firstArgPos)
let options = Array.from(commandLine.substring(firstArgPos).matchAll('(?:((?:[^"]|^)[\\S\s]+(?:[^"]|$)))|(?:"([^"]+)")')).map((e) => {
return (e[2] ? e[2] : e[1]).trim().removePrefix('--')
})
logOut(options);
class Element {
hasArg = false
_drop = false
replacer = (old) => ''
indexInc = (old) => { if (this.hasArg) return 1; else return 0 }
/**
* @param {Boolean} hasArg
* @param {Boolean|(old:String)=>Boolean} drop
* @param {(old:String)=>String|String} replacer
* @param {(old:String)=>number|undefined} inc
* */
constructor(hasArg, drop, replacer, inc) {
this.hasArg = hasArg
this._drop = drop
this.replacer = replacer
if (inc) {
this.indexInc = inc
}
}
drop(old) {
if (typeof this._drop == "boolean") {
return this._drop
} else
return this._drop(this.replacer(old))
}
}
let map = {
"workDir": new Element(
true, false, (old) => 'save-dir'
),
saveName: new Element(
true, false, (old) => 'save-name'
),
baseUrl: new Element(
true, false, (old) => 'base-url'
),
headers: new Element(
true, false, (old) => {
return old.split('|').map((kv) => {
return `--header ${kv.substring(0, kv.indexOf(':'))}: ${kv.substring(kv.indexOf(':'))}`
}).join(' ')
}
),
maxThreads: new Element(
true, (old) =>
args.options.includes('--thread-count')
, (old) => 'thread-count'
),
minThreads: new Element(
true, (old) =>
args.options.includes('--thread-count')
, (old) => 'thread-count'
),
retryCount: new Element(
true, false, (old) => 'download-retry-count'
),
timeOut: new Element(
true, true
),
muxSetJson: new Element(
true, true, (old) => 'mux-import'
),
useKeyFile: new Element(
true, false, (old) => 'custom-hls-key'
),
useKeyBase64: new Element(
true, false, (old) => 'custom-hls-key'
),
useKeyIV: new Element(
true, false, (old) => 'custom-hls-iv'
),
downloadRange: new Element(
true, false, (old) => 'custom-range'
),
liveRecDur: new Element(
true, false, (old) => 'live-record-limit'
),
stopSpeed: new Element(
true, true
),
maxSpeed: new Element(
true, true
),
proxyAddress: new Element(
true, false, (old) => 'custom-proxy'
),
enableDelAfterDone: new Element(
false, false, (old) => 'del-after-done'
),
enableMuxFastStart: new Element(
false, true, (old) => ''
),
enableBinaryMerge: new Element(
false, false, (old) => 'binary-merge'
),
enableParseOnly: new Element(
false, false, (old) => 'drop-audio .* drop-subtitle .*'
),
disableDateInfo: new Element(
false, false, (old) => 'no-date-info'
),
disableIntegrityCheck: new Element(
false, false, (old) => 'check-segments-count False'
),
noMerge: new Element(
false, false, (old) => 'skip-merge'
),
noProxy: new Element(
false, false, (old) => 'use-system-proxy False'
),
chaCha20KeyBase64: new Element(
true, true, (old) => ''
),
chaCha20NonceBase64: new Element(
true, true, (old) => ''
),
}
for (let i = 0; i < options.length; i++) {
const opt = options[i];
logOut(opt)
/**
* @type {Element}
*/
const ele = map[opt]
if (!ele) {
logOut(`${opt}(unknown)`)
writeInfo('--' + opt,'',"unknown",'unknown')
continue
}
let drop = ele.drop(opt)
if (drop) {
logOut(` --${opt}(drop)`);
} else {
args.options.push(`--${ele.replacer(opt)}`)
logOut(`--${opt} => --${ele.replacer(opt)}`);
}
logOut(` hasArg ${ele.hasArg}`);
logOut(` indexInc ${ele.indexInc(opt)}`);
let option = ""
for (let j = i + 1; j <= i + ele.indexInc(opt); j++) {
const element = options[j];
if (!drop) {
option+=element
args.options.push(`"${element}"`)
logOut(` arg: "${element}"`);
} else {
logOut(` arg: ${element}(drop)`);
}
}
if(drop){
writeInfo('--' + opt,option,"drop","droped")
}else{
writeInfo('--' + opt,option,"ok")
}
i += ele.indexInc(opt)
}
if (args.prefix + ' ' + args.options.join(' ').length == 0)
return '转换后的RE命令行将会显示在这里'
return (args.prefix + ' ' + args.options.join(' '));
}
function cleanInfoBox() {
document.getElementById('info-box').innerHTML = ''
}
function writeInfo(argName, argOption, type, details) {
let box = document.getElementById('info-box')
let info = document.createElement('div')
info.classList.add("info")
info.classList.add(type)
let name = document.createElement('div')
name.classList.add('arg-name')
if (details) {
name.innerText = argName + `(${details})`
}else{
name.innerText = argName
}
let option = document.createElement('div')
option.classList.add('arg-option')
option.innerText = argOption
info.appendChild(name)
info.appendChild(option)
box.appendChild(info)
}