[Python-modules-commits] [python-progress] 01/03: import progress_1.2.orig.tar.gz

Barry Warsaw barry at moszumanska.debian.org
Wed Jan 27 20:05:57 UTC 2016


This is an automated email from the git hooks/post-receive script.

barry pushed a commit to branch master
in repository python-progress.

commit b8506f78a44c16adebd7c51855fe53eb341c3bf1
Author: Barry Warsaw <barry at python.org>
Date:   Wed Jan 27 14:45:49 2016 -0500

    import progress_1.2.orig.tar.gz
---
 LICENSE                                |  13 ++++
 MANIFEST.in                            |   1 +
 PKG-INFO                               | 118 +++++++++++++++++++++++++++++++
 README.rst                             | 102 +++++++++++++++++++++++++++
 progress.egg-info/PKG-INFO             | 118 +++++++++++++++++++++++++++++++
 progress.egg-info/SOURCES.txt          |  13 ++++
 progress.egg-info/dependency_links.txt |   1 +
 progress.egg-info/top_level.txt        |   1 +
 progress/__init__.py                   | 123 +++++++++++++++++++++++++++++++++
 progress/bar.py                        |  83 ++++++++++++++++++++++
 progress/counter.py                    |  47 +++++++++++++
 progress/helpers.py                    |  91 ++++++++++++++++++++++++
 progress/spinner.py                    |  40 +++++++++++
 setup.cfg                              |   5 ++
 setup.py                               |  26 +++++++
 15 files changed, 782 insertions(+)

diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..059cc05
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,13 @@
+# Copyright (c) 2012 Giorgos Verigakis <verigak at gmail.com>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
diff --git a/MANIFEST.in b/MANIFEST.in
new file mode 100644
index 0000000..0c73842
--- /dev/null
+++ b/MANIFEST.in
@@ -0,0 +1 @@
+include README.rst LICENSE
diff --git a/PKG-INFO b/PKG-INFO
new file mode 100644
index 0000000..d2c7ac2
--- /dev/null
+++ b/PKG-INFO
@@ -0,0 +1,118 @@
+Metadata-Version: 1.1
+Name: progress
+Version: 1.2
+Summary: Easy to use progress bars
+Home-page: http://github.com/verigak/progress/
+Author: Giorgos Verigakis
+Author-email: verigak at gmail.com
+License: ISC
+Description: Easy progress reporting for Python
+        ==================================
+        
+        Bars
+        ----
+        
+        There are 6 progress bars to choose from:
+        
+        - Bar
+        - ChargingBar
+        - FillingSquaresBar
+        - FillingCirclesBar
+        - IncrementalBar
+        - ShadyBar
+        
+        To use them, just call ``next`` to advance and ``finish`` to finish. ::
+        
+            from progress.bar import Bar
+        
+            bar = Bar('Processing', max=20)
+            for i in range(20):
+                # Do some work
+                bar.next()
+            bar.finish()
+        
+        The result will be a bar like the following: ::
+        
+            Processing |#############                   | 42/100
+        
+        To simplify the common case where the work is done in an iterator, you can
+        use the ``iter`` method. ::
+        
+            for i in Bar('Processing').iter(it):
+                # Do some work
+        
+        Progress bars are very customizable, you can change their width, their fill
+        character, their suffix and more. ::
+        
+            bar = Bar('Loading', fill='@', suffix='%(percent)d%%')
+        
+        This will produce a bar like the following: ::
+        
+            Loading |@@@@@@@@@@@@@                   | 42%
+        
+        You can use a number of template arguments in ``message`` and ``suffix``:
+        
+        ==========  ================================
+        Name        Value
+        ==========  ================================
+        index       current value
+        max         maximum value
+        remaining   max - index
+        progress    index / max
+        percent     progress * 100
+        avg         simple moving average time per item (in seconds)
+        elapsed     elapsed time in seconds
+        elapsed_td  elapsed as a timedelta (useful for printing as a string)
+        eta         avg * remaining
+        eta_td      eta as a timedelta (useful for printing as a string)
+        ==========  ================================
+        
+        Instead of passing all configuration options on instatiation, you can create
+        your custom subclass. ::
+        
+            class FancyBar(Bar):
+                message = 'Loading'
+                fill = '*'
+                suffix = '%(percent).1f%% - %(eta)ds'
+        
+        You can also override any of the arguments or create your own. ::
+        
+            class SlowBar(Bar):
+                suffix = '%(remaining_hours)d hours remaining'
+                @property
+                def remaining_hours(self):
+                    return self.eta // 3600
+        
+        
+        Spinners
+        ========
+        
+        For actions with an unknown number of steps you can use a spinner. ::
+        
+            from progress.spinner import Spinner
+            
+            spinner = Spinner('Loading ')
+            while state != 'FINISHED':
+                # Do some work
+                spinner.next()
+        
+        There are 4 predefined spinners:
+        
+        - Spinner
+        - PieSpinner
+        - MoonSpinner
+        - LineSpinner
+        
+        Other
+        =====
+        
+        Thera are a number of other classes available too, please check the source or
+        subclass one of them to create your own.
+        
+Platform: UNKNOWN
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: ISC License (ISCL)
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.3
diff --git a/README.rst b/README.rst
new file mode 100644
index 0000000..79a8eff
--- /dev/null
+++ b/README.rst
@@ -0,0 +1,102 @@
+Easy progress reporting for Python
+==================================
+
+Bars
+----
+
+There are 6 progress bars to choose from:
+
+- Bar
+- ChargingBar
+- FillingSquaresBar
+- FillingCirclesBar
+- IncrementalBar
+- ShadyBar
+
+To use them, just call ``next`` to advance and ``finish`` to finish. ::
+
+    from progress.bar import Bar
+
+    bar = Bar('Processing', max=20)
+    for i in range(20):
+        # Do some work
+        bar.next()
+    bar.finish()
+
+The result will be a bar like the following: ::
+
+    Processing |#############                   | 42/100
+
+To simplify the common case where the work is done in an iterator, you can
+use the ``iter`` method. ::
+
+    for i in Bar('Processing').iter(it):
+        # Do some work
+
+Progress bars are very customizable, you can change their width, their fill
+character, their suffix and more. ::
+
+    bar = Bar('Loading', fill='@', suffix='%(percent)d%%')
+
+This will produce a bar like the following: ::
+
+    Loading |@@@@@@@@@@@@@                   | 42%
+
+You can use a number of template arguments in ``message`` and ``suffix``:
+
+==========  ================================
+Name        Value
+==========  ================================
+index       current value
+max         maximum value
+remaining   max - index
+progress    index / max
+percent     progress * 100
+avg         simple moving average time per item (in seconds)
+elapsed     elapsed time in seconds
+elapsed_td  elapsed as a timedelta (useful for printing as a string)
+eta         avg * remaining
+eta_td      eta as a timedelta (useful for printing as a string)
+==========  ================================
+
+Instead of passing all configuration options on instatiation, you can create
+your custom subclass. ::
+
+    class FancyBar(Bar):
+        message = 'Loading'
+        fill = '*'
+        suffix = '%(percent).1f%% - %(eta)ds'
+
+You can also override any of the arguments or create your own. ::
+
+    class SlowBar(Bar):
+        suffix = '%(remaining_hours)d hours remaining'
+        @property
+        def remaining_hours(self):
+            return self.eta // 3600
+
+
+Spinners
+========
+
+For actions with an unknown number of steps you can use a spinner. ::
+
+    from progress.spinner import Spinner
+    
+    spinner = Spinner('Loading ')
+    while state != 'FINISHED':
+        # Do some work
+        spinner.next()
+
+There are 4 predefined spinners:
+
+- Spinner
+- PieSpinner
+- MoonSpinner
+- LineSpinner
+
+Other
+=====
+
+Thera are a number of other classes available too, please check the source or
+subclass one of them to create your own.
diff --git a/progress.egg-info/PKG-INFO b/progress.egg-info/PKG-INFO
new file mode 100644
index 0000000..d2c7ac2
--- /dev/null
+++ b/progress.egg-info/PKG-INFO
@@ -0,0 +1,118 @@
+Metadata-Version: 1.1
+Name: progress
+Version: 1.2
+Summary: Easy to use progress bars
+Home-page: http://github.com/verigak/progress/
+Author: Giorgos Verigakis
+Author-email: verigak at gmail.com
+License: ISC
+Description: Easy progress reporting for Python
+        ==================================
+        
+        Bars
+        ----
+        
+        There are 6 progress bars to choose from:
+        
+        - Bar
+        - ChargingBar
+        - FillingSquaresBar
+        - FillingCirclesBar
+        - IncrementalBar
+        - ShadyBar
+        
+        To use them, just call ``next`` to advance and ``finish`` to finish. ::
+        
+            from progress.bar import Bar
+        
+            bar = Bar('Processing', max=20)
+            for i in range(20):
+                # Do some work
+                bar.next()
+            bar.finish()
+        
+        The result will be a bar like the following: ::
+        
+            Processing |#############                   | 42/100
+        
+        To simplify the common case where the work is done in an iterator, you can
+        use the ``iter`` method. ::
+        
+            for i in Bar('Processing').iter(it):
+                # Do some work
+        
+        Progress bars are very customizable, you can change their width, their fill
+        character, their suffix and more. ::
+        
+            bar = Bar('Loading', fill='@', suffix='%(percent)d%%')
+        
+        This will produce a bar like the following: ::
+        
+            Loading |@@@@@@@@@@@@@                   | 42%
+        
+        You can use a number of template arguments in ``message`` and ``suffix``:
+        
+        ==========  ================================
+        Name        Value
+        ==========  ================================
+        index       current value
+        max         maximum value
+        remaining   max - index
+        progress    index / max
+        percent     progress * 100
+        avg         simple moving average time per item (in seconds)
+        elapsed     elapsed time in seconds
+        elapsed_td  elapsed as a timedelta (useful for printing as a string)
+        eta         avg * remaining
+        eta_td      eta as a timedelta (useful for printing as a string)
+        ==========  ================================
+        
+        Instead of passing all configuration options on instatiation, you can create
+        your custom subclass. ::
+        
+            class FancyBar(Bar):
+                message = 'Loading'
+                fill = '*'
+                suffix = '%(percent).1f%% - %(eta)ds'
+        
+        You can also override any of the arguments or create your own. ::
+        
+            class SlowBar(Bar):
+                suffix = '%(remaining_hours)d hours remaining'
+                @property
+                def remaining_hours(self):
+                    return self.eta // 3600
+        
+        
+        Spinners
+        ========
+        
+        For actions with an unknown number of steps you can use a spinner. ::
+        
+            from progress.spinner import Spinner
+            
+            spinner = Spinner('Loading ')
+            while state != 'FINISHED':
+                # Do some work
+                spinner.next()
+        
+        There are 4 predefined spinners:
+        
+        - Spinner
+        - PieSpinner
+        - MoonSpinner
+        - LineSpinner
+        
+        Other
+        =====
+        
+        Thera are a number of other classes available too, please check the source or
+        subclass one of them to create your own.
+        
+Platform: UNKNOWN
+Classifier: Environment :: Console
+Classifier: Intended Audience :: Developers
+Classifier: License :: OSI Approved :: ISC License (ISCL)
+Classifier: Programming Language :: Python :: 2.6
+Classifier: Programming Language :: Python :: 2.7
+Classifier: Programming Language :: Python :: 3.3
diff --git a/progress.egg-info/SOURCES.txt b/progress.egg-info/SOURCES.txt
new file mode 100644
index 0000000..054687d
--- /dev/null
+++ b/progress.egg-info/SOURCES.txt
@@ -0,0 +1,13 @@
+LICENSE
+MANIFEST.in
+README.rst
+setup.py
+progress/__init__.py
+progress/bar.py
+progress/counter.py
+progress/helpers.py
+progress/spinner.py
+progress.egg-info/PKG-INFO
+progress.egg-info/SOURCES.txt
+progress.egg-info/dependency_links.txt
+progress.egg-info/top_level.txt
\ No newline at end of file
diff --git a/progress.egg-info/dependency_links.txt b/progress.egg-info/dependency_links.txt
new file mode 100644
index 0000000..8b13789
--- /dev/null
+++ b/progress.egg-info/dependency_links.txt
@@ -0,0 +1 @@
+
diff --git a/progress.egg-info/top_level.txt b/progress.egg-info/top_level.txt
new file mode 100644
index 0000000..81fae44
--- /dev/null
+++ b/progress.egg-info/top_level.txt
@@ -0,0 +1 @@
+progress
diff --git a/progress/__init__.py b/progress/__init__.py
new file mode 100644
index 0000000..5107bc0
--- /dev/null
+++ b/progress/__init__.py
@@ -0,0 +1,123 @@
+# Copyright (c) 2012 Giorgos Verigakis <verigak at gmail.com>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from __future__ import division
+
+from collections import deque
+from datetime import timedelta
+from math import ceil
+from sys import stderr
+from time import time
+
+
+__version__ = '1.2'
+
+
+class Infinite(object):
+    file = stderr
+    sma_window = 10
+
+    def __init__(self, *args, **kwargs):
+        self.index = 0
+        self.start_ts = time()
+        self._ts = self.start_ts
+        self._dt = deque(maxlen=self.sma_window)
+        for key, val in kwargs.items():
+            setattr(self, key, val)
+
+    def __getitem__(self, key):
+        if key.startswith('_'):
+            return None
+        return getattr(self, key, None)
+
+    @property
+    def avg(self):
+        return sum(self._dt) / len(self._dt) if self._dt else 0
+
+    @property
+    def elapsed(self):
+        return int(time() - self.start_ts)
+
+    @property
+    def elapsed_td(self):
+        return timedelta(seconds=self.elapsed)
+
+    def update(self):
+        pass
+
+    def start(self):
+        pass
+
+    def finish(self):
+        pass
+
+    def next(self, n=1):
+        if n > 0:
+            now = time()
+            dt = (now - self._ts) / n
+            self._dt.append(dt)
+            self._ts = now
+
+        self.index = self.index + n
+        self.update()
+
+    def iter(self, it):
+        for x in it:
+            yield x
+            self.next()
+        self.finish()
+
+
+class Progress(Infinite):
+    def __init__(self, *args, **kwargs):
+        super(Progress, self).__init__(*args, **kwargs)
+        self.max = kwargs.get('max', 100)
+
+    @property
+    def eta(self):
+        return int(ceil(self.avg * self.remaining))
+
+    @property
+    def eta_td(self):
+        return timedelta(seconds=self.eta)
+
+    @property
+    def percent(self):
+        return self.progress * 100
+
+    @property
+    def progress(self):
+        return min(1, self.index / self.max)
+
+    @property
+    def remaining(self):
+        return max(self.max - self.index, 0)
+
+    def start(self):
+        self.update()
+
+    def goto(self, index):
+        incr = index - self.index
+        self.next(incr)
+
+    def iter(self, it):
+        try:
+            self.max = len(it)
+        except TypeError:
+            pass
+
+        for x in it:
+            yield x
+            self.next()
+        self.finish()
diff --git a/progress/bar.py b/progress/bar.py
new file mode 100644
index 0000000..8ce1461
--- /dev/null
+++ b/progress/bar.py
@@ -0,0 +1,83 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 Giorgos Verigakis <verigak at gmail.com>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from . import Progress
+from .helpers import WritelnMixin
+
+
+class Bar(WritelnMixin, Progress):
+    width = 32
+    message = ''
+    suffix = '%(index)d/%(max)d'
+    bar_prefix = ' |'
+    bar_suffix = '| '
+    empty_fill = ' '
+    fill = '#'
+    hide_cursor = True
+
+    def update(self):
+        filled_length = int(self.width * self.progress)
+        empty_length = self.width - filled_length
+
+        message = self.message % self
+        bar = self.fill * filled_length
+        empty = self.empty_fill * empty_length
+        suffix = self.suffix % self
+        line = ''.join([message, self.bar_prefix, bar, empty, self.bar_suffix,
+                        suffix])
+        self.writeln(line)
+
+
+class ChargingBar(Bar):
+    suffix = '%(percent)d%%'
+    bar_prefix = ' '
+    bar_suffix = ' '
+    empty_fill = u'∙'
+    fill = u'█'
+
+
+class FillingSquaresBar(ChargingBar):
+    empty_fill = u'▢'
+    fill = u'▣'
+
+
+class FillingCirclesBar(ChargingBar):
+    empty_fill = u'◯'
+    fill = u'◉'
+
+
+class IncrementalBar(Bar):
+    phases = (u' ', u'▏', u'▎', u'▍', u'▌', u'▋', u'▊', u'▉', u'█')
+
+    def update(self):
+        nphases = len(self.phases)
+        expanded_length = int(nphases * self.width * self.progress)
+        filled_length = int(self.width * self.progress)
+        empty_length = self.width - filled_length
+        phase = expanded_length - (filled_length * nphases)
+
+        message = self.message % self
+        bar = self.phases[-1] * filled_length
+        current = self.phases[phase] if phase > 0 else ''
+        empty = self.empty_fill * max(0, empty_length - len(current))
+        suffix = self.suffix % self
+        line = ''.join([message, self.bar_prefix, bar, current, empty,
+                        self.bar_suffix, suffix])
+        self.writeln(line)
+
+
+class ShadyBar(IncrementalBar):
+    phases = (u' ', u'░', u'▒', u'▓', u'█')
diff --git a/progress/counter.py b/progress/counter.py
new file mode 100644
index 0000000..caaddc6
--- /dev/null
+++ b/progress/counter.py
@@ -0,0 +1,47 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 Giorgos Verigakis <verigak at gmail.com>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from . import Infinite, Progress
+from .helpers import WriteMixin
+
+
+class Counter(WriteMixin, Infinite):
+    message = ''
+    hide_cursor = True
+
+    def update(self):
+        self.write(str(self.index))
+
+
+class Countdown(WriteMixin, Progress):
+    hide_cursor = True
+
+    def update(self):
+        self.write(str(self.remaining))
+
+
+class Stack(WriteMixin, Progress):
+    phases = (u' ', u'▁', u'▂', u'▃', u'▄', u'▅', u'▆', u'▇', u'█')
+    hide_cursor = True
+
+    def update(self):
+        nphases = len(self.phases)
+        i = min(nphases - 1, int(self.progress * nphases))
+        self.write(self.phases[i])
+
+
+class Pie(Stack):
+    phases = (u'○', u'◔', u'◑', u'◕', u'●')
diff --git a/progress/helpers.py b/progress/helpers.py
new file mode 100644
index 0000000..9ed90b2
--- /dev/null
+++ b/progress/helpers.py
@@ -0,0 +1,91 @@
+# Copyright (c) 2012 Giorgos Verigakis <verigak at gmail.com>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from __future__ import print_function
+
+
+HIDE_CURSOR = '\x1b[?25l'
+SHOW_CURSOR = '\x1b[?25h'
+
+
+class WriteMixin(object):
+    hide_cursor = False
+
+    def __init__(self, message=None, **kwargs):
+        super(WriteMixin, self).__init__(**kwargs)
+        self._width = 0
+        if message:
+            self.message = message
+
+        if self.file.isatty():
+            if self.hide_cursor:
+                print(HIDE_CURSOR, end='', file=self.file)
+            print(self.message, end='', file=self.file)
+            self.file.flush()
+
+    def write(self, s):
+        if self.file.isatty():
+            b = '\b' * self._width
+            c = s.ljust(self._width)
+            print(b + c, end='', file=self.file)
+            self._width = max(self._width, len(s))
+            self.file.flush()
+
+    def finish(self):
+        if self.file.isatty() and self.hide_cursor:
+            print(SHOW_CURSOR, end='', file=self.file)
+
+
+class WritelnMixin(object):
+    hide_cursor = False
+
+    def __init__(self, message=None, **kwargs):
+        super(WritelnMixin, self).__init__(**kwargs)
+        if message:
+            self.message = message
+
+        if self.file.isatty() and self.hide_cursor:
+            print(HIDE_CURSOR, end='', file=self.file)
+
+    def clearln(self):
+        if self.file.isatty():
+            print('\r\x1b[K', end='', file=self.file)
+
+    def writeln(self, line):
+        if self.file.isatty():
+            self.clearln()
+            print(line, end='', file=self.file)
+            self.file.flush()
+
+    def finish(self):
+        if self.file.isatty():
+            print(file=self.file)
+            if self.hide_cursor:
+                print(SHOW_CURSOR, end='', file=self.file)
+
+
+from signal import signal, SIGINT
+from sys import exit
+
+
+class SigIntMixin(object):
+    """Registers a signal handler that calls finish on SIGINT"""
+
+    def __init__(self, *args, **kwargs):
+        super(SigIntMixin, self).__init__(*args, **kwargs)
+        signal(SIGINT, self._sigint_handler)
+
+    def _sigint_handler(self, signum, frame):
+        self.finish()
+        exit(0)
diff --git a/progress/spinner.py b/progress/spinner.py
new file mode 100644
index 0000000..969bfbb
--- /dev/null
+++ b/progress/spinner.py
@@ -0,0 +1,40 @@
+# -*- coding: utf-8 -*-
+
+# Copyright (c) 2012 Giorgos Verigakis <verigak at gmail.com>
+#
+# Permission to use, copy, modify, and distribute this software for any
+# purpose with or without fee is hereby granted, provided that the above
+# copyright notice and this permission notice appear in all copies.
+#
+# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+
+from . import Infinite
+from .helpers import WriteMixin
+
+
+class Spinner(WriteMixin, Infinite):
+    message = ''
+    phases = ('-', '\\', '|', '/')
+    hide_cursor = True
+
+    def update(self):
+        i = self.index % len(self.phases)
+        self.write(self.phases[i])
+
+
+class PieSpinner(Spinner):
+    phases = [u'◷', u'◶', u'◵', u'◴']
+
+
+class MoonSpinner(Spinner):
+    phases = [u'◑', u'◒', u'◐', u'◓']
+
+
+class LineSpinner(Spinner):
+    phases = [u'⎺', u'⎻', u'⎼', u'⎽', u'⎼', u'⎻']
diff --git a/setup.cfg b/setup.cfg
new file mode 100644
index 0000000..861a9f5
--- /dev/null
+++ b/setup.cfg
@@ -0,0 +1,5 @@
+[egg_info]
+tag_build = 
+tag_date = 0
+tag_svn_revision = 0
+
diff --git a/setup.py b/setup.py
new file mode 100755
index 0000000..9ec04fc
--- /dev/null
+++ b/setup.py
@@ -0,0 +1,26 @@
+#!/usr/bin/env python
+
+from setuptools import setup
+
+import progress
+
+
+setup(
+    name='progress',
+    version=progress.__version__,
+    description='Easy to use progress bars',
+    long_description=open('README.rst').read(),
+    author='Giorgos Verigakis',
+    author_email='verigak at gmail.com',
+    url='http://github.com/verigak/progress/',
+    license='ISC',
+    packages=['progress'],
+    classifiers=[
+        'Environment :: Console',
+        'Intended Audience :: Developers',
+        'License :: OSI Approved :: ISC License (ISCL)',
+        'Programming Language :: Python :: 2.6',
+        'Programming Language :: Python :: 2.7',
+        'Programming Language :: Python :: 3.3'
+    ]
+)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-progress.git



More information about the Python-modules-commits mailing list