##// END OF EJS Templates
API: added basic upload api for the file storage
marcink -
r3437:206694bc default
parent child Browse files
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