Skip to content

Commit 60c2566

Browse files
authored
Display memory limits/measurements in MiB rather than MB
Rather than kilo/mega/...
1 parent 5e48afe commit 60c2566

2 files changed

Lines changed: 50 additions & 38 deletions

File tree

cms/locale/locale.py

Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,10 @@
5757
logger = logging.getLogger(__name__)
5858

5959

60+
def N_(msgid):
61+
return msgid
62+
63+
6064
class Translation(object):
6165
"""A shim that bundles all sources of translations for a language
6266
@@ -206,20 +210,18 @@ def format_duration(self, d, length="short"):
206210
return babel.units.format_unit(
207211
d, "duration-second", length=length, format=f, locale=self.locale)
208212

209-
PREFIX_FACTOR = 1000
210-
SIZE_UNITS = ["byte", "kilobyte", "megabyte", "gigabyte", "terabyte"]
213+
PREFIX_FACTOR = 1024
214+
SIZE_UNITS = [None, N_("%s KiB"), N_("%s MiB"), N_("%s GiB"), N_("%s TiB")]
211215

212216
def format_size(self, n):
213217
"""Format the given number of bytes.
214218
215-
Format the size of a file, a memory allocation, etc. which is given
216-
as a number of bytes. Use the most appropriate unit, from bytes up
217-
to terabytes. Always use three significant digits, except when this
218-
would mean:
219-
- rounding the integral part (happens only for > 1000 terabytes),
220-
in which case use more than three;
221-
- showing sub-byte values (happens only for < 100 bytes), in which
222-
case use less than three.
219+
Format the size of a file, a memory allocation, etc. which is
220+
given as a number of bytes. Use the most appropriate unit, from
221+
bytes up to tebibytes. Always show the entire integral part plus
222+
as many fractional digits as needed to reach at least three
223+
significant digits in total, except when this would mean showing
224+
sub-byte values (happens only for less than 100 bytes).
223225
224226
n (int): a size, as number of bytes.
225227
@@ -230,21 +232,19 @@ def format_size(self, n):
230232

231233
if n < self.PREFIX_FACTOR:
232234
return babel.units.format_unit(
233-
round(n), "digital-%s" % self.SIZE_UNITS[0], length="short",
234-
locale=self.locale)
235+
round(n), "digital-byte", locale=self.locale)
235236
for unit in self.SIZE_UNITS[1:]:
236237
n /= self.PREFIX_FACTOR
237238
if n < self.PREFIX_FACTOR:
238239
f = copy.copy(self.locale.decimal_formats[None])
239-
# We need int because ceil returns a float in py2.
240-
d = int(math.ceil(math.log10(self.PREFIX_FACTOR / n))) - 1
240+
# We need int because floor returns a float in py2.
241+
d = int(2 - math.floor(math.log10(n)))
241242
f.frac_prec = (d, d)
242-
return babel.units.format_unit(
243-
n, "digital-%s" % unit, length="short", format=f,
244-
locale=self.locale)
245-
return babel.units.format_unit(
246-
round(n), "digital-%s" % self.SIZE_UNITS[-1], length="short",
247-
locale=self.locale)
243+
return (self.gettext(unit)
244+
% babel.numbers.format_decimal(n, format=f,
245+
locale=self.locale))
246+
return (self.gettext(self.SIZE_UNITS[-1])
247+
% babel.numbers.format_decimal(round(n), locale=self.locale))
248248

