@@ -416,386 +416,386 @@ class FilesController(BaseRepoController
content=content, f_path=f_path)
h.flash(_('Successfully committed to %s') % f_path,
category='success')
except Exception:
log.error(traceback.format_exc())
h.flash(_('Error occurred during commit'), category='error')
return redirect(url('changeset_home',
repo_name=c.repo_name, revision='tip'))
return render('files/files_edit.html')
@LoginRequired()
@HasRepoPermissionAnyDecorator('repository.write', 'repository.admin')
def add(self, repo_name, revision, f_path):
repo = Repository.get_by_repo_name(repo_name)
if repo.enable_locking and repo.locked[0]:
h.flash(_('This repository is has been locked by %s on %s')
% (h.person_by_id(repo.locked[0]),
h.fmt_date(h.time_to_datetime(repo.locked[1]))),
'warning')
return redirect(h.url('files_home',
repo_name=repo_name, revision='tip'))
r_post = request.POST
c.cs = self.__get_cs(revision, silent_empty=True)
if c.cs is None:
c.cs = EmptyChangeset(alias=c.db_repo_scm_instance.alias)
c.default_message = (_('Added file via Kallithea'))
c.f_path = f_path
if r_post:
unix_mode = 0
content = convert_line_endings(r_post.get('content', ''), unix_mode)
message = r_post.get('message') or c.default_message
filename = r_post.get('filename')
location = r_post.get('location', '')
file_obj = r_post.get('upload_file', None)
if file_obj is not None and hasattr(file_obj, 'filename'):
filename = file_obj.filename
content = file_obj.file
if hasattr(content, 'file'):
# non posix systems store real file under file attr
content = content.file
if not content:
h.flash(_('No content'), category='warning')
return redirect(url('changeset_home', repo_name=c.repo_name,
revision='tip'))
if not filename:
h.flash(_('No filename'), category='warning')
#strip all crap out of file, just leave the basename
filename = os.path.basename(filename)
node_path = os.path.join(location, filename)
author = self.authuser.full_contact
try:
nodes = {
node_path: {
'content': content
}
self.scm_model.create_nodes(
user=c.authuser.user_id, repo=c.db_repo,
message=message,
nodes=nodes,
parent_cs=c.cs,
author=author,
)
h.flash(_('Successfully committed to %s') % node_path,
except NonRelativePathError, e:
h.flash(_('Location must be relative path and must not '
'contain .. in path'), category='warning')
except (NodeError, NodeAlreadyExistsError), e:
h.flash(_(e), category='error')
return render('files/files_add.html')
@HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
'repository.admin')
def archivefile(self, repo_name, fname):
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]
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)
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.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):
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]
c.changes = cs_changes
return render('files/file_diff.html')
def diff_2way(self, repo_name, f_path):
except ChangesetDoesNotExistError as e:
msg = _('Such revision does not exist for this repository')
h.flash(msg, category='error')
raise HTTPNotFound()
c.node1 = node1
c.node2 = node2
c.cs1 = c.changeset_1
c.cs2 = c.changeset_2
return render('files/diff_2way.html')
def _get_node_history(self, cs, f_path, changesets=None):
"""
get changesets history for given node
:param cs: changeset to calculate history
:param f_path: path for node to calculate history for
:param changesets: if passed don't calculate history and take
changesets defined in this list
# calculate history based on tip
tip_cs = c.db_repo_scm_instance.get_changeset()
if changesets is None:
changesets = tip_cs.get_file_history(f_path)
except (NodeDoesNotExistError, ChangesetError):
#this node is not present at tip !
changesets = cs.get_file_history(f_path)
hist_l = []
changesets_group = ([], _("Changesets"))
branches_group = ([], _("Branches"))
tags_group = ([], _("Tags"))
for chs in changesets:
#_branch = '(%s)' % chs.branch if (cs.repository.alias == 'hg') else ''
_branch = chs.branch
n_desc = '%s (%s)' % (h.show_id(chs), _branch)
changesets_group[0].append((chs.raw_id, n_desc,))
hist_l.append(changesets_group)
for name, chs in c.db_repo_scm_instance.branches.items():
branches_group[0].append((chs, name),)
hist_l.append(branches_group)
for name, chs in c.db_repo_scm_instance.tags.items():
tags_group[0].append((chs, name),)
hist_l.append(tags_group)
return hist_l, changesets
Status change: