diff --git a/README.rst b/README.rst index 37d15f34..5ac59d7c 100644 --- a/README.rst +++ b/README.rst @@ -677,14 +677,24 @@ Colors and Formatting --------------------- Syntax highlighting is applied to HTTP headers and bodies (where it makes -sense). Also, the following formatting is used: +sense). You can choose your prefered color scheme via the ``--style`` option +if you don't like the default onw (see ``$ http --help`` for the possible +values). + +Also, the following formatting is applied: * HTTP headers are sorted by name. * JSON data is indented, sorted by keys, and unicode escapes are converted to the characters they represent. -Colorizing and formatting can be disabled with ``--ugly, -u``. +One of these options can be used to control output processing: +=============== ============================================================== +``--pretty`` Apply both colors and formatting. Default for terminal output. +``--colors`` Apply colors. +``--format`` Apply formatting. +``--ugly, -u`` Disables output processing. Default for redirected output. +=============== ============================================================== ----------- Binary data @@ -722,7 +732,8 @@ Redirected Output HTTPie uses **different defaults** for redirected output than for `terminal output`_: -* Formatting and colors aren't applied (unless ``--pretty`` is set). +* Formatting and colors aren't applied (unless ``--pretty``, ``--format``, + or ``--colors``, is set). * Only the response body is printed (unless one of the `output options`_ is set). * Also, binary data isn't suppressed. @@ -852,7 +863,7 @@ and that only a small portion of the command is used to control HTTPie and doesn't directly correspond to any part of the request (here it's only ``-f`` asking HTTPie to send a form request). -The two modes, ``--pretty, -p`` (default for terminal) and ``--ugly, -u`` +The two modes, ``--pretty`` (default for terminal) and ``--ugly, -u`` (default for redirected output), allow for both user-friendly interactive use and usage from scripts, where HTTPie serves as a generic HTTP client. @@ -922,6 +933,8 @@ Changelog ========= * `0.2.8dev`_ + * Added ``--colors`` and ``--format`` in addition to ``--pretty``, to + be able to separate colorizing and formatting. * `0.2.7`_ (2012-08-07) * Compatibility with Requests 0.13.6. * Streamed terminal output. ``--stream`` / ``-S`` can be used to enable diff --git a/httpie/cli.py b/httpie/cli.py index 76c63e17..5b3cbf40 100644 --- a/httpie/cli.py +++ b/httpie/cli.py @@ -11,10 +11,13 @@ from . import __doc__ from . import __version__ from .output import AVAILABLE_STYLES, DEFAULT_STYLE from .input import (Parser, AuthCredentialsArgType, KeyValueArgType, - PRETTIFY_STDOUT_TTY_ONLY, + PRETTY_STDOUT_TTY_ONLY, SEP_PROXY, SEP_CREDENTIALS, SEP_GROUP_ITEMS, OUT_REQ_HEAD, OUT_REQ_BODY, OUT_RESP_HEAD, - OUT_RESP_BODY, OUTPUT_OPTIONS) + OUT_RESP_BODY, OUTPUT_OPTIONS, + PRETTY_STDOUT_TTY_ONLY, PRETTY_ALL, + PRETTY_FORMAT, + PRETTY_COLORS) def _(text): @@ -71,19 +74,26 @@ parser.add_argument( prettify = parser.add_mutually_exclusive_group(required=False) prettify.add_argument( - '--pretty', dest='prettify', action='store_true', - default=PRETTIFY_STDOUT_TTY_ONLY, + '--pretty', dest='prettify', action='store_const', const=PRETTY_ALL, + default=PRETTY_STDOUT_TTY_ONLY, help=_(''' - If stdout is a terminal, the response is prettified - by default (colorized and indented if it is JSON). - This flag ensures prettifying even when stdout is redirected. + Apply both colors and formatting. Default for terminal output. ''') ) +prettify.add_argument( + '--colors', dest='prettify', action='store_const', const=PRETTY_COLORS, + help=_('''Apply colors to the output.''') +) +prettify.add_argument( + '--format', dest='prettify', action='store_const', const=PRETTY_FORMAT, + help=_('''Apply formatting to the output.''') +) prettify.add_argument( '--ugly', '-u', dest='prettify', action='store_false', help=_(''' - Do not prettify the response. - ''') + Disables output processing. + Default for redirected output. + ''') ) output_options = parser.add_mutually_exclusive_group(required=False) diff --git a/httpie/input.py b/httpie/input.py index 40e06b1c..a4a807f2 100644 --- a/httpie/input.py +++ b/httpie/input.py @@ -66,11 +66,16 @@ OUTPUT_OPTIONS = frozenset([ OUT_RESP_BODY ]) +# Pretty +PRETTY_ALL = ['format', 'colors'] +PRETTY_FORMAT = ['format'] +PRETTY_COLORS = ['colors'] +PRETTY_STDOUT_TTY_ONLY = object() + # Defaults OUTPUT_OPTIONS_DEFAULT = OUT_RESP_HEAD + OUT_RESP_BODY OUTPUT_OPTIONS_DEFAULT_STDOUT_REDIRECTED = OUT_RESP_BODY -PRETTIFY_STDOUT_TTY_ONLY = object() DEFAULT_UA = 'HTTPie/%s' % __version__ @@ -123,8 +128,8 @@ class Parser(argparse.ArgumentParser): # Stdin already read (if not a tty) so it's save to prompt. args.auth.prompt_password(urlparse(args.url).netloc) - if args.prettify == PRETTIFY_STDOUT_TTY_ONLY: - args.prettify = env.stdout_isatty + if args.prettify == PRETTY_STDOUT_TTY_ONLY: + args.prettify = PRETTY_ALL if env.stdout_isatty else [] elif args.prettify and env.is_windows: self.error('Only terminal output can be prettified on Windows.') diff --git a/httpie/output.py b/httpie/output.py index 1bcb7c84..04b4be5f 100644 --- a/httpie/output.py +++ b/httpie/output.py @@ -116,7 +116,8 @@ def make_stream(env, args): elif args.prettify: Stream = partial( PrettyStream if args.stream else BufferedPrettyStream, - processor=OutputProcessor(env, pygments_style=args.style), + processor=OutputProcessor(env, groups=args.prettify, + pygments_style=args.style), env=env) else: Stream = partial(EncodedStream, env=env) @@ -446,17 +447,23 @@ class HeadersProcessor(BaseProcessor): class OutputProcessor(object): """A delegate class that invokes the actual processors.""" - installed_processors = [ - JSONProcessor, - HeadersProcessor, - PygmentsProcessor - ] - - def __init__(self, env, **kwargs): - processors = [ - cls(env, **kwargs) - for cls in self.installed_processors + installed_processors = { + 'format': [ + HeadersProcessor, + JSONProcessor + ], + 'colors': [ + PygmentsProcessor ] + } + + def __init__(self, env, groups, **kwargs): + + processors = [] + for group in groups: + for cls in self.installed_processors[group]: + processors.append(cls(env, **kwargs)) + self.processors = [p for p in processors if p.enabled] def process_headers(self, headers): diff --git a/tests/tests.py b/tests/tests.py index 9e2b2ee4..952aa5bd 100755 --- a/tests/tests.py +++ b/tests/tests.py @@ -503,7 +503,7 @@ class ImplicitHTTPMethodTest(BaseTestCase): self.assertIn(OK, r) -class PrettyFlagTest(BaseTestCase): +class PrettyOptionsTest(BaseTestCase): """Test the --pretty / --ugly flag handling.""" def test_pretty_enabled_by_default(self): @@ -553,6 +553,34 @@ class PrettyFlagTest(BaseTestCase): ) self.assertIn(COLOR, r) + def test_colors_option(self): + r = http( + '--print=B', + '--colors', + 'GET', + httpbin('/get'), + 'a=b', + env=TestEnvironment(colors=256), + ) + #noinspection PyUnresolvedReferences + # Tests that the JSON data isn't formatted. + self.assertEqual(r.strip().count('\n'), 0) + self.assertIn(COLOR, r) + + def test_format_option(self): + r = http( + '--print=B', + '--format', + 'GET', + httpbin('/get'), + 'a=b', + env=TestEnvironment(colors=256), + ) + #noinspection PyUnresolvedReferences + # Tests that the JSON data is formatted. + self.assertEqual(r.strip().count('\n'), 2) + self.assertNotIn(COLOR, r) + class VerboseFlagTest(BaseTestCase):