249249
def format_decimal(self, n):
250250
"""Format a (possibly decimal) number

cmstestsuite/unit_tests/locale/locale_test.py

Lines changed: 30 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,11 @@
3131
import os.path
3232
import unittest
3333
from datetime import datetime, timedelta
34+
from io import BytesIO
3435

3536
import babel.dates
37+
from babel.messages import Catalog
38+
from babel.messages.mofile import write_mo
3639

3740
from cms.locale import Translation, DEFAULT_TRANSLATION, filter_language_codes, \
3841
choose_language_code
@@ -41,9 +44,18 @@
4144
UTC = babel.dates.UTC
4245
ROME = babel.dates.get_timezone("Europe/Rome")
4346

47+
FRENCH_CATALOG = Catalog(locale="fr")
48+
FRENCH_CATALOG.add("%s KiB", "%s Kio")
49+
FRENCH_CATALOG.add("%s MiB", "%s Mio")
50+
FRENCH_CATALOG.add("%s GiB", "%s Gio")
51+
FRENCH_CATALOG.add("%s TiB", "%s Tio")
52+
FRENCH_CATALOG_BUF = BytesIO()
53+
write_mo(FRENCH_CATALOG_BUF, FRENCH_CATALOG)
54+
FRENCH_CATALOG_BUF.seek(0)
55+
4456
ENGLISH = DEFAULT_TRANSLATION
4557
BRITISH_ENGLISH = Translation("en_GB")
46-
FRENCH = Translation("fr")
58+
FRENCH = Translation("fr", mofile=FRENCH_CATALOG_BUF)
4759
HINDI = Translation("hi")
4860
ITALIAN = Translation("it")
4961
NORWEGIAN = Translation("no")
@@ -450,36 +462,36 @@ class TestFormatSize(unittest.TestCase):
450462
def test_zero(self):
451463
# Corner case.
452464
self.assertEqual(ENGLISH.format_size(0),
453-
"0 byte")
465+
"0 bytes")
454466

455467
def test_small_values(self):
456468
# Note that there is no singular/plural.
457469
self.assertEqual(ENGLISH.format_size(1),
458470
"1 byte")
459471
self.assertEqual(ENGLISH.format_size(2),
460-
"2 byte")
472+
"2 bytes")
461473

462474
def test_cutoff(self):
463475
# Cutoff is at 1000, not 1024, as we use kilo, mega, ... rather
464476
# than kibi, mebi, ...
465477
self.assertEqual(ENGLISH.format_size(999),
466-
"999 byte")
478+
"999 bytes")
467479
self.assertEqual(ENGLISH.format_size(1000),
468-
"1.00 kB")
480+
"1,000 bytes")
469481
self.assertEqual(ENGLISH.format_size(1024),
470-
"1.02 kB")
482+
"1.00 KiB")
471483

472484
def test_large(self):
473485
# Ensure larger units are used for larger values, with rounding
474486
# to three significant digits, up to terabytes.
475487
self.assertEqual(ENGLISH.format_size(2.345 * 1000000),
476-
"2.34 MB")
488+
"2.24 MiB")
477489
self.assertEqual(ENGLISH.format_size(34.567 * 1000000000),
478-
"34.6 GB")
490+
"32.2 GiB")
479491
self.assertEqual(ENGLISH.format_size(456.789 * 1000000000000),
480-
"457 TB")
492+
"415 TiB")
481493
self.assertEqual(ENGLISH.format_size(5678.9 * 1000000000000),
482-
"5,679 TB")
494+
"5,165 TiB")
483495

484496
# As above, localized (use French as it's sensibly different).
485497

@@ -491,25 +503,25 @@ def test_localized_small_values(self):
491503
self.assertEqual(FRENCH.format_size(1),
492504
"1 octet")
493505
self.assertEqual(FRENCH.format_size(2),
494-
"2 octet")
506+
"2 octets")
495507

496508
def test_localized_cutoff(self):
497509
self.assertEqual(FRENCH.format_size(999),
498-
"999 octet")
510+
"999 octets")
499511
self.assertEqual(FRENCH.format_size(1000),
500-
"1,00 ko")
512+
"1\N{NO-BREAK SPACE}000 octets")
501513
self.assertEqual(FRENCH.format_size(1024),
502-
"1,02 ko")
514+
"1,00 Kio")
503515

504516
def test_localized_large(self):
505517
self.assertEqual(FRENCH.format_size(2.345 * 1000000),
506-
"2,34 Mo")
518+
"2,24 Mio")
507519
self.assertEqual(FRENCH.format_size(34.567 * 1000000000),
508-
"34,6 Go")
520+
"32,2 Gio")
509521
self.assertEqual(FRENCH.format_size(456.789 * 1000000000000),
510-
"457 To")
522+
"415 Tio")
511523
self.assertEqual(FRENCH.format_size(5678.9123 * 1000000000000),
512-
"5\N{NO-BREAK SPACE}679 To")
524+
"5\N{NO-BREAK SPACE}165 Tio")
513525

514526

515527
class TestFormatDecimal(unittest.TestCase):

0 commit comments

Comments
 (0)