import os
import math
def timedelta_to_seconds(delta):
'''Convert a timedelta to seconds with the microseconds as fraction
>>> from datetime import timedelta
>>> '%d' % timedelta_to_seconds(timedelta(days=1))
'86400'
>>> '%d' % timedelta_to_seconds(timedelta(seconds=1))
'1'
>>> '%.6f' % timedelta_to_seconds(timedelta(seconds=1, microseconds=1))
'1.000001'
>>> '%.6f' % timedelta_to_seconds(timedelta(microseconds=1))
'0.000001'
'''
# Only convert to float if needed
if delta.microseconds:
total = delta.microseconds * 1e-6
else:
total = 0
total += delta.seconds
total += delta.days * 60 * 60 * 24
return total
def scale_1024(x, n_prefixes):
'''Scale a number down to a suitable size, based on powers of 1024.
Returns the scaled number and the power of 1024 used.
Use to format numbers of bytes to KiB, MiB, etc.
>>> scale_1024(310, 3)
(310.0, 0)
>>> scale_1024(2048, 3)
(2.0, 1)
'''
power = min(int(math.log(x, 2) / 10), n_prefixes - 1)
scaled = float(x) / (2 ** (10 * power))
return scaled, power
def get_terminal_size(): # pragma: no cover
'''Get the current size of your terminal
Multiple returns are not always a good idea, but in this case it greatly
simplifies the code so I believe it's justified. It's not the prettiest
function but that's never really possible with cross-platform code.
Returns:
height, width: Two integers containing height and width
'''
try:
# This works for Python 3, but not Pypy3. Probably the best method if
# it's supported so let's always try
import shutil
h, w = shutil.get_terminal_size((0, 0))
if w and h:
return h, w
except: # pragma: no cover
pass
try:
w = int(os.environ.get('COLUMNS'))
h = int(os.environ.get('LINES'))
if w and h:
return h, w
except: # pragma: no cover
pass
try:
import blessings
terminal = blessings.Terminal()
h, w = terminal._height_and_width
if w and h:
return h, w
except: # pragma: no cover
pass
try:
h, w = _get_terminal_size_linux()
if w and h:
return h, w
except: # pragma: no cover
pass
try:
# Windows detection doesn't always work, let's try anyhow
h, w = _get_terminal_size_windows()
if w and h:
return h, w
except: # pragma: no cover
pass
try:
# needed for window's python in cygwin's xterm!
h, w = _get_terminal_size_tput()
if w and h:
return h, w
except: # pragma: no cover
pass
return 80, 25
def _get_terminal_size_windows(): # pragma: no cover
res = None
try:
from ctypes import windll, create_string_buffer
# stdin handle is -10
# stdout handle is -11
# stderr handle is -12
h = windll.kernel32.GetStdHandle(-12)
csbi = create_string_buffer(22)
res = windll.kernel32.GetConsoleScreenBufferInfo(h, csbi)
except:
return None
if res:
import struct
(_, _, _, _, _, left, top, right, bottom, _, _) = \
struct.unpack("hhhhHhhhhhh", csbi.raw)
w = right - left + 1
h = bottom - top + 1
return w, h
else:
return None
def _get_terminal_size_tput(): # pragma: no cover
# get terminal width src: http://stackoverflow.com/questions/263890/
try:
import subprocess
proc = subprocess.Popen(
['tput', 'cols'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output = proc.communicate(input=None)
w = int(output[0])
proc = subprocess.Popen(
['tput', 'lines'], stdin=subprocess.PIPE, stdout=subprocess.PIPE)
output = proc.communicate(input=None)
h = int(output[0])
return w, h
except:
return None
def _get_terminal_size_linux(): # pragma: no cover
def ioctl_GWINSZ(fd):
try:
import fcntl
import termios
import struct
size = struct.unpack(
'hh', fcntl.ioctl(fd, termios.TIOCGWINSZ, '1234'))
except:
return None
return size
size = ioctl_GWINSZ(0) or ioctl_GWINSZ(1) or ioctl_GWINSZ(2)
if not size:
try:
fd = os.open(os.ctermid(), os.O_RDONLY)
size = ioctl_GWINSZ(fd)
os.close(fd)
except:
pass
if not size:
try:
size = os.environ['LINES'], os.environ['COLUMNS']
except:
return None
return int(size[1]), int(size[0])