Show More
@@ -21,6 +21,9 b'' | |||||
21 | import inspect |
|
21 | import inspect | |
22 | import logging |
|
22 | import logging | |
23 | import itertools |
|
23 | import itertools | |
|
24 | import base64 | |||
|
25 | ||||
|
26 | from pyramid import compat | |||
24 |
|
27 | |||
25 | from rhodecode.api import ( |
|
28 | from rhodecode.api import ( | |
26 | jsonrpc_method, JSONRPCError, JSONRPCForbidden, find_methods) |
|
29 | jsonrpc_method, JSONRPCError, JSONRPCForbidden, find_methods) | |
@@ -36,6 +39,9 b' from rhodecode.lib.utils2 import safe_in' | |||||
36 | from rhodecode.model.db import UserIpMap |
|
39 | from rhodecode.model.db import UserIpMap | |
37 | from rhodecode.model.scm import ScmModel |
|
40 | from rhodecode.model.scm import ScmModel | |
38 | from rhodecode.model.settings import VcsSettingsModel |
|
41 | from rhodecode.model.settings import VcsSettingsModel | |
|
42 | from rhodecode.apps.upload_store import utils | |||
|
43 | from rhodecode.apps.upload_store.exceptions import FileNotAllowedException, \ | |||
|
44 | FileOverSizeException | |||
39 |
|
45 | |||
40 | log = logging.getLogger(__name__) |
|
46 | log = logging.getLogger(__name__) | |
41 |
|
47 | |||
@@ -412,3 +418,64 b' def store_exception(request, apiuser, ex' | |||||
412 | 'admin_settings_exception_tracker_show', exception_id=exc_id) |
|
418 | 'admin_settings_exception_tracker_show', exception_id=exc_id) | |
413 | return {'exc_id': exc_id, 'exc_url': exc_url} |
|
419 | return {'exc_id': exc_id, 'exc_url': exc_url} | |
414 |
|
420 | |||
|
421 | ||||
|
422 | @jsonrpc_method() | |||
|
423 | def upload_file(request, apiuser, filename, content): | |||
|
424 | """ | |||
|
425 | Upload API for the file_store | |||
|
426 | ||||
|
427 | Example usage from CLI:: | |||
|
428 | rhodecode-api --instance-name=enterprise-1 upload_file "{\"content\": \"$(cat image.jpg | base64)\", \"filename\":\"image.jpg\"}" | |||
|
429 | ||||
|
430 | ||||
|
431 | This command can only be run using an |authtoken| with admin rights to | |||
|
432 | the specified repository. | |||
|
433 | ||||
|
434 | This command takes the following options: | |||
|
435 | ||||
|
436 | :param apiuser: This is filled automatically from the |authtoken|. | |||
|
437 | :type apiuser: AuthUser | |||
|
438 | :param filename: name of the file uploaded | |||
|
439 | :type filename: str | |||
|
440 | :param content: base64 encoded content of the uploaded file | |||
|
441 | :type prefix: str | |||
|
442 | ||||
|
443 | Example output: | |||
|
444 | ||||
|
445 | .. code-block:: bash | |||
|
446 | ||||
|
447 | id : <id_given_in_input> | |||
|
448 | result: { | |||
|
449 | "access_path": "/_file_store/download/84d156f7-8323-4ad3-9fce-4a8e88e1deaf-0.jpg", | |||
|
450 | "access_path_fqn": "http://server.domain.com/_file_store/download/84d156f7-8323-4ad3-9fce-4a8e88e1deaf-0.jpg", | |||
|
451 | "store_fid": "84d156f7-8323-4ad3-9fce-4a8e88e1deaf-0.jpg" | |||
|
452 | } | |||
|
453 | error : null | |||
|
454 | """ | |||
|
455 | if not has_superadmin_permission(apiuser): | |||
|
456 | raise JSONRPCForbidden() | |||
|
457 | ||||
|
458 | storage = utils.get_file_storage(request.registry.settings) | |||
|
459 | ||||
|
460 | try: | |||
|
461 | file_obj = compat.NativeIO(base64.decodestring(content)) | |||
|
462 | except Exception as exc: | |||
|
463 | raise JSONRPCError('File `{}` content decoding error: {}.'.format(filename, exc)) | |||
|
464 | ||||
|
465 | metadata = { | |||
|
466 | 'filename': filename, | |||
|
467 | 'size': '', # filled by save_file | |||
|
468 | 'user_uploaded': {'username': apiuser.username, | |||
|
469 | 'user_id': apiuser.user_id, | |||
|
470 | 'ip': apiuser.ip_addr}} | |||
|
471 | try: | |||
|
472 | store_fid = storage.save_file(file_obj, filename, metadata=metadata) | |||
|
473 | except FileNotAllowedException: | |||
|
474 | raise JSONRPCError('File `{}` is not allowed.'.format(filename)) | |||
|
475 | ||||
|
476 | except FileOverSizeException: | |||
|
477 | raise JSONRPCError('File `{}` is exceeding allowed limit.'.format(filename)) | |||
|
478 | ||||
|
479 | return {'store_fid': store_fid, | |||
|
480 | 'access_path_fqn': request.route_url('download_file', fid=store_fid), | |||
|
481 | 'access_path': request.route_path('download_file', fid=store_fid)} |
@@ -19,6 +19,7 b'' | |||||
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ |
|
19 | # and proprietary license terms, please see https://rhodecode.com/licenses/ | |
20 |
|
20 | |||
21 | import os |
|
21 | import os | |
|
22 | import time | |||
22 | import shutil |
|
23 | import shutil | |
23 |
|
24 | |||
24 | from rhodecode.lib.ext_json import json |
|
25 | from rhodecode.lib.ext_json import json | |
@@ -26,6 +27,8 b' from rhodecode.apps.upload_store import ' | |||||
26 | from rhodecode.apps.upload_store.extensions import resolve_extensions |
|
27 | from rhodecode.apps.upload_store.extensions import resolve_extensions | |
27 | from rhodecode.apps.upload_store.exceptions import FileNotAllowedException |
|
28 | from rhodecode.apps.upload_store.exceptions import FileNotAllowedException | |
28 |
|
29 | |||
|
30 | METADATA_VER = 'v1' | |||
|
31 | ||||
29 |
|
32 | |||
30 | class LocalFileStorage(object): |
|
33 | class LocalFileStorage(object): | |
31 |
|
34 | |||
@@ -157,7 +160,8 b' class LocalFileStorage(object):' | |||||
157 |
|
160 | |||
158 | if metadata: |
|
161 | if metadata: | |
159 | size = os.stat(path).st_size |
|
162 | size = os.stat(path).st_size | |
160 |
metadata.update({'size': size |
|
163 | metadata.update({'size': size, "time": time.time(), | |
|
164 | "meta_ver": METADATA_VER}) | |||
161 | with open(os.path.join(dest_directory, filename_meta), "wb") as dest_meta: |
|
165 | with open(os.path.join(dest_directory, filename_meta), "wb") as dest_meta: | |
162 | dest_meta.write(json.dumps(metadata)) |
|
166 | dest_meta.write(json.dumps(metadata)) | |
163 |
|
167 |
General Comments 0
You need to be logged in to leave comments.
Login now