source: trunk/src/allmydata/util/abbreviate.py

Last change on this file was 1cfe843d, checked in by Alexandre Detiste <alexandre.detiste@…>, at 2024-02-22T23:40:25Z

more python2 removal

  • Property mode set to 100644
File size: 3.2 KB
Line 
1"""
2Convert timestamps to abbreviated English text.
3
4Ported to Python 3.
5"""
6
7import re
8from datetime import timedelta
9
10HOUR = 3600
11DAY = 24*3600
12WEEK = 7*DAY
13MONTH = 30*DAY
14YEAR = 365*DAY
15
16def abbreviate_time(s):
17    """
18    Given time in seconds (float or int) or timedelta, summarize as English by
19    returning unicode string.
20    """
21    postfix = ''
22    if isinstance(s, timedelta):
23        # this feels counter-intuitive that positive numbers in a
24        # time-delta are "the past"; but if you "do math" on two
25        # datetime instances as below, you get a "positve seconds"
26        # timedelta instance:
27        # a = datetime.utcnow()
28        # time.sleep(1)
29        # b = datetime.utcnow()
30        # print(b - a)  # 0:00:01.001203
31        s = s.total_seconds()
32        if s >= 0.0:
33            postfix = ' ago'
34        else:
35            postfix = ' in the future'
36            s = -s
37    def _plural(count, unit):
38        count = int(count)
39        if count == 1:
40            return "%d %s%s" % (count, unit, postfix)
41        return "%d %ss%s" % (count, unit, postfix)
42    if s is None:
43        return "unknown"
44    if s < 120:
45        return _plural(s, "second")
46    if s < 3*HOUR:
47        return _plural(s / 60, "minute")
48    if s < 2*DAY:
49        return _plural(s / HOUR, "hour")
50    if s < 2*MONTH:
51        return _plural(s / DAY, "day")
52    if s < 4*YEAR:
53        return _plural(s / MONTH, "month")
54    return _plural(s / YEAR, "year")
55
56def abbreviate_space(s, SI=True):
57    """
58    Given size in bytes summarize as English by returning unicode string.
59    """
60    if s is None:
61        return "unknown"
62    if SI:
63        U = 1000.0
64        isuffix = "B"
65    else:
66        U = 1024.0
67        isuffix = "iB"
68    def r(count, suffix):
69        return "%.2f %s%s" % (count, suffix, isuffix)
70
71    if s < 1024: # 1000-1023 get emitted as bytes, even in SI mode
72        return "%d B" % s
73    if s < U*U:
74        return r(s/U, "k")
75    if s < U*U*U:
76        return r(s/(U*U), "M")
77    if s < U*U*U*U:
78        return r(s/(U*U*U), "G")
79    if s < U*U*U*U*U:
80        return r(s/(U*U*U*U), "T")
81    if s < U*U*U*U*U*U:
82        return r(s/(U*U*U*U*U), "P")
83    return r(s/(U*U*U*U*U*U), "E")
84
85def abbreviate_space_both(s):
86    return "(%s, %s)" % (abbreviate_space(s, True),
87                         abbreviate_space(s, False))
88
89def parse_abbreviated_size(s):
90    if s is None or s == "":
91        return None
92    m = re.match(r"^(\d+)([KMGTPE]?[I]?[B]?)$", s.upper())
93    if not m:
94        raise ValueError("unparseable value %s" % s)
95    number, suffix = m.groups()
96    if suffix.endswith("B"):
97        suffix = suffix[:-1]
98    multiplier = {"":   1,
99                  "I":  1,
100                  "K":  1000,
101                  "M":  1000 * 1000,
102                  "G":  1000 * 1000 * 1000,
103                  "T":  1000 * 1000 * 1000 * 1000,
104                  "P":  1000 * 1000 * 1000 * 1000 * 1000,
105                  "E":  1000 * 1000 * 1000 * 1000 * 1000 * 1000,
106                  "KI": 1024,
107                  "MI": 1024 * 1024,
108                  "GI": 1024 * 1024 * 1024,
109                  "TI": 1024 * 1024 * 1024 * 1024,
110                  "PI": 1024 * 1024 * 1024 * 1024 * 1024,
111                  "EI": 1024 * 1024 * 1024 * 1024 * 1024 * 1024,
112                  }[suffix]
113    return int(number) * multiplier
Note: See TracBrowser for help on using the repository browser.