- Add FIFO semaphore for per-hoster concurrency control - Add token-bucket speed limiter with abort signal support - Rewrite upload-manager with retry loop, speed monitoring, and rich progress events - Add per-hoster settings: retries, max speed, parallel count, restart below speed, time interval, max size - Add context menu with shutdown-after-finish (sleep/shutdown/restart), always-on-top - Add z-o-o-m-style queue table with 8 columns, status-colored rows, progress bars - Add debounced queue rendering with scroll position preservation - Add statusbar with global speed, total bytes, elapsed time - Fix speedMonitor interval leak on error and scoping bug - Fix throttle not respecting abort signal during cancellation - Fix combined signal listener cleanup - Bump version to 1.1.0 Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
106 lines
3.1 KiB
JavaScript
106 lines
3.1 KiB
JavaScript
const fs = require('fs');
|
|
const path = require('path');
|
|
|
|
const HOSTER_SETTINGS_DEFAULTS = {
|
|
retries: 3,
|
|
maxSpeedKbs: 0, // 0 = unlimited
|
|
parallelCount: 2, // 1-10
|
|
restartBelowKbs: 0, // 0 = off
|
|
timeIntervalSec: 0, // delay between jobs
|
|
maxSizeMb: 0 // 0 = unlimited
|
|
};
|
|
|
|
const DEFAULTS = {
|
|
hosters: {
|
|
'doodstream.com': { enabled: true, apiKey: '' },
|
|
'voe.sx': { enabled: true, apiKey: '' },
|
|
'vidmoly.me': { enabled: true, authType: 'login', username: '', password: '' },
|
|
'byse.sx': { enabled: true, apiKey: '' }
|
|
},
|
|
hosterSettings: {
|
|
'doodstream.com': { ...HOSTER_SETTINGS_DEFAULTS },
|
|
'voe.sx': { ...HOSTER_SETTINGS_DEFAULTS },
|
|
'vidmoly.me': { ...HOSTER_SETTINGS_DEFAULTS },
|
|
'byse.sx': { ...HOSTER_SETTINGS_DEFAULTS }
|
|
},
|
|
globalSettings: {
|
|
alwaysOnTop: false,
|
|
shutdownAfterFinish: 'nothing' // nothing | sleep | shutdown | restart
|
|
},
|
|
history: []
|
|
};
|
|
|
|
const MAX_HISTORY = 100;
|
|
|
|
class ConfigStore {
|
|
constructor(app) {
|
|
const dir = app && app.isPackaged
|
|
? app.getPath('userData')
|
|
: path.join(__dirname, '..');
|
|
this.filePath = path.join(dir, 'electron-config.json');
|
|
}
|
|
|
|
load() {
|
|
try {
|
|
const raw = fs.readFileSync(this.filePath, 'utf-8');
|
|
const data = JSON.parse(raw);
|
|
// Merge with defaults so new hosters are always present
|
|
const hosters = { ...DEFAULTS.hosters };
|
|
for (const [name, val] of Object.entries(data.hosters || {})) {
|
|
if (hosters[name]) {
|
|
hosters[name] = { ...hosters[name], ...val };
|
|
}
|
|
}
|
|
// Merge hoster settings with defaults
|
|
const hosterSettings = {};
|
|
for (const name of Object.keys(DEFAULTS.hosterSettings)) {
|
|
hosterSettings[name] = {
|
|
...HOSTER_SETTINGS_DEFAULTS,
|
|
...(data.hosterSettings && data.hosterSettings[name] || {})
|
|
};
|
|
}
|
|
const globalSettings = {
|
|
...DEFAULTS.globalSettings,
|
|
...(data.globalSettings || {})
|
|
};
|
|
return { hosters, hosterSettings, globalSettings, history: data.history || [] };
|
|
} catch {
|
|
return JSON.parse(JSON.stringify(DEFAULTS));
|
|
}
|
|
}
|
|
|
|
save(config) {
|
|
const current = this.load();
|
|
// Update hosters credentials
|
|
if (config.hosters) current.hosters = config.hosters;
|
|
// Update hoster settings
|
|
if (config.hosterSettings) current.hosterSettings = config.hosterSettings;
|
|
// Update global settings
|
|
if (config.globalSettings) current.globalSettings = config.globalSettings;
|
|
fs.writeFileSync(this.filePath, JSON.stringify(current, null, 2), 'utf-8');
|
|
}
|
|
|
|
loadHistory() {
|
|
const config = this.load();
|
|
return config.history || [];
|
|
}
|
|
|
|
appendHistory(entry) {
|
|
const config = this.load();
|
|
config.history.push(entry);
|
|
// Cap at MAX_HISTORY
|
|
if (config.history.length > MAX_HISTORY) {
|
|
config.history = config.history.slice(-MAX_HISTORY);
|
|
}
|
|
fs.writeFileSync(this.filePath, JSON.stringify(config, null, 2), 'utf-8');
|
|
}
|
|
|
|
clearHistory() {
|
|
const config = this.load();
|
|
config.history = [];
|
|
fs.writeFileSync(this.filePath, JSON.stringify(config, null, 2), 'utf-8');
|
|
}
|
|
}
|
|
|
|
module.exports = ConfigStore;
|