refactor: split downloader into modules
This commit is contained in:
+126
@@ -0,0 +1,126 @@
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
const ROOT_DIR = path.join(__dirname, '..');
|
||||
const APP_CONFIG_FILE = path.join(ROOT_DIR, 'config.json');
|
||||
const DEFAULT_APP_CONFIG = {
|
||||
api: {
|
||||
music: 'https://api.chksz.top/api/163_music',
|
||||
lyric: 'https://api.chksz.top/api/163_lyric',
|
||||
search: 'https://api.chksz.top/api/163_search',
|
||||
playlist: 'https://api.chksz.top/api/163_playlist',
|
||||
neteaseBaseUrl: 'https://music.163.com',
|
||||
},
|
||||
paths: {
|
||||
downloadDir: 'downloads',
|
||||
historyFile: 'download_history.json',
|
||||
runtimeConfigFile: 'downloader_config.json',
|
||||
trashDir: '.trash',
|
||||
tempZipDir: '.tmp_zip',
|
||||
},
|
||||
defaults: {
|
||||
quality: 'jymaster',
|
||||
retries: 3,
|
||||
historyLimit: 500,
|
||||
},
|
||||
};
|
||||
|
||||
function loadAppConfig() {
|
||||
try {
|
||||
if (!fs.existsSync(APP_CONFIG_FILE)) return DEFAULT_APP_CONFIG;
|
||||
const config = JSON.parse(fs.readFileSync(APP_CONFIG_FILE, 'utf-8'));
|
||||
return {
|
||||
api: { ...DEFAULT_APP_CONFIG.api, ...(config.api || {}) },
|
||||
paths: { ...DEFAULT_APP_CONFIG.paths, ...(config.paths || {}) },
|
||||
defaults: { ...DEFAULT_APP_CONFIG.defaults, ...(config.defaults || {}) },
|
||||
};
|
||||
} catch (e) {
|
||||
console.warn(`⚠️ 配置文件读取失败,将使用默认配置: ${e.message}`);
|
||||
return DEFAULT_APP_CONFIG;
|
||||
}
|
||||
}
|
||||
|
||||
function resolveConfigPath(configPath, fallback) {
|
||||
const value = typeof configPath === 'string' && configPath.trim() ? configPath.trim() : fallback;
|
||||
return path.isAbsolute(value) ? value : path.join(ROOT_DIR, value);
|
||||
}
|
||||
|
||||
function getConfigString(value, fallback) {
|
||||
return typeof value === 'string' && value.trim() ? value.trim() : fallback;
|
||||
}
|
||||
|
||||
const APP_CONFIG = loadAppConfig();
|
||||
const API = {
|
||||
music: getConfigString(APP_CONFIG.api.music, DEFAULT_APP_CONFIG.api.music),
|
||||
lyric: getConfigString(APP_CONFIG.api.lyric, DEFAULT_APP_CONFIG.api.lyric),
|
||||
search: getConfigString(APP_CONFIG.api.search, DEFAULT_APP_CONFIG.api.search),
|
||||
playlist: getConfigString(APP_CONFIG.api.playlist, DEFAULT_APP_CONFIG.api.playlist),
|
||||
neteaseBaseUrl: getConfigString(APP_CONFIG.api.neteaseBaseUrl, DEFAULT_APP_CONFIG.api.neteaseBaseUrl),
|
||||
};
|
||||
const NETEASE_BASE_URL = API.neteaseBaseUrl.replace(/\/$/, '');
|
||||
const DOWNLOAD_DIR = resolveConfigPath(APP_CONFIG.paths.downloadDir, DEFAULT_APP_CONFIG.paths.downloadDir);
|
||||
const HISTORY_FILE = resolveConfigPath(APP_CONFIG.paths.historyFile, DEFAULT_APP_CONFIG.paths.historyFile);
|
||||
const CONFIG_FILE = resolveConfigPath(APP_CONFIG.paths.runtimeConfigFile, DEFAULT_APP_CONFIG.paths.runtimeConfigFile);
|
||||
const TRASH_DIR = resolveConfigPath(APP_CONFIG.paths.trashDir, DEFAULT_APP_CONFIG.paths.trashDir);
|
||||
const TEMP_ZIP_DIR = resolveConfigPath(APP_CONFIG.paths.tempZipDir, DEFAULT_APP_CONFIG.paths.tempZipDir);
|
||||
const QUALITY_LEVELS = ['standard', 'exhigh', 'lossless', 'hires', 'jymaster', 'sky', 'jyeffect'];
|
||||
const QUALITY_LABELS = {
|
||||
standard: '标准',
|
||||
exhigh: '极高',
|
||||
lossless: '无损',
|
||||
hires: 'Hi-Res',
|
||||
jymaster: '超清母带',
|
||||
sky: '空间音频',
|
||||
jyeffect: '高清臻品',
|
||||
};
|
||||
const DEFAULT_LEVEL = QUALITY_LEVELS.includes(APP_CONFIG.defaults.quality)
|
||||
? APP_CONFIG.defaults.quality
|
||||
: DEFAULT_APP_CONFIG.defaults.quality;
|
||||
const DEFAULT_RETRIES = Number.isInteger(APP_CONFIG.defaults.retries) && APP_CONFIG.defaults.retries > 0
|
||||
? APP_CONFIG.defaults.retries
|
||||
: DEFAULT_APP_CONFIG.defaults.retries;
|
||||
const HISTORY_LIMIT = Number.isInteger(APP_CONFIG.defaults.historyLimit) && APP_CONFIG.defaults.historyLimit > 0
|
||||
? APP_CONFIG.defaults.historyLimit
|
||||
: DEFAULT_APP_CONFIG.defaults.historyLimit;
|
||||
|
||||
function loadRuntimeConfig() {
|
||||
try {
|
||||
if (fs.existsSync(CONFIG_FILE)) return JSON.parse(fs.readFileSync(CONFIG_FILE, 'utf-8'));
|
||||
} catch {}
|
||||
return {};
|
||||
}
|
||||
|
||||
function saveRuntimeConfig(config) {
|
||||
fs.mkdirSync(path.dirname(CONFIG_FILE), { recursive: true });
|
||||
fs.writeFileSync(CONFIG_FILE, JSON.stringify(config, null, 2), 'utf-8');
|
||||
}
|
||||
|
||||
function getConfig(key, defaultVal) {
|
||||
const config = loadRuntimeConfig();
|
||||
return config[key] !== undefined ? config[key] : defaultVal;
|
||||
}
|
||||
|
||||
function setConfig(key, val) {
|
||||
const config = loadRuntimeConfig();
|
||||
config[key] = val;
|
||||
saveRuntimeConfig(config);
|
||||
}
|
||||
|
||||
if (!fs.existsSync(DOWNLOAD_DIR)) fs.mkdirSync(DOWNLOAD_DIR, { recursive: true });
|
||||
|
||||
module.exports = {
|
||||
API,
|
||||
NETEASE_BASE_URL,
|
||||
DOWNLOAD_DIR,
|
||||
HISTORY_FILE,
|
||||
CONFIG_FILE,
|
||||
TRASH_DIR,
|
||||
TEMP_ZIP_DIR,
|
||||
QUALITY_LEVELS,
|
||||
QUALITY_LABELS,
|
||||
DEFAULT_LEVEL,
|
||||
DEFAULT_RETRIES,
|
||||
HISTORY_LIMIT,
|
||||
getConfig,
|
||||
setConfig,
|
||||
};
|
||||
Reference in New Issue
Block a user