35 Commits

Author SHA1 Message Date
Jason Piper 57955b9156 Pushing 0.3.7 to pypi 2014-04-17 16:05:53 +01:00
Jason Piper f1ab574413 Merge pull request #106 from joemiller/features/force_color
if env var CLINT_FORCE_COLOR is set, always output color codes
2014-03-23 10:36:55 +00:00
Jason Piper 2aff70618c Merge pull request #111 from jezdez/fix-yn
Fixed the prompt.yn function to work on Python3.
2014-03-23 10:36:04 +00:00
Jason Piper 4b7688b220 Merge pull request #110 from infamy/master
Fixed bold issue
2014-03-23 10:35:03 +00:00
Jannis Leidel 03731d6ef2 Fixed the prompt.yn function to work on Python3. 2014-03-23 11:31:59 +01:00
infamy 8a2aed6c32 Fixed bold issue
Bold would get "stuck" on in powershell/cmd prompt.
2014-03-19 22:19:51 -07:00
joe miller 98cab56e97 if env var CLINT_FORCE_COLOR is set, always output color codes even if stdout is not a tty 2014-03-14 16:58:06 +00:00
Jason Piper 13df32316f 0.3.5 2014-03-14 11:35:35 +00:00
Jason Piper 93c3f9a4e1 Merge pull request #105 from gazpachoking/colored_bytes
ColoredString doesn't attempt to decode explicitly given bytes in python 2
2014-03-14 11:27:31 +00:00
Jason Piper 9f14dbb6c5 Merge pull request #103 from jric/master
Ability to update progress bar in non-linear fashion.
2014-03-14 11:26:30 +00:00
Chase Sterling 0e0284f967 ColoredString doesn't attempt to decode explicitly given bytes in python 2 2014-02-27 23:47:59 -05:00
Joshua Richardson c5dbe0708e Extended .gitignore. 2014-02-21 11:26:11 -08:00
Joshua Richardson 00b522510c Don't need to call show(0), since that's done automatically in the
__init__() function.
2014-02-11 20:49:17 -08:00
Joshua Richardson 4b98c46519 Remove commented-out implementation. 2014-02-11 20:28:06 -08:00
Joshua Richardson e62f5657a5 Added ability to "update" the progress bar without iterating over
every value.
2014-02-11 20:25:15 -08:00
Jason Piper 8e17e8ce50 Merge pull request #102 from daveFNbuck/buck_fix_mills
Fixes progress.mill display when every is greater than 1
2014-02-06 09:34:49 +00:00
Dave Buchfuhrer 84dafbeabe Clears the mill when complete 2014-02-05 22:01:56 -08:00
Dave Buchfuhrer 5305d1e116 Properly updates mill characters when every isn't equal to 1 mod 4 2014-02-05 22:01:46 -08:00
Jason Piper 73b1bdd2d4 0.3.4 2014-01-28 23:17:46 +00:00
Jason Piper 7bde48ce53 0.3.4 2014-01-28 23:14:37 +00:00
Jason Piper a0e14e4181 Fix for Python 3 basestring deprecation 2014-01-28 23:10:41 +00:00
Jason Piper de2cbfca90 Add self as a maintainer 2014-01-13 14:17:52 +00:00
Jason Piper c909d7dca0 Fix examples and pull request instructions 2014-01-13 14:17:52 +00:00
Jason Piper 6220552ebf Merge pull request #99 from haqthat/patch-1
fix unicode.py import error
2014-01-10 15:02:07 -08:00
haqthat a9623213e3 fix args.py import error
args.sh fails 

Traceback (most recent call last):
  File "unicode.py", line 14, in <module>
    from clint import args
