From e6c94bf51f02fc50abaaf83e9d572baede32dd04 Mon Sep 17 00:00:00 2001 From: rubik Date: Wed, 8 Oct 2014 07:03:00 +0800 Subject: [PATCH 1/6] Colorize output to terminal --- supervisor_stdout.py | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/supervisor_stdout.py b/supervisor_stdout.py index 34cfff9..0187454 100644 --- a/supervisor_stdout.py +++ b/supervisor_stdout.py @@ -1,5 +1,11 @@ import sys +COLORS = tuple(range(30, 38)) + +def get_color(key): + use_string = key if isinstance(key, basestring) else str(key) + return COLORS[use_string.__hash__() % len(COLORS)] + def write_stdout(s): sys.stdout.write(s) sys.stdout.flush() @@ -19,7 +25,11 @@ def main(): def event_handler(event, response): line, data = response.split('\n', 1) headers = dict([ x.split(':') for x in line.split() ]) - print '%s %s | %s'%(headers['processname'], headers['channel'], data), + print '\033[1;%sm%s\033[1;m | \033[1;%sm%s\033[1;m | %s' % (get_color(headers['processname']), + headers['processname'], + get_color(headers['channel']), + headers['channel'], + data), if __name__ == '__main__': main() From 1b352db919ad77dc6a9962ce2aece5b96886e03c Mon Sep 17 00:00:00 2001 From: rubik Date: Wed, 8 Oct 2014 08:45:36 +0800 Subject: [PATCH 2/6] Add check to determine if we should send colorized output --- supervisor_stdout.py | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/supervisor_stdout.py b/supervisor_stdout.py index 0187454..bb1fc3a 100644 --- a/supervisor_stdout.py +++ b/supervisor_stdout.py @@ -6,6 +6,22 @@ def get_color(key): use_string = key if isinstance(key, basestring) else str(key) return COLORS[use_string.__hash__() % len(COLORS)] +def supports_color(): + """ + Taken from https://github.com/django/django/blob/master/django/core/management/color.py + + Returns True if the running system's terminal supports color, and False + otherwise. + """ + plat = sys.platform + supported_platform = plat != 'Pocket PC' and (plat != 'win32' or + 'ANSICON' in os.environ) + # isatty is not always implemented, #6223. + is_a_tty = hasattr(sys.stdout, 'isatty') and sys.stdout.isatty() + if not supported_platform or not is_a_tty: + return False + return True + def write_stdout(s): sys.stdout.write(s) sys.stdout.flush() @@ -25,11 +41,14 @@ def main(): def event_handler(event, response): line, data = response.split('\n', 1) headers = dict([ x.split(':') for x in line.split() ]) - print '\033[1;%sm%s\033[1;m | \033[1;%sm%s\033[1;m | %s' % (get_color(headers['processname']), - headers['processname'], - get_color(headers['channel']), - headers['channel'], - data), + if supports_color(): + print '\033[1;%sm%s\033[1;m | \033[1;%sm%s\033[1;m | %s' % (get_color(headers['processname']), + headers['processname'], + get_color(headers['channel']), + headers['channel'], + data) + else: + print '%s | %s | %s'%(headers['processname'], headers['channel'], data) if __name__ == '__main__': main() From 1ab7d8ed1809048d98b29b0895c1363947bf14d3 Mon Sep 17 00:00:00 2001 From: rubik Date: Wed, 8 Oct 2014 09:03:17 +0800 Subject: [PATCH 3/6] Add support for env variables STDOUT_ALWAYS_ENABLE_COLOR_OUTPUT and STDOUT_DISABLE_COLOR_OUTPUT --- supervisor_stdout.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/supervisor_stdout.py b/supervisor_stdout.py index bb1fc3a..f66de64 100644 --- a/supervisor_stdout.py +++ b/supervisor_stdout.py @@ -1,3 +1,4 @@ +import os import sys COLORS = tuple(range(30, 38)) @@ -13,6 +14,13 @@ def supports_color(): Returns True if the running system's terminal supports color, and False otherwise. """ + + if os.getenv("STDOUT_ALWAYS_ENABLE_COLOR_OUTPUT") is True: + return True + + if os.getenv("STDOUT_DISABLE_COLOR_OUTPUT") is True: + return False + plat = sys.platform supported_platform = plat != 'Pocket PC' and (plat != 'win32' or 'ANSICON' in os.environ) From d99e13fab82f4eff52aca7234e6335a6434889d6 Mon Sep 17 00:00:00 2001 From: rubik Date: Wed, 8 Oct 2014 09:59:32 +0800 Subject: [PATCH 4/6] Fixed check for env vars. os.getenv does not return bool --- supervisor_stdout.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/supervisor_stdout.py b/supervisor_stdout.py index f66de64..fa0cf03 100644 --- a/supervisor_stdout.py +++ b/supervisor_stdout.py @@ -15,10 +15,10 @@ def supports_color(): otherwise. """ - if os.getenv("STDOUT_ALWAYS_ENABLE_COLOR_OUTPUT") is True: + if os.getenv("STDOUT_ALWAYS_ENABLE_COLOR_OUTPUT"): return True - if os.getenv("STDOUT_DISABLE_COLOR_OUTPUT") is True: + if os.getenv("STDOUT_DISABLE_COLOR_OUTPUT"): return False plat = sys.platform From 1cac8a1279b837f50c529c50f0d8f215502b91cf Mon Sep 17 00:00:00 2001 From: rubik Date: Wed, 8 Oct 2014 11:10:01 +0800 Subject: [PATCH 5/6] Add in copyright attribution to the Django project and a license statement --- supervisor_stdout.py | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/supervisor_stdout.py b/supervisor_stdout.py index fa0cf03..268e6f9 100644 --- a/supervisor_stdout.py +++ b/supervisor_stdout.py @@ -1,3 +1,33 @@ +# This file contains code that was adapted from Django. [https://github.com/django/django/] + +# Copyright (c) Django Software Foundation and individual contributors. +# All rights reserved. + +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: + +# 1. Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. + +# 2. Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. + +# 3. Neither the name of Django nor the names of its contributors may be used +# to endorse or promote products derived from this software without +# specific prior written permission. + +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR +# ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES +# (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; +# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON +# ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS +# SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + import os import sys From df00a69875f67fa33afb0eac741fe78c0886adf6 Mon Sep 17 00:00:00 2001 From: rubik Date: Wed, 8 Oct 2014 14:29:32 +0800 Subject: [PATCH 6/6] Add comma to end of print statements --- supervisor_stdout.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/supervisor_stdout.py b/supervisor_stdout.py index 268e6f9..3289fd8 100644 --- a/supervisor_stdout.py +++ b/supervisor_stdout.py @@ -81,12 +81,12 @@ def event_handler(event, response): headers = dict([ x.split(':') for x in line.split() ]) if supports_color(): print '\033[1;%sm%s\033[1;m | \033[1;%sm%s\033[1;m | %s' % (get_color(headers['processname']), - headers['processname'], - get_color(headers['channel']), - headers['channel'], - data) + headers['processname'], + get_color(headers['channel']), + headers['channel'], + data), else: - print '%s | %s | %s'%(headers['processname'], headers['channel'], data) + print '%s | %s | %s' % (headers['processname'], headers['channel'], data), if __name__ == '__main__': main()