Browse Source

iTerm worker logo: Support for screen/tmux

Ask Solem 8 years ago
parent
commit
8cb37f251a
6 changed files with 37 additions and 19 deletions
  1. 1 1
      MANIFEST.in
  2. 4 10
      celery/apps/worker.py
  3. 0 7
      celery/utils/static/__init__.py
  4. 0 0
      celery/utils/static/celery_128.png
  5. 31 0
      celery/utils/term.py
  6. 1 1
      docs/conf.py

+ 1 - 1
MANIFEST.in

@@ -17,7 +17,7 @@ recursive-include extra/systemd *
 recursive-include extra/zsh-completion *
 recursive-include examples *
 recursive-include requirements *.txt *.rst
-recursive-include celery/static *.png
+recursive-include celery/utils/static *.png
 
 recursive-exclude * __pycache__
 recursive-exclude * *.py[co]

+ 4 - 10
celery/apps/worker.py

@@ -21,12 +21,13 @@ from kombu.utils.encoding import safe_str
 from celery import VERSION_BANNER
 from celery import platforms
 from celery import signals
-from celery import static
 from celery.app import trace
 from celery.exceptions import WorkerShutdown, WorkerTerminate
 from celery.five import string, string_t
 from celery.loaders.app import AppLoader
 from celery.platforms import EX_FAILURE, EX_OK, check_privileges, isatty
+from celery.utils import static
+from celery.utils import term
 from celery.utils.debug import cry
 from celery.utils.imports import qualname
 from celery.utils.log import get_logger, in_sighandler, set_in_sighandler
@@ -135,9 +136,9 @@ class Worker(WorkController):
 
         # Dump configuration to screen so we have some basic information
         # for when users sends bug reports.
-        use_image = self._term_supports_images()
+        use_image = term.supports_images()
         if use_image:
-            self.termimage(static.logo_as_base64())
+            print(term.imgcat(static.logo()))
         print(safe_str(''.join([
             string(self.colored.cyan(
                 ' \n', self.startup_info(artlines=not use_image))),
@@ -148,9 +149,6 @@ class Worker(WorkController):
         if not self._custom_logging and self.redirect_stdouts:
             app.log.redirect_stdouts(self.redirect_stdouts_level)
 
-    def _term_supports_images(self):
-        return isatty(sys.stdin) and os.environ.get('ITERM_PROFILE')
-
     def on_consumer_ready(self, consumer):
         signals.worker_ready.send(sender=consumer)
         print('{0} ready.'.format(safe_str(self.hostname),))
@@ -182,10 +180,6 @@ class Worker(WorkController):
             tasklist = self.tasklist(include_builtins=include_builtins)
             return EXTRA_INFO_FMT.format(tasks=tasklist)
 
-    def termimage(self, s):
-        print('\n\033]1337;File=inline=1;'
-              'preserveAspectRatio=0:%s\a' % (s,))
-
     def startup_info(self, artlines=True):
         app = self.app
         concurrency = string(self.concurrency)

+ 0 - 7
celery/static/__init__.py → celery/utils/static/__init__.py

@@ -1,7 +1,5 @@
 from __future__ import absolute_import, unicode_literals
 
-import base64
-import codecs
 import os
 
 
@@ -11,8 +9,3 @@ def get_file(*args):
 
 def logo():
     return get_file('celery_128.png')
-
-
-def logo_as_base64():
-    with codecs.open(logo(), mode='rb') as fh:
-        return base64.b64encode(fh.read())

+ 0 - 0
celery/static/celery_128.png → celery/utils/static/celery_128.png


+ 31 - 0
celery/utils/term.py

@@ -2,11 +2,17 @@
 """Terminals and colors."""
 from __future__ import absolute_import, unicode_literals
 
+import base64
+import codecs
+import os
+import sys
+
 import platform
 
 from functools import reduce
 
 from celery.five import python_2_unicode_compatible, string
+from celery.platforms import isatty
 
 __all__ = ['colored']
 
@@ -17,6 +23,16 @@ COLOR_SEQ = '\033[1;%dm'
 
 IS_WINDOWS = platform.system() == 'Windows'
 
+ITERM_PROFILE = os.environ.get('ITERM_PROFILE')
+TERM = os.environ.get('TERM')
+TERM_IS_SCREEN = TERM.startswith('screen')
+
+# tmux requires unrecognized OSC sequences to be wrapped with DCS tmux;
+# <sequence> ST, and for all ESCs in <sequence> to be replaced with ESC ESC.
+# It only accepts ESC backslash for ST.
+_IMG_PRE = '\033Ptmux;\033\033]' if TERM_IS_SCREEN else '\033]'
+_IMG_POST = '\a\033\\' if TERM_IS_SCREEN else '\a'
+
 
 def fg(s):
     return COLOR_SEQ % s
@@ -150,3 +166,18 @@ class colored(object):
 
     def __add__(self, other):
         return string(self) + string(other)
+
+
+def supports_images():
+    return isatty(sys.stdin) and ITERM_PROFILE
+
+
+def _read_as_base64(path):
+    with codecs.open(path, mode='rb') as fh:
+        return base64.b64encode(fh.read())
+
+
+def imgcat(path, inline=1, preserve_aspect_ratio=0, **kwargs):
+    return '\n%s1337;File=inline=%d;preserveAspectRatio=%d:%s%s' % (
+        _IMG_PRE, inline, preserve_aspect_ratio,
+        _read_as_base64(path), _IMG_POST)

+ 1 - 1
docs/conf.py

@@ -39,9 +39,9 @@ globals().update(conf.build_config(
         'celery.app.base',
         'celery.apps',
         'celery.canvas',
-        'celery.static',
         'celery.concurrency.asynpool',
         'celery.utils.encoding',
+        r'celery.utils.static.*',
     ],
 ))