Test Failed
Push — master ( cc9054...a8608f )
by Nicolas
03:40
created

glances.outputs.glances_colors   A

Complexity

Total Complexity 15

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 113
dl 0
loc 161
rs 10
c 0
b 0
f 0
wmc 15

5 Methods

Rating   Name   Duplication   Size   Complexity  
A GlancesColors.__repr__() 0 2 1
B GlancesColors.__define_colors() 0 51 5
A GlancesColors.__define_bw() 0 19 1
B GlancesColors.__init__() 0 31 7
A GlancesColors.get() 0 27 1
1
#
2
# This file is part of Glances.
3
#
4
# SPDX-FileCopyrightText: 2024 Nicolas Hennion <[email protected]>
5
#
6
# SPDX-License-Identifier: LGPL-3.0-only
7
#
8
9
"""Glances colors."""
10
11
import sys
12
13
from glances.logger import logger
14
15
try:
16
    import curses
17
except ImportError:
18
    logger.critical("Curses module not found. Glances cannot start in standalone mode.")
19
    sys.exit(1)
20
21
22
class GlancesColors:
23
    """Class to manage colors in Glances UI
24
    For the moment limited to Curses interface.
25
    But will be used in the WebUI through the issue #2048"""
26
27
    def __init__(self, args) -> None:
28
        self.args = args
29
30
        # Define "home made" bold
31
        self.A_BOLD = 0 if args.disable_bold else curses.A_BOLD
32
33
        # Set defaults curses colors
34
        try:
35
            if hasattr(curses, 'start_color'):
36
                curses.start_color()
37
                logger.debug(f'Curses interface compatible with {curses.COLORS} colors')
38
            if hasattr(curses, 'use_default_colors'):
39
                # Use -1 to use the default foregound/background color
40
                curses.use_default_colors()
41
            if hasattr(curses, 'assume_default_colors'):
42
                # Define the color index 0 with -1 and -1 for foregound/background
43
                # = curses.init_pair(0, -1, -1)
44
                curses.assume_default_colors(-1, -1)
45
        except Exception as e:
46
            logger.warning(f'Error initializing terminal color ({e})')
47
48
        if curses.has_colors():
49
            # The screen is compatible with a colored design
50
            # ex: export TERM=xterm-256color
51
            #     export TERM=xterm-color
52
            self.__define_colors()
53
        else:
54
            # The screen is NOT compatible with a colored design
55
            # switch to B&W text styles
56
            # ex: export TERM=xterm-mono
57
            self.__define_bw()
58
59
    def __repr__(self) -> dict:
60
        return self.get()
61
62
    def __define_colors(self) -> None:
63
        curses.init_pair(1, -1, -1)
64
        if self.args.disable_bg:
65
            curses.init_pair(2, curses.COLOR_RED, -1)
66
            curses.init_pair(3, curses.COLOR_GREEN, -1)
67
            curses.init_pair(5, curses.COLOR_MAGENTA, -1)
68
        else:
69
            curses.init_pair(2, -1, curses.COLOR_RED)
70
            curses.init_pair(3, curses.COLOR_BLACK, curses.COLOR_GREEN)
71
            curses.init_pair(5, -1, curses.COLOR_MAGENTA)
72
        curses.init_pair(4, curses.COLOR_BLUE, -1)
73
        curses.init_pair(6, curses.COLOR_RED, -1)
74
        curses.init_pair(7, curses.COLOR_GREEN, -1)
75
        curses.init_pair(8, curses.COLOR_MAGENTA, -1)
76
77
        # Colors text styles
78
        self.DEFAULT = curses.color_pair(1)
79
        self.OK_LOG = curses.color_pair(3) | self.A_BOLD
80
        self.NICE = curses.color_pair(8)
81
        self.CPU_TIME = curses.color_pair(8)
82
        self.CAREFUL_LOG = curses.color_pair(4) | self.A_BOLD
