mirror of
https://github.com/esphome/esphome.git
synced 2024-11-26 12:27:13 +01:00
Re-do dashboard ANSI colors
This commit is contained in:
parent
dd5274341d
commit
cf2752b9e0
@ -78,8 +78,6 @@ class EsphomeyamlCommandWebSocket(tornado.websocket.WebSocketHandler):
|
|||||||
data = yield self.proc.stdout.read_until_regex('[\n\r]')
|
data = yield self.proc.stdout.read_until_regex('[\n\r]')
|
||||||
except tornado.iostream.StreamClosedError:
|
except tornado.iostream.StreamClosedError:
|
||||||
break
|
break
|
||||||
if data.endswith('\r') and random.randrange(100) < 90:
|
|
||||||
continue
|
|
||||||
try:
|
try:
|
||||||
data = data.replace('\033', '\\033')
|
data = data.replace('\033', '\\033')
|
||||||
except UnicodeDecodeError:
|
except UnicodeDecodeError:
|
||||||
|
@ -57,42 +57,27 @@ i.very-large {
|
|||||||
font-family: "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;
|
font-family: "SFMono-Regular",Consolas,"Liberation Mono",Menlo,Courier,monospace;
|
||||||
}
|
}
|
||||||
|
|
||||||
.log.bold {
|
.log-bold { font-weight: bold; }
|
||||||
font-weight: bold;
|
.log-italic { font-style: italic; }
|
||||||
}
|
.log-underline { text-decoration: underline; }
|
||||||
|
.log-strikethrough { text-decoration: line-through; }
|
||||||
.log .v {
|
.log-underline.log-strikethrough { text-decoration: underline line-through; }
|
||||||
color: #888888;
|
.log-fg-black { color: rgb(128,128,128); }
|
||||||
}
|
.log-fg-red { color: rgb(255,0,0); }
|
||||||
|
.log-fg-green { color: rgb(0,255,0); }
|
||||||
.log .d {
|
.log-fg-yellow { color: rgb(255,255,0); }
|
||||||
color: #00DDDD;
|
.log-fg-blue { color: rgb(0,0,255); }
|
||||||
}
|
.log-fg-magenta { color: rgb(255,0,255); }
|
||||||
|
.log-fg-cyan { color: rgb(0,255,255); }
|
||||||
.log .c {
|
.log-fg-white { background-color: rgb(255,255,255); }
|
||||||
color: magenta;
|
.log-bg-black { background-color: rgb(0,0,0); }
|
||||||
}
|
.log-bg-red { background-color: rgb(255,0,0); }
|
||||||
|
.log-bg-green { background-color: rgb(0,255,0); }
|
||||||
.log .i {
|
.log-bg-yellow { background-color: rgb(255,255,0); }
|
||||||
color: limegreen;
|
.log-bg-blue { background-color: rgb(0,0,255); }
|
||||||
}
|
.log-bg-magenta { background-color: rgb(255,0,255); }
|
||||||
|
.log-bg-cyan { background-color: rgb(0,255,255); }
|
||||||
.log .w {
|
.log-bg-white { background-color: rgb(255,255,255); }
|
||||||
color: yellow;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log .e {
|
|
||||||
color: red;
|
|
||||||
font-weight: bold;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log .e {
|
|
||||||
color: red;
|
|
||||||
}
|
|
||||||
|
|
||||||
.log .ww {
|
|
||||||
color: white;
|
|
||||||
}
|
|
||||||
|
|
||||||
.modal {
|
.modal {
|
||||||
width: 95%;
|
width: 95%;
|
||||||
|
@ -1,26 +1,153 @@
|
|||||||
document.addEventListener('DOMContentLoaded', () => {
|
document.addEventListener('DOMContentLoaded', () => {
|
||||||
M.AutoInit(document.body);
|
M.AutoInit(document.body);
|
||||||
});
|
});
|
||||||
|
|
||||||
const colorReplace = (input) => {
|
const initializeColorState = () => {
|
||||||
input = input.replace(/&/g, "&").replace(/</g, "<").replace(/>/g, ">").replace(/"/g, """).replace(/'/g, "'");
|
return {
|
||||||
input = input.replace(/\\033\[(?:0;)?31m/g, '<span class="e">');
|
bold: false,
|
||||||
input = input.replace(/\\033\[(?:0?1;)?31m/g, '<span class="e bold">');
|
italic: false,
|
||||||
input = input.replace(/\\033\[(?:0;)?32m/g, '<span class="i">');
|
underline: false,
|
||||||
input = input.replace(/\\033\[(?:0?1;)?32m/g, '<span class="i bold">');
|
strikethrough: false,
|
||||||
input = input.replace(/\\033\[(?:0;)?33m/g, '<span class="w">');
|
foregroundColor: false,
|
||||||
input = input.replace(/\\033\[(?:0?1;)?33m/g, '<span class="w bold">');
|
backgroundColor: false,
|
||||||
input = input.replace(/\\033\[(?:0;)?35m/g, '<span class="c">');
|
carriageReturn: false,
|
||||||
input = input.replace(/\\033\[(?:0?1;)?35m/g, '<span class="c bold">');
|
};
|
||||||
input = input.replace(/\\033\[(?:0;)?36m/g, '<span class="d">');
|
};
|
||||||
input = input.replace(/\\033\[(?:0?1;)?36m/g, '<span class="d bold">');
|
|
||||||
input = input.replace(/\\033\[(?:0;)?37m/g, '<span class="v">');
|
|
||||||
input = input.replace(/\\033\[(?:0?1;)?37m/g, '<span class="v bold">');
|
|
||||||
input = input.replace(/\\033\[(?:0;)?38m/g, '<span class="vv">');
|
|
||||||
input = input.replace(/\\033\[(?:0?1;)?38m/g, '<span class="vv bold">');
|
|
||||||
input = input.replace(/\\033\[0m/g, '</span>');
|
|
||||||
|
|
||||||
return input;
|
const colorReplace = (pre, state, text) => {
|
||||||
|
const re = /(?:\033|\\033)(?:\[(.*?)[@-~]|\].*?(?:\007|\033\\))/g;
|
||||||
|
let i = 0;
|
||||||
|
|
||||||
|
if (state.carriageReturn) {
|
||||||
|
pre.removeChild(pre.lastChild);
|
||||||
|
state.carriageReturn = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (text.includes("\r")) {
|
||||||
|
state.carriageReturn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
const lineSpan = document.createElement("span");
|
||||||
|
lineSpan.classList.add("line");
|
||||||
|
pre.appendChild(lineSpan);
|
||||||
|
|
||||||
|
const addSpan = (content) => {
|
||||||
|
if (content === "")
|
||||||
|
return;
|
||||||
|
|
||||||
|
const span = document.createElement("span");
|
||||||
|
if (state.bold) span.classList.add("log-bold");
|
||||||
|
if (state.italic) span.classList.add("log-italic");
|
||||||
|
if (state.underline) span.classList.add("log-underline");
|
||||||
|
if (state.strikethrough) span.classList.add("log-strikethrough");
|
||||||
|
if (state.foregroundColor !== null) span.classList.add(`log-fg-${state.foregroundColor}`);
|
||||||
|
if (state.backgroundColor !== null) span.classList.add(`log-bg-${state.backgroundColor}`);
|
||||||
|
span.appendChild(document.createTextNode(content));
|
||||||
|
lineSpan.appendChild(span);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
while (true) {
|
||||||
|
const match = re.exec(text);
|
||||||
|
if (match === null)
|
||||||
|
break;
|
||||||
|
|
||||||
|
const j = match.index;
|
||||||
|
addSpan(text.substring(i, j));
|
||||||
|
i = j + match[0].length;
|
||||||
|
|
||||||
|
if (match[1] === undefined) continue;
|
||||||
|
|
||||||
|
for (const colorCode of match[1].split(";")) {
|
||||||
|
switch (parseInt(colorCode)) {
|
||||||
|
case 0:
|
||||||
|
// reset
|
||||||
|
state.bold = false;
|
||||||
|
state.italic = false;
|
||||||
|
state.underline = false;
|
||||||
|
state.strikethrough = false;
|
||||||
|
state.foregroundColor = null;
|
||||||
|
state.backgroundColor = null;
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
state.bold = true;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
state.italic = true;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
state.underline = true;
|
||||||
|
break;
|
||||||
|
case 9:
|
||||||
|
state.strikethrough = true;
|
||||||
|
break;
|
||||||
|
case 22:
|
||||||
|
state.bold = false;
|
||||||
|
break;
|
||||||
|
case 23:
|
||||||
|
state.italic = false;
|
||||||
|
break;
|
||||||
|
case 24:
|
||||||
|
state.underline = false;
|
||||||
|
break;
|
||||||
|
case 29:
|
||||||
|
state.strikethrough = false;
|
||||||
|
break;
|
||||||
|
case 30:
|
||||||
|
state.foregroundColor = "black";
|
||||||
|
break;
|
||||||
|
case 31:
|
||||||
|
state.foregroundColor = "red";
|
||||||
|
state.bold = true;
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
state.foregroundColor = "green";
|
||||||
|
break;
|
||||||
|
case 33:
|
||||||
|
state.foregroundColor = "yellow";
|
||||||
|
break;
|
||||||
|
case 34:
|
||||||
|
state.foregroundColor = "blue";
|
||||||
|
break;
|
||||||
|
case 35:
|
||||||
|
state.foregroundColor = "magenta";
|
||||||
|
break;
|
||||||
|
case 36:
|
||||||
|
state.foregroundColor = "cyan";
|
||||||
|
break;
|
||||||
|
case 37:
|
||||||
|
case 39:
|
||||||
|
state.foregroundColor = null;
|
||||||
|
break;
|
||||||
|
case 41:
|
||||||
|
state.backgroundColor = "red";
|
||||||
|
break;
|
||||||
|
case 42:
|
||||||
|
state.backgroundColor = "green";
|
||||||
|
break;
|
||||||
|
case 43:
|
||||||
|
state.backgroundColor = "yellow";
|
||||||
|
break;
|
||||||
|
case 44:
|
||||||
|
state.backgroundColor = "blue";
|
||||||
|
break;
|
||||||
|
case 45:
|
||||||
|
state.backgroundColor = "magenta";
|
||||||
|
break;
|
||||||
|
case 46:
|
||||||
|
state.backgroundColor = "cyan";
|
||||||
|
break;
|
||||||
|
case 47:
|
||||||
|
state.backgroundColor = "white";
|
||||||
|
break;
|
||||||
|
case 40:
|
||||||
|
case 49:
|
||||||
|
state.backgroundColor = null;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
addSpan(text.substring(i));
|
||||||
};
|
};
|
||||||
|
|
||||||
const removeUpdateAvailable = (filename) => {
|
const removeUpdateAvailable = (filename) => {
|
||||||
@ -144,6 +271,7 @@ document.querySelectorAll(".action-show-logs").forEach((showLogs) => {
|
|||||||
const modalInstance = M.Modal.getInstance(logsModalElem);
|
const modalInstance = M.Modal.getInstance(logsModalElem);
|
||||||
const log = logsModalElem.querySelector(".log");
|
const log = logsModalElem.querySelector(".log");
|
||||||
log.innerHTML = "";
|
log.innerHTML = "";
|
||||||
|
const colorState = initializeColorState();
|
||||||
const stopLogsButton = logsModalElem.querySelector(".stop-logs");
|
const stopLogsButton = logsModalElem.querySelector(".stop-logs");
|
||||||
let stopped = false;
|
let stopped = false;
|
||||||
stopLogsButton.innerHTML = "Stop";
|
stopLogsButton.innerHTML = "Stop";
|
||||||
@ -156,8 +284,7 @@ document.querySelectorAll(".action-show-logs").forEach((showLogs) => {
|
|||||||
logSocket.addEventListener('message', (event) => {
|
logSocket.addEventListener('message', (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
if (data.event === "line") {
|
if (data.event === "line") {
|
||||||
const msg = data.data;
|
colorReplace(log, colorState, data.data);
|
||||||
log.insertAdjacentHTML('beforeend', colorReplace(msg));
|
|
||||||
} else if (data.event === "exit") {
|
} else if (data.event === "exit") {
|
||||||
if (data.code === 0) {
|
if (data.code === 0) {
|
||||||
M.toast({html: "Program exited successfully."});
|
M.toast({html: "Program exited successfully."});
|
||||||
@ -192,6 +319,7 @@ document.querySelectorAll(".action-upload").forEach((upload) => {
|
|||||||
const modalInstance = M.Modal.getInstance(uploadModalElem);
|
const modalInstance = M.Modal.getInstance(uploadModalElem);
|
||||||
const log = uploadModalElem.querySelector(".log");
|
const log = uploadModalElem.querySelector(".log");
|
||||||
log.innerHTML = "";
|
log.innerHTML = "";
|
||||||
|
const colorState = initializeColorState();
|
||||||
const stopLogsButton = uploadModalElem.querySelector(".stop-logs");
|
const stopLogsButton = uploadModalElem.querySelector(".stop-logs");
|
||||||
let stopped = false;
|
let stopped = false;
|
||||||
stopLogsButton.innerHTML = "Stop";
|
stopLogsButton.innerHTML = "Stop";
|
||||||
@ -204,8 +332,7 @@ document.querySelectorAll(".action-upload").forEach((upload) => {
|
|||||||
logSocket.addEventListener('message', (event) => {
|
logSocket.addEventListener('message', (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
if (data.event === "line") {
|
if (data.event === "line") {
|
||||||
const msg = data.data;
|
colorReplace(log, colorState, data.data);
|
||||||
log.insertAdjacentHTML('beforeend', colorReplace(msg));
|
|
||||||
} else if (data.event === "exit") {
|
} else if (data.event === "exit") {
|
||||||
if (data.code === 0) {
|
if (data.code === 0) {
|
||||||
M.toast({html: "Program exited successfully."});
|
M.toast({html: "Program exited successfully."});
|
||||||
@ -241,6 +368,7 @@ document.querySelectorAll(".action-validate").forEach((upload) => {
|
|||||||
const modalInstance = M.Modal.getInstance(validateModalElem);
|
const modalInstance = M.Modal.getInstance(validateModalElem);
|
||||||
const log = validateModalElem.querySelector(".log");
|
const log = validateModalElem.querySelector(".log");
|
||||||
log.innerHTML = "";
|
log.innerHTML = "";
|
||||||
|
const colorState = initializeColorState();
|
||||||
const stopLogsButton = validateModalElem.querySelector(".stop-logs");
|
const stopLogsButton = validateModalElem.querySelector(".stop-logs");
|
||||||
let stopped = false;
|
let stopped = false;
|
||||||
stopLogsButton.innerHTML = "Stop";
|
stopLogsButton.innerHTML = "Stop";
|
||||||
@ -253,8 +381,7 @@ document.querySelectorAll(".action-validate").forEach((upload) => {
|
|||||||
logSocket.addEventListener('message', (event) => {
|
logSocket.addEventListener('message', (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
if (data.event === "line") {
|
if (data.event === "line") {
|
||||||
const msg = data.data;
|
colorReplace(log, colorState, data.data);
|
||||||
log.insertAdjacentHTML('beforeend', colorReplace(msg));
|
|
||||||
} else if (data.event === "exit") {
|
} else if (data.event === "exit") {
|
||||||
if (data.code === 0) {
|
if (data.code === 0) {
|
||||||
M.toast({
|
M.toast({
|
||||||
@ -296,6 +423,7 @@ document.querySelectorAll(".action-compile").forEach((upload) => {
|
|||||||
const modalInstance = M.Modal.getInstance(compileModalElem);
|
const modalInstance = M.Modal.getInstance(compileModalElem);
|
||||||
const log = compileModalElem.querySelector(".log");
|
const log = compileModalElem.querySelector(".log");
|
||||||
log.innerHTML = "";
|
log.innerHTML = "";
|
||||||
|
const colorState = initializeColorState();
|
||||||
const stopLogsButton = compileModalElem.querySelector(".stop-logs");
|
const stopLogsButton = compileModalElem.querySelector(".stop-logs");
|
||||||
let stopped = false;
|
let stopped = false;
|
||||||
stopLogsButton.innerHTML = "Stop";
|
stopLogsButton.innerHTML = "Stop";
|
||||||
@ -310,8 +438,7 @@ document.querySelectorAll(".action-compile").forEach((upload) => {
|
|||||||
logSocket.addEventListener('message', (event) => {
|
logSocket.addEventListener('message', (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
if (data.event === "line") {
|
if (data.event === "line") {
|
||||||
const msg = data.data;
|
colorReplace(log, colorState, data.data);
|
||||||
log.insertAdjacentHTML('beforeend', colorReplace(msg));
|
|
||||||
} else if (data.event === "exit") {
|
} else if (data.event === "exit") {
|
||||||
if (data.code === 0) {
|
if (data.code === 0) {
|
||||||
M.toast({html: "Program exited successfully."});
|
M.toast({html: "Program exited successfully."});
|
||||||
@ -354,6 +481,7 @@ document.querySelectorAll(".action-clean-mqtt").forEach((btn) => {
|
|||||||
const modalInstance = M.Modal.getInstance(cleanMqttModalElem);
|
const modalInstance = M.Modal.getInstance(cleanMqttModalElem);
|
||||||
const log = cleanMqttModalElem.querySelector(".log");
|
const log = cleanMqttModalElem.querySelector(".log");
|
||||||
log.innerHTML = "";
|
log.innerHTML = "";
|
||||||
|
const colorState = initializeColorState();
|
||||||
const stopLogsButton = cleanMqttModalElem.querySelector(".stop-logs");
|
const stopLogsButton = cleanMqttModalElem.querySelector(".stop-logs");
|
||||||
let stopped = false;
|
let stopped = false;
|
||||||
stopLogsButton.innerHTML = "Stop";
|
stopLogsButton.innerHTML = "Stop";
|
||||||
@ -366,8 +494,7 @@ document.querySelectorAll(".action-clean-mqtt").forEach((btn) => {
|
|||||||
logSocket.addEventListener('message', (event) => {
|
logSocket.addEventListener('message', (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
if (data.event === "line") {
|
if (data.event === "line") {
|
||||||
const msg = data.data;
|
colorReplace(log, colorState, data.data);
|
||||||
log.insertAdjacentHTML('beforeend', colorReplace(msg));
|
|
||||||
} else if (data.event === "exit") {
|
} else if (data.event === "exit") {
|
||||||
stopLogsButton.innerHTML = "Close";
|
stopLogsButton.innerHTML = "Close";
|
||||||
stopped = true;
|
stopped = true;
|
||||||
@ -396,6 +523,7 @@ document.querySelectorAll(".action-clean").forEach((btn) => {
|
|||||||
const modalInstance = M.Modal.getInstance(cleanModalElem);
|
const modalInstance = M.Modal.getInstance(cleanModalElem);
|
||||||
const log = cleanModalElem.querySelector(".log");
|
const log = cleanModalElem.querySelector(".log");
|
||||||
log.innerHTML = "";
|
log.innerHTML = "";
|
||||||
|
const colorState = initializeColorState();
|
||||||
const stopLogsButton = cleanModalElem.querySelector(".stop-logs");
|
const stopLogsButton = cleanModalElem.querySelector(".stop-logs");
|
||||||
let stopped = false;
|
let stopped = false;
|
||||||
stopLogsButton.innerHTML = "Stop";
|
stopLogsButton.innerHTML = "Stop";
|
||||||
@ -408,8 +536,7 @@ document.querySelectorAll(".action-clean").forEach((btn) => {
|
|||||||
logSocket.addEventListener('message', (event) => {
|
logSocket.addEventListener('message', (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
if (data.event === "line") {
|
if (data.event === "line") {
|
||||||
const msg = data.data;
|
colorReplace(log, colorState, data.data);
|
||||||
log.insertAdjacentHTML('beforeend', colorReplace(msg));
|
|
||||||
} else if (data.event === "exit") {
|
} else if (data.event === "exit") {
|
||||||
if (data.code === 0) {
|
if (data.code === 0) {
|
||||||
M.toast({html: "Program exited successfully."});
|
M.toast({html: "Program exited successfully."});
|
||||||
@ -444,6 +571,7 @@ document.querySelectorAll(".action-hass-config").forEach((btn) => {
|
|||||||
const modalInstance = M.Modal.getInstance(hassConfigModalElem);
|
const modalInstance = M.Modal.getInstance(hassConfigModalElem);
|
||||||
const log = hassConfigModalElem.querySelector(".log");
|
const log = hassConfigModalElem.querySelector(".log");
|
||||||
log.innerHTML = "";
|
log.innerHTML = "";
|
||||||
|
const colorState = initializeColorState();
|
||||||
const stopLogsButton = hassConfigModalElem.querySelector(".stop-logs");
|
const stopLogsButton = hassConfigModalElem.querySelector(".stop-logs");
|
||||||
let stopped = false;
|
let stopped = false;
|
||||||
stopLogsButton.innerHTML = "Stop";
|
stopLogsButton.innerHTML = "Stop";
|
||||||
@ -456,8 +584,7 @@ document.querySelectorAll(".action-hass-config").forEach((btn) => {
|
|||||||
logSocket.addEventListener('message', (event) => {
|
logSocket.addEventListener('message', (event) => {
|
||||||
const data = JSON.parse(event.data);
|
const data = JSON.parse(event.data);
|
||||||
if (data.event === "line") {
|
if (data.event === "line") {
|
||||||
const msg = data.data;
|
colorReplace(log, colorState, data.data);
|
||||||
log.insertAdjacentHTML('beforeend', colorReplace(msg));
|
|
||||||
} else if (data.event === "exit") {
|
} else if (data.event === "exit") {
|
||||||
if (data.code === 0) {
|
if (data.code === 0) {
|
||||||
M.toast({html: "Program exited successfully."});
|
M.toast({html: "Program exited successfully."});
|
||||||
|
@ -253,7 +253,7 @@ class CheckForUpdateThread(threading.Thread):
|
|||||||
|
|
||||||
req = requests.get('{}/_static/version'.format(self.docs_base))
|
req = requests.get('{}/_static/version'.format(self.docs_base))
|
||||||
req.raise_for_status()
|
req.raise_for_status()
|
||||||
storage.remote_version = req.text
|
storage.remote_version = req.text.strip()
|
||||||
storage.last_update_check = datetime.utcnow()
|
storage.last_update_check = datetime.utcnow()
|
||||||
storage.save(self._path)
|
storage.save(self._path)
|
||||||
return storage
|
return storage
|
||||||
|
@ -5,6 +5,8 @@ import logging
|
|||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
|
from esphomeyaml import core
|
||||||
|
|
||||||
_LOGGER = logging.getLogger(__name__)
|
_LOGGER = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
@ -48,6 +50,21 @@ def shlex_quote(s):
|
|||||||
return u"'" + s.replace(u"'", u"'\"'\"'") + u"'"
|
return u"'" + s.replace(u"'", u"'\"'\"'") + u"'"
|
||||||
|
|
||||||
|
|
||||||
|
class RedirectText(object):
|
||||||
|
def __init__(self, out):
|
||||||
|
self._out = out
|
||||||
|
|
||||||
|
def write(self, s):
|
||||||
|
s = s.replace('\033', '\\033')
|
||||||
|
self._out.write(s)
|
||||||
|
|
||||||
|
def flush(self):
|
||||||
|
self._out.flush()
|
||||||
|
|
||||||
|
def isatty(self):
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
def run_external_command(func, *cmd, **kwargs):
|
def run_external_command(func, *cmd, **kwargs):
|
||||||
def mock_exit(return_code):
|
def mock_exit(return_code):
|
||||||
raise SystemExit(return_code)
|
raise SystemExit(return_code)
|
||||||
@ -57,6 +74,10 @@ def run_external_command(func, *cmd, **kwargs):
|
|||||||
full_cmd = u' '.join(shlex_quote(x) for x in cmd)
|
full_cmd = u' '.join(shlex_quote(x) for x in cmd)
|
||||||
_LOGGER.info(u"Running: %s", full_cmd)
|
_LOGGER.info(u"Running: %s", full_cmd)
|
||||||
|
|
||||||
|
if core.FROM_DASHBOARD:
|
||||||
|
sys.stdout = RedirectText(sys.stdout)
|
||||||
|
sys.stderr = RedirectText(sys.stderr)
|
||||||
|
|
||||||
capture_stdout = kwargs.get('capture_stdout', False)
|
capture_stdout = kwargs.get('capture_stdout', False)
|
||||||
if capture_stdout:
|
if capture_stdout:
|
||||||
sys.stdout = io.BytesIO()
|
sys.stdout = io.BytesIO()
|
||||||
@ -76,6 +97,11 @@ def run_external_command(func, *cmd, **kwargs):
|
|||||||
sys.argv = orig_argv
|
sys.argv = orig_argv
|
||||||
sys.exit = orig_exit
|
sys.exit = orig_exit
|
||||||
|
|
||||||
|
if isinstance(sys.stdout, RedirectText):
|
||||||
|
sys.stdout = sys.__stdout__
|
||||||
|
if isinstance(sys.stderr, RedirectText):
|
||||||
|
sys.stderr = sys.__stderr__
|
||||||
|
|
||||||
if capture_stdout:
|
if capture_stdout:
|
||||||
# pylint: disable=lost-exception
|
# pylint: disable=lost-exception
|
||||||
stdout = sys.stdout.getvalue()
|
stdout = sys.stdout.getvalue()
|
||||||
|
Loading…
Reference in New Issue
Block a user