Selaa lähdekoodia

Merge branch 'offbyone/ncurses-ui-layout'

Ask Solem 14 vuotta sitten
vanhempi
commit
87c310a151
4 muutettua tiedostoa jossa 91 lisäystä ja 13 poistoa
  1. 1 0
      .gitignore
  2. 33 12
      celery/events/cursesmon.py
  3. 56 0
      celery/tests/test_cursesmon.py
  4. 1 1
      celery/utils/__init__.py

+ 1 - 0
.gitignore

@@ -15,3 +15,4 @@ erl_crash.dump
 *.db
 Documentation/
 .tox/
+.ropeproject/

+ 33 - 12
celery/events/cursesmon.py

@@ -7,11 +7,18 @@ import time
 from datetime import datetime
 from itertools import count
 from textwrap import wrap
+from math import ceil
 
 from celery import states
 from celery.app import app_or_default
 from celery.utils import abbr, abbrtask
 
+BORDER_SPACING = 4
+UUID_WIDTH = 36
+STATE_WIDTH = 8
+TIMESTAMP_WIDTH = 8
+MIN_WORKER_WIDTH = 15
+MIN_TASK_WIDTH = 16
 
 class CursesMonitor(object):
     keymap = {}
@@ -43,22 +50,36 @@ class CursesMonitor(object):
                           "L": self.selection_rate_limit}
         self.keymap = dict(default_keymap, **self.keymap)
 
-    def format_row(self, uuid, worker, task, timestamp, state):
-        my, mx = self.win.getmaxyx()
-        mx = mx - 3
-        uuid_max = 36
-        if mx < 88:
-            uuid_max = mx - 52 - 2
-        uuid = abbr(uuid, uuid_max).ljust(uuid_max)
-        worker = abbr(worker, 16).ljust(16)
-        task = abbrtask(task, 16).ljust(16)
-        state = abbr(state, 8).ljust(8)
-        timestamp = timestamp.ljust(8)
+    def format_row(self, uuid, task, worker, timestamp, state):
+        mx = self.display_width
+        detail_width = mx - 1 - STATE_WIDTH - 1 - TIMESTAMP_WIDTH # include spacing
+        uuid_space = detail_width - 1 - MIN_TASK_WIDTH - 1 - MIN_WORKER_WIDTH # include spacing
+
+        if uuid_space < UUID_WIDTH:
+            uuid_width = uuid_space
+        else:
+            uuid_width = UUID_WIDTH
+
+        detail_width = detail_width - uuid_width - 1
+        task_width = int(ceil(detail_width / 2.0))
+        worker_width = detail_width - task_width - 1
+
+        uuid = abbr(uuid, uuid_width).ljust(uuid_width)
+        worker = abbr(worker, worker_width).ljust(worker_width)
+        task = abbrtask(task, task_width).ljust(task_width)
+        state = abbr(state, STATE_WIDTH).ljust(STATE_WIDTH)
+        timestamp = timestamp.ljust(TIMESTAMP_WIDTH)
+
         row = "%s %s %s %s %s " % (uuid, worker, task, timestamp, state)
         if self.screen_width is None:
             self.screen_width = len(row[:mx])
         return row[:mx]
 
+    @property
+    def display_width(self):
+         _, mx = self.win.getmaxyx()
+         return mx - BORDER_SPACING
+
     def find_position(self):
         if not self.tasks:
             return 0
@@ -283,7 +304,7 @@ class CursesMonitor(object):
                     lineno = y()
                     win.addstr(lineno, x, line, attr)
                     if state_color:
-                        win.addstr(lineno, len(line) - len(task.state) + 1,
+                        win.addstr(lineno, len(line) - STATE_WIDTH + BORDER_SPACING - 1,
                                 task.state, state_color | attr)
                     if task.ready:
                         task.visited = time.time()

+ 56 - 0
celery/tests/test_cursesmon.py

@@ -0,0 +1,56 @@
+from celery.tests.utils import unittest
+
+from celery.events import cursesmon
+
+class MockWindow(object):
+
+    def getmaxyx(self):
+        return self.y, self.x
+
+class TestCursesDisplay(unittest.TestCase):
+
+    def setUp(self):
+        self.monitor = cursesmon.CursesMonitor(object())
+        self.win = MockWindow()
+        self.monitor.win = self.win
+
+    def test_format_row_with_default_widths(self):
+        self.win.x, self.win.y = 91, 24
+        row = self.monitor.format_row(
+            '783da208-77d0-40ca-b3d6-37dd6dbb55d3',
+            'task.task.task.task.task.task.task.task.task.tas',
+            'workerworkerworkerworkerworkerworkerworkerworker',
+            '21:13:20',
+            'SUCCESS')
+        self.assertEqual('783da208-77d0-40ca-b3d6-37dd6dbb55d3 workerworker... task.task.[.]tas 21:13:20 SUCCESS ',
+                         row)
+
+    def test_format_row_with_truncated_uuid(self):
+        self.win.x, self.win.y = 80, 24
+        row = self.monitor.format_row(
+            '783da208-77d0-40ca-b3d6-37dd6dbb55d3',
+            'task.task.task.task.task.task.task.task.task.tas',
+            'workerworkerworkerworkerworkerworkerworkerworker',
+            '21:13:20',
+            'SUCCESS')
+        self.assertEqual('783da208-77d0-40ca-b3d... workerworker... task.task.[.]tas 21:13:20 SUCCESS ',
+                         row)
+
+    def test_format_title_row(self):
+        self.win.x, self.win.y = 80, 24
+        row = self.monitor.format_row("UUID", "TASK",
+                                      "WORKER", "TIME", "STATE")
+        self.assertEqual('UUID                      WORKER          TASK             TIME     STATE   ',
+                         row)
+
+    def test_format_row_for_wide_screen_with_short_uuid(self):
+        self.win.x, self.win.y = 140, 24
+        row = self.monitor.format_row(
+            '783da208-77d0-40ca-b3d6-37dd6dbb55d3',
+            'task.task.task.task.task.task.task.task.task.tas',
+            'workerworkerworkerworkerworkerworkerworkerworker',
+            '21:13:20',
+            'SUCCESS')
+        self.assertEqual(136, len(row))
+        self.assertEqual('783da208-77d0-40ca-b3d6-37dd6dbb55d3 workerworkerworkerworkerworkerworker... task.task.task.task.task.task.task.[.]tas 21:13:20 SUCCESS ',
+                         row)

+ 1 - 1
celery/utils/__init__.py

@@ -306,7 +306,7 @@ def abbrtask(S, max):
         return "???"
     if len(S) > max:
         module, _, cls = rpartition(S, ".")
-        module = abbr(module, max - len(cls), False)
+        module = abbr(module, max - len(cls) - 3, False)
         return module + "[.]" + cls
     return S