forked from extern/httpie-cli
Merge pull request #45 from gandaro/pygments-lexers
Use the Pygments HTTP and JSON lexers
This commit is contained in:
commit
126130455e
@ -1,8 +1,11 @@
|
|||||||
#!/usr/bin/env python
|
#!/usr/bin/env python
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import requests
|
import requests
|
||||||
|
|
||||||
from requests.compat import str
|
from requests.compat import str
|
||||||
|
|
||||||
from . import httpmessage
|
from . import httpmessage
|
||||||
from . import cliparse
|
from . import cliparse
|
||||||
from . import cli
|
from . import cli
|
||||||
|
@ -3,15 +3,19 @@ CLI argument parsing logic.
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
import os
|
import os
|
||||||
import json
|
|
||||||
import re
|
import re
|
||||||
|
import json
|
||||||
|
import argparse
|
||||||
|
|
||||||
from collections import namedtuple
|
from collections import namedtuple
|
||||||
|
|
||||||
try:
|
try:
|
||||||
from collections import OrderedDict
|
from collections import OrderedDict
|
||||||
except ImportError:
|
except ImportError:
|
||||||
OrderedDict = dict
|
OrderedDict = dict
|
||||||
import argparse
|
|
||||||
from requests.structures import CaseInsensitiveDict
|
from requests.structures import CaseInsensitiveDict
|
||||||
|
|
||||||
from . import __version__
|
from . import __version__
|
||||||
|
|
||||||
|
|
||||||
|
@ -38,7 +38,7 @@ def from_response(response):
|
|||||||
return HTTPMessage(
|
return HTTPMessage(
|
||||||
line='HTTP/{version} {status} {reason}'.format(
|
line='HTTP/{version} {status} {reason}'.format(
|
||||||
version='.'.join(str(original.version)),
|
version='.'.join(str(original.version)),
|
||||||
status=original.status, reason=original.reason,),
|
status=original.status, reason=original.reason),
|
||||||
headers=str(original.msg),
|
headers=str(original.msg),
|
||||||
body=response.content.decode(encoding) if response.content else '',
|
body=response.content.decode(encoding) if response.content else '',
|
||||||
content_type=response_headers.get('Content-Type'))
|
content_type=response_headers.get('Content-Type'))
|
||||||
@ -47,20 +47,21 @@ def from_response(response):
|
|||||||
def format(message, prettifier=None,
|
def format(message, prettifier=None,
|
||||||
with_headers=True, with_body=True):
|
with_headers=True, with_body=True):
|
||||||
"""Return a `unicode` representation of `message`. """
|
"""Return a `unicode` representation of `message`. """
|
||||||
|
pretty = prettifier is not None
|
||||||
bits = []
|
bits = []
|
||||||
|
|
||||||
if with_headers:
|
if with_headers:
|
||||||
if prettifier:
|
bits.append(message.line)
|
||||||
bits.append(prettifier.headers(message.line))
|
bits.append(message.headers)
|
||||||
bits.append(prettifier.headers(message.headers))
|
if pretty:
|
||||||
else:
|
bits = [prettifier.headers('\n'.join(bits))]
|
||||||
bits.append(message.line)
|
|
||||||
bits.append(message.headers)
|
|
||||||
if with_body and message.body:
|
if with_body and message.body:
|
||||||
bits.append('\n')
|
bits.append('\n')
|
||||||
|
|
||||||
if with_body and message.body:
|
if with_body and message.body:
|
||||||
if prettifier and message.content_type:
|
if pretty and message.content_type:
|
||||||
bits.append(prettifier.body(message.body, message.content_type))
|
bits.append(prettifier.body(message.body, message.content_type))
|
||||||
else:
|
else:
|
||||||
bits.append(message.body)
|
bits.append(message.body)
|
||||||
bits.append('\n')
|
|
||||||
return '\n'.join(bit.strip() for bit in bits)
|
return '\n'.join(bit.strip() for bit in bits)
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
|
|
||||||
import pygments
|
import pygments
|
||||||
from pygments import token
|
|
||||||
from pygments.util import ClassNotFound
|
from pygments.util import ClassNotFound
|
||||||
from pygments.lexers import get_lexer_for_mimetype
|
from pygments.styles import get_style_by_name, STYLE_MAP
|
||||||
|
from pygments.lexers import get_lexer_for_mimetype, HttpLexer
|
||||||
from pygments.formatters.terminal256 import Terminal256Formatter
|
from pygments.formatters.terminal256 import Terminal256Formatter
|
||||||
from pygments.formatters.terminal import TerminalFormatter
|
from pygments.formatters.terminal import TerminalFormatter
|
||||||
from pygments.lexer import RegexLexer, bygroups
|
|
||||||
from pygments.styles import get_style_by_name, STYLE_MAP
|
|
||||||
from .pygson import JSONLexer
|
|
||||||
from . import solarized
|
from . import solarized
|
||||||
|
|
||||||
|
|
||||||
@ -19,24 +19,6 @@ FORMATTER = (Terminal256Formatter
|
|||||||
else TerminalFormatter)
|
else TerminalFormatter)
|
||||||
|
|
||||||
|
|
||||||
class HTTPLexer(RegexLexer):
|
|
||||||
name = 'HTTP'
|
|
||||||
aliases = ['http']
|
|
||||||
filenames = ['*.http']
|
|
||||||
tokens = {
|
|
||||||
'root': [
|
|
||||||
(r'\s+', token.Text),
|
|
||||||
# Request-Line
|
|
||||||
(r'([A-Z]+\s+)(/.*?)(\s+HTTP/[\d.]+)', bygroups(
|
|
||||||
token.Keyword, token.String, token.Keyword)),
|
|
||||||
# Status-Line
|
|
||||||
(r'(HTTP/[\d.]+\s+)(\d+)(\s+.+)', bygroups(
|
|
||||||
token.Keyword, token.Number, token.String)),
|
|
||||||
# Header
|
|
||||||
(r'(.*?:)(.+)', bygroups(token.Name, token.Keyword))
|
|
||||||
]}
|
|
||||||
|
|
||||||
|
|
||||||
class PrettyHttp(object):
|
class PrettyHttp(object):
|
||||||
|
|
||||||
def __init__(self, style_name):
|
def __init__(self, style_name):
|
||||||
@ -47,22 +29,21 @@ class PrettyHttp(object):
|
|||||||
self.formatter = FORMATTER(style=style)
|
self.formatter = FORMATTER(style=style)
|
||||||
|
|
||||||
def headers(self, content):
|
def headers(self, content):
|
||||||
return pygments.highlight(content, HTTPLexer(), self.formatter)
|
return pygments.highlight(content, HttpLexer(), self.formatter)
|
||||||
|
|
||||||
def body(self, content, content_type):
|
def body(self, content, content_type):
|
||||||
lexer = None
|
|
||||||
content_type = content_type.split(';')[0]
|
content_type = content_type.split(';')[0]
|
||||||
if 'json' in content_type:
|
try:
|
||||||
lexer = JSONLexer()
|
lexer = get_lexer_for_mimetype(content_type)
|
||||||
|
except ClassNotFound:
|
||||||
|
return content
|
||||||
|
|
||||||
|
if content_type == 'application/json':
|
||||||
try:
|
try:
|
||||||
# Indent the JSON data.
|
# Indent and sort the JSON data.
|
||||||
content = json.dumps(json.loads(content),
|
content = json.dumps(json.loads(content),
|
||||||
sort_keys=True, indent=4)
|
sort_keys=True, indent=4)
|
||||||
except Exception:
|
except:
|
||||||
pass
|
pass
|
||||||
if not lexer:
|
|
||||||
try:
|
|
||||||
lexer = get_lexer_for_mimetype(content_type)
|
|
||||||
except ClassNotFound:
|
|
||||||
return content
|
|
||||||
return pygments.highlight(content, lexer, self.formatter)
|
return pygments.highlight(content, lexer, self.formatter)
|
||||||
|
@ -1,77 +0,0 @@
|
|||||||
"""
|
|
||||||
JSON lexer by Norman Richards
|
|
||||||
|
|
||||||
It's already been merged into Pygments but not released yet,
|
|
||||||
so we are temporarily bundling it with HTTPie.
|
|
||||||
|
|
||||||
It can be removed once Pygments > 1.4 has been released.
|
|
||||||
|
|
||||||
See <https://github.com/jkbr/httpie/pull/25> for more details.
|
|
||||||
|
|
||||||
"""
|
|
||||||
import re
|
|
||||||
from pygments import token
|
|
||||||
from pygments.lexer import RegexLexer, include
|
|
||||||
|
|
||||||
|
|
||||||
class JSONLexer(RegexLexer):
|
|
||||||
name = 'JSON Lexer'
|
|
||||||
aliases = ['json']
|
|
||||||
filenames = ['*.json']
|
|
||||||
mimetypes = []
|
|
||||||
|
|
||||||
|
|
||||||
flags = re.DOTALL
|
|
||||||
tokens = {
|
|
||||||
'whitespace': [
|
|
||||||
(r'\s+', token.Text),
|
|
||||||
],
|
|
||||||
|
|
||||||
# represents a simple terminal value
|
|
||||||
'simplevalue':[
|
|
||||||
(r'(true|false|null)\b', token.Keyword.Constant),
|
|
||||||
(r'-?[0-9]+', token.Number.Integer),
|
|
||||||
(r'"(\\\\|\\"|[^"])*"', token.String.Double),
|
|
||||||
],
|
|
||||||
|
|
||||||
|
|
||||||
# the right hand side of an object, after the attribute name
|
|
||||||
'objectattribute': [
|
|
||||||
include('value'),
|
|
||||||
(r':', token.Punctuation),
|
|
||||||
# comma terminates the attribute but expects more
|
|
||||||
(r',', token.Punctuation, '#pop'),
|
|
||||||
# a closing bracket terminates the entire object, so pop twice
|
|
||||||
(r'}', token.Punctuation, ('#pop', '#pop')),
|
|
||||||
],
|
|
||||||
|
|
||||||
# a json object - { attr, attr, ... }
|
|
||||||
'objectvalue': [
|
|
||||||
include('whitespace'),
|
|
||||||
(r'"(\\\\|\\"|[^"])*"', token.Name.Tag, 'objectattribute'),
|
|
||||||
(r'}', token.Punctuation, '#pop'),
|
|
||||||
],
|
|
||||||
|
|
||||||
# json array - [ value, value, ... }
|
|
||||||
'arrayvalue': [
|
|
||||||
include('whitespace'),
|
|
||||||
include('value'),
|
|
||||||
(r',', token.Punctuation),
|
|
||||||
(r']', token.Punctuation, '#pop'),
|
|
||||||
],
|
|
||||||
|
|
||||||
# a json value - either a simple value or a complex value (object or array)
|
|
||||||
'value': [
|
|
||||||
include('whitespace'),
|
|
||||||
include('simplevalue'),
|
|
||||||
(r'{', token.Punctuation, 'objectvalue'),
|
|
||||||
(r'\[', token.Punctuation, 'arrayvalue'),
|
|
||||||
],
|
|
||||||
|
|
||||||
|
|
||||||
# the root of a json document would be a value
|
|
||||||
'root': [
|
|
||||||
include('value'),
|
|
||||||
],
|
|
||||||
|
|
||||||
}
|
|
@ -27,7 +27,8 @@ THE SOFTWARE.
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
from pygments.style import Style
|
from pygments.style import Style
|
||||||
from pygments.token import Token, Comment, Name, Keyword, Generic, Number, Operator, String
|
from pygments.token import (Token, Comment, Name, Keyword, Generic, Number,
|
||||||
|
Operator, String)
|
||||||
|
|
||||||
|
|
||||||
BASE03 = '#002B36'
|
BASE03 = '#002B36'
|
||||||
|
2
setup.py
2
setup.py
@ -9,7 +9,7 @@ if sys.argv[-1] == 'test':
|
|||||||
sys.exit()
|
sys.exit()
|
||||||
|
|
||||||
|
|
||||||
requirements = ['requests>=0.10.1', 'Pygments>=1.4']
|
requirements = ['requests>=0.10.1', 'Pygments>=1.5']
|
||||||
if sys.version_info[:2] in ((2, 6), (3, 1)):
|
if sys.version_info[:2] in ((2, 6), (3, 1)):
|
||||||
# argparse has been added in Python 3.2 / 2.7
|
# argparse has been added in Python 3.2 / 2.7
|
||||||
requirements.append('argparse>=1.2.1')
|
requirements.append('argparse>=1.2.1')
|
||||||
|
Loading…
Reference in New Issue
Block a user