diff options
| author | Agando <roduccomm@gmail.com> | 2026-05-25 18:02:02 +0200 |
|---|---|---|
| committer | Agando <roduccomm@gmail.com> | 2026-05-25 18:02:02 +0200 |
| commit | 4baa484b84c5184286cac2743575251454a5ee2b (patch) | |
| tree | cb9002f93644f363d0f35831dc97e6492bbb0ed6 /modules/ext/cron.js | |
auto: 2026-05-25_18:02 changes
Diffstat (limited to 'modules/ext/cron.js')
| -rw-r--r-- | modules/ext/cron.js | 110 |
1 files changed, 110 insertions, 0 deletions
diff --git a/modules/ext/cron.js b/modules/ext/cron.js new file mode 100644 index 0000000..66cd18e --- /dev/null +++ b/modules/ext/cron.js @@ -0,0 +1,110 @@ +class CronModule { + constructor() { + this.commands = {}; + this.terminal = null; + this.jobs = {}; + this.counter = 0; + this.MIN_INTERVAL = 5; + this.STORAGE_KEY = 'webx11_cron_jobs'; + this._restoreJobs(); + } + requirements() { + return { met: true, missing: [] }; + } + getHelpInfo() { + return { + 'cron-every': 'cron-every <seconds> <command> — Schedule a command to run every N seconds', + 'cron-list': 'cron-list — List all active cron jobs', + 'cron-stop': 'cron-stop <id> — Stop a specific cron job', + 'cron-clear': 'cron-clear — Stop all cron jobs' + }; + } + registerCommands() { + this.commands['cron-every'] = (args) => this.every(args); + this.commands['cron-list'] = () => this.list(); + this.commands['cron-stop'] = (args) => this.stop(args); + this.commands['cron-clear'] = () => this.clear(); + } + _restoreJobs() { + try { + const saved = localStorage.getItem(this.STORAGE_KEY); + if (!saved) return; + const data = JSON.parse(saved); + if (!Array.isArray(data) || data.length === 0) return; + let maxId = 0; + data.forEach(j => { + if (j.id > maxId) maxId = j.id; + if (this.counter < j.id) this.counter = j.id; + this.jobs[j.id] = { + cmd: j.cmd, + interval: j.interval, + runs: j.runs || 0, + timer: setInterval(() => { + if (!this.jobs[j.id]) return; + this.jobs[j.id].runs++; + this.terminal.print(`[cron #${j.id}] Running: ${j.cmd}`, 'info'); + this.terminal.executeCommand(j.cmd); + }, j.interval) + }; + }); + this.counter = maxId; + if (data.length > 0) this.terminal.print(`↻ Restored ${data.length} cron job(s) from storage`, 'info'); + } catch (e) { /* silently ignore corrupt data */ } + } + _saveJobs() { + try { + const data = Object.entries(this.jobs).map(([id, j]) => ({ + id: parseInt(id), + cmd: j.cmd, + interval: j.interval, + runs: j.runs + })); + localStorage.setItem(this.STORAGE_KEY, JSON.stringify(data)); + } catch (e) { /* quota exceeded */ } + } + every(args) { + if (args.length < 2) return this.terminal.print('Usage: cron-every <seconds> <command>', 'warning'); + const secs = parseInt(args[0]); + if (isNaN(secs) || secs < this.MIN_INTERVAL) return this.terminal.print(`Interval must be >= ${this.MIN_INTERVAL} seconds`, 'warning'); + const cmd = args.slice(1).join(' '); + this.counter++; + const id = this.counter; + this.jobs[id] = { + cmd, interval: secs * 1000, runs: 0, + timer: setInterval(() => { + this.jobs[id].runs++; + this.terminal.print(`[cron #${id}] Running: ${cmd}`, 'info'); + this.terminal.executeCommand(cmd); + }, secs * 1000) + }; + this._saveJobs(); + this.terminal.print(`Cron job #${id} started: "${cmd}" every ${secs}s`, 'success'); + } + list() { + const ids = Object.keys(this.jobs); + if (ids.length === 0) return this.terminal.print('No active cron jobs', 'info'); + this.terminal.print('=== Cron Jobs ===', 'info'); + ids.forEach(id => { + const j = this.jobs[id]; + this.terminal.print(` #${id}: "${j.cmd}" every ${j.interval / 1000}s (${j.runs} runs)`); + }); + } + stop(args) { + if (!args[0]) return this.terminal.print('Usage: cron-stop <id>', 'warning'); + const id = parseInt(args[0]); + if (!this.jobs[id]) return this.terminal.print(`Cron job #${id} not found`, 'error'); + clearInterval(this.jobs[id].timer); + delete this.jobs[id]; + this._saveJobs(); + this.terminal.print(`Cron job #${id} stopped`, 'success'); + } + clear() { + Object.keys(this.jobs).forEach(id => { clearInterval(this.jobs[id].timer); }); + this.jobs = {}; + localStorage.removeItem(this.STORAGE_KEY); + this.terminal.print('All cron jobs stopped', 'success'); + } +} +if (typeof window.webx11 !== 'undefined' && window.webx11) { + webx11.moduleManager.registerModule(new CronModule(), 'https://webx11.duckdns.org/spaces/chatstudio/newos4/modules/cron.js'); +} |