Skip to content

Commit e7de516

Browse files
committed
Simplify color management
We get rid of the colors.FIELD_BY_MODE dict and: - define PINNED_COLOR and FOCUSED_COLOR when rows are pinned or focused; - let the functions in colors module return the color name directly, instead of previously indirecting to FIELD_BY_MODE dict; - move default color values UI.make() body. Also, the methods and attributes of types.Column are changed a bit: now 'default_color' holds the default color (or None when "normal" should be used, but we don't repeat it there) and value_color() is the callable (typically a function from 'colors' module), previously name color_key().
1 parent 7d73795 commit e7de516

File tree

4 files changed

+61
-165
lines changed

4 files changed

+61
-165
lines changed

pgactivity/colors.py

Lines changed: 12 additions & 126 deletions
Original file line numberDiff line numberDiff line change
@@ -1,134 +1,20 @@
1+
from __future__ import annotations
2+
13
from . import utils
24

3-
FIELD_BY_MODE = {
4-
"pid": {
5-
"default": "cyan",
6-
"cursor": "cyan_reverse",
7-
"pinned": "yellow_bold",
8-
},
9-
"database": {
10-
"default": "black_bold",
11-
"cursor": "cyan_reverse",
12-
"pinned": "yellow_bold",
13-
},
14-
"application_name": {
15-
"default": "black_bold",
16-
"cursor": "cyan_reverse",
17-
"pinned": "yellow_bold",
18-
},
19-
"user": {
20-
"default": "black_bold",
21-
"cursor": "cyan_reverse",
22-
"pinned": "yellow_bold",
23-
},
24-
"client": {
25-
"default": "cyan",
26-
"cursor": "cyan_reverse",
27-
"pinned": "yellow_bold",
28-
},
29-
"cpu": {
30-
"default": "normal",
31-
"cursor": "cyan_reverse",
32-
"pinned": "yellow_bold",
33-
},
34-
"mem": {
35-
"default": "normal",
36-
"cursor": "cyan_reverse",
37-
"pinned": "yellow_bold",
38-
},
39-
"read": {
40-
"default": "normal",
41-
"cursor": "cyan_reverse",
42-
"pinned": "yellow_bold",
43-
},
44-
"write": {
45-
"default": "normal",
46-
"cursor": "cyan_reverse",
47-
"pinned": "yellow_bold",
48-
},
49-
"time_red": {
50-
"default": "red",
51-
"cursor": "cyan_reverse",
52-
"pinned": "yellow_bold",
53-
},
54-
"time_yellow": {
55-
"default": "yellow",
56-
"cursor": "cyan_reverse",
57-
"pinned": "yellow_bold",
58-
},
59-
"time_green": {
60-
"default": "green",
61-
"cursor": "cyan_reverse",
62-
"pinned": "yellow_bold",
63-
},
64-
"wait_green": {
65-
"default": "green_bold",
66-
"cursor": "cyan_reverse",
67-
"pinned": "yellow_bold",
68-
},
69-
"wait_red": {
70-
"default": "red_bold",
71-
"cursor": "cyan_reverse",
72-
"pinned": "yellow_bold",
73-
},
74-
"state_default": {
75-
"default": "normal",
76-
"cursor": "cyan_reverse",
77-
"pinned": "yellow_bold",
78-
},
79-
"state_yellow": {
80-
"default": "yellow",
81-
"cursor": "cyan_reverse",
82-
"pinned": "yellow_bold",
83-
},
84-
"state_green": {
85-
"default": "green",
86-
"cursor": "cyan_reverse",
87-
"pinned": "yellow_bold",
88-
},
89-
"state_red": {
90-
"default": "red",
91-
"cursor": "cyan_reverse",
92-
"pinned": "yellow_bold",
93-
},
94-
"query": {
95-
"default": "normal",
96-
"cursor": "cyan_reverse",
97-
"pinned": "yellow_bold",
98-
},
99-
"relation": {
100-
"default": "cyan",
101-
"cursor": "cyan_reverse",
102-
"pinned": "yellow_bold",
103-
},
104-
"type": {
105-
"default": "normal",
106-
"cursor": "cyan_reverse",
107-
"pinned": "yellow_bold",
108-
},
109-
"mode_yellow": {
110-
"default": "yellow_bold",
111-
"cursor": "cyan_reverse",
112-
"pinned": "yellow_bold",
113-
},
114-
"mode_red": {
115-
"default": "red_bold",
116-
"cursor": "cyan_reverse",
117-
"pinned": "yellow_bold",
118-
},
119-
}
5+
PINNED_COLOR = "bold_yellow"
6+
FOCUSED_COLOR = "cyan_reverse"
1207

1218

122-
def short_state(state: str) -> str:
9+
def short_state(state: str) -> str | None:
12310
state = utils.short_state(state)
12411
if state == "active":
125-
return "state_green"
12+
return "green"
12613
elif state == "idle in trans":
127-
return "state_yellow"
14+
return "yellow"
12815
elif state == "idle in trans (a)":
129-
return "state_red"
130-
else:
131-
return "state_default"
16+
return "red"
17+
return None
13218

13319

13420
def lock_mode(mode: str) -> str:
@@ -137,10 +23,10 @@ def lock_mode(mode: str) -> str:
13723
"RowExclusiveLock",
13824
"AccessExclusiveLock",
13925
):
140-
return "mode_red"
26+
return "bold_red"
14127
else:
142-
return "mode_yellow"
28+
return "bold_yellow"
14329

