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. |
|
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( |
|
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( |
|
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( |
|
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 |
|
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( |
|
172 | if isinstance(str_, unicode): | |
171 |
return |
|
173 | return str_ | |
172 |
|
174 | |||
173 | try: |
|
175 | try: | |
174 |
|
|
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( |
|
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 |
|
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( |
|
202 | if isinstance(unicode_, str): | |
192 |
return |
|
203 | return unicode_ | |
193 |
|
204 | |||
194 | try: |
|
205 | try: | |
195 |
|
|
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