mirror of
https://github.com/kennethreitz/clint.git
synced 2026-06-05 23:00:18 +00:00
Compare commits
22 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 13df32316f | |||
| 93c3f9a4e1 | |||
| 9f14dbb6c5 | |||
| 0e0284f967 | |||
| c5dbe0708e | |||
| 00b522510c | |||
| 4b98c46519 | |||
| e62f5657a5 | |||
| 8e17e8ce50 | |||
| 84dafbeabe | |||
| 5305d1e116 | |||
| 73b1bdd2d4 | |||
| 7bde48ce53 | |||
| a0e14e4181 | |||
| de2cbfca90 | |||
| c909d7dca0 | |||
| 6220552ebf | |||
| a9623213e3 | |||
| 77eab0c0e6 | |||
| 3d01b405b3 | |||
| 6c50b92cb3 | |||
| e00476d195 |
@@ -1,5 +1,11 @@
|
||||
.idea
|
||||
.project
|
||||
.settings
|
||||
.pydevproject
|
||||
MANIFEST
|
||||
*.pyc
|
||||
.tox
|
||||
build/
|
||||
clint.egg-info/
|
||||
dist/
|
||||
|
||||
|
||||
@@ -6,6 +6,10 @@ Development Lead
|
||||
|
||||
- Kenneth Reitz <me@kennethreitz.com>
|
||||
|
||||
Maintainers
|
||||
```````````
|
||||
|
||||
- Jason Piper <j.piper@me.com>
|
||||
|
||||
Patches and Suggestions
|
||||
```````````````````````
|
||||
@@ -25,3 +29,4 @@ Patches and Suggestions
|
||||
- Justin Barber <barber.justin (at) gmail>
|
||||
- Dmitry Medvinsky
|
||||
- Eric Anderson
|
||||
- Joshua Richardson
|
||||
|
||||
+10
@@ -1,6 +1,16 @@
|
||||
History
|
||||
-------
|
||||
|
||||
0.3.5
|
||||
+++++
|
||||
* progress.bar is now a context manager - doesn't require an iterable anymore (thanks to @jric)
|
||||
* Bug fixes
|
||||
|
||||
0.3.4
|
||||
+++++
|
||||
* Fixed Python 3 basestring deprecation
|
||||
* Fixed examples
|
||||
|
||||
0.3.3
|
||||
+++++
|
||||
* Fixed Python 3 build issues
|
||||
|
||||
+4
-3
@@ -91,7 +91,9 @@ I want to get data piped to stdin. ::
|
||||
|
||||
I want to get the first commandline argument passed in. ::
|
||||
|
||||
>>> clint.args.get(0)
|
||||
>>> from clint import arguments
|
||||
>>> args = arguments.Args()
|
||||
>>> args.get(0)
|
||||
|
||||
# if no argument was passed, get returns None
|
||||
|
||||
@@ -147,7 +149,7 @@ Contribute
|
||||
----------
|
||||
|
||||
If you'd like to contribute, simply fork `the repository`_, commit your changes
|
||||
to the **develop** branch (or branch off of it), and send a pull request. Make
|
||||
to the **master** branch (or branch off of it), and send a pull request. Make
|
||||
sure you add yourself to AUTHORS_.
|
||||
|
||||
|
||||
@@ -155,7 +157,6 @@ Roadmap
|
||||
-------
|
||||
- Unittests
|
||||
- Sphinx Documentation
|
||||
- Python 2.5, 3.1, 3.2 Support
|
||||
|
||||
|
||||
|
||||
|
||||
+2
-2
@@ -26,8 +26,8 @@ from .pipes import piped_in
|
||||
|
||||
|
||||
__title__ = 'clint'
|
||||
__version__ = '0.3.3'
|
||||
__build__ = 0x000303
|
||||
__version__ = '0.3.5'
|
||||
__build__ = 0x000305
|
||||
__author__ = 'Kenneth Reitz'
|
||||
__license__ = 'ISC'
|
||||
__copyright__ = 'Copyright 2012 Kenneth Reitz'
|
||||
|
||||
+17
-10
@@ -48,15 +48,19 @@ class ColoredString(object):
|
||||
self.bold = bold
|
||||
|
||||
def __getattr__(self, att):
|
||||
def func_help(*args, **kwargs):
|
||||
result = getattr(self.s, att)(*args, **kwargs)
|
||||
if isinstance(result, basestring):
|
||||
return self._new(result)
|
||||
elif isinstance(result, list):
|
||||
return [self._new(x) for x in result]
|
||||
else:
|
||||
return result
|
||||
return func_help
|
||||
def func_help(*args, **kwargs):
|
||||
result = getattr(self.s, att)(*args, **kwargs)
|
||||
try:
|
||||
is_result_string = isinstance(result, basestring)
|
||||
except NameError:
|
||||
is_result_string = isinstance(result, str)
|
||||
if is_result_string:
|
||||
return self._new(result)
|
||||
elif isinstance(result, list):
|
||||
return [self._new(x) for x in result]
|
||||
else:
|
||||
return result
|
||||
return func_help
|
||||
|
||||
@property
|
||||
def color_str(self):
|
||||
@@ -87,7 +91,10 @@ class ColoredString(object):
|
||||
__str__ = __unicode__
|
||||
else:
|
||||
def __str__(self):
|
||||
return unicode(self).encode('utf8')
|
||||
value = self.color_str
|
||||
if isinstance(value, bytes):
|
||||
return value
|
||||
return value.encode('utf8')
|
||||
|
||||
def __iter__(self):
|
||||
return iter(self.color_str)
|
||||
|
||||
+68
-33
@@ -33,43 +33,78 @@ ETA_INTERVAL = 1
|
||||
#How many intervals (excluding the current one) to calculate the simple moving average
|
||||
ETA_SMA_WINDOW = 9
|
||||
|
||||
def bar(it, label='', width=32, hide=HIDE_DEFAULT, empty_char=BAR_EMPTY_CHAR, filled_char=BAR_FILLED_CHAR, expected_size=None, every=1):
|
||||
"""Progress iterator. Wrap your iterables with it."""
|
||||
|
||||
def _show(_i):
|
||||
if (time.time() - bar.etadelta) > ETA_INTERVAL:
|
||||
bar.etadelta = time.time()
|
||||
bar.ittimes = bar.ittimes[-ETA_SMA_WINDOW:]+[-(bar.start-time.time())/(_i+1)]
|
||||
bar.eta = sum(bar.ittimes)/float(len(bar.ittimes)) * (count-_i)
|
||||
bar.etadisp = time.strftime('%H:%M:%S', time.gmtime(bar.eta))
|
||||
x = int(width*_i/count)
|
||||
if not hide:
|
||||
if ((_i % every)==0 or # True every "every" updates
|
||||
(_i == count)): # And when we're done
|
||||
class Bar(object):
|
||||
def __enter__(self):
|
||||
return self
|
||||
|
||||
def __exit__(self, exc_type, exc_val, exc_tb):
|
||||
self.done()
|
||||
return False # we're not surpressing exceptions
|
||||
|
||||
def __init__(self, label='', width=32, hide=None, empty_char=BAR_EMPTY_CHAR,
|
||||
filled_char=BAR_FILLED_CHAR, expected_size=None, every=1):
|
||||
self.label = label
|
||||
self.width = width
|
||||
self.hide = hide
|
||||
if hide is None:
|
||||
try:
|
||||
self.hide = not STREAM.isatty()
|
||||
except AttributeError: # output does not support isatty()
|
||||
self.hide = True
|
||||
self.empty_char = empty_char
|
||||
self.filled_char = filled_char
|
||||
self.expected_size = expected_size
|
||||
self.every = every
|
||||
self.start = time.time()
|
||||
self.ittimes = []
|
||||
self.eta = 0
|
||||
self.etadelta = time.time()
|
||||
self.etadisp = time.strftime('%H:%M:%S', time.gmtime(self.eta))
|
||||
if (self.expected_size):
|
||||
self.show(0)
|
||||
|
||||
def show(self, progress, count=None):
|
||||
if count is not None:
|
||||
self.expected_size = count
|
||||
if self.expected_size is None:
|
||||
raise Exception("expected_size not initialized")
|
||||
if (time.time() - self.etadelta) > ETA_INTERVAL:
|
||||
self.etadelta = time.time()
|
||||
self.ittimes = \
|
||||
self.ittimes[-ETA_SMA_WINDOW:]+\
|
||||
[-(self.start-time.time())/(progress+1)]
|
||||
self.eta = \
|
||||
sum(self.ittimes)/float(len(self.ittimes)) * \
|
||||
(self.expected_size-progress)
|
||||
self.etadisp = time.strftime('%H:%M:%S', time.gmtime(self.eta))
|
||||
x = int(self.width*progress/self.expected_size)
|
||||
if not self.hide:
|
||||
if ((progress % self.every)==0 or # True every "every" updates
|
||||
(progress == self.expected_size)): # And when we're done
|
||||
STREAM.write(BAR_TEMPLATE % (
|
||||
label, filled_char*x, empty_char*(width-x), _i, count, bar.etadisp))
|
||||
self.label, self.filled_char*x,
|
||||
self.empty_char*(self.width-x), progress,
|
||||
self.expected_size, self.etadisp))
|
||||
STREAM.flush()
|
||||
|
||||
count = len(it) if expected_size is None else expected_size
|
||||
|
||||
bar.start = time.time()
|
||||
bar.ittimes = []
|
||||
bar.eta = 0
|
||||
bar.etadelta = time.time()
|
||||
bar.etadisp = time.strftime('%H:%M:%S', time.gmtime(bar.eta))
|
||||
|
||||
if count:
|
||||
_show(0)
|
||||
|
||||
for i, item in enumerate(it):
|
||||
|
||||
yield item
|
||||
_show(i+1)
|
||||
|
||||
if not hide:
|
||||
def done(self):
|
||||
if not self.hide:
|
||||
STREAM.write('\n')
|
||||
STREAM.flush()
|
||||
|
||||
def bar(it, label='', width=32, hide=HIDE_DEFAULT, empty_char=BAR_EMPTY_CHAR, filled_char=BAR_FILLED_CHAR, expected_size=None, every=1):
|
||||
"""Progress iterator. Wrap your iterables with it."""
|
||||
|
||||
count = len(it) if expected_size is None else expected_size
|
||||
|
||||
with Bar(label=label, width=width, hide=hide, empty_char=BAR_EMPTY_CHAR,
|
||||
filled_char=BAR_FILLED_CHAR, expected_size=count, every=every) \
|
||||
as bar:
|
||||
|
||||
for i, item in enumerate(it):
|
||||
|
||||
yield item
|
||||
bar.show(i+1)
|
||||
|
||||
def dots(it, label='', hide=HIDE_DEFAULT, every=1):
|
||||
"""Progress iterator. Prints a dot for each item being iterated"""
|
||||
@@ -97,10 +132,10 @@ def mill(it, label='', hide=HIDE_DEFAULT, expected_size=None, every=1):
|
||||
"""Progress iterator. Prints a mill while iterating over the items."""
|
||||
|
||||
def _mill_char(_i):
|
||||
if _i == 100:
|
||||
if _i >= count:
|
||||
return ' '
|
||||
else:
|
||||
return MILL_CHARS[_i % len(MILL_CHARS)]
|
||||
return MILL_CHARS[(_i / every) % len(MILL_CHARS)]
|
||||
|
||||
def _show(_i):
|
||||
if not hide:
|
||||
|
||||
+7
-29
@@ -61,37 +61,15 @@ def mkdir_p(path):
|
||||
|
||||
def tsplit(string, delimiters):
|
||||
"""Behaves str.split but supports tuples of delimiters."""
|
||||
|
||||
delimiters = tuple(delimiters)
|
||||
stack = [string,]
|
||||
if len(delimiters) < 1:
|
||||
return [string,]
|
||||
final_delimiter = delimiters[0]
|
||||
for i in delimiters[1:]:
|
||||
string = string.replace(i, final_delimiter)
|
||||
return string.split(final_delimiter)
|
||||
|
||||
for delimiter in delimiters:
|
||||
for i, substring in enumerate(stack):
|
||||
substack = substring.split(delimiter)
|
||||
stack.pop(i)
|
||||
for j, _substring in enumerate(substack):
|
||||
stack.insert(i+j, _substring)
|
||||
|
||||
return stack
|
||||
|
||||
def schunk(string, size):
|
||||
"""Splits string into n sized chunks."""
|
||||
|
||||
stack = []
|
||||
|
||||
substack = []
|
||||
current_count = 0
|
||||
|
||||
for char in string:
|
||||
if not current_count < size:
|
||||
stack.append(''.join(substack))
|
||||
substack = []
|
||||
current_count = 0
|
||||
|
||||
substack.append(char)
|
||||
current_count += 1
|
||||
|
||||
if len(substack):
|
||||
stack.append(''.join(substack))
|
||||
|
||||
return stack
|
||||
return [string[i:i+size] for i in range(0, len(string), size)]
|
||||
|
||||
Regular → Executable
+3
-1
@@ -6,9 +6,11 @@ import os
|
||||
|
||||
sys.path.insert(0, os.path.abspath('..'))
|
||||
|
||||
from clint import args
|
||||
from clint.arguments import Args
|
||||
from clint.textui import puts, colored, indent
|
||||
|
||||
args = Args()
|
||||
|
||||
with indent(4, quote='>>>'):
|
||||
puts(colored.red('Aruments passed in: ') + str(args.all))
|
||||
puts(colored.red('Flags detected: ') + str(args.flags))
|
||||
|
||||
Regular → Executable
+2
-2
@@ -1,10 +1,10 @@
|
||||
#! /usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
from clint import args
|
||||
from clint.arguments import Args
|
||||
from clint.textui import puts, colored
|
||||
|
||||
all_args = args.grouped
|
||||
all_args = Args().grouped
|
||||
|
||||
for item in all_args:
|
||||
if item is not '_':
|
||||
|
||||
@@ -14,6 +14,13 @@ from clint.textui import progress
|
||||
if __name__ == '__main__':
|
||||
for i in progress.bar(range(100)):
|
||||
sleep(random() * 0.2)
|
||||
|
||||
with progress.Bar(label="nonlinear", expected_size=10) as bar:
|
||||
last_val = 0
|
||||
for val in (1,2,3,9,10):
|
||||
sleep(2 * (val - last_val))
|
||||
bar.show(val)
|
||||
last_val = val
|
||||
|
||||
for i in progress.dots(range(100)):
|
||||
sleep(random() * 0.2)
|
||||
|
||||
+3
-1
@@ -11,10 +11,12 @@ try:
|
||||
except:
|
||||
import simplejson as json
|
||||
|
||||
from clint import args
|
||||
from clint.arguments import Args
|
||||
from clint import piped_in
|
||||
from clint.textui import colored, puts, indent
|
||||
|
||||
args = Args()
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
||||
puts('Test:')
|
||||
|
||||
@@ -42,5 +42,13 @@ class ColoredStringTestCase(unittest.TestCase):
|
||||
output = new_str.replace("world", "universe")
|
||||
assert output.s == "hello universe"
|
||||
|
||||
def test_py2_bytes_not_mangled(self):
|
||||
from clint.textui.colored import ColoredString
|
||||
# On python 2 make sure the same bytes come out as went in
|
||||
new_str = ColoredString('RED', '\xe4')
|
||||
assert '\xe4' in str(new_str)
|
||||
from clint.textui import puts
|
||||
puts(new_str)
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
||||
Reference in New Issue
Block a user