##// END OF EJS Templates
files: allow partial tree downloads
marcink -
r3709:d3048a59 new-ui
parent child Browse files
Show More
@@ -42,7 +42,7 b' from rhodecode.lib.exceptions import Non'
42 from rhodecode.lib.codeblocks import (
42 from rhodecode.lib.codeblocks import (
43 filenode_as_lines_tokens, filenode_as_annotated_lines_tokens)
43 filenode_as_lines_tokens, filenode_as_annotated_lines_tokens)
44 from rhodecode.lib.utils2 import (
44 from rhodecode.lib.utils2 import (
45 convert_line_endings, detect_mode, safe_str, str2bool, safe_int)
45 convert_line_endings, detect_mode, safe_str, str2bool, safe_int, sha1)
46 from rhodecode.lib.auth import (
46 from rhodecode.lib.auth import (
47 LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired)
47 LoginRequired, HasRepoPermissionAnyDecorator, CSRFRequired)
48 from rhodecode.lib.vcs import path as vcspath
48 from rhodecode.lib.vcs import path as vcspath
@@ -243,16 +243,16 b' class RepoFilesView(RepoAppView):'
243
243
244 @region.conditional_cache_on_arguments(namespace=cache_namespace_uid,
244 @region.conditional_cache_on_arguments(namespace=cache_namespace_uid,
245 condition=cache_on)
245 condition=cache_on)
246 def compute_file_tree(repo_id, commit_id, f_path, full_load):
246 def compute_file_tree(ver, repo_id, commit_id, f_path, full_load):
247 log.debug('Generating cached file tree for repo_id: %s, %s, %s',
247 log.debug('Generating cached file tree at ver:%s for repo_id: %s, %s, %s',
248 repo_id, commit_id, f_path)
248 ver, repo_id, commit_id, f_path)
249
249
250 c.full_load = full_load
250 c.full_load = full_load
251 return render(
251 return render(
252 'rhodecode:templates/files/files_browser_tree.mako',
252 'rhodecode:templates/files/files_browser_tree.mako',
253 self._get_template_context(c), self.request)
253 self._get_template_context(c), self.request)
254
254
255 return compute_file_tree(self.db_repo.repo_id, commit_id, f_path, full_load)
255 return compute_file_tree('v1', self.db_repo.repo_id, commit_id, f_path, full_load)
256
256
257 def _get_archive_spec(self, fname):
257 def _get_archive_spec(self, fname):
258 log.debug('Detecting archive spec for: `%s`', fname)
258 log.debug('Detecting archive spec for: `%s`', fname)
@@ -291,6 +291,7 b' class RepoFilesView(RepoAppView):'
291
291
292 fname = self.request.matchdict['fname']
292 fname = self.request.matchdict['fname']
293 subrepos = self.request.GET.get('subrepos') == 'true'
293 subrepos = self.request.GET.get('subrepos') == 'true'
294 at_path = self.request.GET.get('at_path') or '/'
294
295
295 if not self.db_repo.enable_downloads:
296 if not self.db_repo.enable_downloads:
296 return Response(_('Downloads disabled'))
297 return Response(_('Downloads disabled'))
@@ -310,10 +311,19 b' class RepoFilesView(RepoAppView):'
310 except EmptyRepositoryError:
311 except EmptyRepositoryError:
311 return Response(_('Empty repository'))
312 return Response(_('Empty repository'))
312
313
313 archive_name = '%s-%s%s%s' % (
314 try:
315 at_path = commit.get_node(at_path).path
316 except Exception:
317 return Response(_('No node at path {} for this repository').format(at_path))
318
319 path_sha = sha1(at_path)[:8]
320
321 archive_name = '{}-{}{}-{}{}'.format(
314 safe_str(self.db_repo_name.replace('/', '_')),
322 safe_str(self.db_repo_name.replace('/', '_')),
315 '-sub' if subrepos else '',
323 '-sub' if subrepos else '',
316 safe_str(commit.short_id), ext)
324 safe_str(commit.short_id),
325 path_sha,
326 ext)
317
327
318 use_cached_archive = False
328 use_cached_archive = False
319 archive_cache_enabled = CONFIG.get(
329 archive_cache_enabled = CONFIG.get(
@@ -338,7 +348,8 b' class RepoFilesView(RepoAppView):'
338 fd, archive = tempfile.mkstemp()
348 fd, archive = tempfile.mkstemp()
339 log.debug('Creating new temp archive in %s', archive)
349 log.debug('Creating new temp archive in %s', archive)
340 try:
350 try:
341 commit.archive_repo(archive, kind=fileformat, subrepos=subrepos)
351 commit.archive_repo(archive, kind=fileformat, subrepos=subrepos,
352 archive_at_path=at_path)
342 except ImproperArchiveTypeError:
353 except ImproperArchiveTypeError:
343 return _('Unknown archive type')
354 return _('Unknown archive type')
344 if archive_cache_enabled:
355 if archive_cache_enabled:
@@ -1094,12 +1094,12 b' class BaseCommit(object):'
1094 """
1094 """
1095 return None
1095 return None
1096
1096
1097 def archive_repo(self, file_path, kind='tgz', subrepos=None,
1097 def archive_repo(self, archive_dest_path, kind='tgz', subrepos=None,
1098 prefix=None, write_metadata=False, mtime=None):
1098 prefix=None, write_metadata=False, mtime=None, archive_at_path='/'):
1099 """
1099 """
1100 Creates an archive containing the contents of the repository.
1100 Creates an archive containing the contents of the repository.
1101
1101
1102 :param file_path: path to the file which to create the archive.
1102 :param archive_dest_path: path to the file which to create the archive.
1103 :param kind: one of following: ``"tbz2"``, ``"tgz"``, ``"zip"``.
1103 :param kind: one of following: ``"tbz2"``, ``"tgz"``, ``"zip"``.
1104 :param prefix: name of root directory in archive.
1104 :param prefix: name of root directory in archive.
1105 Default is repository name and commit's short_id joined with dash:
1105 Default is repository name and commit's short_id joined with dash:
@@ -1107,6 +1107,7 b' class BaseCommit(object):'
1107 :param write_metadata: write a metadata file into archive.
1107 :param write_metadata: write a metadata file into archive.
1108 :param mtime: custom modification time for archive creation, defaults
1108 :param mtime: custom modification time for archive creation, defaults
1109 to time.time() if not given.
1109 to time.time() if not given.
1110 :param archive_at_path: pack files at this path (default '/')
1110
1111
1111 :raise VCSError: If prefix has a problem.
1112 :raise VCSError: If prefix has a problem.
1112 """
1113 """
@@ -1122,7 +1123,7 b' class BaseCommit(object):'
1122
1123
1123 file_info = []
1124 file_info = []
1124 cur_rev = self.repository.get_commit(commit_id=self.raw_id)
1125 cur_rev = self.repository.get_commit(commit_id=self.raw_id)
1125 for _r, _d, files in cur_rev.walk('/'):
1126 for _r, _d, files in cur_rev.walk(archive_at_path):
1126 for f in files:
1127 for f in files:
1127 f_path = os.path.join(prefix, f.path)
1128 f_path = os.path.join(prefix, f.path)
1128 file_info.append(
1129 file_info.append(
@@ -1131,6 +1132,7 b' class BaseCommit(object):'
1131 if write_metadata:
1132 if write_metadata:
1132 metadata = [
1133 metadata = [
1133 ('repo_name', self.repository.name),
1134 ('repo_name', self.repository.name),
1135 ('commit_id', self.raw_id),
1134 ('rev', self.raw_id),
1136 ('rev', self.raw_id),
1135 ('create_time', mtime),
1137 ('create_time', mtime),
1136 ('branch', self.branch),
1138 ('branch', self.branch),
@@ -1139,7 +1141,7 b' class BaseCommit(object):'
1139 meta = ["%s:%s" % (f_name, value) for f_name, value in metadata]
1141 meta = ["%s:%s" % (f_name, value) for f_name, value in metadata]
1140 file_info.append(('.archival.txt', 0o644, False, '\n'.join(meta)))
1142 file_info.append(('.archival.txt', 0o644, False, '\n'.join(meta)))
1141
1143
1142 connection.Hg.archive_repo(file_path, mtime, file_info, kind)
1144 connection.Hg.archive_repo(archive_dest_path, mtime, file_info, kind)
1143
1145
1144 def _validate_archive_prefix(self, prefix):
1146 def _validate_archive_prefix(self, prefix):
1145 if prefix is None:
1147 if prefix is None:
@@ -35,7 +35,7 b''
35 </td>
35 </td>
36 <td class="td-actions">
36 <td class="td-actions">
37 <a href="${h.route_path('repo_compare',repo_name=c.repo_name, source_ref_type="rev", source_ref=cs.raw_id,target_ref_type="rev", target_ref=c.commit_id,_query=dict(merge='1',f_path=c.changelog_for_path))}">
37 <a href="${h.route_path('repo_compare',repo_name=c.repo_name, source_ref_type="rev", source_ref=cs.raw_id,target_ref_type="rev", target_ref=c.commit_id,_query=dict(merge='1',f_path=c.changelog_for_path))}">
38 ${_('Diff File')}
38 <span title="${'Diff {} vs {}'.format(cs.raw_id[:8],c.commit_id[:8])}">${_('Diff File')}</span>
39 </a>
39 </a>
40 </td>
40 </td>
41 </tr>
41 </tr>
@@ -35,7 +35,7 b''
35 ${_('Download full tree ZIP')}
35 ${_('Download full tree ZIP')}
36 </a>
36 </a>
37 % else:
37 % else:
38 <a href="${h.route_path('repo_archivefile',repo_name=c.repo_name, fname='{}.zip'.format(c.commit.raw_id))}">
38 <a href="${h.route_path('repo_archivefile',repo_name=c.repo_name, fname='{}.zip'.format(c.commit.raw_id), _query={'at_path':c.f_path})}">
39 ${_('Download this tree ZIP')}
39 ${_('Download this tree ZIP')}
40 </a>
40 </a>
41 % endif
41 % endif
General Comments 0
You need to be logged in to leave comments. Login now