Merge branch 'fix/stripAnsiFromPipOutput' into devel

Conflicts:
	src/octoprint/util/pip.py
This commit is contained in:
Gina Häußge 2016-02-09 13:00:30 +01:00
commit 910d965ede
2 changed files with 66 additions and 5 deletions

View file

@ -8,6 +8,39 @@ __copyright__ = "Copyright (C) 2015 The OctoPrint Project - Released under terms
import sarge
import logging
import re
# These regexes are based on the colorama package
# Author: Jonathan Hartley
# License: BSD-3 (https://github.com/tartley/colorama/blob/master/LICENSE.txt)
# Website: https://github.com/tartley/colorama/
_ANSI_CSI_PATTERN = "\001?\033\[(\??(?:\d|;)*)([a-zA-Z])\002?" # Control Sequence Introducer
_ANSI_OSC_PATTERN = "\001?\033\]((?:.|;)*?)(\x07)\002?" # Operating System Command
_ANSI_REGEX = re.compile("|".join([_ANSI_CSI_PATTERN,
_ANSI_OSC_PATTERN]))
def clean_ansi(line):
"""
Removes ANSI control codes from ``line``.
Parameters:
line (str or unicode): the line to process
Returns:
(str or unicode) The line without any ANSI control codes
Example::
>>> text = "Some text with some \x1b[31mred words\x1b[39m in it"
>>> clean_ansi(text)
'Some text with some red words in it'
>>> text = "We \x1b[?25lhide the cursor here and then \x1b[?25hshow it again here"
>>> clean_ansi(text)
'We hide the cursor here and then show it again here'
"""
return _ANSI_REGEX.sub("", line)
class CommandlineError(Exception):
@ -53,11 +86,13 @@ class CommandlineCaller(object):
while p.returncode is None:
line = p.stderr.readline(timeout=0.5)
if line:
line = self._preprocess_lines(line)
self._log_stderr(line)
all_stderr.append(line)
line = p.stdout.readline(timeout=0.5)
if line:
line = self._preprocess_lines(line)
self._log_stdout(line)
all_stdout.append(line)
@ -68,13 +103,14 @@ class CommandlineCaller(object):
stderr = p.stderr.text
if stderr:
split_lines = stderr.split("\n")
split_lines = self._preprocess_lines(
stderr.split("\n"))
self._log_stderr(*split_lines)
all_stderr += split_lines
stdout = p.stdout.text
if stdout:
split_lines = stdout.split("\n")
split_lines = self._preprocess_lines(stdout.split("\n"))
self._log_stdout(*split_lines)
all_stdout += split_lines
@ -85,3 +121,6 @@ class CommandlineCaller(object):
def _log_stderr(self, *lines):
self.on_log_stderr(*lines)
def _preprocess_lines(self, lines):
return lines

View file

@ -9,12 +9,12 @@ __copyright__ = "Copyright (C) 2015 The OctoPrint Project - Released under terms
import sarge
import sys
import logging
import re
import site
import pkg_resources
from .commandline import CommandlineCaller
from .commandline import CommandlineCaller, clean_ansi
from octoprint.util import to_unicode
_cache = dict(version=dict(), setup=dict())
@ -258,7 +258,7 @@ class PipCaller(CommandlineCaller):
self._logger.warn("Error while trying to run pip --version: {}".format(p.stderr.text))
return None, None
output = p.stdout.text
output = PipCaller._preprocess(p.stdout.text)
# output should look something like this:
#
# pip <version> from <path> (<python version>)
@ -363,6 +363,28 @@ class PipCaller(CommandlineCaller):
self._logger.debug("Could not detect desired output from testballoon install, got this instead: {!r}".format(data))
return False, False, False, None
def _preprocess_lines(self, lines):
return map(self._preprocess, lines)
@staticmethod
def _preprocess(text):
"""
Strips ANSI and VT100 cursor control characters from line and makes sure it's a unicode.
Parameters:
text (str or unicode): The text to process
Returns:
(unicode) The processed text as a unicode, stripped of ANSI and VT100 cursor show/hide codes
Example::
>>> text = b'some text with some\x1b[?25h ANSI codes for \x1b[31mred words\x1b[39m and\x1b[?25l also some cursor control codes'
>>> PipCaller._preprocess(text)
u'some text with some ANSI codes for red words and also some cursor control codes'
"""
return to_unicode(clean_ansi(text))
class LocalPipCaller(PipCaller):
"""
The LocalPipCaller always uses the pip instance associated with