164 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
Kenneth Reitz cab8004284 v0.3.1 2013-12-02 22:15:42 -05:00
Kenneth Reitz c76cc35289 support always_color 2013-12-02 22:14:57 -05:00
Kenneth Reitz 8e86e4c1fa Merge pull request #92 from joshmoore/patch-1
Point README.rst to master/examples rather than develop
2013-08-06 08:36:50 -07:00
Josh Moore 858db011d8 Point README.rst to master/examples rather than develop 2013-08-06 10:24:14 +02:00
Kenneth Reitz c111ba5d92 Update README.rst 2013-07-15 09:04:42 -04:00
Kenneth Reitz 9e43717921 Merge pull request #88 from ewa/develop
Added optional "every" argument to progress.{bar,dots,mill}
2013-06-12 23:36:28 -07:00
Kenneth Reitz 8e351ac4d0 Merge pull request #82 from techniq/patch-1
Fix test name (TabLib->Clint)
2013-04-13 20:44:12 -07:00
Eric W. Anderson cb8bcee077 And, add self to AUTHORS 2013-03-01 00:21:22 -05:00
Eric W. Anderson 3df99a6a2b Added "every" option to dots and mill as well 2013-03-01 00:19:10 -05:00
Eric W. Anderson 5b37fb544d Add "every" option to progress.bar:
Only redraw bar every "every" steps.  Useful for very long sequences of small
operations.
2013-03-01 00:05:21 -05:00
Eric W. Anderson 099a506344 Expliclity refer to pwd for arugments package 2013-02-28 23:59:31 -05:00
Kenneth Reitz d7fdbe85a9 Merge pull request #84 from sghill/develop
Fix 404 to AUTHORS in README
2013-01-24 20:00:08 -08:00
Steve Hill 7b2130e582 Fix 404 to AUTHORS in README 2013-01-24 19:50:08 -08:00
Sean Lynch f884841082 Fix test name (TabLib->Clint) 2013-01-20 23:45:31 -05:00
Kenneth Reitz 112ea81b51 Merge pull request #73 from dmedvinsky/bug/add-textui-streams-to-all
Add textui streams to __all__
2012-11-15 18:42:58 -08:00
Kenneth Reitz 399fa2bb24 Merge pull request #74 from techtonik/patch-1
Fix image
2012-11-15 17:57:43 -08:00
anatoly techtonik ab2f37219a Fix image 2012-11-07 15:06:46 +03:00
Dmitry Medvinsky 464849e575 Add textui streams to __all__
So that I could write

    from clint import textui as ui
    ui.puts(ui.colored.red('fatal error'), stream=ui.STDERR)
2012-09-24 18:59:52 +04:00
Kenneth Reitz acdddbabea Merge pull request #42 from takluyver/colorama-init2
Initialise colorama for textui on Windows.
2012-09-24 07:23:17 -07:00
Kenneth Reitz 1a11a670e7 Merge pull request #57 from aerenchyma/fix-issue56
Fix - issue56
2012-09-24 07:19:32 -07:00
Kenneth Reitz 1dc521de1a Merge pull request #63 from dendright/develop
Only write progress bars to terminal by default
2012-09-24 07:18:52 -07:00
Kenneth Reitz 1e3888e530 Merge pull request #70 from gekitsuu/develop
changed import args to import arguments
2012-09-10 16:26:18 -07:00
Adam Glenn 2c8561a492 changed import args to import arguments 2012-09-10 12:52:51 -04:00
Kenneth Reitz 04f0cdd646 Merge pull request #69 from brandly/develop
Fix minor spelling mistake
2012-09-09 14:14:24 -07:00
Matthew Brandly 0bd5026d21 Fix minor spelling mistake 2012-09-09 14:54:52 -04:00
jczetta b69ceb18d2 redefined __getattr__ so all str methods work
All str methods work for ColoredStrings with expected functionality, excepting .join(). Retained some other method definitions in order to retain expected functionality. Added tests for ColoredString.
2012-08-25 12:43:29 -04:00
Jack Riches e1bdaa4d0d More robust checking for if output is a tty 2012-08-14 09:47:34 +01:00
Jack Riches 8103032de8 Only write progress bars to terminal by default
This removes unwanted progress bar output when piping to another command
or file. Progress bars may be explicitly shown in this case with
progess.bar(iterable, hide=False)
2012-08-08 15:01:06 +01:00
Kenneth Reitz ab401e7af2 Merge pull request #61 from barberj/args_integration
Args integration
2012-08-01 09:32:49 -07:00
barberj fc841b0a61 consistency is key 2012-08-01 09:15:58 -04:00
barberj b591c3edc2 forgot to include args dependency 2012-08-01 08:49:48 -04:00
barberj 70c0680b8c credit 2012-08-01 08:47:29 -04:00
barberj e7db8c7e37 Updated to use arguments module.
Removed py25 support and tox testing since try/except statements were >=2.5.
Try setup import from setuptools so python setup.py develop is available.
2012-08-01 08:42:34 -04:00
Kenneth Reitz 944af48ba5 Merge pull request #55 from donspaulding/develop
Added an expected_size parameter to progress.bar and progress.mill.
2012-06-14 10:30:43 -07:00
Don Spaulding a1808173d9 Added an expected_size parameter to progress.bar and progress.mill.
Some objects you might want to show progress on while iterating over
do not support calling len().  In these cases you can now pass
`expected_size` in to the progress.bar and progress.mill functions
to avoid the len() call on the iterable.
2012-06-14 12:23:05 -05:00
Kenneth Reitz c2aa315a58 Merge pull request #53 from johtso/develop
Make prompt module accessible
2012-06-14 10:07:15 -07:00
Johannes 3e03a9ceb9 Make prompt module accessible 2012-05-14 12:43:19 +02:00
Kenneth Reitz 02016e8b06 Merge pull request #38 from Lothiraldan/develop
Try a reimplementation of clint.textui.core
2012-05-09 16:28:42 -07:00
Kenneth Reitz a7e2d21273 Merge pull request #51 from kracekumar/develop
Develop
2012-05-09 11:19:39 -07:00
kracekumar 911a84406e added an example get_each_args.py 2012-05-09 01:06:03 +05:30
kracekumar afd410125d added an example get_each_args.py 2012-05-09 01:05:32 +05:30
Kenneth Reitz e2a169ab9c Merge pull request #44 from mjs2600/develop
Fixed a typo in README.rst
2012-04-22 17:55:01 -07:00
Kenneth Reitz cfad07a774 Merge pull request #49 from gbrindisi/prompt
Added basic yes/no prompt module
2012-04-06 10:05:22 -07:00
Gianluca Brindisi 48d9c16f0f Added basic yes/no prompt module 2012-04-06 15:01:14 +02:00
Michael Simpson 86b196811f Update README.rst 2012-02-23 14:26:05 -05:00
Thomas Kluyver d479ea3a3c Initialise colorama for textui on Windows.
Closes gh-39
2012-02-23 10:08:55 +00:00
Kenneth Reitz fc873deb3b Merge pull request #40 from verigak/develop
Allow multiple occurences of a flag in grouped
2012-02-14 14:04:00 -08:00
Giorgos Verigakis d4cb4e8c01 Allow multiple occurences of a flag in grouped 2012-02-14 23:57:45 +02:00
FELD Boris 7c48045b57 Update clint.textui.core's docstrings 2012-02-12 17:46:33 +01:00
FELD Boris ea9b2186d5 More simple implementation of indent context 2012-02-12 17:32:59 +01:00
FELD Boris 761dce7237 Try to reimplement clint.textui.core in a more simpler way 2012-02-12 17:27:18 +01:00
Boris Feld 72b04cf5af Add a dedent util function, useful when using indent otherwise than as a context. 2012-02-11 22:51:20 +01:00
Kenneth Reitz 0378771f94 Merge pull request #32 from jpiper/develop
Added ETA timer to progress.bar
2012-01-23 11:04:07 -08:00
Jason Piper 129fea5e4f added myself to AUTHORS 2012-01-23 14:38:39 +00:00
Jason Piper a9d1089bbd Updated averaging method
Calculates a simple moving average based on the number of iterations
done in (1) second intervals over the last (10) seconds
2012-01-23 14:27:57 +00:00
Jason Piper 270afcca03 Added progress bar ETA
Very simplistic, currently updates every iteration (not a performance
issue, but not the prettiest way to do it)
2012-01-23 13:50:45 +00:00
Kenneth Reitz c7f5296b13 Merge pull request #31 from collinwat/f/unicode-bytes
Explicitly chack for instances of bytes to distinguish between py2 and py3
2012-01-20 09:12:51 -08:00
Collin Watson e8f6f7737a Explicitly chack for instances of bytes to distinguish between py2 and py3. 2012-01-17 08:07:42 -08:00
Kenneth Reitz 43b152cf0e Merge branch 'develop' of github.com:kennethreitz/clint into develop 2012-01-16 09:22:05 -05:00
Kenneth Reitz 0d0d482156 Merge branch 'f/unicode' of https://github.com/collinwat/clint 2012-01-16 09:15:29 -05:00
Collin Watson 3a40b682f4 Support python 3 by checking if the decode attribute exists. 2012-01-14 17:03:10 -08:00
Collin Watson 1d1bb71203 Added unicode file and input examples 2012-01-14 12:17:46 -08:00
Collin Watson b917e68837 Removed unnecessary interpolation since it's a known string 2012-01-14 12:17:29 -08:00
Kenneth Reitz 66a6148088 Merge pull request #30 from alejandrogomez/develop
Add a mill progress indicator to `progress.py`
2012-01-14 10:20:52 -08:00
Alejandro Gómez a95e803268 Add a mill progress indicator to progress.py
I've created a progress indicator that outputs a "mill" and added it to
the `progress.py` file.