14430

14531
def wait(value: bool) -> str:
146-
return "wait_red" if value else "wait_green"
32+
return "red" if value else "green"

pgactivity/types.py

Lines changed: 21 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -98,9 +98,6 @@ class DurationMode(enum.IntEnum):
9898
backend = 3
9999

100100

101-
_color_key_marker = f"{id(object())}"
102-
103-
104101
def if_none(default: str) -> Callable[[Any], str]:
105102
def transform(value: Any) -> str:
106103
if value is None:
@@ -127,8 +124,6 @@ class Column:
127124
'4321 '
128125
>>> c.render('12345678')
129126
'876543'
130-
>>> c.color_key
131-
'pid'
132127
133128
>>> c = attr.evolve(c, justify="right", min_width=4, max_width=5)
134129
>>> c.title_render()
@@ -149,16 +144,14 @@ class Column:
149144
"left", validator=validators.in_(["left", "center", "right"])
150145
)
151146
transform: Callable[[Any], str] = attr.ib(default=if_none(""), repr=False)
152-
color_key: str | Callable[[Any], str] = attr.ib(
153-
default=_color_key_marker, repr=False
154-
)
147+
default_color: str | None = attr.ib(default=None, repr=False)
148+
value_color: Callable[[Any], str | None] | None = attr.ib(default=None, repr=False)
149+
# A callable returning a color name given a cell value or None to fall back to
150+
# "default_color"
155151

156152
_justify: Callable[[str], str] = attr.ib(init=False)
157153

158154
def __attrs_post_init__(self) -> None:
159-
if self.color_key == _color_key_marker:
160-
object.__setattr__(self, "color_key", self.key)
161-
162155
if self.justify == "left":
163156

164157
def _justify(value: str) -> str:
@@ -187,10 +180,12 @@ def title_color(self, sort_by: SortKey) -> str:
187180
def render(self, value: Any) -> str:
188181
return self._justify(self.transform(value))
189182

190-
def color(self, value: Any) -> str:
191-
if callable(self.color_key):
192-
return self.color_key(value)
193-
return self.color_key
183+
def color(self, value: Any) -> str | None:
184+
if callable(self.value_color):
185+
color = self.value_color(value)
186+
if color is not None:
187+
return color
188+
return self.default_color
194189

195190

