API: added basic upload api for the file storage

This commit is contained in:
Marcin Kuzminski 2019-01-28 17:17:37 +01:00
parent 93808de957
commit 45f8b0282a
2 changed files with 72 additions and 1 deletions

View file

@ -21,6 +21,9 @@
import inspect
import logging
import itertools
import base64
from pyramid import compat
from rhodecode.api import (
jsonrpc_method, JSONRPCError, JSONRPCForbidden, find_methods)
@ -36,6 +39,9 @@ from rhodecode.lib.utils2 import safe_int
from rhodecode.model.db import UserIpMap
from rhodecode.model.scm import ScmModel
from rhodecode.model.settings import VcsSettingsModel
from rhodecode.apps.upload_store import utils
from rhodecode.apps.upload_store.exceptions import FileNotAllowedException, \
FileOverSizeException
log = logging.getLogger(__name__)
@ -412,3 +418,64 @@ def store_exception(request, apiuser, exc_data_json, prefix=Optional('rhodecode'
'admin_settings_exception_tracker_show', exception_id=exc_id)
return {'exc_id': exc_id, 'exc_url': exc_url}
@jsonrpc_method()
def upload_file(request, apiuser, filename, content):
"""
Upload API for the file_store
Example usage from CLI::
rhodecode-api --instance-name=enterprise-1 upload_file "{\"content\": \"$(cat image.jpg | base64)\", \"filename\":\"image.jpg\"}"
This command can only be run using an |authtoken| with admin rights to
the specified repository.
This command takes the following options:
:param apiuser: This is filled automatically from the |authtoken|.
:type apiuser: AuthUser
:param filename: name of the file uploaded
:type filename: str
:param content: base64 encoded content of the uploaded file
:type prefix: str
Example output:
.. code-block:: bash
id : <id_given_in_input>
result: {
"access_path": "/_file_store/download/84d156f7-8323-4ad3-9fce-4a8e88e1deaf-0.jpg",
"access_path_fqn": "http://server.domain.com/_file_store/download/84d156f7-8323-4ad3-9fce-4a8e88e1deaf-0.jpg",
"store_fid": "84d156f7-8323-4ad3-9fce-4a8e88e1deaf-0.jpg"
}
error : null
"""
if not has_superadmin_permission(apiuser):
raise JSONRPCForbidden()
storage = utils.get_file_storage(request.registry.settings)
try:
file_obj = compat.NativeIO(base64.decodestring(content))
except Exception as exc:
raise JSONRPCError('File `{}` content decoding error: {}.'.format(filename, exc))
metadata = {
'filename': filename,
'size': '', # filled by save_file
'user_uploaded': {'username': apiuser.username,
'user_id': apiuser.user_id,
'ip': apiuser.ip_addr}}
try:
store_fid = storage.save_file(file_obj, filename, metadata=metadata)
except FileNotAllowedException:
raise JSONRPCError('File `{}` is not allowed.'.format(filename))
except FileOverSizeException:
raise JSONRPCError('File `{}` is exceeding allowed limit.'.format(filename))
return {'store_fid': store_fid,
'access_path_fqn': request.route_url('download_file', fid=store_fid),
'access_path': request.route_path('download_file', fid=store_fid)}

View file

@ -19,6 +19,7 @@
# and proprietary license terms, please see https://rhodecode.com/licenses/
import os
import time
import shutil
from rhodecode.lib.ext_json import json
@ -26,6 +27,8 @@ from rhodecode.apps.upload_store import utils
from rhodecode.apps.upload_store.extensions import resolve_extensions
from rhodecode.apps.upload_store.exceptions import FileNotAllowedException
METADATA_VER = 'v1'
class LocalFileStorage(object):
@ -157,7 +160,8 @@ class LocalFileStorage(object):
if metadata:
size = os.stat(path).st_size
metadata.update({'size': size})
metadata.update({'size': size, "time": time.time(),
"meta_ver": METADATA_VER})
with open(os.path.join(dest_directory, filename_meta), "wb") as dest_meta:
dest_meta.write(json.dumps(metadata))