##// END OF EJS Templates
marcink -
r1493:5a3252dd merge beta
parent child Browse files
Show More
@@ -7,7 +7,8 API
7
7
8 Starting from RhodeCode version 1.2 a simple API was implemented.
8 Starting from RhodeCode version 1.2 a simple API was implemented.
9 There's one schema for calling all api methods. API is implemented
9 There's one schema for calling all api methods. API is implemented
10 with JSON protocol both ways.
10 with JSON protocol both ways. An url to send API request in RhodeCode is
11 <your-server>/_admin/api
11
12
12
13
13 Clients need to send JSON data in such format::
14 Clients need to send JSON data in such format::
@@ -50,7 +51,7 remote repos upto date. This command can
50 api_key
51 api_key
51
52
52 ::
53 ::
53
54 api_key:"<api_key>"
54 method: "pull"
55 method: "pull"
55 args: {"repo":<repo_name>}
56 args: {"repo":<repo_name>}
56
57
@@ -39,7 +39,7 from pylons.controllers.util import Resp
39 from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError, \
39 from webob.exc import HTTPNotFound, HTTPForbidden, HTTPInternalServerError, \
40 HTTPBadRequest, HTTPError
40 HTTPBadRequest, HTTPError
41
41
42 from rhodecode.model.user import User
42 from rhodecode.model.db import User
43 from rhodecode.lib.auth import AuthUser
43 from rhodecode.lib.auth import AuthUser
44
44
45 log = logging.getLogger('JSONRPC')
45 log = logging.getLogger('JSONRPC')
@@ -85,10 +85,9 class JSONRPCController(WSGIController):
85 Parse the request body as JSON, look up the method on the
85 Parse the request body as JSON, look up the method on the
86 controller and if it exists, dispatch to it.
86 controller and if it exists, dispatch to it.
87 """
87 """
88
89 if 'CONTENT_LENGTH' not in environ:
88 if 'CONTENT_LENGTH' not in environ:
90 log.debug("No Content-Length")
89 log.debug("No Content-Length")
91 return jsonrpc_error(0, "No Content-Length")
90 return jsonrpc_error(message="No Content-Length in request")
92 else:
91 else:
93 length = environ['CONTENT_LENGTH'] or 0
92 length = environ['CONTENT_LENGTH'] or 0
94 length = int(environ['CONTENT_LENGTH'])
93 length = int(environ['CONTENT_LENGTH'])
@@ -96,7 +95,7 class JSONRPCController(WSGIController):
96
95
97 if length == 0:
96 if length == 0:
98 log.debug("Content-Length is 0")
97 log.debug("Content-Length is 0")
99 return jsonrpc_error(0, "Content-Length is 0")
98 return jsonrpc_error(message="Content-Length is 0")
100
99
101 raw_body = environ['wsgi.input'].read(length)
100 raw_body = environ['wsgi.input'].read(length)
102
101
@@ -104,12 +103,10 class JSONRPCController(WSGIController):
104 json_body = json.loads(urllib.unquote_plus(raw_body))
103 json_body = json.loads(urllib.unquote_plus(raw_body))
105 except ValueError as e:
104 except ValueError as e:
106 #catch JSON errors Here
105 #catch JSON errors Here
107 return jsonrpc_error("JSON parse error ERR:%s RAW:%r" \
106 return jsonrpc_error(message="JSON parse error ERR:%s RAW:%r" \
108 % (e, urllib.unquote_plus(raw_body)))
107 % (e, urllib.unquote_plus(raw_body)))
109
108
110
111 #check AUTH based on API KEY
109 #check AUTH based on API KEY
112
113 try:
110 try:
114 self._req_api_key = json_body['api_key']
111 self._req_api_key = json_body['api_key']
115 self._req_method = json_body['method']
112 self._req_method = json_body['method']
@@ -131,7 +128,7 class JSONRPCController(WSGIController):
131 try:
128 try:
132 self._func = self._find_method()
129 self._func = self._find_method()
133 except AttributeError, e:
130 except AttributeError, e:
134 return jsonrpc_error(str(e))
131 return jsonrpc_error(message=str(e))
135
132
136 # now that we have a method, add self._req_params to
133 # now that we have a method, add self._req_params to
137 # self.kargs and dispatch control to WGIController
134 # self.kargs and dispatch control to WGIController
@@ -143,7 +140,7 class JSONRPCController(WSGIController):
143 self.rhodecode_user = auth_u
140 self.rhodecode_user = auth_u
144
141
145 if 'user' not in arglist:
142 if 'user' not in arglist:
146 return jsonrpc_error('This method [%s] does not support '
143 return jsonrpc_error(message='This method [%s] does not support '
147 'authentication (missing user param)' %
144 'authentication (missing user param)' %
148 self._func.__name__)
145 self._func.__name__)
149
146
@@ -155,7 +152,7 class JSONRPCController(WSGIController):
155 continue
152 continue
156
153
157 if not self._req_params or arg not in self._req_params:
154 if not self._req_params or arg not in self._req_params:
158 return jsonrpc_error('Missing %s arg in JSON DATA' % arg)
155 return jsonrpc_error(message='Missing %s arg in JSON DATA' % arg)
159
156
160 self._rpc_args = dict(user=u)
157 self._rpc_args = dict(user=u)
161 self._rpc_args.update(self._req_params)
158 self._rpc_args.update(self._req_params)
@@ -157,44 +157,66 def generate_api_key(username, salt=None
157 return hashlib.sha1(username + salt).hexdigest()
157 return hashlib.sha1(username + salt).hexdigest()
158
158
159
159
160 def safe_unicode(_str, from_encoding='utf8'):
160 def safe_unicode(str_, from_encoding='utf8'):
161 """
161 """
162 safe unicode function. In case of UnicodeDecode error we try to return
162 safe unicode function. Does few trick to turn str_ into unicode
163 unicode with errors replaceed
163
164 In case of UnicodeDecode error we try to return it with encoding detected
165 by chardet library if it fails fallback to unicode with errors replaced
164
166
165 :param _str: string to decode
167 :param str_: string to decode
166 :rtype: unicode
168 :rtype: unicode
167 :returns: unicode object
169 :returns: unicode object
168 """
170 """
169
171
170 if isinstance(_str, unicode):
172 if isinstance(str_, unicode):
171 return _str
173 return str_
172
174
173 try:
175 try:
174 u_str = unicode(_str, from_encoding)
176 return unicode(str_, from_encoding)
175 except UnicodeDecodeError:
177 except UnicodeDecodeError:
176 u_str = unicode(_str, from_encoding, 'replace')
178 pass
177
179
178 return u_str
180 try:
179
181 import chardet
182 encoding = chardet.detect(str_)['encoding']
183 if encoding is None:
184 raise UnicodeDecodeError()
185
186 return str_.decode(encoding)
187 except (ImportError, UnicodeDecodeError):
188 return unicode(str_, from_encoding, 'replace')
180
189
181 def safe_str(_unicode, to_encoding='utf8'):
190 def safe_str(unicode_, to_encoding='utf8'):
182 """
191 """
183 safe str function. In case of UnicodeEncode error we try to return
192 safe str function. Does few trick to turn unicode_ into string
184 str with errors replaceed
193
194 In case of UnicodeEncodeError we try to return it with encoding detected
195 by chardet library if it fails fallback to string with errors replaced
185
196
186 :param _unicode: unicode to encode
197 :param unicode_: unicode to encode
187 :rtype: str
198 :rtype: str
188 :returns: str object
199 :returns: str object
189 """
200 """
190
201
191 if isinstance(_unicode, str):
202 if isinstance(unicode_, str):
192 return _unicode
203 return unicode_
193
204
194 try:
205 try:
195 safe_str = str(_unicode)
206 return str(unicode_)
196 except UnicodeEncodeError:
207 except UnicodeEncodeError:
197 safe_str = _unicode.encode(to_encoding, 'replace')
208 pass
209
210 try:
211 import chardet
212 encoding = chardet.detect(unicode_)['encoding']
213 print encoding
214 if encoding is None:
215 raise UnicodeEncodeError()
216
217 return unicode_.encode(encoding)
218 except (ImportError, UnicodeEncodeError):
219 return unicode_.encode(to_encoding, 'replace')
198
220
199 return safe_str
221 return safe_str
200
222
General Comments 0
You need to be logged in to leave comments. Login now