Skip to content
This repository was archived by the owner on Mar 31, 2024. It is now read-only.
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clint/textui/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
colorama.init()

from . import colored
from . import elapsedtime
from . import progress
from . import prompt

Expand Down
99 changes: 99 additions & 0 deletions clint/textui/elapsedtime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-

"""
clint.textui.elapsedtime
~~~~~~~~~~~~~~~~~

This module provides a simple timer to measure elapsed time.

"""

from __future__ import absolute_import
from threading import Thread

import time
import sys

INDICATOR_TEMPLATE = '%s %s %s\r'
NO_INDICATOR_TEMPLATE = '%s %s\r'

INDICATOR_CHARS = ['|', '/', '-', '\\']

STREAM = sys.stderr


class ElapsedTime(object):
"""Timer class for measuring elapsed time.
This provides a timer with animation.

Intended usage:
with ElapsedTime(*kwargs):
<code>
"""
def __enter__(self):
th = Thread(target=self._print_indicator)
th.start()
return self

def __exit__(self, type_, value, traceback):
self._done()
self._running = False
return False

def __init__(self, label=None, indicator_chars=INDICATOR_CHARS,
interval=0.2, hidden=False):
self._running = True
self.label = label
self.indicator_chars = indicator_chars
self.interval = interval
self.hidden = hidden
self.label = label
if not self.label:
self.label = ''
self._start = time.time()
self._indicator_index = 0

def show(self):
"""Write elapsed time to stream, with newline, without indicator."""
self._write_time(newline=True, show_indicator=False)

def reset(self):
"""Reset the timer."""
self._start = time.time()

def _done(self):
if not self.hidden:
self._write_time(newline=True)

def _show(self):
if not self.hidden:
self._write_time()

def _write_time(self, newline=False, show_indicator=True):
elapsed = time.time() - self._start
elapsed_disp = ElapsedTime._format_time(elapsed)
if not self.indicator_chars or not show_indicator:
STREAM.write(NO_INDICATOR_TEMPLATE % (
self.label, elapsed_disp))
if newline:
STREAM.write('\n')
STREAM.flush()
else:
STREAM.write(INDICATOR_TEMPLATE % (
self.label, self.indicator_chars[self._indicator_index],
elapsed_disp))
if newline:
STREAM.write('\n')
STREAM.flush()
self._indicator_index = (
(self._indicator_index+1) % len(self.indicator_chars))

def _print_indicator(self):
while self._running:
self._show()
time.sleep(self.interval)

@staticmethod
def _format_time(seconds):
time_ = time.gmtime(seconds)
return time.strftime('%H:%M:%S', time_)
50 changes: 50 additions & 0 deletions examples/elapsedtime.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-

from __future__ import print_function

import sys
import os

sys.path.insert(0, os.path.abspath('..'))

from time import sleep
from clint.textui import elapsedtime


if __name__ == '__main__':
# Basic use
with elapsedtime.ElapsedTime():
sleep(3)

# Use with options
with elapsedtime.ElapsedTime(
label='Running long job...',
interval=0.1,
indicator_chars=['o', 'O', '8']):
sleep(5)

# Use without indicator
with elapsedtime.ElapsedTime(
label='Without indicator:',
indicator_chars=None):
sleep(3)

# Hide the animated timer
with elapsedtime.ElapsedTime(
label='Elapsed time:',
hidden=True) as et:
for i in range(3):
print('This is loop: %d/3' % (i+1))
sleep(1)
et.show()

# Use without 'with' statement
et = elapsedtime.ElapsedTime(label='Without with:')
print('Running long job...')
sleep(3)
et.show()
et.reset()
print('Running another long job...')
sleep(3)
et.show()