1
2
3
4
5
6 from __future__ import with_statement
7 import os
8 import optparse as op
9 import sys
10
11
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
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.misc 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
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
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
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
80
82 if not pygments or not 'content-type' in response.headers:
83 return response.body_string()
84
85 ctype = response.headers['content-type']
86 try:
87 mimetype, encoding = ctype.split(";")
88 except ValueError:
89 mimetype = ctype.split(";")[0]
90
91
92 body = indent(mimetype, response.body_string())
93
94
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 body
103
105 if value.lower() in ('true', '1'):
106 return True
107 return False
108
110 config = os.path.expanduser('~/.restcli')
111 if os.path.isfile(config):
112 for line in open(config):
113 key, value = line.split('=', 1)
114 key = key.lower().strip()
115 key = key.replace('-', '_')
116 if key.startswith('header'):
117 key = 'headers'
118 value = value.strip()
119 if key in defaults:
120 default = defaults[key]
121 if default in (True, False):
122 value = as_bool(value)
123 elif isinstance(default, list):
124 default.append(value)
125 value = default
126 defaults[key] = value
127
129 """ build command lines options """
130
131 defaults = dict(
132 headers=[],
133 request='GET',
134 follow_redirect=False,
135 server_response=False,
136 prettify=False,
137 log_level='info',
138 input=None,
139 output=None,
140 )
141 update_defaults(defaults)
142
143 def opt_args(option, *help):
144 help = ' '.join(help)
145 help = help.strip()
146 default = defaults.get(option)
147 if default is not None:
148 help += ' Default to %r.' % default
149 return dict(default=defaults.get(option), help=help)
150
151 return [
152 op.make_option('-H', '--header', action='append', dest='headers',
153 **opt_args('headers',
154 'HTTP string header in the form of Key:Value. ',
155 'For example: "Accept: application/json".')),
156 op.make_option('-X', '--request', action='store', dest='method',
157 **opt_args('request', 'HTTP request method.')),
158 op.make_option('--follow-redirect', action='store_false',
159 dest='follow_redirect', **opt_args('follow_redirect')),
160 op.make_option('-S', '--server-response', action='store_true',
161 dest='server_response',
162 **opt_args('server_response', 'Print server response.')),
163 op.make_option('-p', '--prettify', dest="prettify", action='store_true',
164 **opt_args('prettify', "Prettify display.")),
165 op.make_option('--log-level', dest="log_level",
166 **opt_args('log_level',
167 "Log level below which to silence messages.")),
168 op.make_option('-i', '--input', action='store', dest='input',
169 metavar='FILE',
170 **opt_args('input', 'The name of the file to read from.')),
171 op.make_option('-o', '--output', action='store', dest='output',
172 **opt_args('output', 'The name of the file to write to.')),
173 op.make_option('--shell', action='store_true', dest='shell',
174 help='Open a IPython shell'),
175 ]
176
178 """ function to manage restkit command line """
179 parser = op.OptionParser(usage=__usage__, option_list=options(),
180 version="%prog " + __version__)
181
182 opts, args = parser.parse_args()
183 args_len = len(args)
184
185 if opts.shell:
186 try:
187 from restkit.contrib import ipython_shell as shell
188 shell.main(options=opts, *args)
189 except Exception, e:
190 print >>sys.stderr, str(e)
191 sys.exit(1)
192 return
193
194 if args_len < 1:
195 return parser.error('incorrect number of arguments')
196
197 set_logging(opts.log_level)
198
199 body = None
200 headers = []
201 if opts.input:
202 if opts.input == '-':
203 body = sys.stdin.read()
204 headers.append(("Content-Length", str(len(body))))
205 else:
206 fname = os.path.normpath(os.path.join(os.getcwd(),opts.input))
207 body = open(fname, 'r')
208
209 if opts.headers:
210 for header in opts.headers:
211 try:
212 k, v = header.split(':')
213 headers.append((k, v))
214 except ValueError:
215 pass
216
217
218 try:
219 if len(args) == 2:
220 if args[1] == "-" and not opts.input:
221 body = sys.stdin.read()
222 headers.append(("Content-Length", str(len(body))))
223
224 if not opts.method and opts.input:
225 method = 'POST'
226 else:
227 method=opts.method.upper()
228
229 resp = request(args[0], method=method, body=body,
230 headers=headers, follow_redirect=opts.follow_redirect)
231
232 if opts.output and opts.output != '-':
233 with open(opts.output, 'wb') as f:
234 if opts.server_response:
235 f.write("Server response from %s:\n" % resp.final_url)
236 for k, v in resp.headerslist:
237 f.write( "%s: %s" % (k, v))
238 else:
239 with resp.body_stream() as body:
240 for block in body:
241 f.write(block)
242 else:
243 if opts.server_response:
244 if opts.prettify:
245 print "\n\033[0m\033[95mServer response from %s:\n\033[0m" % (
246 resp.final_url)
247 for k, v in resp.headerslist:
248 print "\033[94m%s\033[0m: %s" % (k, v)
249 print "\033[0m"
250 else:
251 print "Server response from %s:\n" % (resp.final_url)
252 for k, v in resp.headerslist:
253 print "%s: %s" % (k, v)
254 print ""
255
256 if opts.output == '-':
257 if opts.prettify:
258 print prettify(resp)
259 else:
260 print resp.body_string()
261 else:
262 if opts.prettify:
263 print prettify(resp)
264 else:
265 print resp.body_string()
266
267 except Exception, e:
268 sys.stderr.write("An error happened: %s" % str(e))
269 sys.stderr.flush()
270 sys.exit(1)
271
272 sys.exit(0)
273