mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-10-26 21:32:51 +08:00
125 lines
2.8 KiB
JavaScript
125 lines
2.8 KiB
JavaScript
'use strict';
|
|
'require poll';
|
|
'require rpc';
|
|
|
|
// run/test/restore are backgrounded by rpcd ({started:true}); the only way to
|
|
// see how they went is to tail `log` until a terminal line appears. LuCI hands
|
|
// every view the same instance: one operation at a time per view.
|
|
|
|
var callLog = rpc.declare({
|
|
object: 'luci.gitbackup',
|
|
method: 'log',
|
|
params: [ 'lines' ]
|
|
});
|
|
|
|
function gbFetchLog() {
|
|
return L.resolveDefault(callLog(500), null).then(function(res) {
|
|
return (res && res.text) || '';
|
|
});
|
|
}
|
|
|
|
return L.Class.extend({
|
|
callLog: callLog,
|
|
|
|
// Resolves only once the operation is over, so a createHandlerFn button
|
|
// stays disabled until then. Exactly one of opts.onFinish/onTimeout/onFail
|
|
// fires.
|
|
run: function(opts) {
|
|
var self = this;
|
|
var pre = opts.pre ? document.getElementById(opts.pre) : null;
|
|
|
|
self._idle = 0;
|
|
self._ticks = 0;
|
|
self._lines = 0;
|
|
self._done = false;
|
|
|
|
if (pre) {
|
|
pre.hidden = false;
|
|
pre.textContent = '';
|
|
}
|
|
|
|
return new Promise(function(resolve) {
|
|
self._opts = opts;
|
|
self._resolve = resolve;
|
|
|
|
// Baseline before the call, or the operation's first line is missed.
|
|
gbFetchLog().then(function(text) {
|
|
self._lines = text ? text.split('\n').length : 0;
|
|
|
|
if (!self._bound)
|
|
self._bound = L.bind(self._tick, self);
|
|
|
|
poll.remove(self._bound);
|
|
poll.add(self._bound, 2);
|
|
|
|
return opts.call();
|
|
}).then(function(res) {
|
|
if (!res || res.started !== true)
|
|
throw new Error((res && res.reason) || '');
|
|
}).catch(function(e) {
|
|
self._end(opts.onFail, e.message);
|
|
});
|
|
});
|
|
},
|
|
|
|
stop: function() {
|
|
if (this._bound)
|
|
poll.remove(this._bound);
|
|
},
|
|
|
|
_append: function(add) {
|
|
var pre = this._opts.pre ? document.getElementById(this._opts.pre) : null;
|
|
|
|
if (!pre)
|
|
return;
|
|
|
|
pre.textContent = pre.textContent ? pre.textContent + '\n' + add : add;
|
|
pre.scrollTop = pre.scrollHeight;
|
|
},
|
|
|
|
_end: function(cb, arg) {
|
|
if (this._done)
|
|
return;
|
|
this._done = true;
|
|
this.stop();
|
|
if (cb)
|
|
cb(arg);
|
|
this._resolve();
|
|
},
|
|
|
|
_tick: function() {
|
|
var self = this;
|
|
var opts = self._opts;
|
|
|
|
self._ticks++;
|
|
|
|
return callLog(500).then(function(res) {
|
|
var lines = ((res && res.text) || '').split('\n');
|
|
var newLines = (lines.length >= self._lines) ? lines.slice(self._lines) : lines;
|
|
var add = newLines.filter(function(l) { return l; }).join('\n');
|
|
var matched = null;
|
|
var i;
|
|
|
|
self._lines = lines.length;
|
|
|
|
if (add) {
|
|
self._idle = 0;
|
|
self._append(add);
|
|
for (i = 0; i < newLines.length; i++) {
|
|
if (opts.terminalRe.test(newLines[i]))
|
|
matched = newLines[i];
|
|
}
|
|
} else {
|
|
self._idle++;
|
|
}
|
|
|
|
if (matched !== null)
|
|
self._end(opts.onFinish, matched);
|
|
else if (self._idle >= 30 || self._ticks >= 150)
|
|
self._end(opts.onTimeout);
|
|
}, function() {
|
|
self._end(opts.onTimeout);
|
|
});
|
|
}
|
|
});
|