File: format.py

package info (click to toggle)
bumblebee-status 2.2.0-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 2,844 kB
  • sloc: python: 13,430; sh: 68; makefile: 29
file content (156 lines) | stat: -rw-r--r-- 4,557 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
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
86
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
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
155
156
# -*- coding: utf-8 -*-

import re


def asbool(val):
    """Converts a value into a boolean

    :param val: value to convert; accepts a wide range of
        possible representations, such as yes, no, true, false, on, off

    :return: True of val maps to true, False otherwise
    :rtype: boolean
    """
    if val is None:
        return False
    if isinstance(val, bool):
        return val
    val = str(val).strip().lower()
    return val in ("t", "true", "y", "yes", "on", "1")


def asint(val, minimum=None, maximum=None):
    """Converts a value into an integer

    :param val: value to convert
    :param minimum: if specified, this determines the lower
        boundary for the returned value, defaults to None
    :param maximum: if specified, this determines the upper
        boundary for the returned value, defaults to None

    :return: integer representation of value
    :rtype: integer
    """
    if val is None:
        val = 0
    val = int(val)
    val = min(val, maximum if maximum else val)
    val = max(val, minimum if minimum else val)
    return val


def aslist(val):
    """Converts a comma-separated value string into a list

    :param val: value to convert, either a single value or a comma-separated string

    :return: list representation of the value passed in
    :rtype: list of strings
    """
    if val is None:
        return []
    if isinstance(val, list):
        return val
    return str(val).replace(" ", "").split(",")


__UNITS = {"metric": "C", "kelvin": "K", "imperial": "F", "default": "C"}


def astemperature(val, unit="metric"):
    """Returns a temperature representation of the input value

    :param val: value to format, must be convertible into an integer
    :param unit: unit of the input value, supported units are:
        metric, kelvin, imperial, defaults to metric

    :return: temperature representation of the input value
    :rtype: string
    """
    return "{}°{}".format(int(val), __UNITS.get(unit.lower(), __UNITS["default"]))


def byte(val, fmt="{:.2f}", sys="IEC"):
    """Returns a byte representation of the input value

    :param val: value to format, must be convertible into a float
    :param fmt: optional output format string, defaults to {:.2f}
    :param sys: optional unit system specifier - SI (kilo, Mega, Giga, ...) or
        IEC (kibi, Mebi, Gibi, ...) - defaults to IEC

    :return: byte representation (e.g. <X> KiB, GiB, etc.) of the input value
    :rtype: string
    """

    if sys == "IEC":
        div = 1024.0
        units = ["", "Ki", "Mi", "Gi", "Ti"]
        final = "TiB"
    elif sys == "SI":
        div = 1000.0
        units = ["", "K", "M", "G", "T"]
        final = "TB"

    val = float(val)
    for unit in units:
        if val < div:
            return "{}{}B".format(fmt, unit).format(val)
        val /= div
    return "{}{}".format(fmt).format(val * div, final)


__seconds_pattern = re.compile(r"(([\d\.?]+)h)?(([\d\.]+)m)?([\d\.]+)?s?")


def seconds(duration):
    """Returns a time duration (in seconds) representation of the input value

    :param duration: value to format (e.g. 5h30m2s)

    :return: duration in seconds of the input value
    :rtype: float
    """
    if isinstance(duration, int) or isinstance(duration, float):
        return float(duration)

    matches = __seconds_pattern.match(duration)
    result = 0.0
    if matches.group(2):
        result += float(matches.group(2)) * 3600  # hours
    if matches.group(4):
        result += float(matches.group(4)) * 60  # minutes
    if matches.group(5):
        result += float(matches.group(5))  # seconds

    return result


def duration(duration, compact=False, unit=False):
    """Returns a time duration string representing the input value

    :param duration: value to format, must be convertible into an into
    :param compact: whether to show also seconds, defaults to False
    :param unit: whether to display he unit, defaults to False

    :return: duration representation (e.g. 5:02s) of the input value
    :rtype: string
    """
    duration = int(duration)
    if duration < 0:
        return "n/a"
    minutes, seconds = divmod(duration, 60)
    hours, minutes = divmod(minutes, 60)
    suf = "m"
    res = "{:02d}:{:02d}".format(minutes, seconds)
    if hours > 0:
        if compact:
            res = "{:02d}:{:02d}".format(hours, minutes)
        else:
            res = "{:02d}:{}".format(hours, res)
        suf = "h"

    return "{}{}".format(res, suf if unit else "")


# vim: tabstop=8 expandtab shiftwidth=4 softtabstop=4