Print human readable sizes in downloads

This commit is contained in:
Florian Bruhin 2014-06-13 07:13:47 +02:00
parent 8c673ee66c
commit efd83f40ca
3 changed files with 60 additions and 3 deletions

View File

@ -26,7 +26,8 @@ import qutebrowser.config.config as config
import qutebrowser.utils.message as message
from qutebrowser.utils.log import downloads as logger
from qutebrowser.utils.usertypes import PromptMode
from qutebrowser.utils.misc import interpolate_color, format_seconds
from qutebrowser.utils.misc import (interpolate_color, format_seconds,
format_size)
class DownloadItem(QObject):
@ -94,9 +95,12 @@ class DownloadItem(QObject):
remaining = (format_seconds(self.remaining_time)
if self.remaining_time is not None else
'?')
speed = format_size(self.speed, suffix='B/s')
down = format_size(self.bytes_done, suffix='B')
total = format_size(self.bytes_total, suffix='B')
return '{name} [{speed}|{remaining}|{perc: 2}%|{down}/{total}]'.format(
name=self.basename, speed=self.speed, remaining=remaining,
perc=perc, down=self.bytes_done, total=self.bytes_total)
name=self.basename, speed=speed, remaining=remaining, perc=perc,
down=down, total=total)
def _die(self, msg):
"""Abort the download and emit an error."""

View File

@ -553,5 +553,43 @@ class FormatSecondsTests(TestCase):
self.assertEqual(utils.format_seconds(seconds), out, seconds)
class FormatSizeTests(TestCase):
"""Tests for format_size.
Class attributes:
TESTS: A list of (input, output) tuples.
"""
TESTS = [
(-1024, '-1.00k'),
(-1, '-1.00'),
(0, '0.00'),
(1023, '1023.00'),
(1024, '1.00k'),
(1034.24, '1.01k'),
(1024 * 1024 * 2, '2.00M'),
(1024 ** 10, '1024.00Y'),
(None, '?.??'),
]
def test_format_size(self):
"""Test format_size with several tests."""
for size, out in self.TESTS:
self.assertEqual(utils.format_size(size), out, size)
def test_suffix(self):
"""Test the suffix option."""
for size, out in self.TESTS:
self.assertEqual(utils.format_size(size, suffix='B'), out + 'B',
size)
def test_base(self):
"""Test with an alternative base."""
kilo_tests = [(999, '999.00'), (1000, '1.00k'), (1010, '1.01k')]
for size, out in kilo_tests:
self.assertEqual(utils.format_size(size, base=1000), out, size)
if __name__ == '__main__':
unittest.main()

View File

@ -370,3 +370,18 @@ def format_seconds(total_seconds):
chunks.append(min_format.format(minutes))
chunks.append('{:02}'.format(seconds))
return prefix + ':'.join(chunks)
def format_size(size, base=1024, suffix=''):
"""Format a byte size so it's human readable.
Inspired by http://stackoverflow.com/q/1094841
"""
prefixes = ['', 'k', 'M', 'G', 'T', 'P', 'E', 'Z', 'Y']
if size is None:
return '?.??' + suffix
for p in prefixes:
if -base < size < base:
return '{:.02f}{}{}'.format(size, p, suffix)
size /= base
return '{:.02f}{}{}'.format(size, prefixes[-1], suffix)