diff --git a/rhodecode/apps/file_store/backends/local_store.py b/rhodecode/apps/file_store/backends/local_store.py --- a/rhodecode/apps/file_store/backends/local_store.py +++ b/rhodecode/apps/file_store/backends/local_store.py @@ -21,7 +21,6 @@ import os import time import errno -import shutil import hashlib from rhodecode.lib.ext_json import json @@ -212,10 +211,19 @@ class LocalFileStorage(object): filename, path = self.resolve_name(uid_filename, dest_directory) stored_file_dir = os.path.dirname(path) - file_obj.seek(0) + no_body_seek = kwargs.pop('no_body_seek', False) + if no_body_seek: + pass + else: + file_obj.seek(0) with open(path, "wb") as dest: - shutil.copyfileobj(file_obj, dest) + length = 256 * 1024 + while 1: + buf = file_obj.read(length) + if not buf: + break + dest.write(buf) metadata = {} if extra_metadata: diff --git a/rhodecode/lib/ext_json_renderer.py b/rhodecode/lib/ext_json_renderer.py --- a/rhodecode/lib/ext_json_renderer.py +++ b/rhodecode/lib/ext_json_renderer.py @@ -27,11 +27,14 @@ def pyramid_ext_json(info): """ def _render(value, system): request = system.get('request') + indent = None if request is not None: response = request.response ct = response.content_type if ct == response.default_content_type: response.content_type = 'application/json' - return json.dumps(value) + indent = getattr(request, 'ext_json_indent', None) + + return json.dumps(value, indent=indent) return _render diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py --- a/rhodecode/model/db.py +++ b/rhodecode/model/db.py @@ -749,8 +749,11 @@ class User(Base, BaseModel): def get_artifact_token(self, cache=True): artifacts_tokens = UserApiKeys.query()\ - .filter(UserApiKeys.user == self)\ + .filter(UserApiKeys.user == self) \ + .filter(or_(UserApiKeys.expires == -1, + UserApiKeys.expires >= time.time())) \ .filter(UserApiKeys.role == UserApiKeys.ROLE_ARTIFACT_DOWNLOAD) + if cache: artifacts_tokens = artifacts_tokens.options( FromCache("sql_cache_short", "get_user_artifact_token_%s" % self.user_id)) @@ -760,6 +763,24 @@ class User(Base, BaseModel): return artifacts_tokens[0].api_key return 'NO_ARTIFACT_TOKEN_AVAILABLE' + def get_or_create_artifact_token(self): + artifacts_tokens = UserApiKeys.query()\ + .filter(UserApiKeys.user == self) \ + .filter(or_(UserApiKeys.expires == -1, + UserApiKeys.expires >= time.time())) \ + .filter(UserApiKeys.role == UserApiKeys.ROLE_ARTIFACT_DOWNLOAD) + + artifacts_tokens = artifacts_tokens.all() + if artifacts_tokens: + return artifacts_tokens[0].api_key + else: + from rhodecode.model.auth_token import AuthTokenModel + artifact_token = AuthTokenModel().create( + self, 'auto-generated-artifact-token', + lifetime=-1, role=UserApiKeys.ROLE_ARTIFACT_DOWNLOAD) + Session.commit() + return artifact_token.api_key + @classmethod def get(cls, user_id, cache=False): if not user_id: diff --git a/rhodecode/model/repo_group.py b/rhodecode/model/repo_group.py --- a/rhodecode/model/repo_group.py +++ b/rhodecode/model/repo_group.py @@ -60,6 +60,9 @@ class RepoGroupModel(BaseModel): return self._get_instance(RepoGroup, repo_group, callback=RepoGroup.get_by_group_name) + def get_repo_group(self, repo_group): + return self._get_repo_group(repo_group) + @LazyProperty def repos_path(self): """ diff --git a/rhodecode/public/js/rhodecode/routes.js b/rhodecode/public/js/rhodecode/routes.js --- a/rhodecode/public/js/rhodecode/routes.js +++ b/rhodecode/public/js/rhodecode/routes.js @@ -270,6 +270,8 @@ function registerRCRoutes() { pyroutes.register('repo_artifacts_list', '/%(repo_name)s/artifacts', ['repo_name']); pyroutes.register('repo_artifacts_new', '/%(repo_name)s/artifacts/new', ['repo_name']); pyroutes.register('repo_artifacts_store', '/%(repo_name)s/artifacts/store', ['repo_name']); + pyroutes.register('repo_artifacts_stream_script', '/_file_store/stream-upload-script', []); + pyroutes.register('repo_artifacts_stream_store', '/_file_store/stream-upload', []); pyroutes.register('repo_artifacts_update', '/%(repo_name)s/artifacts/update/%(uid)s', ['repo_name', 'uid']); pyroutes.register('repo_automation', '/%(repo_name)s/settings/automation', ['repo_name']); pyroutes.register('repo_automation_update', '/%(repo_name)s/settings/automation/%(entry_id)s/update', ['repo_name', 'entry_id']);