1 Commits

Author SHA1 Message Date
Kenneth Reitz 4336c354de v0.3.1 2012-01-16 09:25:54 -05:00
18 changed files with 166 additions and 308 deletions
-6
View File
@@ -19,9 +19,3 @@ Patches and Suggestions
- takluyver
- kracekumar
- Alejandro Gómez <alejandrogomez>
- Jason Piper <jpiper>
- Gianluca Brindisi <gbrindisi>
- Don Spaulding <donspauldingii@gmail.com>
- Justin Barber <barber.justin (at) gmail>
- Dmitry Medvinsky
- Eric Anderson
+8
View File
@@ -1,6 +1,14 @@
History
-------
0.3.1
+++++
* Progress mill indicator.
* Colored unicode support.
* Fix ipython nuance.
0.3.0
+++++
+4 -4
View File
@@ -4,7 +4,7 @@ Clint: Python Command-line Application Tools
**Clint** is a module filled with a set of awesome tools for developing
commandline applications.
.. image:: https://raw.github.com/kennethreitz/clint/master/misc/clint.jpeg
.. image:: https://github.com/kennethreitz/clint/raw/master/misc/clint.jpeg
**C** ommand
**L** ine
@@ -24,7 +24,7 @@ The world's easiest to use implicit argument system w/ chaining methods for filt
Run the various executables in examples_ to get a good feel for what Clint offers.
.. _examples: https://github.com/kennethreitz/clint/tree/master/examples
.. _examples: https://github.com/kennethreitz/clint/tree/develop/examples
You'll never want to not use it.
@@ -70,7 +70,7 @@ I want to quote my console text (like email). ::
>>> puts('pretty cool, eh?')
not indented text
> quoted text
> indented text
> pretty cool, eh?
I want to color my console text. ::
@@ -160,4 +160,4 @@ Roadmap
.. _`the repository`: http://github.com/kennethreitz/clint
.. _AUTHORS: http://github.com/kennethreitz/clint/blob/develop/AUTHORS
.. _AUTHORS: http://github.com/kennethreitz/clint/blob/master/AUTHORS
+6 -10
View File
@@ -11,14 +11,7 @@ This module sets up the main interface for all of clint.
from __future__ import absolute_import
try:
from collections import OrderedDict
except ImportError:
from .packages.ordereddict import OrderedDict
import collections
collections.OrderedDict = OrderedDict
from .arguments import *
from . import arguments
from . import textui
from . import utils
from .pipes import piped_in
@@ -26,9 +19,12 @@ from .pipes import piped_in
__title__ = 'clint'
__version__ = '0.3.2'
__build__ = 0x000302
__version__ = '0.3.1'
__build__ = 0x000301
__author__ = 'Kenneth Reitz'
__license__ = 'ISC'
__copyright__ = 'Copyright 2012 Kenneth Reitz'
__docformat__ = 'restructuredtext'
args = arguments.Args()
+1 -1
View File
@@ -241,7 +241,7 @@ class Args(object):
for arg in self.all:
if arg.startswith('-'):
_current_group = arg
collection.setdefault(arg, Args(no_argv=True))
collection[arg] = Args(no_argv=True)
else:
if _current_group:
collection[_current_group]._args.append(arg)
+4 -4
View File
@@ -20,12 +20,12 @@ except NameError:
unicode = str
def join(l, conj=CONJUNCTION, im_a_moron=MORON_MODE, separator=COMMA):
def join(l, conj=CONJUNCTION, im_a_moron=MORON_MODE, seperator=COMMA):
"""Joins lists of words. Oxford comma and all."""
collector = []
left = len(l)
separator = separator + SPACE
seperator = seperator + SPACE
conj = conj + SPACE
for _l in l[:]:
@@ -37,12 +37,12 @@ def join(l, conj=CONJUNCTION, im_a_moron=MORON_MODE, separator=COMMA):
if len(l) == 2 or im_a_moron:
collector.append(SPACE)
else:
collector.append(separator)
collector.append(seperator)
collector.append(conj)
elif left is not 0:
collector.append(separator)
collector.append(seperator)
return unicode(str().join(collector))
+1 -5
View File
@@ -7,13 +7,9 @@ clint.textui
This module provides the text output helper system.
"""
import sys
if sys.platform.startswith('win'):
from ..packages import colorama
colorama.init()
from . import colored
from . import progress
from . import prompt
from .core import *
+24 -36
View File
@@ -40,31 +40,16 @@ else:
class ColoredString(object):
"""Enhanced string for __len__ operations on Colored output."""
def __init__(self, color, s, always_color=False):
def __init__(self, color, s):
super(ColoredString, self).__init__()
self.s = s
self.color = color
self.always_color = always_color
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
@property
def color_str(self):
c = '%s%s%s' % (getattr(colorama.Fore, self.color), self.s, colorama.Fore.RESET)
if self.always_color:
return c
elif sys.stdout.isatty() and not DISABLE_COLOR:
return c
if sys.stdout.isatty() and not DISABLE_COLOR:
return '%s%s%s' % (
getattr(colorama.Fore, self.color), self.s, colorama.Fore.RESET)
else:
return self.s
@@ -77,7 +62,7 @@ class ColoredString(object):
def __unicode__(self):
value = self.color_str
if isinstance(value, bytes):
if isinstance(value, str) and hasattr(value, 'decode'):
return value.decode('utf8')
return value
@@ -99,6 +84,9 @@ class ColoredString(object):
def __mul__(self, other):
return (self.color_str * other)
def split(self, sep=None):
return [self._new(s) for s in self.s.split(sep)]
def _new(self, s):
return ColoredString(self.color, s)
@@ -113,29 +101,29 @@ def clean(s):
return txt
def black(string, always=False):
return ColoredString('BLACK', string, always_color=always)
def black(string):
return ColoredString('BLACK', string)
def red(string, always=False):
return ColoredString('RED', string, always_color=always)
def red(string):
return ColoredString('RED', string)
def green(string, always=False):
return ColoredString('GREEN', string, always_color=always)
def green(string):
return ColoredString('GREEN', string)
def yellow(string, always=False):
return ColoredString('YELLOW', string, always_color=always)
def yellow(string):
return ColoredString('YELLOW', string)
def blue(string, always=False):
return ColoredString('BLUE', string, always_color=always)
def blue(string):
return ColoredString('BLUE', string)
def magenta(string, always=False):
return ColoredString('MAGENTA', string, always_color=always)
def magenta(string):
return ColoredString('MAGENTA', string)
def cyan(string, always=False):
return ColoredString('CYAN', string, always_color=always)
def cyan(string):
return ColoredString('CYAN', string)
def white(string, always=False):
return ColoredString('WHITE', string, always_color=always)
def white(string):
return ColoredString('WHITE', string)
def disable():
"""Disables colors."""
+54 -49
View File
@@ -13,15 +13,12 @@ from __future__ import absolute_import
import sys
from contextlib import contextmanager
from .formatters import max_width, min_width
from .cols import columns
from ..utils import tsplit
__all__ = ('puts', 'puts_err', 'indent', 'dedent', 'columns', 'max_width',
'min_width', 'STDOUT', 'STDERR')
__all__ = ('puts', 'puts_err', 'indent', 'columns', 'max_width', 'min_width')
STDOUT = sys.stdout.write
@@ -29,60 +26,68 @@ STDERR = sys.stderr.write
NEWLINES = ('\n', '\r', '\r\n')
INDENT_STRINGS = []
# Private
def _indent(indent=0, quote='', indent_char=' '):
"""Indent util function, compute new indent_string"""
if indent > 0:
indent_string = ''.join((
str(quote),
(indent_char * (indent - len(quote)))
class Writer(object):
"""WriterUtilized by context managers."""
shared = dict(indent_level=0, indent_strings=[])
def __init__(self, indent=0, quote='', indent_char=' '):
self.indent = indent
self.indent_char = indent_char
self.indent_quote = quote
if self.indent > 0:
self.indent_string = ''.join((
str(quote),
(self.indent_char * (indent - len(self.indent_quote)))
))
else:
self.indent_string = ''.join((
('\x08' * (-1 * (indent - len(self.indent_quote)))),
str(quote))
)
if len(self.indent_string):
self.shared['indent_strings'].append(self.indent_string)
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.shared['indent_strings'].pop()
def __call__(self, s, newline=True, stream=STDOUT):
if newline:
s = tsplit(s, NEWLINES)
s = map(str, s)
indent = ''.join(self.shared['indent_strings'])
s = (str('\n' + indent)).join(s)
_str = ''.join((
''.join(self.shared['indent_strings']),
str(s),
'\n' if newline else ''
))
else:
indent_string = ''.join((
('\x08' * (-1 * (indent - len(quote)))),
str(quote))
)
stream(_str)
if len(indent_string):
INDENT_STRINGS.append(indent_string)
# Public
def puts(s='', newline=True, stream=STDOUT):
"""Prints given string to stdout."""
if newline:
s = tsplit(s, NEWLINES)
s = map(str, s)
indent = ''.join(INDENT_STRINGS)
"""Prints given string to stdout via Writer interface."""
Writer()(s, newline, stream=stream)
s = (str('\n' + indent)).join(s)
_str = ''.join((
''.join(INDENT_STRINGS),
str(s),
'\n' if newline else ''
))
stream(_str)
def puts_err(s='', newline=True, stream=STDERR):
"""Prints given string to stderr."""
puts(s, newline, stream)
"""Prints given string to stderr via Writer interface."""
Writer()(s, newline, stream=stream)
def dedent():
"""Dedent next strings, use only if you use indent otherwise than as a
context."""
INDENT_STRINGS.pop()
@contextmanager
def _indent_context():
"""Indentation context manager."""
yield
dedent()
def indent(indent=4, quote=''):
"""Indentation manager, return an indentation context manager."""
_indent(indent, quote)
return _indent_context()
"""Indentation context manager."""
return Writer(indent=indent, quote=quote)
+56 -84
View File
@@ -11,16 +11,10 @@ This module provides the progressbar functionality.
from __future__ import absolute_import
import sys
import time
STREAM = sys.stderr
# Only show bar in terminals by default (better for piping, logging etc.)
try:
HIDE_DEFAULT = not STREAM.isatty()
except AttributeError: # output does not support isatty()
HIDE_DEFAULT = True
BAR_TEMPLATE = '%s[%s%s] %i/%i - %s\r'
BAR_TEMPLATE = '%s[%s%s] %i/%i\r'
MILL_TEMPLATE = '%s %s %i/%i\r'
DOTS_CHAR = '.'
@@ -28,90 +22,68 @@ BAR_FILLED_CHAR = '#'
BAR_EMPTY_CHAR = ' '
MILL_CHARS = ['|', '/', '-', '\\']
#How long to wait before recalculating the ETA
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):
def bar(it, label='', width=32, hide=False, empty_char=BAR_EMPTY_CHAR, filled_char=BAR_FILLED_CHAR):
"""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
STREAM.write(BAR_TEMPLATE % (
label, filled_char*x, empty_char*(width-x), _i, count, bar.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:
STREAM.write('\n')
STREAM.write(BAR_TEMPLATE % (
label, filled_char*x, empty_char*(width-x), _i, count))
STREAM.flush()
def dots(it, label='', hide=HIDE_DEFAULT, every=1):
"""Progress iterator. Prints a dot for each item being iterated"""
count = 0
if not hide:
STREAM.write(label)
for (i, item) in enumerate(it):
if not hide:
if (i % every)==0: # True every "every" updates
STREAM.write(DOTS_CHAR)
sys.stderr.flush()
count += 1
yield item
STREAM.write('\n')
STREAM.flush()
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:
return ' '
else:
return MILL_CHARS[_i % len(MILL_CHARS)]
def _show(_i):
if not hide:
if ((_i % every)==0 or # True every "every" updates
(_i == count)): # And when we're done
STREAM.write(MILL_TEMPLATE % (
label, _mill_char(_i), _i, count))
STREAM.flush()
count = len(it) if expected_size is None else expected_size
count = len(it)
if count:
_show(0)
for i, item in enumerate(it):
yield item
_show(i+1)
if not hide:
STREAM.write('\n')
STREAM.flush()
def dots(it, label='', hide=False):
"""Progress iterator. Prints a dot for each item being iterated"""
count = 0
if not hide:
STREAM.write(label)
for item in it:
if not hide:
STREAM.write(DOTS_CHAR)
sys.stderr.flush()
count += 1
yield item
STREAM.write('\n')
STREAM.flush()
def mill(it, label='', hide=False,):
"""Progress iterator. Prints a mill while iterating over the items."""
def _mill_char(_i):
if _i == 100:
return ' '
else:
return MILL_CHARS[_i % len(MILL_CHARS)]
def _show(_i):
if not hide:
STREAM.write(MILL_TEMPLATE % (
label, _mill_char(_i), _i, count))
STREAM.flush()
count = len(it)
if count:
_show(0)
-49
View File
@@ -1,49 +0,0 @@
# -*- coding: utf8 -*-
"""
clint.textui.prompt
~~~~~~~~~~~~~~~~~~~
Module for simple interactive prompts handling
"""
from __future__ import absolute_import
from re import match, I
def yn(prompt, default='y', batch=False):
# A sanity check against default value
# 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 + ' '
# If input is not a yes/no variant or empty
# keep asking
while True:
# If batch option is True then auto reply
# with default input
if not batch:
input = raw_input(prompt).strip()
else:
print prompt
input = ''
# If input is empty default choice is assumed
# so we return True
if input == '':
return True
# Given 'yes' as input if default choice is y
# then return True, False otherwise
if match('y(?:es)?', input, I):
return True if default == 'y' else False
# Given 'no' as input if default choice is n
# then return True, False otherwise
elif match('n(?:o)?', input, I):
return True if default == 'n' else False
+1 -2
View File
@@ -16,5 +16,4 @@ with indent(4, quote='>>>'):
puts(colored.red('NOT Files detected: ') + str(args.not_files))
puts(colored.red('Grouped Arguments: ') + str(dict(args.grouped)))
print
print
-13
View File
@@ -1,13 +0,0 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from clint import args
from clint.textui import puts, colored
all_args = args.grouped
for item in all_args:
if item is not '_':
puts(colored.red("key:%s"%item))
print(all_args[item].all)
-4
View File
@@ -1,4 +0,0 @@
echo "python get_each_args.py --name kracekumar --email me@kracekumar.com"
python get_each_args.py --name kracekumar --email me@kracekumar.com
echo "python get_each_args.py --languages python c html ruby --email me@kracekumar.com"
python get_each_args.py --langauges python c html ruby --email me@kracekumar.com
+1 -6
View File
@@ -17,11 +17,6 @@ if __name__ == '__main__':
for i in progress.dots(range(100)):
sleep(random() * 0.2)
for i in progress.mill(range(100)):
sleep(random() * 0.2)
# Override the expected_size, for iterables that don't support len()
D = dict(zip(range(100), range(100)))
for k, v in progress.bar(D.iteritems(), expected_size=len(D)):
sleep(random() * 0.2)
+3 -5
View File
@@ -4,10 +4,7 @@
import os
import sys
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
from distutils.core import setup
import clint
@@ -21,7 +18,7 @@ if sys.argv[-1] == "publish":
publish()
sys.exit()
required = ['args']
required = []
setup(
name='clint',
@@ -51,6 +48,7 @@ setup(
'License :: OSI Approved :: ISC License (ISCL)',
'Programming Language :: Python',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
'Programming Language :: Python :: 3',
+2 -28
View File
@@ -6,8 +6,8 @@
import unittest
class ClintTestCase(unittest.TestCase):
"""Clint test cases."""
class TablibTestCase(unittest.TestCase):
"""Tablib test cases."""
def setUp(self):
import clint
@@ -16,31 +16,5 @@ class ClintTestCase(unittest.TestCase):
def tearDown(self):
pass
class ColoredStringTestCase(unittest.TestCase):
def setUp(self):
from clint.textui.colored import ColoredString
def tearDown(self):
pass
def test_split(self):
from clint.textui.colored import ColoredString
new_str = ColoredString('red', "hello world")
output = new_str.split()
assert output[0].s == "hello"
def test_find(self):
from clint.textui.colored import ColoredString
new_str = ColoredString('blue', "hello world")
output = new_str.find('h')
self.assertEqual(output, 0)
def test_replace(self):
from clint.textui.colored import ColoredString
new_str = ColoredString('green', "hello world")
output = new_str.replace("world", "universe")
assert output.s == "hello universe"
if __name__ == '__main__':
unittest.main()
+1 -2
View File
@@ -1,10 +1,9 @@
[tox]
envlist = py26,py27,py3
envlist = py25,py26,py27,py3
[testenv]
commands=py.test --junitxml=junit-{envname}.xml
deps = pytest
args
[testenv:pypy]
basepython=/usr/bin/pypy-c