helpers.py 4.78 KB
Newer Older
Mario Hock's avatar
Mario Hock committed
1
#!/usr/bin/env python3
2
3
4
5
# -*- coding:utf-8 -*-

from collections import namedtuple
import os
Mario Hock's avatar
Mario Hock committed
6
import netifaces
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
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
75
76
77
78
79
80
81
82
83
84
85

_ptime_cpu_perc_nt = None


### Copied from »psutil« source code and adapted to calculate percentage on two input values rather than "live"
#     see: psutil/__init__.py:1282  (Version: 1.2.1-1ubuntu2)
def calculate_cpu_times_percent(cpu_times_older, cpu_times_younger, percpu=False):
    """Same as cpu_percent() but provides utilization percentages
    for each specific CPU time as is returned by cpu_times().
    For instance, on Linux we'll get:

      >>> cpu_times_percent()
      cpupercent(user=4.8, nice=0.0, system=4.8, idle=90.5, iowait=0.0,
                 irq=0.0, softirq=0.0, steal=0.0, guest=0.0, guest_nice=0.0)
      >>>

    interval and percpu arguments have the same meaning as in
    cpu_percent().
    """
    #global _last_cpu_times_2
    #global _last_per_cpu_times_2
#    blocking = interval is not None and interval > 0.0
    WINDOWS = os.name == 'nt'

    def calculate(t1, t2):
        global _ptime_cpu_perc_nt
        nums = []
        all_delta = sum(t2) - sum(t1)
        for field in t1._fields:
            field_delta = getattr(t2, field) - getattr(t1, field)
            try:
                field_perc = (100 * field_delta) / all_delta
            except ZeroDivisionError:
                field_perc = 0.0
            field_perc = round(field_perc, 1)
            if WINDOWS:
                # XXX
                # Work around:
                # https://code.google.com/p/psutil/issues/detail?id=392
                # CPU times are always supposed to increase over time
                # or at least remain the same and that's because time
                # cannot go backwards.
                # Surprisingly sometimes this might not be the case on
                # Windows where 'system' CPU time can be smaller
                # compared to the previous call, resulting in corrupted
                # percentages (< 0 or > 100).
                # I really don't know what to do about that except
                # forcing the value to 0 or 100.
                if field_perc > 100.0:
                    field_perc = 100.0
                elif field_perc < 0.0:
                    field_perc = 0.0
            nums.append(field_perc)
        if _ptime_cpu_perc_nt is None:
            _ptime_cpu_perc_nt = namedtuple('cpupercent', ' '.join(t1._fields))
        return _ptime_cpu_perc_nt(*nums)

    # system-wide usage
    if not percpu:
        #if blocking:
            #t1 = cpu_times()
            #time.sleep(interval)
        #else:
            #t1 = _last_cpu_times_2
        #_last_cpu_times_2 = cpu_times()
        #return calculate(t1, _last_cpu_times_2)
        return calculate(cpu_times_older, cpu_times_younger)
    # per-cpu usage
    else:
        ret = []
        #if blocking:
            #tot1 = cpu_times(percpu=True)
            #time.sleep(interval)
        #else:
            #tot1 = _last_per_cpu_times_2
        #_last_per_cpu_times_2 = cpu_times(percpu=True)
        for t1, t2 in zip(cpu_times_older, cpu_times_younger):
            ret.append(calculate(t1, t2))
        return ret
Mario Hock's avatar
Mario Hock committed
86
87
88
89
90
91
92
93
94
95
96
97



def get_nics():
    return netifaces.interfaces()

def get_nic_speeds():
    ret = dict()

    for nic in get_nics():
        try:
            with open("/sys/class/net/" + nic + "/speed", "r") as f:
Mario Hock's avatar
Mario Hock committed
98
                speed = int( f.read().strip() ) * 1000 * 1000
Mario Hock's avatar
Mario Hock committed
99
100
101
102
103
104
105

            ret[nic] = speed
        except OSError:
            speed = 0

    return ret

Mario Hock's avatar
Mario Hock committed
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154

def split_proprtionally(text, weights, size=0, fill=" "):
    """
    Split a string proportional to a given weight-distribution.

    If a |size| is specified, that string is filled with |fill| at the end to match that length.
    (NOTE: len(fill) must be 1)
    """

    if ( size > 0 ):
        ## Fill text with spaces.
        if ( len(text) < size ):
            text += fill * (size-len(text))
        ## Truncate text if it's too long.
        elif ( len(text) > size ):
            text = text[size]
    else:
        size = len(text)

    # sum of all weights
    total_weights = float( sum(weights) )

    ## Calculate an int for each weight so that they sum appropriately to |size|.
    weighted_lengths = [ int(round( (w / total_weights)*size )) for w in weights ]

    ## XXX debugging...
    if( sum(weighted_lengths) != size ):
        ## TODO can this fail due to rounding issues?
        ##          --> What do we do then? Expand smallest/shrink biggest?


        ## XXX Hotfix..
        if( sum(weighted_lengths)+1 == size ):
            weighted_lengths[0] += 1
        else:
            print( weighted_lengths )

        assert( sum(weighted_lengths) == size )



    ## * split *
    ret = list()
    last_pos = 0
    for pos in weighted_lengths:
        ret.append( text[last_pos:last_pos + pos] )
        last_pos += pos

    return ret