-
Job '{{job.name}}'
+<% extends "base.html" %>
-
+<% block content %>
+
+
+
Job '{{job.name}}'
-
- State | {{job.state}} |
- Target revision | {{job.target_revision}} |
- YunoHost version | {{job.yunohost_version}} |
- Created time | {{timestampToDate(job.created_time)}} |
- Started time | {{timestampToDate(job.started_time)}} |
- End time | {{timestampToDate(job.end_time)}} |
-
+
-
Excution log:
-
-
-
-
-
-
-
+ AnsiUp.prototype.old_escape_for_html = function (txt) {
+ return txt.replace(/[&<>]/gm, function (str) {
+ if (str === "&")
+ return "&";
+ if (str === "<")
+ return "<";
+ if (str === ">")
+ return ">";
+ });
+ };
+ AnsiUp.prototype.old_linkify = function (txt) {
+ return txt.replace(/(https?:\/\/[^\s]+)/gm, function (str) {
+ return "
" + str + "";
+ });
+ };
+ AnsiUp.prototype.detect_incomplete_ansi = function (txt) {
+ return !(/.*?[\x40-\x7e]/.test(txt));
+ };
+ AnsiUp.prototype.detect_incomplete_link = function (txt) {
+ var found = false;
+ for (var i = txt.length - 1; i > 0; i--) {
+ if (/\s|\x1B/.test(txt[i])) {
+ found = true;
+ break;
+ }
+ }
+ if (!found) {
+ if (/(https?:\/\/[^\s]+)/.test(txt))
+ return 0;
+ else
+ return -1;
+ }
+ var prefix = txt.substr(i + 1, 4);
+ if (prefix.length === 0)
+ return -1;
+ if ("http".indexOf(prefix) === 0)
+ return (i + 1);
+ };
+ AnsiUp.prototype.ansi_to = function (txt, formatter) {
+ var pkt = this._buffer + txt;
+ this._buffer = '';
+ var raw_text_pkts = pkt.split(/\x1B\[/);
+ if (raw_text_pkts.length === 1)
+ raw_text_pkts.push('');
+ this.handle_incomplete_sequences(raw_text_pkts);
+ var first_chunk = this.with_state(raw_text_pkts.shift());
+ var blocks = new Array(raw_text_pkts.length);
+ for (var i = 0, len = raw_text_pkts.length; i < len; ++i) {
+ blocks[i] = (formatter.transform(this.process_ansi(raw_text_pkts[i]), this));
+ }
+ if (first_chunk.text.length > 0)
+ blocks.unshift(formatter.transform(first_chunk, this));
+ return formatter.compose(blocks, this);
+ };
+ AnsiUp.prototype.ansi_to_html = function (txt) {
+ return this.ansi_to(txt, this.htmlFormatter);
+ };
+ AnsiUp.prototype.ansi_to_text = function (txt) {
+ return this.ansi_to(txt, this.textFormatter);
+ };
+ AnsiUp.prototype.with_state = function (text) {
+ return { bold: this.bold, fg: this.fg, bg: this.bg, text: text };
+ };
+ AnsiUp.prototype.handle_incomplete_sequences = function (chunks) {
+ var last_chunk = chunks[chunks.length - 1];
+ if ((last_chunk.length > 0) && this.detect_incomplete_ansi(last_chunk)) {
+ this._buffer = "\x1B[" + last_chunk;
+ chunks.pop();
+ chunks.push('');
+ }
+ else {
+ if (last_chunk.slice(-1) === "\x1B") {
+ this._buffer = "\x1B";
+ console.log("raw", chunks);
+ chunks.pop();
+ chunks.push(last_chunk.substr(0, last_chunk.length - 1));
+ console.log(chunks);
+ console.log(last_chunk);
+ }
+ if (chunks.length === 2 &&
+ chunks[1] === "" &&
+ chunks[0].slice(-1) === "\x1B") {
+ this._buffer = "\x1B";
+ last_chunk = chunks.shift();
+ chunks.unshift(last_chunk.substr(0, last_chunk.length - 1));
+ }
+ }
+ };
+ AnsiUp.prototype.process_ansi = function (block) {
+ if (!this._sgr_regex) {
+ this._sgr_regex = (_a = ["\n ^ # beginning of line\n ([!<-?]?) # a private-mode char (!, <, =, >, ?)\n ([d;]*) # any digits or semicolons\n ([ -/]? # an intermediate modifier\n [@-~]) # the command\n ([sS]*) # any text following this CSI sequence\n "], _a.raw = ["\n ^ # beginning of line\n ([!\\x3c-\\x3f]?) # a private-mode char (!, <, =, >, ?)\n ([\\d;]*) # any digits or semicolons\n ([\\x20-\\x2f]? # an intermediate modifier\n [\\x40-\\x7e]) # the command\n ([\\s\\S]*) # any text following this CSI sequence\n "], rgx(_a));
+ }
+ var matches = block.match(this._sgr_regex);
+ if (!matches) {
+ return this.with_state(block);
+ }
+ var orig_txt = matches[4];
+ if (matches[1] !== '' || matches[3] !== 'm') {
+ return this.with_state(orig_txt);
+ }
+ var sgr_cmds = matches[2].split(';');
+ while (sgr_cmds.length > 0) {
+ var sgr_cmd_str = sgr_cmds.shift();
+ var num = parseInt(sgr_cmd_str, 10);
+ if (isNaN(num) || num === 0) {
+ this.fg = this.bg = null;
+ this.bold = false;
+ }
+ else if (num === 1) {
+ this.bold = true;
+ }
+ else if (num === 22) {
+ this.bold = false;
+ }
+ else if (num === 39) {
+ this.fg = null;
+ }
+ else if (num === 49) {
+ this.bg = null;
+ }
+ else if ((num >= 30) && (num < 38)) {
+ this.fg = this.ansi_colors[0][(num - 30)];
+ }
+ else if ((num >= 40) && (num < 48)) {
+ this.bg = this.ansi_colors[0][(num - 40)];
+ }
+ else if ((num >= 90) && (num < 98)) {
+ this.fg = this.ansi_colors[1][(num - 90)];
+ }
+ else if ((num >= 100) && (num < 108)) {
+ this.bg = this.ansi_colors[1][(num - 100)];
+ }
+ else if (num === 38 || num === 48) {
+ if (sgr_cmds.length > 0) {
+ var is_foreground = (num === 38);
+ var mode_cmd = sgr_cmds.shift();
+ if (mode_cmd === '5' && sgr_cmds.length > 0) {
+ var palette_index = parseInt(sgr_cmds.shift(), 10);
+ if (palette_index >= 0 && palette_index <= 255) {
+ if (is_foreground)
+ this.fg = this.palette_256[palette_index];
+ else
+ this.bg = this.palette_256[palette_index];
+ }
+ }
+ if (mode_cmd === '2' && sgr_cmds.length > 2) {
+ var r = parseInt(sgr_cmds.shift(), 10);
+ var g = parseInt(sgr_cmds.shift(), 10);
+ var b = parseInt(sgr_cmds.shift(), 10);
+ if ((r >= 0 && r <= 255) && (g >= 0 && g <= 255) && (b >= 0 && b <= 255)) {
+ var c = { rgb: [r, g, b], class_name: 'truecolor' };
+ if (is_foreground)
+ this.fg = c;
+ else
+ this.bg = c;
+ }
+ }
+ }
+ }
+ }
+ return this.with_state(orig_txt);
+ var _a;
+ };
+ return AnsiUp;
+ }());
+ //# sourceMappingURL=ansi_up.js.map
+ Object.defineProperty(exports, "__esModule", { value: true });
+ exports.default = AnsiUp;
+ }));
+
+ var app = new Vue({
+ el: '#job',
+ data: {
+ job: {}
+ },
+ methods: {
+ timestampToDate: function (timestamp) {
+ return new Date(timestamp * 1000).toLocaleString()
+ },
+ cancelJob: function() {
+ $.post("/api/job/" + this.job.id + "/stop")
+ }
+ },
+ computed: {
+ logWithColors: function() {
+ if (this.job.log != undefined) {
+ var ansiup = new AnsiUp;
+ return ansiup.ansi_to_html(this.job.log);
+ } else {
+ return "";
+ }
+ }
+ }
+ })
+
+ ws = new WebSocket('ws://' + document.domain + ':' + location.port + '/job-<{ job.id }>-ws');
+
+ ws.onmessage = function (event) {
+ var message = JSON.parse(event.data);
+ var data = message.data;
+ var action = message.action;
+
+ if (action == "init_job" || action == "update_job") {
+ app.job = data;
+ }
+ };
+ })()
+
+<% endblock %>