Package restkit :: Module console
[hide private]
[frames] | no frames]

Source Code for Module restkit.console

  1  # -*- coding: utf-8 - 
  2  # 
  3  # This file is part of restkit released under the MIT license.  
  4  # See the NOTICE for more information. 
  5   
  6  from __future__ import with_statement 
  7  import os 
  8  import optparse as op 
  9  import sys 
 10   
 11  # import pygments if here 
 12  try: 
 13      import pygments 
 14      from pygments.lexers import get_lexer_for_mimetype 
 15      from pygments.formatters import TerminalFormatter 
 16  except ImportError: 
 17      pygments = False 
 18       
 19  # import json    
 20  try: 
 21      import simplejson as json 
 22  except ImportError: 
 23      try: 
 24          import json 
 25      except ImportError: 
 26          json = False 
 27   
 28  from restkit import __version__, request, set_logging 
 29  from restkit.util import popen3, locate_program 
 30   
 31  __usage__ = "'%prog [options] url [METHOD] [filename]'" 
 32   
 33   
 34  pretties = { 
 35      'application/json': 'text/javascript', 
 36      'text/plain': 'text/javascript' 
 37  } 
 38   
39 -def external(cmd, data):
40 try: 41 (child_stdin, child_stdout, child_stderr) = popen3(cmd) 42 err = child_stderr.read() 43 if err: 44 return data 45 return child_stdout.read() 46 except: 47 return data
48
49 -def indent_xml(data):
50 tidy_cmd = locate_program("tidy") 51 if tidy_cmd: 52 cmd = " ".join([tidy_cmd, '-qi', '-wrap', '70', '-utf8', data]) 53 return external(cmd, data) 54 return data
55
56 -def indent_json(data):
57 if not json: 58 return data 59 info = json.loads(data) 60 return json.dumps(info, indent=2, sort_keys=True)
61 62 63 common_indent = { 64 'application/json': indent_json, 65 'text/html': indent_xml, 66 'text/xml': indent_xml, 67 'application/xhtml+xml': indent_xml, 68 'application/xml': indent_xml, 69 'image/svg+xml': indent_xml, 70 'application/rss+xml': indent_xml, 71 'application/atom+xml': indent_xml, 72 'application/xsl+xml': indent_xml, 73 'application/xslt+xml': indent_xml 74 } 75
76 -def indent(mimetype, data):
77 if mimetype in common_indent: 78 return common_indent[mimetype](data) 79 return data
80
81 -def prettify(response, cli=True):
82 if not pygments or not 'content-type' in response.headers: 83 return response.body 84 85 ctype = response.headers['content-type'] 86 try: 87 mimetype, encoding = ctype.split(";") 88 except ValueError: 89 mimetype = ctype.split(";")[0] 90 91 # indent body 92 body = indent(mimetype, response.body) 93 94 # get pygments mimetype 95 mimetype = pretties.get(mimetype, mimetype) 96 97 try: 98 lexer = get_lexer_for_mimetype(mimetype) 99 body = pygments.highlight(body, lexer, TerminalFormatter()) 100 return body 101 except: 102 return response.body
103
104 -def options():
105 """ build command lines options """ 106 return [ 107 op.make_option('-H', '--header', action='append', dest='headers', 108 help='http string header in the form of Key:Value. '+ 109 'For example: "Accept: application/json" '), 110 op.make_option('-X', '--request', action='store', dest='method', 111 help='http request method', default='GET'), 112 op.make_option('--follow-redirect', action='store_false', 113 dest='follow_redirect', default=False), 114 op.make_option('-S', '--server-response', action='store_true', 115 default=False, dest='server_response', 116 help='print server response'), 117 op.make_option('-p', '--prettify', dest="prettify", action='store_true', 118 default=False, help="Prettify display"), 119 op.make_option('--log-level', dest="log_level", 120 help="Log level below which to silence messages. [info]", 121 default="info"), 122 op.make_option('-i', '--input', action='store', dest='input', 123 metavar='FILE', help='the name of the file to read from'), 124 op.make_option('-o', '--output', action='store', dest='output', 125 help='the name of the file to write to'), 126 127 ]
128
129 -def main():
130 """ function to manage restkit command line """ 131 parser = op.OptionParser(usage=__usage__, option_list=options(), 132 version="%prog " + __version__) 133 134 opts, args = parser.parse_args() 135 args_len = len(args) 136 137 if args_len < 1: 138 return parser.error('incorrect number of arguments') 139 140 set_logging(opts.log_level) 141 142 body = None 143 headers = [] 144 if opts.input: 145 if opts.input == '-': 146 body = sys.stdin.read() 147 headers.append(("Content-Length", str(len(body)))) 148 else: 149 fname = os.path.normpath(os.path.join(os.getcwd(),opts.input)) 150 body = open(fname, 'r') 151 152 if opts.headers: 153 for header in opts.headers: 154 try: 155 k, v = header.split(':') 156 headers.append((k, v)) 157 except ValueError: 158 pass 159 160 161 try: 162 if len(args) == 2: 163 if args[1] == "-" and not opts.input: 164 body = sys.stdin.read() 165 headers.append(("Content-Length", str(len(body)))) 166 167 if not opts.method and opts.input: 168 method = 'POST' 169 else: 170 method=opts.method.upper() 171 172 resp = request(args[0], method=method, body=body, 173 headers=headers, follow_redirect=opts.follow_redirect) 174 175 if opts.output: 176 with open(opts.output, 'wb') as f: 177 if opts.server_response: 178 f.write("Server response from %s:\n" % resp.final_url) 179 for k, v in resp.headerslist: 180 f.write( "%s: %s" % (k, v)) 181 else: 182 for block in resp.body_file: 183 f.write(block) 184 else: 185 if opts.server_response: 186 print "\n\033[0m\033[95mServer response from %s:\n\033[0m" % ( 187 resp.final_url) 188 for k, v in resp.headerslist: 189 print "\033[94m%s\033[0m: %s" % (k, v) 190 print "\033[0m" 191 else: 192 if opts.prettify: 193 print prettify(resp) 194 else: 195 print resp.body 196 197 except Exception, e: 198 sys.stderr.write("An error happened: %s" % str(e)) 199 sys.stderr.flush() 200 sys.exit(1) 201 202 sys.exit(0)
203