83
        self.WARNING_LOG = curses.color_pair(5) | self.A_BOLD
84
        self.CRITICAL_LOG = curses.color_pair(2) | self.A_BOLD
85
        self.OK = curses.color_pair(7)
86
        self.CAREFUL = curses.color_pair(4)
87
        self.WARNING = curses.color_pair(8) | self.A_BOLD
88
        self.CRITICAL = curses.color_pair(6) | self.A_BOLD
89
        self.INFO = curses.color_pair(4)
90
        self.FILTER = self.A_BOLD
91
        self.SELECTED = self.A_BOLD
92
        self.SEPARATOR = curses.color_pair(1)
93
94
        if curses.COLORS > 8:
95
            # ex: export TERM=xterm-256color
96
            try:
97
                curses.init_pair(9, curses.COLOR_CYAN, -1)
98
                curses.init_pair(10, curses.COLOR_YELLOW, -1)
99
            except Exception:
100
                curses.init_pair(9, -1, -1)
101
                curses.init_pair(10, -1, -1)
102
            self.FILTER = curses.color_pair(9) | self.A_BOLD
103
            self.SELECTED = curses.color_pair(10) | self.A_BOLD
104
105
            # Define separator line style
106
            try:
107
                curses.init_color(11, 500, 500, 500)
108
                curses.init_pair(11, curses.COLOR_BLACK, -1)
109
                self.SEPARATOR = curses.color_pair(11)
110
            except Exception:
111
                # Catch exception in TMUX
112
                pass
113
114
    def __define_bw(self) -> None:
115
        # The screen is NOT compatible with a colored design
116
        # switch to B&W text styles
117
        # ex: export TERM=xterm-mono
118
        self.DEFAULT = -1
119
        self.OK_LOG = -1
120
        self.NICE = self.A_BOLD
121
        self.CPU_TIME = self.A_BOLD
122
        self.CAREFUL_LOG = self.A_BOLD
123
        self.WARNING_LOG = curses.A_UNDERLINE
124
        self.CRITICAL_LOG = curses.A_REVERSE
125
        self.OK = -1
126
        self.CAREFUL = self.A_BOLD
127
        self.WARNING = curses.A_UNDERLINE
128
        self.CRITICAL = curses.A_REVERSE
129
        self.INFO = self.A_BOLD
130
        self.FILTER = self.A_BOLD
131
        self.SELECTED = self.A_BOLD
132
        self.SEPARATOR = -1
133
134
    def get(self) -> dict:
135
        return {
136
            'DEFAULT': self.DEFAULT,
137
            'UNDERLINE': curses.A_UNDERLINE,
138
            'BOLD': self.A_BOLD,
139
            'SORT': curses.A_UNDERLINE | self.A_BOLD,
140
            'OK': self.OK,
141
            'MAX': self.OK | self.A_BOLD,
142
            'FILTER': self.FILTER,
143
            'TITLE': self.A_BOLD,
144
            'PROCESS': self.OK,
145
            'PROCESS_SELECTED': self.OK | curses.A_UNDERLINE,
146
            'STATUS': self.OK,
147
            'NICE': self.NICE,
148
            'CPU_TIME': self.CPU_TIME,
149
            'CAREFUL': self.CAREFUL,
150
            'WARNING': self.WARNING,
151
            'CRITICAL': self.CRITICAL,
152
            'OK_LOG': self.OK_LOG,
153
            'CAREFUL_LOG': self.CAREFUL_LOG,
154
            'WARNING_LOG': self.WARNING_LOG,
155
            'CRITICAL_LOG': self.CRITICAL_LOG,
156
            'PASSWORD': curses.A_PROTECT,
157
            'SELECTED': self.SELECTED,
158
            'INFO': self.INFO,
159
            'ERROR': self.SELECTED,
160
            'SEPARATOR': self.SEPARATOR,
161
        }
162