ImportError: cannot import name args
2014-01-10 14:29:18 -05:00
Jason Piper 77eab0c0e6 Fix broken example 2014-01-10 17:45:05 +00:00
Jason Piper 3d01b405b3 Fix broken example 2014-01-10 16:20:44 +00:00
Jason Piper 6c50b92cb3 Python 2.5 and 3.2 support added a long time ago 2014-01-10 11:21:08 +00:00
Jason Piper e00476d195 optimisations for schunk and tsplit 2014-01-10 11:20:43 +00:00
Jason Piper fc463f16c3 0.3.3 2014-01-09 23:45:19 +00:00
Jason Piper 9324af95b2 Fixed README and HISTORY being installed to /usr 2014-01-09 22:52:08 +00:00
Jason Piper 50294ea2dc Merge pull request #95 from saimn/patch-1
Use print() function to fix install on python 3
2014-01-09 12:25:27 -08:00
kennethreitz 56fe6138b6 Merge pull request #96 from sephii/bold_support
Add support for bold text
2014-01-08 11:59:57 -08:00
Sylvain Fankhauser d22847fb95 add support for bold text 2013-12-18 17:02:38 +01:00
Simon Conseil ce25cea7e8 Use print() function to fix install on python 3
clint 0.3.2 can't be installed on python 3.3 because of a print statement.
2013-12-05 23:42:27 +01:00
15 changed files with 212 additions and 114 deletions
+6
View File
@@ -1,5 +1,11 @@
.idea
.project
.settings
.pydevproject
MANIFEST
*.pyc
.tox
build/
clint.egg-info/
dist/
+5
View File
@@ -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
+32
View File
@@ -1,6 +1,38 @@
History
-------
0.3.7
+++++
* Clint now obeys the CLINT_FORCE_COLOR environmental variable
0.3.6
+++++
* Fixed faulty PyPI deployment
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
* Fixed README and HISTORY being installed to /usr
* Support added for bold text
0.3.2
+++++
* Unknown
0.3.1
+++++
* Unknown
0.3.0
+++++
+8 -3
View File
@@ -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
@@ -107,6 +109,10 @@ I want to store a configuration file. ::
# Windows: 'C:\\Users\\appuser\\AppData\\Local\\Company\\AppName\\config.ini'
# Linux: '/home/appuser/.config/appname/config.ini'
I want to force color output even if stdout is not a TTY:
$ export CLINT_FORCE_COLOR=1
Installation
------------
@@ -147,7 +153,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 +161,6 @@ Roadmap
-------
- Unittests
- Sphinx Documentation
- Python 2.5, 3.1, 3.2 Support
+2 -2
View File
@@ -26,8 +26,8 @@ from .pipes import piped_in
__title__ = 'clint'
__version__ = '0.3.1'
__build__ = 0x000301
__version__ = '0.3.7'
__build__ = 0x000307
__author__ = 'Kenneth Reitz'
__license__ = 'ISC'
__copyright__ = 'Copyright 2012 Kenneth Reitz'
+40 -29
View File
@@ -11,6 +11,7 @@ This module provides a simple and elegant wrapper for colorama.
from __future__ import absolute_import
import os
import re
import sys
@@ -37,29 +38,36 @@ else:
DISABLE_COLOR = False
class ColoredString(object):
"""Enhanced string for __len__ operations on Colored output."""
def __init__(self, color, s, always_color=False):
def __init__(self, color, s, always_color=False, bold=False):
super(ColoredString, self).__init__()
self.s = s
self.color = color
self.always_color = always_color
self.bold = bold
if os.environ.get('CLINT_FORCE_COLOR'):
self.always_color = True
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):
c = '%s%s%s' % (getattr(colorama.Fore, self.color), self.s, colorama.Fore.RESET)
style = 'BRIGHT' if self.bold else 'NORMAL'
c = '%s%s%s%s%s' % (getattr(colorama.Fore, self.color), getattr(colorama.Style, style), self.s, colorama.Fore.RESET, getattr(colorama.Style, 'NORMAL'))
if self.always_color:
return c
@@ -85,7 +93,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)
@@ -113,29 +124,29 @@ def clean(s):
return txt
def black(string, always=False):
return ColoredString('BLACK', string, always_color=always)
def black(string, always=False, bold=False):
return ColoredString('BLACK', string, always_color=always, bold=bold)
def red(string, always=False):
return ColoredString('RED', string, always_color=always)
def red(string, always=False, bold=False):
return ColoredString('RED', string, always_color=always, bold=bold)
def green(string, always=False):
return ColoredString('GREEN', string, always_color=always)
def green(string, always=False, bold=False):
return ColoredString('GREEN', string, always_color=always, bold=bold)
def yellow(string, always=False):
return ColoredString('YELLOW', string, always_color=always)
def yellow(string, always=False, bold=False):
return ColoredString('YELLOW', string, always_color=always, bold=bold)
def blue(string, always=False):
return ColoredString('BLUE', string, always_color=always)
def blue(string, always=False, bold=False):
return ColoredString('BLUE', string, always_color=always, bold=bold)
def magenta(string, always=False):
return ColoredString('MAGENTA', string, always_color=always)
def magenta(string, always=False, bold=False):
return ColoredString('MAGENTA', string, always_color=always, bold=bold)
def cyan(string, always=False):
return ColoredString('CYAN', string, always_color=always)
def cyan(string, always=False, bold=False):
return ColoredString('CYAN', string, always_color=always, bold=bold)
def white(string, always=False):
return ColoredString('WHITE', string, always_color=always)
def white(string, always=False, bold=False):
return ColoredString('WHITE', string, always_color=always, bold=bold)
def disable():
"""Disables colors."""
+68 -33
View File
@@ -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:
+13 -8
View File
@@ -8,29 +8,34 @@ Module for simple interactive prompts handling
"""
from __future__ import absolute_import
from __future__ import absolute_import, print_function
from re import match, I
try:
raw_input
except NameError:
raw_input = input
def yn(prompt, default='y', batch=False):
# A sanity check against default value
# If not y/n then y is assumed
# If not y/n then y is assumed
if default not in ['y', 'n']:
default = 'y'
# Let's build the prompt
choicebox = '[Y/n]' if default == 'y' else '[y/N]'
prompt = prompt + ' ' + choicebox + ' '
choicebox = '[Y/n]' if default == 'y' else '[y/N]'
prompt = prompt + ' ' + choicebox + ' '
# If input is not a yes/no variant or empty
# keep asking
while True:
# If batch option is True then auto reply
# If batch option is True then auto reply
# with default input
if not batch:
input = raw_input(prompt).strip()
else:
print prompt
print(prompt)
input = ''
# If input is empty default choice is assumed
@@ -39,7 +44,7 @@ def yn(prompt, default='y', batch=False):
return True
# Given 'yes' as input if default choice is y
# then return True, False otherwise
# then return True, False otherwise
if match('y(?:es)?', input, I):
return True if default == 'y' else False
+7 -29
View File
@@ -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
View File
@@ -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
View File
@@ -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 '_':
+7
View File
@@ -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
View File
@@ -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:')
-6
View File
@@ -11,8 +11,6 @@ except ImportError:
import clint
def publish():
"""Publish to PyPi"""
os.system("python setup.py sdist upload")
@@ -32,10 +30,6 @@ setup(
author='Kenneth Reitz',
author_email='me@kennethreitz.com',
url='https://github.com/kennethreitz/clint',
data_files=[
'README.rst',
'HISTORY.rst',
],
packages= [
'clint',
'clint.textui',
+16
View File
@@ -3,6 +3,7 @@
"""Clint Test Suite."""
import os
import unittest
@@ -42,5 +43,20 @@ 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)
def test_clint_force_color_env_var(self):
from clint.textui.colored import ColoredString
os.environ['CLINT_FORCE_COLOR'] = "1"
new_str = ColoredString('RED', 'hello world')
assert new_str.always_color == True
if __name__ == '__main__':
unittest.main()