curses_display.py 5.39 KB
Newer Older
Mario Hock's avatar
Mario Hock committed
1
2
3
4
5
6
7
8
9
10
11
# -*- coding:utf-8 -*-

'''
Curses display for »cpunetlog«.

This code is inspired and partially copied from »bwtop« written by
"Mahmoud Adel <mahmoud.adel2@gmail.com>" and distributed under the MIT license.
'''

import curses
import time
Mario Hock's avatar
Mario Hock committed
12
import helpers
Mario Hock's avatar
Mario Hock committed
13
14
15
16
17
18
19
20

## XXX disable colors
disablecolorskipped = True

stdscr = None

## some "constants"/preferences
nics = None
Mario Hock's avatar
Mario Hock committed
21
nic_speeds = None
Mario Hock's avatar
Mario Hock committed
22
divisor = 1000000.0
Mario Hock's avatar
Mario Hock committed
23
rounding_digits = 2
Mario Hock's avatar
Mario Hock committed
24
unit = "MBits"
Mario Hock's avatar
Mario Hock committed
25
26


Mario Hock's avatar
..    
Mario Hock committed
27
28
29
30
31
32
## TODO ideas..
#   - total (GB transferred)
#   - other (CPU usage)

## TODO idea: smoothing..?

Mario Hock's avatar
Mario Hock committed
33
34
35
36
37
38
39
40

def _format_net_speed(speed):
    return str( round(speed / divisor, rounding_digits) )



def init():
    global stdscr
Mario Hock's avatar
Mario Hock committed
41
42
43
44
    global nic_speeds

    if not nic_speeds:
        nic_speeds = helpers.get_nic_speeds()
Mario Hock's avatar
Mario Hock committed
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

    stdscr = curses.initscr()
    curses.noecho()
    curses.cbreak()
    stdscr.keypad(True)
    curses.curs_set(False)
    stdscr.nodelay(True)

    curses.start_color()
    curses.use_default_colors()
    if not disablecolorskipped:
        curses.init_pair(1, -1, -1)
        curses.init_pair(2, -1, -1)
        curses.init_pair(3, -1, -1)
        curses.init_pair(4, -1, -1)
    else:
        curses.init_pair(1, curses.COLOR_MAGENTA, -1)
        curses.init_pair(2, curses.COLOR_BLUE, -1)
        curses.init_pair(3, curses.COLOR_GREEN, -1)
        curses.init_pair(4, curses.COLOR_YELLOW, -1)

    ## Show some output to avoid upsetting the user
    stdscr.addstr(3, 3, "loading ...", curses.A_BOLD)
    stdscr.refresh()



def display(measurement):
    global stdscr

Mario Hock's avatar
Mario Hock committed
75
    ## Press 'q' to quit.
Mario Hock's avatar
Mario Hock committed
76
77
78
79
    pressedkey = stdscr.getch()
    if pressedkey == ord('q'):
        return False

Mario Hock's avatar
Mario Hock committed
80
    ## Header
Mario Hock's avatar
Mario Hock committed
81
82
83
    stdscr.clear()
    stdscr.border(0)
    timenow = time.strftime("%H:%M:%S")
Mario Hock's avatar
Mario Hock committed
84
    stdscr.addstr(1, 1, 'CPUnetLOG          Time: {0}                Interval: {1}s'.format(timenow, round(measurement.timespan, 1)), curses.A_BOLD)
Mario Hock's avatar
Mario Hock committed
85
86
    stdscr.refresh()

Mario Hock's avatar
Mario Hock committed
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
    y = 3

    ## CPU ##
    num=1
    for cpu in measurement.cpu_times_percent:
        stdscr.addstr(y, 1, 'CPU{0}'.format( num ), curses.color_pair(1))
        stdscr.addstr(y, 20, 'util:', curses.color_pair(2))
        stdscr.addstr(y, 26, '{0:.2%}'.format( (100-cpu.idle)/100.0 ), curses.color_pair(3))
        stdscr.addstr(y, 50, 'user:', curses.color_pair(2))
        stdscr.addstr(y, 56, '{0:.2%}'.format( cpu.user/100.0 ), curses.color_pair(3))
        stdscr.addstr(y, 66, 'system:', curses.color_pair(2))
        stdscr.addstr(y, 74, '{0:.2%}'.format( cpu.system/100.0 ), curses.color_pair(3))

        num += 1
        y += 1




    ## Network ##

    y += 1
    stdscr.hline(y, 1, "-", 85)
    y += 1

