@@ -512,194 +512,194 @@ class FilesController(BaseRepoController
fileformat = None
revision = None
ext = None
subrepos = request.GET.get('subrepos') == 'true'
for a_type, ext_data in settings.ARCHIVE_SPECS.items():
archive_spec = fname.split(ext_data[1])
if len(archive_spec) == 2 and archive_spec[1] == '':
fileformat = a_type or ext_data[1]
revision = archive_spec[0]
ext = ext_data[1]
try:
dbrepo = RepoModel().get_by_repo_name(repo_name)
if not dbrepo.enable_downloads:
return _('Downloads disabled')
if c.db_repo_scm_instance.alias == 'hg':
# patch and reset hooks section of UI config to not run any
# hooks on fetching archives with subrepos
for k, v in c.db_repo_scm_instance._repo.ui.configitems('hooks'):
c.db_repo_scm_instance._repo.ui.setconfig('hooks', k, None)
cs = c.db_repo_scm_instance.get_changeset(revision)
content_type = settings.ARCHIVE_SPECS[fileformat][0]
except ChangesetDoesNotExistError:
return _('Unknown revision %s') % revision
except EmptyRepositoryError:
return _('Empty repository')
except (ImproperArchiveTypeError, KeyError):
return _('Unknown archive type')
# archive cache
from kallithea import CONFIG
rev_name = cs.raw_id[:12]
archive_name = '%s-%s%s' % (safe_str(repo_name.replace('/', '_')),
safe_str(rev_name), ext)
use_cached_archive = False # defines if we use cached version of archive
archive_cache_enabled = CONFIG.get('archive_cache_dir')
if not subrepos and archive_cache_enabled:
#check if we it's ok to write
if not os.path.isdir(CONFIG['archive_cache_dir']):
os.makedirs(CONFIG['archive_cache_dir'])
cached_archive_path = os.path.join(CONFIG['archive_cache_dir'], archive_name)
if os.path.isfile(cached_archive_path):
log.debug('Found cached archive in %s' % cached_archive_path)
fd, archive = None, cached_archive_path
use_cached_archive = True
else:
log.debug('Archive %s is not yet cached' % (archive_name))
if not use_cached_archive:
# generate new archive
temp_stream = None
fd, archive = tempfile.mkstemp()
temp_stream = open(archive, 'wb')
log.debug('Creating new temp archive in %s' % archive)
cs.fill_archive(stream=temp_stream, kind=fileformat, subrepos=subrepos)
#if we generated the archive and use cache rename that
log.debug('Storing new archive in %s' % cached_archive_path)
shutil.move(archive, cached_archive_path)
archive = cached_archive_path
finally:
if temp_stream:
temp_stream.close()
def get_chunked_archive(archive):
stream = open(archive, 'rb')
while True:
data = stream.read(16 * 1024)
if not data:
stream.close()
if fd: # fd means we used temporary file
os.close(fd)
if not archive_cache_enabled:
log.debug('Destroing temp archive %s' % archive)
os.remove(archive)
break
yield data
# store download action
action_logger(user=c.authuser,
action='user_downloaded_archive:%s' % (archive_name),
repo=repo_name, ipaddr=self.ip_addr, commit=True)
response.content_disposition = str('attachment; filename=%s' % (archive_name))
response.content_type = str(content_type)
return get_chunked_archive(archive)
@LoginRequired()
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
'repository.admin')
def diff(self, repo_name, f_path):
ignore_whitespace = request.GET.get('ignorews') == '1'
line_context = request.GET.get('context', 3)
diff1 = request.GET.get('diff1', '')
diff2 = request.GET.get('diff2', '')
diff1 = request.GET.get('diff1', '') or diff2
c.action = request.GET.get('diff')
c.no_changes = diff1 == diff2
c.f_path = f_path
c.big_diff = False
c.anchor_url = anchor_url
c.ignorews_url = _ignorews_url
c.context_url = _context_url
c.changes = OrderedDict()
c.changes[diff2] = []
#special case if we want a show rev only, it's impl here
#to reduce JS and callbacks
if request.GET.get('show_rev'):
if str2bool(request.GET.get('annotate', 'False')):
_url = url('files_annotate_home', repo_name=c.repo_name,
revision=diff1, f_path=c.f_path)
_url = url('files_home', repo_name=c.repo_name,
return redirect(_url)
if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
c.changeset_1 = c.db_repo_scm_instance.get_changeset(diff1)
node1 = c.changeset_1.get_node(f_path)
if node1.is_dir():
raise NodeError('%s path is a %s not a file'
% (node1, type(node1)))
except NodeDoesNotExistError:
c.changeset_1 = EmptyChangeset(cs=diff1,
revision=c.changeset_1.revision,
repo=c.db_repo_scm_instance)
node1 = FileNode(f_path, '', changeset=c.changeset_1)
c.changeset_1 = EmptyChangeset(repo=c.db_repo_scm_instance)
if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]:
c.changeset_2 = c.db_repo_scm_instance.get_changeset(diff2)
node2 = c.changeset_2.get_node(f_path)
if node2.is_dir():
% (node2, type(node2)))
c.changeset_2 = EmptyChangeset(cs=diff2,
revision=c.changeset_2.revision,
node2 = FileNode(f_path, '', changeset=c.changeset_2)
c.changeset_2 = EmptyChangeset(repo=c.db_repo_scm_instance)
except (RepositoryError, NodeError):
log.error(traceback.format_exc())
return redirect(url('files_home', repo_name=c.repo_name,
f_path=f_path))
if c.action == 'download':
_diff = diffs.get_gitdiff(node1, node2,
ignore_whitespace=ignore_whitespace,
context=line_context)
diff = diffs.DiffProcessor(_diff, format='gitdiff')
diff_name = '%s_vs_%s.diff' % (diff1, diff2)
response.content_type = 'text/plain'
response.content_disposition = (
'attachment; filename=%s' % diff_name
)
return diff.as_raw()
elif c.action == 'raw':
fid = h.FID(diff2, node2.path)
line_context_lcl = get_line_ctx(fid, request.GET)
ign_whitespace_lcl = get_ignore_ws(fid, request.GET)
lim = request.GET.get('fulldiff') or self.cut_off_limit
_, cs1, cs2, diff, st = diffs.wrapped_diff(filenode_old=node1,
filenode_new=node2,
cut_off_limit=lim,
ignore_whitespace=ign_whitespace_lcl,
line_context=line_context_lcl,
enable_comments=False)
op = ''
filename = node1.path
cs_changes = {
'fid': [cs1, cs2, op, filename, diff, st]
Status change: