~abentley/bzrtools/bzrtools.dev

« back to all changes in this revision

Viewing changes to progress.py

  • Committer: Aaron Bentley
  • Date: 2011-06-27 22:03:53 UTC
  • mfrom: (770.1.1 trunk)
  • Revision ID: aaron@aaronbentley.com-20110627220353-c7ikthkaap2amfzm
Support importing .tar.xz and .tar.lzma files.  (Jelmer)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
# Copyright (C) 2005 Aaron Bentley
2
 
# <aaron.bentley@utoronto.ca>
 
2
# <aaron@aaronbentley.com>
3
3
#
4
4
#    This program is free software; you can redistribute it and/or modify
5
5
#    it under the terms of the GNU General Public License as published by
17
17
 
18
18
import sys
19
19
import datetime
 
20
from bzrlib.progress import ProgressBar
20
21
 
21
22
class Progress(object):
22
23
    def __init__(self, units, current, total=None):
23
24
        self.units = units
24
25
        self.current = current
25
26
        self.total = total
26
 
        self.percent = None
27
 
        if self.total is not None:
28
 
            self.percent = 100.0 * current / total
 
27
 
 
28
    def _get_percent(self):
 
29
        if self.total is None:
 
30
            return None
 
31
        return 100.0 * self.current / self.total
 
32
 
 
33
    percent = property(_get_percent)
29
34
 
30
35
    def __str__(self):
31
36
        if self.total is not None:
32
37
            return "%i of %i %s %.1f%%" % (self.current, self.total, self.units,
33
38
                                         self.percent)
34
39
        else:
35
 
            return "%i %s" (self.current, self.units) 
36
 
 
37
 
class ProgressBar(object):
38
 
    def __init__(self):
39
 
        self.start = None
40
 
        object.__init__(self)
41
 
 
42
 
    def __call__(self, progress):
43
 
        if self.start is None:
44
 
            self.start = datetime.datetime.now()
45
 
        progress_bar(progress, start_time=self.start)
46
 
        
47
 
def divide_timedelta(delt, divisor):
48
 
    """Divides a timedelta object"""
49
 
    return datetime.timedelta(float(delt.days)/divisor, 
50
 
                              float(delt.seconds)/divisor, 
51
 
                              float(delt.microseconds)/divisor)
52
 
 
53
 
def str_tdelta(delt):
54
 
    if delt is None:
55
 
        return "-:--:--"
56
 
    return str(datetime.timedelta(delt.days, delt.seconds))
57
 
 
58
 
def get_eta(start_time, progress, enough_samples=20):
59
 
    if start_time is None or progress.current == 0:
60
 
        return None
61
 
    elif progress.current < enough_samples:
62
 
        return None
63
 
    elapsed = datetime.datetime.now() - start_time
64
 
    total_duration = divide_timedelta((elapsed) * long(progress.total), 
65
 
                                      progress.current)
66
 
    if elapsed < total_duration:
67
 
        eta = total_duration - elapsed
68
 
    else:
69
 
        eta = total_duration - total_duration
70
 
    return eta
71
 
 
72
 
def progress_bar(progress, start_time=None):
73
 
    eta = get_eta(start_time, progress)
74
 
    if start_time is not None:
75
 
        eta_str = " "+str_tdelta(eta)
76
 
    else:
77
 
        eta_str = ""
78
 
 
79
 
    fmt = " %i of %i %s (%.1f%%)"
80
 
    f = fmt % (progress.total, progress.total, progress.units, 100.0)
81
 
    max = len(f)
82
 
    cols = 77 - max
83
 
    if start_time is not None:
84
 
        cols -= len(eta_str)
85
 
    markers = int (float(cols) * progress.current / progress.total)
86
 
    txt = fmt % (progress.current, progress.total, progress.units,
87
 
                 progress.percent)
88
 
    sys.stderr.write("\r[%s%s]%s%s" % ('='*markers, ' '*(cols-markers), txt, 
89
 
                                       eta_str))
 
40
            return "%i %s" (self.current, self.units)
 
41
 
 
42
def show_progress(pi, prog):
 
43
    pi.update(prog.units, prog.current, prog.total)
90
44
 
91
45
def clear_progress_bar():
92
46
    sys.stderr.write('\r%s\r' % (' '*79))
93
 
 
94
 
def spinner_str(progress, show_text=False):
95
 
    """
96
 
    Produces the string for a textual "spinner" progress indicator
97
 
    :param progress: an object represinting current progress
98
 
    :param show_text: If true, show progress text as well
99
 
    :return: The spinner string
100
 
 
101
 
    >>> spinner_str(Progress("baloons", 0))
102
 
    '|'
103
 
    >>> spinner_str(Progress("baloons", 5))
104
 
    '/'
105
 
    >>> spinner_str(Progress("baloons", 6), show_text=True)
106
 
    '- 6 baloons'
107
 
    """
108
 
    positions = ('|', '/', '-', '\\')
109
 
    text = positions[progress.current % 4]
110
 
    if show_text:
111
 
        text+=" %i %s" % (progress.current, progress.units)
112
 
    return text
113
 
 
114
 
def spinner(progress, show_text=False, output=sys.stderr):
115
 
    """
116
 
    Update a spinner progress indicator on an output
117
 
    :param progress: The progress to display
118
 
    :param show_text: If true, show text as well as spinner
119
 
    :param output: The output to write to
120
 
 
121
 
    >>> spinner(Progress("baloons", 6), show_text=True, output=sys.stdout)
122
 
    \r- 6 baloons
123
 
    """
124
 
    output.write('\r%s' % spinner_str(progress, show_text))
125
 
 
126
 
def run_tests():
127
 
    import doctest
128
 
    result = doctest.testmod()
129
 
    if result[1] > 0:
130
 
        if result[0] == 0:
131
 
            print "All tests passed"
132
 
    else:
133
 
        print "No tests to run"
134
 
if __name__ == "__main__":
135
 
    run_tests()