Mario Hock's avatar
Mario Hock committed
112
113
114
115
116
117
118
119
120
121
122
123
124
    # display all nics (if not set otherwise)
    if nics:
        active_nics = nics
    else:
        active_nics = measurement.net_io.keys()

    sum_sending = 0
    sum_receiving = 0

    ## display the values
    for nic in active_nics:
        values = measurement.net_io[nic]

Mario Hock's avatar
Mario Hock committed
125
126
        _send = values.ratio["bytes_sent"] * 8  # Bits/s
        _recv = values.ratio["bytes_recv"] * 8  # Bits/s
Mario Hock's avatar
Mario Hock committed
127
        sending = _format_net_speed( _send )
Mario Hock's avatar
Mario Hock committed
128
        send_ratio = _send/nic_speeds[nic]
Mario Hock's avatar
Mario Hock committed
129
        receiving = _format_net_speed( _recv )
Mario Hock's avatar
Mario Hock committed
130
        receive_ratio = _recv/nic_speeds[nic]
Mario Hock's avatar
Mario Hock committed
131
132
133

        sum_sending += _send
        sum_receiving += _recv
Mario Hock's avatar
Mario Hock committed
134
135

        stdscr.addstr(y, 1, '{0}'.format(nic), curses.color_pair(1))
Mario Hock's avatar
Mario Hock committed
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
        stdscr.addstr(y, 20, 'Sent: |', curses.color_pair(2))
        stdscr.addstr(y, 50, 'Received: |', curses.color_pair(2))
        stdscr.addstr(y, 47, "|", curses.color_pair(2))
        stdscr.addstr(y, 81, "|", curses.color_pair(2))

        ## XXX prototypical "inline"-coloring
        _snd_str = '{0} {1}/s'.format(sending, unit, send_ratio)
        _snd_str += " " * (20-len(_snd_str))
        _load_len = int(send_ratio * 20)
        stdscr.addstr(y, 27, _snd_str[0:_load_len], curses.color_pair(3)|curses.A_REVERSE)
        stdscr.addstr(y, 27+_load_len, _snd_str[_load_len:], curses.color_pair(3))

        _recv_str = '{0} {1}/s'.format(receiving, unit, send_ratio)
        _recv_str += " " * (20-len(_recv_str))
        _load_len = int(receive_ratio * 20)
        stdscr.addstr(y, 61, _recv_str[0:_load_len], curses.color_pair(3)|curses.A_REVERSE)
        stdscr.addstr(y, 61+_load_len, _recv_str[_load_len:], curses.color_pair(3))
Mario Hock's avatar
Mario Hock committed
153

Mario Hock's avatar
Mario Hock committed
154
        ## XXX TESTING
Mario Hock's avatar
Mario Hock committed
155
156
157
158
159
        #y += 1
        #stdscr.addstr(y, 25, "|" + " "*20 + "|", curses.color_pair(2))
        #stdscr.addstr(y, 26, " " * int(send_ratio * 20), curses.color_pair(3)|curses.A_REVERSE)
        #stdscr.addstr(y, 59, "|" + " "*20 + "|", curses.color_pair(2))
        #stdscr.addstr(y, 60, " " * int(receive_ratio * 20), curses.color_pair(3)|curses.A_REVERSE)
Mario Hock's avatar
Mario Hock committed
160

Mario Hock's avatar
Mario Hock committed
161
162
163
164
165
166
        y += 1

    ## Total
    y+=1
    stdscr.addstr(y, 1, 'Total:', curses.color_pair(4))
    stdscr.addstr(y, 20, 'Sent:', curses.color_pair(2))
Mario Hock's avatar
Mario Hock committed
167
168
    #stdscr.addstr(y, 26, '{0} {1}/s'.format(_format_net_speed(sum_sending), unit), curses.color_pair(3) | curses.A_STANDOUT)
    stdscr.addstr(y, 26, '{0} {1}/s'.format(_format_net_speed(sum_sending), unit), curses.color_pair(3))
Mario Hock's avatar
Mario Hock committed
169
    stdscr.addstr(y, 50, 'Received:', curses.color_pair(2))
Mario Hock's avatar
Mario Hock committed
170
171
    #stdscr.addstr(y, 60, '{0} {1}/s'.format(_format_net_speed(sum_receiving),unit), curses.color_pair(3) | curses.A_STANDOUT)
    stdscr.addstr(y, 60, '{0} {1}/s'.format(_format_net_speed(sum_receiving),unit), curses.color_pair(3))
Mario Hock's avatar
Mario Hock committed
172
173
174
175
176
177
178
179
180
181
182
183
184
185

    stdscr.refresh()

    return True


def close():
    global stdscr

    curses.nocbreak()
    stdscr.keypad(False)
    curses.echo()
    curses.curs_set(True)
    curses.endwin()