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 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=None,
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_true',
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 if opts.log_level is not None:
198 set_logging(opts.log_level)
199
200 body = None
201 headers = []
202 if opts.input:
203 if opts.input == '-':
204 body = sys.stdin.read()
205 headers.append(("Content-Length", str(len(body))))
206 else:
207 fname = os.path.normpath(os.path.join(os.getcwd(),opts.input))
208 body = open(fname, 'r')
209
210 if opts.headers:
211 for header in opts.headers:
212 try:
213 k, v = header.split(':')
214 headers.append((k, v))
215 except ValueError:
216 pass
217
218
219 try:
220 if len(args) == 2:
221 if args[1] == "-" and not opts.input:
222 body = sys.stdin.read()
223 headers.append(("Content-Length", str(len(body))))
224
225 if not opts.method and opts.input:
226 method = 'POST'
227 else:
228 method=opts.method.upper()
229
230 resp = request(args[0], method=method, body=body,
231 headers=headers, follow_redirect=opts.follow_redirect)
232
233 if opts.output and opts.output != '-':
234 with open(opts.output, 'wb') as f:
235 if opts.server_response:
236 f.write("Server response from %s:\n" % resp.final_url)
237 for k, v in resp.headerslist:
238 f.write( "%s: %s" % (k, v))
239 else:
240 with resp.body_stream() as body:
241 for block in body:
242 f.write(block)
243 else:
244 if opts.server_response:
245 if opts.prettify:
246 print "\n\033[0m\033[95mServer response from %s:\n\033[0m" % (
247 resp.final_url)
248 for k, v in resp.headerslist:
249 print "\033[94m%s\033[0m: %s" % (k, v)
250 print "\033[0m"
251 else:
252 print "Server response from %s:\n" % (resp.final_url)
253 for k, v in resp.headerslist:
254 print "%s: %s" % (k, v)
255 print ""
256
257 if opts.output == '-':
258 if opts.prettify:
259 print prettify(resp)
260 else:
261 print resp.body_string()
262 else:
263 if opts.prettify:
264 print prettify(resp)
265 else:
266 print resp.body_string()
267
268 except Exception, e:
269 sys.stderr.write("An error happened: %s" % str(e))
270 sys.stderr.flush()
271 sys.exit(1)
272
273 sys.exit(0)
274