Very simple stuff but its more compact than the other progress bars and
it can be useful when using long labels.
2012-01-14 19:01:23 +01:00
Collin Watson 7e1c739755 Ignore unicode strings as they are already decoded 2012-01-14 01:11:47 -08:00
Collin Watson ec46d65bd2 Added support for colored unicode 2012-01-14 00:59:44 -08:00
Kenneth Reitz 73a9cd836b Merge pull request #24 from kracekumar/develop
Develop - fixed issue 9
2012-01-11 05:42:50 -08:00
kracekumar c9bf3bac3a works perfectly fine with ipython, standard python interpreter and unfortuantely clint colors wont work in dreampie :( 2012-01-07 21:54:17 +05:30
kracekumar 5f2df1218a fixed spaces 2012-01-07 21:47:55 +05:30
kracekumar 526cf84ebb added a method to find current python interpreter is ipython, if so color shoudl be disabled 2012-01-07 21:45:31 +05:30
Kenneth Reitz 3709f090b4 Merge pull request #22 from teh/develop
Distribute README.rst and HISTORY.rst when building sdist.
2012-01-06 15:45:01 -08:00
Thomas Hunger d6214ababb Distribute README.rst and HISTORY.rst when building sdist. 2012-01-06 23:43:14 +00:00
Kenneth Reitz ee089c2d39 Merge branch 'develop' 2012-01-05 22:14:51 -05:00
Kenneth Reitz dbb063840a v0.3.0 2012-01-05 22:14:33 -05:00
Thomas Kluyver 9a4705f090 Update trove classifiers. 2012-01-06 00:16:14 +00:00
Thomas Kluyver b16b2ce723 All examples work on Python 3. 2012-01-06 00:11:51 +00:00
Thomas Kluyver 1ea4c5afdc Installable on Python 3. 2012-01-05 23:24:25 +00:00
Kenneth Reitz 39bb08253f Merge pull request #20 from robbles/develop
fix mismatch with argument names for progress.bar
2011-12-24 23:01:49 -08:00
Kenneth Reitz 8e6973253f Update clint/textui/progress.py 2011-10-28 13:04:31 -03:00
robbles 84419f6bfb fix mismatch with argument names for progress.bar 2011-09-28 11:13:26 -07:00
Kenneth Reitz 53ec4c2e09 Merge branch 'develop' 2011-09-24 14:38:05 -04:00
Kenneth Reitz 7b6138eda6 v0.2.5 2011-09-24 14:36:30 -04:00
Kenneth Reitz d19650b93c add userpath and environ var expansion to expand_path 2011-09-24 14:33:13 -04:00
Kenneth Reitz 98edec43e9 move expand_path to utils 2011-09-24 14:32:47 -04:00
Kenneth Reitz ef48a47b8d Merge branch 'master' into develop 2011-09-24 14:30:05 -04:00
Kenneth Reitz 3be47add4a rename arguments for bar 2011-08-12 09:48:24 -04:00
Kenneth Reitz bf99084ece Merge pull request #18 from maraujop/develop
Adding kwargs to progress bar, so that bar chars can be customized
2011-08-12 06:46:42 -07:00
Miguel Araujo Perez 705cda4443 Adding kwargs to progress bar, so that bar_empty_char and bar_filled_char can be easily customized. 2011-08-11 16:19:48 +02:00
Kenneth Reitz 79cf7a023b Merge branch 'develop' 2011-06-25 12:28:03 -04:00
Kenneth Reitz 7900853dbc v0.2.4 2011-06-25 12:27:44 -04:00
Kenneth Reitz 96827698df Update colorama to v0.2.3 2011-06-21 18:44:46 -04:00
Kenneth Reitz 23689f8b0a updated history 2011-06-15 12:40:14 -04:00
Kenneth Reitz 1a9e15dbba added Greg Haskins to AUTHORS 2011-06-15 12:39:34 -04:00
Greg Haskins a07602fdeb call colorama.init(..) at import time to ensure stdout/stderr get wrapped 2011-06-15 12:24:52 -04:00
Kenneth Reitz 0855525fca added eng.join example 2011-04-18 12:49:37 -04:00
Kenneth Reitz 872c78a5b9 no need to init colorama 2011-04-18 12:39:20 -04:00
Kenneth Reitz 5d7485c144 cleaner eng.join 2011-04-18 12:38:56 -04:00
Kenneth Reitz 25b8d6a10e oops 2011-04-18 12:25:06 -04:00
Kenneth Reitz 003411ebcd eng.plural! 2011-04-18 12:18:54 -04:00
star:Kenneth Reitz f651e71093 Merge branch 'develop' 2011-04-06 13:06:51 -04:00
star:Kenneth Reitz e500773da3 version bump (v0.2.3) 2011-04-06 13:06:14 -04:00
star:Kenneth Reitz 4b9e35c631 configurable progress interator streams 2011-04-06 13:02:40 -04:00
star:Kenneth Reitz e85fffdbb6 puts/puts_err fixes, defaults for string 2011-04-06 13:00:13 -04:00
star:Kenneth Reitz b58f8dccdc no colorama auto-init upon import 2011-04-06 10:08:25 -04:00
star:Kenneth Reitz 3d63ed01f9 whitespace cleanup 2011-04-03 08:11:23 -04:00
star:Kenneth Reitz 81165754a4 allow clint.textui.puts() to accept arbitrary file-like objects (like StringIO for <pre> generation) 2011-04-03 08:11:17 -04:00
star:Kenneth Reitz 6f106e2f12 toxic 2011-04-01 10:05:55 -04:00
star:Kenneth Reitz 8adda14a27 Merge branch 'feature/multiversion-testing' of https://github.com/offbyone/clint into develop 2011-04-01 10:04:28 -04:00
Chris Rose cc072a18f3 Add tox support 2011-04-01 07:58:48 -06:00
star:Kenneth Reitz c226b6b736 progress bar examples 2011-03-31 14:52:44 -04:00
Will Thames 3406ab5329 Added Will Thames to list of authors 2011-03-31 12:24:42 +01:00
Will Thames cf0c0bda70 Moved from __future__ line closer to the top of the file to prevent
File "piped.py", line 7
    from __future__ import with_statement
SyntaxError: from __future__ imports must occur at the beginning of the file
2011-03-31 12:21:57 +01:00
star:Kenneth Reitz a4c2be8865 pre me right 2011-03-31 06:16:09 -04:00
star:Kenneth Reitz fa2bbf9a0d link to examples directory 2011-03-31 01:07:54 -04:00
star:Kenneth Reitz 9736b4cd71 oh yeah, columns. 2011-03-31 01:05:07 -04:00
star:Kenneth Reitz 2e68207d0a updated readme for newcomers 2011-03-31 00:48:02 -04:00
star:Kenneth Reitz 164d68ce37 loggin' 2011-03-30 23:08:33 -04:00
star:Kenneth Reitz aa5008b2e0 namespace fix 2011-03-30 23:03:39 -04:00
star:Kenneth Reitz 8b7161b15b Configurable progress bars :)
Argument changes.
2011-03-30 23:03:34 -04:00
star:Kenneth Reitz 763ca94e7b newline support for textui.puts 2011-03-30 23:03:13 -04:00
star:Kenneth Reitz 2d200e3709 progress.bar(width=), not size. 2011-03-30 22:53:36 -04:00
star:Kenneth Reitz d0f2375a7b No more '>' in progress bar 2011-03-30 22:51:49 -04:00
star:Kenneth Reitz 2369bc387d progressbar => bar 2011-03-30 22:47:33 -04:00
star:Kenneth Reitz f12e47fa7c add dots progress iterator 2011-03-30 22:47:18 -04:00
star:Kenneth Reitz 5d733d123d put progress uis in separate namespace (for now) 2011-03-30 22:46:57 -04:00
star:Kenneth Reitz 9e1ea1ef91 Automatically disable color 2011-03-30 22:41:40 -04:00
star:Kenneth Reitz 6d151a0794 mention examples. 2011-03-24 07:10:40 -04:00
star:Kenneth Reitz 13afb11dea Elaborate on what Clint IS. 2011-03-24 07:08:00 -04:00
35 changed files with 924 additions and 254 deletions
+10 -1
View File
@@ -1,2 +1,11 @@
.idea
MANIFEST
.project
.settings
.pydevproject
MANIFEST
*.pyc
.tox
build/
clint.egg-info/
dist/
+18 -1
View File
@@ -6,10 +6,27 @@ Development Lead
- Kenneth Reitz <me@kennethreitz.com>
Maintainers
```````````
- Jason Piper <j.piper@me.com>
Patches and Suggestions
```````````````````````
- Jeff Forcier
- Morgan Goose
- Travis Swicegood
- Travis Swicegood
- Will Thames
- Greg Haskins
- Miguel Araujo <maraujop>
- 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
- Joshua Richardson
+1 -1
View File
@@ -11,4 +11,4 @@ All functionality should be available in pure Python. Optional C (via Cython)
implementations may be written for performance reasons, but should never
replace the Python implementation.
Lastly, don't take yourself too seriously :)
Lastly, don't take yourself too seriously :)
+61
View File
@@ -1,6 +1,67 @@
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
+++++
* Python 3 support!
0.2.4
+++++
* New eng module
* Win32 Bugfix
0.2.3
+++++
* Only init colors if they are used (iPython compatability)
* New progress module
* Various bugfixes
0.2.2
+++++
* Auto Color Disabling
* Progress Namespace Change
* New Progress Bars
* textui.puts newline fix
0.2.1 (2011-03-24)
++++++++++++++++++
+41 -9
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://github.com/kennethreitz/clint/raw/master/misc/clint.jpeg
.. image:: https://raw.github.com/kennethreitz/clint/master/misc/clint.jpeg
**C** ommand
**L** ine
@@ -12,16 +12,43 @@ commandline applications.
**T** ools
.
Features:
---------
Clint is awesome. Crazy awesome. It supports colors, but detects if the session is a TTY, so doesn't render the colors if you're piping stuff around. Automagically.
Awesome nest-able indentation context manager. Example: (``with indent(4): puts('indented text')``). It supports custom email-style quotes. Of course, it supports color too, if and when needed.
It has an awesome Column printer with optional auto-expanding columns. It detects how wide your current console is and adjusts accordingly. It wraps your words properly to fit the column size. With or without colors mixed in. All with a single function call.
The world's easiest to use implicit argument system w/ chaining methods for filtering. Seriously.
Run the various executables in examples_ to get a good feel for what Clint offers.
.. _examples: https://github.com/kennethreitz/clint/tree/master/examples
You'll never want to not use it.
Current Features:
-----------------
- Little Documentation (bear with me for now)
- CLI Colors and Indents
- Extremely Simple + Powerful Column Printer
- Iterator-based Progress Bar
- Implicit Argument Handling
- Simple Support for Unix Pipes
- Simple Support for Incoming Unix Pipes
- Application Directory management
Future Features:
----------------
- Documentation!
- Simple choice system ``Are you sure? [Yn]``
- Default query system ``Installation Path [/usr/local/bin/]``
- Suggestions welcome.
Example
-------
@@ -43,7 +70,7 @@ I want to quote my console text (like email). ::
>>> puts('pretty cool, eh?')
not indented text
> indented text
> quoted text
> pretty cool, eh?
I want to color my console text. ::
@@ -64,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
@@ -80,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
------------
@@ -120,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_.
@@ -128,9 +161,8 @@ Roadmap
-------
- Unittests
- Sphinx Documentation
- Python 2.5, 3.1, 3.2 Support
.. _`the repository`: http://github.com/kennethreitz/clint
.. _AUTHORS: http://github.com/kennethreitz/clint/blob/master/AUTHORS
.. _AUTHORS: http://github.com/kennethreitz/clint/blob/develop/AUTHORS
+11 -7
View File
@@ -11,7 +11,14 @@ This module sets up the main interface for all of clint.
from __future__ import absolute_import
from . import arguments
try:
from collections import OrderedDict
except ImportError:
from .packages.ordereddict import OrderedDict
import collections
collections.OrderedDict = OrderedDict
from .arguments import *
from . import textui
from . import utils
from .pipes import piped_in
@@ -19,12 +26,9 @@ from .pipes import piped_in
__title__ = 'clint'
__version__ = '0.2.1'
__build__ = 0x000201
__version__ = '0.3.7'
__build__ = 0x000307
__author__ = 'Kenneth Reitz'
__license__ = 'ISC'
__copyright__ = 'Copyright 2011 Kenneth Reitz'
__copyright__ = 'Copyright 2012 Kenneth Reitz'
__docformat__ = 'restructuredtext'
args = arguments.Args()
+23 -39
View File
@@ -13,33 +13,17 @@ from __future__ import absolute_import
import os
from sys import argv
from glob import glob
from .packages.ordereddict import OrderedDict
from .utils import is_collection
try:
from collections import OrderedDict
except ImportError:
from .packages.ordereddict import OrderedDict
from .utils import expand_path, is_collection
__all__ = ('Args', )
def _expand_path(path):
"""Expands directories and globs in given path."""
paths = []
if os.path.isdir(path):
for (dir, dirs, files) in os.walk(path):
for file in files:
paths.append(os.path.join(dir, file))
else:
paths.extend(glob(path))
return paths
class Args(object):
"""CLI Argument management."""
@@ -110,20 +94,20 @@ class Args(object):
def any_contain(self, x):
"""Tests if given string is contained in any stored argument."""
return bool(self.first_with(x))
def contains(self, x):
"""Tests if given object is in arguments list.
"""Tests if given object is in arguments list.
Accepts strings and lists of strings."""
return self.__contains__(x)
def first(self, x):
"""Returns first found index of given value (or list of values)"""
def _find( x):
try:
return self.all.index(str(x))
@@ -212,7 +196,7 @@ class Args(object):
return False
else:
return (x in self.all[index])
except IndexError:
return False
@@ -221,7 +205,7 @@ class Args(object):
"""Returns true if argument exists at given index.
Accepts: integer.
"""
try:
self.all[x]
return True
@@ -231,15 +215,15 @@ class Args(object):
def value_after(self, x):
"""Returns value of argument after given found argument (or list thereof)."""
try:
try:
i = self.all.index(x)
except ValueError:
return None
return self.all[i + 1]
except IndexError:
return None
@@ -257,7 +241,7 @@ class Args(object):
for arg in self.all:
if arg.startswith('-'):
_current_group = arg
collection[arg] = Args(no_argv=True)
collection.setdefault(arg, Args(no_argv=True))
else:
if _current_group:
collection[_current_group]._args.append(arg)
@@ -266,21 +250,21 @@ class Args(object):
return collection
@property
def last(self):
"""Returns last argument."""
try:
return self.all[-1]
except IndexError:
return None
@property
def all(self):
"""Returns all arguments."""
return self._args
@@ -288,7 +272,7 @@ class Args(object):
"""Returns all arguments containing given string (or list thereof)"""
_args = []
for arg in self.all:
if is_collection(x):
for _x in x:
@@ -327,7 +311,7 @@ class Args(object):
return self.start_with('-')
@property
@property
def not_flags(self):
"""Returns Arg object excluding flagged arguments."""
@@ -341,7 +325,7 @@ class Args(object):
_paths = []
for arg in self.all:
for path in _expand_path(arg):
for path in expand_path(arg):
if os.path.exists(path):
if absolute:
_paths.append(os.path.abspath(path))
@@ -358,7 +342,7 @@ class Args(object):
_args = []
for arg in self.all:
if not len(_expand_path(arg)):
if not len(expand_path(arg)):
if not os.path.exists(arg):
_args.append(arg)
+55
View File
@@ -0,0 +1,55 @@
# -*- coding: utf-8 -*-
"""
clint.eng
~~~~~~~~~
This module provides English language string helpers.
"""
from __future__ import print_function
MORON_MODE = False
COMMA = ','
CONJUNCTION = 'and'
SPACE = ' '
try:
unicode
except NameError:
unicode = str
def join(l, conj=CONJUNCTION, im_a_moron=MORON_MODE, separator=COMMA):
"""Joins lists of words. Oxford comma and all."""
collector = []
left = len(l)
separator = separator + SPACE
conj = conj + SPACE
for _l in l[:]:
left += -1
collector.append(_l)
if left == 1:
if len(l) == 2 or im_a_moron:
collector.append(SPACE)
else:
collector.append(separator)
collector.append(conj)
elif left is not 0:
collector.append(separator)
return unicode(str().join(collector))
if __name__ == '__main__':
print(join(['blue', 'red', 'yellow'], conj='or', im_a_moron=True))
print(join(['blue', 'red', 'yellow'], conj='or'))
print(join(['blue', 'red'], conj='or'))
print(join(['blue', 'red'], conj='and'))
print(join(['blue'], conj='and'))
print(join(['blue', 'red', 'yellow', 'green', 'ello'], conj='and'))
+2 -2
View File
@@ -1,6 +1,6 @@
from .initialise import init
from .initialise import init, deinit, reinit
from .ansi import Fore, Back, Style
from .ansitowin32 import AnsiToWin32
VERSION = '0.1.18'
VERSION = '0.2.3'
+8 -2
View File
@@ -118,12 +118,12 @@ class AnsiToWin32(object):
self.wrapped.flush()
if self.autoreset:
self.reset_all()
def reset_all(self):
if self.convert:
self.call_win32('m', (0,))
else:
elif is_a_tty(self.wrapped):
self.wrapped.write(Style.RESET_ALL)
@@ -173,4 +173,10 @@ class AnsiToWin32(object):
args = func_args[1:]
kwargs = dict(on_stderr=self.on_stderr)
func(*args, **kwargs)
elif command in ('H', 'f'): # set cursor position
func = winterm.set_cursor_position
func(params, on_stderr=self.on_stderr)
elif command in ('J'):
func = winterm.erase_data
func(params, on_stderr=self.on_stderr)
+20 -3
View File
@@ -7,6 +7,9 @@ from .ansitowin32 import AnsiToWin32
orig_stdout = sys.stdout
orig_stderr = sys.stderr
wrapped_stdout = sys.stdout
wrapped_stderr = sys.stderr
atexit_done = False
@@ -16,11 +19,14 @@ def reset_all():
def init(autoreset=False, convert=None, strip=None, wrap=True):
if wrap==False and (autoreset==True or convert==True or strip==True):
if not wrap and any([autoreset, convert, strip]):
raise ValueError('wrap=False conflicts with any other arg=True')
sys.stdout = wrap_stream(orig_stdout, convert, strip, autoreset, wrap)
sys.stderr = wrap_stream(orig_stderr, convert, strip, autoreset, wrap)
global wrapped_stdout, wrapped_stderr
sys.stdout = wrapped_stdout = \
wrap_stream(orig_stdout, convert, strip, autoreset, wrap)
sys.stderr = wrapped_stderr = \
wrap_stream(orig_stderr, convert, strip, autoreset, wrap)
global atexit_done
if not atexit_done:
@@ -28,6 +34,16 @@ def init(autoreset=False, convert=None, strip=None, wrap=True):
atexit_done = True
def deinit():
sys.stdout = orig_stdout
sys.stderr = orig_stderr
def reinit():
sys.stdout = wrapped_stdout
sys.stderr = wrapped_stdout
def wrap_stream(stream, convert, strip, autoreset, wrap):
if wrap:
wrapper = AnsiToWin32(stream,
@@ -36,3 +52,4 @@ def wrap_stream(stream, convert, strip, autoreset, wrap):
stream = wrapper.stream
return stream
+44 -16
View File
@@ -48,8 +48,16 @@ else:
("srWindow", SMALL_RECT),
("dwMaximumWindowSize", COORD),
]
def __str__(self):
return '(%d,%d,%d,%d,%d,%d,%d,%d,%d,%d,%d)' % (
self.dwSize.Y, self.dwSize.X
, self.dwCursorPosition.Y, self.dwCursorPosition.X
, self.wAttributes
, self.srWindow.Top, self.srWindow.Left, self.srWindow.Bottom, self.srWindow.Right
, self.dwMaximumWindowSize.Y, self.dwMaximumWindowSize.X
)
def GetConsoleScreenBufferInfo(stream_id):
def GetConsoleScreenBufferInfo(stream_id=STDOUT):
handle = handles[stream_id]
csbi = CONSOLE_SCREEN_BUFFER_INFO()
success = windll.kernel32.GetConsoleScreenBufferInfo(
@@ -62,34 +70,54 @@ else:
def SetConsoleTextAttribute(stream_id, attrs):
handle = handles[stream_id]
success = windll.kernel32.SetConsoleTextAttribute(handle, attrs)
assert success
return windll.kernel32.SetConsoleTextAttribute(handle, attrs)
def SetConsoleCursorPosition(stream_id, position):
handle = handles[stream_id]
position = COORD(*position)
success = windll.kernel32.SetConsoleCursorPosition(handle, position)
assert success
# If the position is out of range, do nothing.
if position.Y <= 0 or position.X <= 0:
return
# Adjust for Windows' SetConsoleCursorPosition:
# 1. being 0-based, while ANSI is 1-based.
# 2. expecting (x,y), while ANSI uses (y,x).
adjusted_position = COORD(position.Y - 1, position.X - 1)
# Adjust for viewport's scroll position
sr = GetConsoleScreenBufferInfo(STDOUT).srWindow
adjusted_position.Y += sr.Top
adjusted_position.X += sr.Left
# Resume normal processing
handle = handles[stream_id]
success = windll.kernel32.SetConsoleCursorPosition(handle, adjusted_position)
return success
def FillConsoleOutputCharacter(stream_id, char, length, start):
handle = handles[stream_id]
char = TCHAR(char)
length = DWORD(length)
start = COORD(*start)
num_written = DWORD(0)
# AttributeError: function 'FillConsoleOutputCharacter' not found
# could it just be that my types are wrong?
success = windll.kernel32.FillConsoleOutputCharacter(
# Note that this is hard-coded for ANSI (vs wide) bytes.
success = windll.kernel32.FillConsoleOutputCharacterA(
handle, char, length, start, byref(num_written))
assert success
return num_written.value
def FillConsoleOutputAttribute(stream_id, attr, length, start):
''' FillConsoleOutputAttribute( hConsole, csbi.wAttributes, dwConSize, coordScreen, &cCharsWritten )'''
handle = handles[stream_id]
attribute = WORD(attr)
length = DWORD(length)
num_written = DWORD(0)
# Note that this is hard-coded for ANSI (vs wide) bytes.
success = windll.kernel32.FillConsoleOutputAttribute(
handle, attribute, length, start, byref(num_written))
return success
if __name__=='__main__':
x = GetConsoleScreenBufferInfo(STDOUT)
print(x.dwSize)
print(x.dwCursorPosition)
print(x.wAttributes)
print(x.srWindow)
print(x.dwMaximumWindowSize)
print(x)
print('dwSize(height,width) = (%d,%d)' % (x.dwSize.Y, x.dwSize.X))
print('dwCursorPosition(y,x) = (%d,%d)' % (x.dwCursorPosition.Y, x.dwCursorPosition.X))
print('wAttributes(color) = %d = 0x%02x' % (x.wAttributes, x.wAttributes))
print('srWindow(Top,Left)-(Bottom,Right) = (%d,%d)-(%d,%d)' % (x.srWindow.Top, x.srWindow.Left, x.srWindow.Bottom, x.srWindow.Right))
print('dwMaximumWindowSize(maxHeight,maxWidth) = (%d,%d)' % (x.dwMaximumWindowSize.Y, x.dwMaximumWindowSize.X))
+35 -2
View File
@@ -22,8 +22,7 @@ class WinStyle(object):
class WinTerm(object):
def __init__(self):
self._default = \
win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes
self._default = win32.GetConsoleScreenBufferInfo(win32.STDOUT).wAttributes
self.set_attrs(self._default)
self._default_fore = self._fore
self._default_back = self._back
@@ -67,3 +66,37 @@ class WinTerm(object):
handle = win32.STDERR
win32.SetConsoleTextAttribute(handle, attrs)
def set_cursor_position(self, position=None, on_stderr=False):
if position is None:
#I'm not currently tracking the position, so there is no default.
#position = self.get_position()
return
handle = win32.STDOUT
if on_stderr:
handle = win32.STDERR
win32.SetConsoleCursorPosition(handle, position)
def erase_data(self, mode=0, on_stderr=False):
# 0 (or None) should clear from the cursor to the end of the screen.
# 1 should clear from the cursor to the beginning of the screen.
# 2 should clear the entire screen. (And maybe move cursor to (1,1)?)
#
# At the moment, I only support mode 2. From looking at the API, it
# should be possible to calculate a different number of bytes to clear,
# and to do so relative to the cursor position.
if mode[0] not in (2,):
return
handle = win32.STDOUT
if on_stderr:
handle = win32.STDERR
# here's where we'll home the cursor
coord_screen = win32.COORD(0,0)
csbi = win32.GetConsoleScreenBufferInfo(handle)
# get the number of character cells in the current buffer
dw_con_size = csbi.dwSize.X * csbi.dwSize.Y
# fill the entire screen with blanks
win32.FillConsoleOutputCharacter(handle, ord(' '), dw_con_size, coord_screen)
# now set the buffer's attributes accordingly
win32.FillConsoleOutputAttribute(handle, self.get_attrs(), dw_con_size, coord_screen );
# put the cursor at (0, 0)
win32.SetConsoleCursorPosition(handle, (coord_screen.X, coord_screen.Y))
+9 -9
View File
@@ -39,7 +39,7 @@ class AppDir(object):
def __repr__(self):
return '<app-dir: %s>' % (self.path)
def __getattribute__(self, name):
@@ -53,11 +53,11 @@ class AppDir(object):
"""Raises if operations are carried out on an unconfigured AppDir."""
if not self.path:
raise NotConfigured()
def _create(self):
"""Creates current AppDir at AppDir.path."""
self._raise_if_none()
if not self._exists:
mkdir_p(self.path)
@@ -66,7 +66,7 @@ class AppDir(object):
def open(self, filename, mode='r'):
"""Returns file object from given filename."""
self._raise_if_none()
fn = path_join(self.path, filename)
@@ -115,17 +115,17 @@ class AppDir(object):
remove(fn)
else:
removedirs(fn)
except OSError, why:
except OSError as why:
if why.errno == errno.ENOENT:
pass
else:
raise why
def read(self, filename, binary=False):
"""Returns contents of given file with AppDir.
If file doesn't exist, returns None."""
self._raise_if_none()
fn = path_join(self.path, filename)
@@ -161,11 +161,11 @@ log = AppDir()
def init(vendor, name):
global user, site, cache, log
ad = AppDirs(name, vendor)
user.path = ad.user_data_dir
site.path = ad.site_data_dir
cache.path = ad.user_cache_dir
log.path = ad.user_log_dir
+8 -2
View File
@@ -7,7 +7,13 @@ 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 core import *
from . import progress
from . import prompt
from .core import *
+76 -35
View File
@@ -11,9 +11,12 @@ This module provides a simple and elegant wrapper for colorama.
from __future__ import absolute_import
import os
import re
import sys
PY3 = sys.version_info[0] >= 3
from ..packages import colorama
__all__ = (
@@ -23,51 +26,89 @@ __all__ = (
)
COLORS = __all__[:-2]
DISABLE_COLOR = False
if sys.stdout.isatty():
colorama.init(autoreset=True)
if 'get_ipython' in dir():
"""
when ipython is fired lot of variables like _oh, etc are used.
There are so many ways to find current python interpreter is ipython.
get_ipython is easiest is most appealing for readers to understand.
"""
DISABLE_COLOR = True
else:
DISABLE_COLOR = False
class ColoredString(object):
"""Enhanced string for __len__ operations on Colored output."""
def __init__(self, color, s):
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)
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):
if sys.stdout.isatty() and not DISABLE_COLOR:
return '%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
elif sys.stdout.isatty() and not DISABLE_COLOR:
return c
else:
return self.s
def __len__(self):
return len(self.s)
def __repr__(self):
return "<%s-string: '%s'>" % (self.color, self.s)
def __str__(self):
return self.__unicode__().encode('utf8')
def __unicode__(self):
return self.color_str
value = self.color_str
if isinstance(value, bytes):
return value.decode('utf8')
return value
if PY3:
__str__ = __unicode__
else:
def __str__(self):
value = self.color_str
if isinstance(value, bytes):
return value
return value.encode('utf8')
def __iter__(self):
return iter(self.color_str)
def __add__(self, other):
return str(self.color_str) + str(other)
def __radd__(self, other):
return str(other) + str(self.color_str)
def __mul__(self, other):
return (self.color_str * other)
def split(self, x=' '):
return map(self._new, self.s.split(x))
def _new(self, s):
return ColoredString(self.color, s)
@@ -83,29 +124,29 @@ def clean(s):
return txt
def black(string):
return ColoredString('BLACK', string)
def black(string, always=False, bold=False):
return ColoredString('BLACK', string, always_color=always, bold=bold)
def red(string):
return ColoredString('RED', string)
def red(string, always=False, bold=False):
return ColoredString('RED', string, always_color=always, bold=bold)
def green(string):
return ColoredString('GREEN', string)
def green(string, always=False, bold=False):
return ColoredString('GREEN', string, always_color=always, bold=bold)
def yellow(string):
return ColoredString('YELLOW', string)
def yellow(string, always=False, bold=False):
return ColoredString('YELLOW', string, always_color=always, bold=bold)
def blue(string):
return ColoredString('BLUE', string)
def blue(string, always=False, bold=False):
return ColoredString('BLUE', string, always_color=always, bold=bold)
def magenta(string):
return ColoredString('MAGENTA', string)
def magenta(string, always=False, bold=False):
return ColoredString('MAGENTA', string, always_color=always, bold=bold)
def cyan(string):
return ColoredString('CYAN', string)
def cyan(string, always=False, bold=False):
return ColoredString('CYAN', string, always_color=always, bold=bold)
def white(string):
return ColoredString('WHITE', string)
def white(string, always=False, bold=False):
return ColoredString('WHITE', string, always_color=always, bold=bold)
def disable():
"""Disables colors."""
+51 -57
View File
@@ -13,13 +13,15 @@ from __future__ import absolute_import
import sys
from .progress import progressbar
from contextlib import contextmanager
from .formatters import max_width, min_width
from .cols import columns
from ..utils import tsplit
__all__ = ('puts', 'puts_err', 'indent', 'progressbar', 'columns', 'max_width', 'min_width')
__all__ = ('puts', 'puts_err', 'indent', 'dedent', 'columns', 'max_width',
'min_width', 'STDOUT', 'STDERR')
STDOUT = sys.stdout.write
@@ -27,68 +29,60 @@ STDERR = sys.stderr.write
NEWLINES = ('\n', '\r', '\r\n')
INDENT_STRINGS = []
# Private
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 ''
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)))
))
stream(_str)
else:
indent_string = ''.join((
('\x08' * (-1 * (indent - len(quote)))),
str(quote))
)
if len(indent_string):
INDENT_STRINGS.append(indent_string)
def puts(s, newline=True):
"""Prints given string to stdout via Writer interface."""
Writer()(s, stream=STDOUT)
# 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)
def puts_err(s, newline=True):
"""Prints given string to stderr via Writer interface."""
Writer()(s, stream=STDERR)
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)
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 context manager."""
return Writer(indent=indent, quote=quote)
"""Indentation manager, return an indentation context manager."""
_indent(indent, quote)
return _indent_context()
+139 -10
View File
@@ -11,22 +11,151 @@ 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
def progressbar(it, prefix='', size=32, hide=False):
BAR_TEMPLATE = '%s[%s%s] %i/%i - %s\r'
MILL_TEMPLATE = '%s %s %i/%i\r'
DOTS_CHAR = '.'
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
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 % (
self.label, self.filled_char*x,
self.empty_char*(self.width-x), progress,
self.expected_size, self.etadisp))
STREAM.flush()
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 count:
def _show(_i):
x = int(size*_i/count)
if not hide:
sys.stdout.write("%s[%s>%s] %i/%i\r" % (prefix, "="*x, "-"*(size-x), _i, count))
sys.stdout.flush()
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"""
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 >= count:
return ' '
else:
return MILL_CHARS[(_i / every) % 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
if count:
_show(0)
for i, item in enumerate(it):
yield item
_show(i+1)
if not hide:
sys.stdout.write("\n")
sys.stdout.flush()
STREAM.write('\n')
STREAM.flush()
+54
View File
@@ -0,0 +1,54 @@
# -*- coding: utf8 -*-
"""
clint.textui.prompt
~~~~~~~~~~~~~~~~~~~
Module for simple interactive prompts handling
"""
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 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
+34 -32
View File
@@ -11,9 +11,33 @@ Various Python helpers used within clint.
from __future__ import absolute_import
from __future__ import with_statement
import sys
import errno
import os.path
from os import makedirs
from glob import glob
try:
basestring
except NameError:
basestring = str
def expand_path(path):
"""Expands directories and globs in given path."""
paths = []
path = os.path.expanduser(path)
path = os.path.expandvars(path)
if os.path.isdir(path):
for (dir, dirs, files) in os.walk(path):
for file in files:
paths.append(os.path.join(dir, file))
else:
paths.extend(glob(path))
return paths
def is_collection(obj):
@@ -29,7 +53,7 @@ def mkdir_p(path):
"""Emulates `mkdir -p` behavior."""
try:
makedirs(path)
except OSError, exc: # Python >2.5
except OSError as exc: # Python >2.5
if exc.errno == errno.EEXIST:
pass
else:
@@ -37,37 +61,15 @@ def mkdir_p(path):
def tsplit(string, delimiters):
"""Behaves str.split but supports tuples of delimiters."""
delimiters = tuple(delimiters)
stack = [string,]
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
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)
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
+5 -2
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))
@@ -16,4 +18,5 @@ 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
+3 -1
View File
@@ -1,6 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys
import os
@@ -13,4 +15,4 @@ text = 'THIS TEXT IS COLORED %s!'
if __name__ == '__main__':
for color in colored.COLORS:
print getattr(colored, color)(text % color.upper())
print(getattr(colored, color)(text % color.upper()))
+31
View File
@@ -0,0 +1,31 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import sys
import os
sys.path.insert(0, os.path.abspath('..'))
from clint.eng import join
from clint.textui import colored, indent, puts
colors = [
colored.blue('blue'),
colored.red('red'),
colored.yellow('yellow'),
colored.green('green'),
colored.magenta('magenta')
]
colors = [str(cs) for cs in colors]
puts('Smart:')
with indent(4):
for i in range(len(colors)):
puts(join(colors[:i+1]))
puts('\n')
puts('Stupid:')
with indent(4):
for i in range(len(colors)):
puts(join(colors[:i+1], im_a_moron=True, conj='\'n'))
+13
View File
@@ -0,0 +1,13 @@
#! /usr/bin/env python
# -*- coding: utf-8 -*-
from clint.arguments 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
@@ -0,0 +1,4 @@
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
+3 -3
View File
@@ -1,11 +1,11 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import with_statement
import sys
import os
from __future__ import with_statement
sys.path.insert(0, os.path.abspath('..'))
from clint import piped_in
@@ -23,4 +23,4 @@ if __name__ == '__main__':
with indent(5, quote=colored.red(' |')):
puts(in_data)
else:
puts(colored.red('Warning: ') + 'No data was piped in.')
puts(colored.red('Warning: ') + 'No data was piped in.')
+19 -4
View File
@@ -8,12 +8,27 @@ sys.path.insert(0, os.path.abspath('..'))
from time import sleep
from random import random
from clint.textui import progressbar
from clint.textui import progress
if __name__ == '__main__':
for i in progressbar(range(100)):
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)
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)
+7 -5
View File
@@ -1,6 +1,8 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
from __future__ import print_function
import sys
import os
@@ -13,16 +15,16 @@ resources.init('kennethreitz', 'clint')
lorem = 'Lorem ipsum dolor sit amet, consectetur adipisicing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.'
print '%s created.' % resources.user.path
print('%s created.' % resources.user.path)
resources.user.write('lorem.txt', lorem)
print 'lorem.txt created'
print('lorem.txt created')
assert resources.user.read('lorem.txt') == lorem
print 'lorem.txt has correct contents'
print('lorem.txt has correct contents')
resources.user.delete('lorem.txt')
print 'lorem.txt deleted'
print('lorem.txt deleted')
assert resources.user.read('lorem.txt') == None
print 'lorem.txt deletion confirmed'
print('lorem.txt deletion confirmed')
+3 -2
View File
@@ -19,5 +19,6 @@ if __name__ == '__main__':
col = 60
puts(columns([(colored.red('Column 1')), col], [(colored.green('Column Two')), None], [(colored.magenta('Column III')), col]))
puts(columns(['hi there my name is kenneth and this is a columns', col], [lorem, None], ['kenneths', col]))
puts(columns([(colored.red('Column 1')), col], [(colored.green('Column Two')), None],
[(colored.magenta('Column III')), col]))
puts(columns(['hi there my name is kenneth and this is a columns', col], [lorem, None], ['kenneths', col]))
+4
View File
@@ -0,0 +1,4 @@
{
"title": "Bashō's 'old pond'",
"text": "古池や蛙飛込む水の音"
}
+61
View File
@@ -0,0 +1,61 @@
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import os
import sys
import codecs
sys.path.insert(0, os.path.abspath('..'))
try:
import json
except:
import simplejson as json
from clint.arguments import Args
from clint import piped_in
from clint.textui import colored, puts, indent
args = Args()
if __name__ == '__main__':
puts('Test:')
with indent(4):
puts('%s Fake test 1.' % colored.green(''))
puts('%s Fake test 2.' % colored.red(''))
puts('')
puts('Greet:')
with indent(4):
puts(colored.red('Здравствуйте'))
puts(colored.green('你好。'))
puts(colored.yellow('سلام'))
puts(colored.magenta('안녕하세요'))
puts(colored.blue('नमस्ते'))
puts(colored.cyan('γειά σου'))
puts('')
puts('Arguments:')
with indent(4):
puts('%s' % colored.red(args[0]))
puts('')
puts('File:')
with indent(4):
f = args.files[0]
puts(colored.yellow('%s:' % f))
with indent(2):
fd = codecs.open(f, encoding='utf-8')
for line in fd:
line = line.strip('\n\r')
puts(colored.yellow(' %s' % line))
fd.close()
puts('')
puts('Input:')
with indent(4):
in_data = json.loads(piped_in())
title = in_data['title']
text = in_data['text']
puts(colored.blue('Title: %s' % title))
puts(colored.magenta('Text: %s' % text))
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env sh
python unicode.py こんにちは。 unicode.json < unicode.json
Regular → Executable
+11 -7
View File
@@ -4,12 +4,13 @@
import os
import sys
from distutils.core import setup
try:
from setuptools import setup
except ImportError:
from distutils.core import setup
import clint
def publish():
"""Publish to PyPi"""
os.system("python setup.py sdist upload")
@@ -18,7 +19,7 @@ if sys.argv[-1] == "publish":
publish()
sys.exit()
required = []
required = ['args']
setup(
name='clint',
@@ -38,14 +39,17 @@ setup(
license='ISC',
classifiers=(
# 'Development Status :: 5 - Production/Stable',
'Environment :: Console',
'Intended Audience :: Developers',
'Natural Language :: English',
'License :: OSI Approved :: ISC License (ISCL)',
'Programming Language :: Python',
'Programming Language :: Python :: 2.5',
'Programming Language :: Python :: 2',
'Programming Language :: Python :: 2.6',
'Programming Language :: Python :: 2.7',
# 'Programming Language :: Python :: 3.0',
# 'Programming Language :: Python :: 3.1',
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.1',
'Programming Language :: Python :: 3.2',
'Topic :: Terminals :: Terminal Emulators/X Terminals',
),
)
+44 -2
View File
@@ -3,11 +3,12 @@
"""Clint Test Suite."""
import os
import unittest
class TablibTestCase(unittest.TestCase):
"""Tablib test cases."""
class ClintTestCase(unittest.TestCase):
"""Clint test cases."""
def setUp(self):
import clint
@@ -16,5 +17,46 @@ class TablibTestCase(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"
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()
+13
View File
@@ -0,0 +1,13 @@
[tox]
envlist = py26,py27,py3
[testenv]
commands=py.test --junitxml=junit-{envname}.xml
deps = pytest
args
[testenv:pypy]
basepython=/usr/bin/pypy-c
[testenv:py3]
basepython=/usr/bin/python3