196191
@attr.s(auto_attribs=True, slots=True)
@@ -316,6 +311,7 @@ def add_column(key: str, name: str, **kwargs: Any) -> None:
316311
min_width=16,
317312
max_width=16,
318313
justify="right",
314+
default_color="bold_black",
319315
)
320316
if Flag.CLIENT & flag:
321317
add_column(
@@ -325,6 +321,7 @@ def add_column(key: str, name: str, **kwargs: Any) -> None:
325321
max_width=16,
326322
justify="right",
327323
transform=if_none("local"),
324+
default_color="cyan",
328325
)
329326
if Flag.CPU & flag:
330327
add_column(
@@ -342,14 +339,15 @@ def add_column(key: str, name: str, **kwargs: Any) -> None:
342339
lambda v: utils.ellipsis(v, width=16) if v else "",
343340
),
344341
sort_key=None,
342+
default_color="bold_black",
345343
)
346344
if Flag.IOWAIT & flag:
347345
add_column(
348346
key="io_wait",
349347
name="IOW",
350348
min_width=4,
351349
transform=utils.yn,
352-
color_key=colors.wait,
350+
value_color=colors.wait,
353351
)
354352
if Flag.MEM & flag:
355353
add_column(
@@ -366,13 +364,14 @@ def add_column(key: str, name: str, **kwargs: Any) -> None:
366364
min_width=16,
367365
max_width=16,
368366
justify="right",
369-
color_key=colors.lock_mode,
367+
value_color=colors.lock_mode,
370368
)
371369
if Flag.PID & flag:
372370
add_column(
373371
key="pid",
374372
name="PID",
375373
min_width=6,
374+
default_color="cyan",
376375
)
377376
add_column(
378377
key="query",
@@ -394,14 +393,15 @@ def add_column(key: str, name: str, **kwargs: Any) -> None:
394393
min_width=9,
395394
max_width=9,
396395
justify="right",
396+
default_color="cyan",
397397
)
398398
add_column(
399399
key="state",
400400
name="state",
401401
min_width=17,
402402
justify="right",
403403
transform=utils.short_state,
404-
color_key=colors.short_state,
404+
value_color=colors.short_state,
405405
)
406406
if Flag.TIME & flag:
407407
add_column(
@@ -411,7 +411,7 @@ def add_column(key: str, name: str, **kwargs: Any) -> None:
411411
justify="right",
412412
sort_key=SortKey.duration,
413413
transform=lambda v: utils.format_duration(v)[0],
414-
color_key=lambda v: utils.format_duration(v)[1],
414+
value_color=lambda v: utils.format_duration(v)[1],
415415
)
416416
if Flag.TYPE & flag:
417417
add_column(
@@ -428,6 +428,7 @@ def add_column(key: str, name: str, **kwargs: Any) -> None:
428428
min_width=16,
429429
max_width=16,
430430
justify="right",
431+
default_color="bold_black",
431432
)
432433
if Flag.WAIT & flag:
433434
add_column(
@@ -437,7 +438,7 @@ def add_column(key: str, name: str, **kwargs: Any) -> None:
437438
max_width=16,
438439
justify="right",
439440
transform=utils.wait_status,
440-
color_key=colors.wait,
441+
value_color=colors.wait,
441442
)
442443
if Flag.WRITE & flag:
443444
add_column(

pgactivity/utils.py

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -128,31 +128,31 @@ def format_duration(duration: float | None) -> tuple[str, str]:
128128
"""Return a string from 'duration' value along with the color for rendering.
129129
130130
>>> format_duration(None)
131-
('N/A ', 'time_green')
131+
('N/A ', 'green')
132132
>>> format_duration(-0.000062)
133-
('0.000000', 'time_green')
133+
('0.000000', 'green')
134134
>>> format_duration(0.1)
135-
('0.100000', 'time_green')
135+
('0.100000', 'green')
136136
>>> format_duration(1.2)
137-
('00:01.20', 'time_yellow')
137+
('00:01.20', 'yellow')
138138
>>> format_duration(12345)
139-
('205:45.00', 'time_red')
139+
('205:45.00', 'red')
140140
>>> format_duration(60001)
141-
('16 h', 'time_red')
141+
('16 h', 'red')
142142
"""
143143
if duration is None:
144-
return "N/A".ljust(8), "time_green"
144+
return "N/A".ljust(8), "green"
145145

146146
if duration < 1:
147147
if duration < 0:
148148
duration = 0
149149
ctime = f"{duration:.6f}"
150-
color = "time_green"
150+
color = "green"
151151
elif duration < 60000:
152152
if duration < 3:
153-
color = "time_yellow"
153+
color = "yellow"
154154
else:
155-
color = "time_red"
155+
color = "red"
156156
duration_d = timedelta(seconds=float(duration))
157157
mic = "%.6d" % duration_d.microseconds
158158
ctime = "{}:{}.{}".format(
@@ -162,7 +162,7 @@ def format_duration(duration: float | None) -> tuple[str, str]:
162162
)
163163
else:
164164
ctime = "%s h" % str(int(duration / 3600))
165-
color = "time_red"
165+
color = "red"
166166

167167
return ctime, color
168168

0 commit comments

Comments
 (0)