comparison rhodecode/controllers/files.py @ 2031:82a88013a3fd

merge 1.3 into stable
author Marcin Kuzminski <marcin@python-works.com>
date Sun, 26 Feb 2012 17:25:09 +0200
parents bab80d1436fb 324ac367a4da
children 79a95f338fd0
comparison
equal deleted inserted replaced
2005:ab0e122b38a7 2031:82a88013a3fd
25 25
26 import os 26 import os
27 import logging 27 import logging
28 import traceback 28 import traceback
29 29
30 from os.path import join as jn 30 from pylons import request, response, tmpl_context as c, url
31
32 from pylons import request, response, session, tmpl_context as c, url
33 from pylons.i18n.translation import _ 31 from pylons.i18n.translation import _
34 from pylons.controllers.util import redirect 32 from pylons.controllers.util import redirect
35 from pylons.decorators import jsonify 33 from pylons.decorators import jsonify
36 34
37 from vcs.conf import settings 35 from rhodecode.lib.vcs.conf import settings
38 from vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \ 36 from rhodecode.lib.vcs.exceptions import RepositoryError, ChangesetDoesNotExistError, \
39 EmptyRepositoryError, ImproperArchiveTypeError, VCSError, NodeAlreadyExistsError 37 EmptyRepositoryError, ImproperArchiveTypeError, VCSError, \
40 from vcs.nodes import FileNode, NodeKind 38 NodeAlreadyExistsError
41 from vcs.utils import diffs as differ 39 from rhodecode.lib.vcs.nodes import FileNode
42 40
41 from rhodecode.lib.compat import OrderedDict
43 from rhodecode.lib import convert_line_endings, detect_mode, safe_str 42 from rhodecode.lib import convert_line_endings, detect_mode, safe_str
44 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator 43 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
45 from rhodecode.lib.base import BaseRepoController, render 44 from rhodecode.lib.base import BaseRepoController, render
46 from rhodecode.lib.utils import EmptyChangeset 45 from rhodecode.lib.utils import EmptyChangeset
46 from rhodecode.lib import diffs
47 import rhodecode.lib.helpers as h 47 import rhodecode.lib.helpers as h
48 from rhodecode.model.repo import RepoModel 48 from rhodecode.model.repo import RepoModel
49 from rhodecode.controllers.changeset import anchor_url, _ignorews_url,\
50 _context_url, get_line_ctx, get_ignore_ws
51 from rhodecode.lib.diffs import wrapped_diff
52 from rhodecode.model.scm import ScmModel
49 53
50 log = logging.getLogger(__name__) 54 log = logging.getLogger(__name__)
51 55
52 56
53 class FilesController(BaseRepoController): 57 class FilesController(BaseRepoController):
102 redirect(h.url('files_home', repo_name=repo_name, 106 redirect(h.url('files_home', repo_name=repo_name,
103 revision=cs.raw_id)) 107 revision=cs.raw_id))
104 108
105 return file_node 109 return file_node
106 110
107
108 def __get_paths(self, changeset, starting_path):
109 """recursive walk in root dir and return a set of all path in that dir
110 based on repository walk function
111 """
112 _files = list()
113 _dirs = list()
114
115 try:
116 tip = changeset
117 for topnode, dirs, files in tip.walk(starting_path):
118 for f in files:
119 _files.append(f.path)
120 for d in dirs:
121 _dirs.append(d.path)
122 except RepositoryError, e:
123 log.debug(traceback.format_exc())
124 pass
125 return _dirs, _files
126
127 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 111 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
128 'repository.admin') 112 'repository.admin')
129 def index(self, repo_name, revision, f_path): 113 def index(self, repo_name, revision, f_path):
130 # redirect to given revision from form if given 114 # redirect to given revision from form if given
131 post_revision = request.POST.get('at_rev', None) 115 post_revision = request.POST.get('at_rev', None)
160 except (ChangesetDoesNotExistError, VCSError): 144 except (ChangesetDoesNotExistError, VCSError):
161 c.url_next = '#' 145 c.url_next = '#'
162 146
163 # files or dirs 147 # files or dirs
164 try: 148 try:
165 c.files_list = c.changeset.get_node(f_path) 149 c.file = c.changeset.get_node(f_path)
166 150
167 if c.files_list.is_file(): 151 if c.file.is_file():
168 c.file_history = self._get_node_history(c.changeset, f_path) 152 c.file_history = self._get_node_history(c.changeset, f_path)
169 else: 153 else:
170 c.file_history = [] 154 c.file_history = []
171 except RepositoryError, e: 155 except RepositoryError, e:
172 h.flash(str(e), category='warning') 156 h.flash(str(e), category='warning')
403 return get_chunked_archive(archive) 387 return get_chunked_archive(archive)
404 388
405 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 389 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
406 'repository.admin') 390 'repository.admin')
407 def diff(self, repo_name, f_path): 391 def diff(self, repo_name, f_path):
408 diff1 = request.GET.get('diff1') 392 ignore_whitespace = request.GET.get('ignorews') == '1'
409 diff2 = request.GET.get('diff2') 393 line_context = request.GET.get('context', 3)
394 diff1 = request.GET.get('diff1', '')
395 diff2 = request.GET.get('diff2', '')
410 c.action = request.GET.get('diff') 396 c.action = request.GET.get('diff')
411 c.no_changes = diff1 == diff2 397 c.no_changes = diff1 == diff2
412 c.f_path = f_path 398 c.f_path = f_path
413 c.big_diff = False 399 c.big_diff = False
414 400 c.anchor_url = anchor_url
401 c.ignorews_url = _ignorews_url
402 c.context_url = _context_url
403 c.changes = OrderedDict()
404 c.changes[diff2] = []
415 try: 405 try:
416 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]: 406 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]:
417 c.changeset_1 = c.rhodecode_repo.get_changeset(diff1) 407 c.changeset_1 = c.rhodecode_repo.get_changeset(diff1)
418 node1 = c.changeset_1.get_node(f_path) 408 node1 = c.changeset_1.get_node(f_path)
419 else: 409 else:
425 node2 = c.changeset_2.get_node(f_path) 415 node2 = c.changeset_2.get_node(f_path)
426 else: 416 else:
427 c.changeset_2 = EmptyChangeset(repo=c.rhodecode_repo) 417 c.changeset_2 = EmptyChangeset(repo=c.rhodecode_repo)
428 node2 = FileNode('.', '', changeset=c.changeset_2) 418 node2 = FileNode('.', '', changeset=c.changeset_2)
429 except RepositoryError: 419 except RepositoryError:
430 return redirect(url('files_home', 420 return redirect(url('files_home', repo_name=c.repo_name,
431 repo_name=c.repo_name, f_path=f_path)) 421 f_path=f_path))
432 422
433 if c.action == 'download': 423 if c.action == 'download':
434 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2), 424 _diff = diffs.get_gitdiff(node1, node2,
435 format='gitdiff') 425 ignore_whitespace=ignore_whitespace,
426 context=line_context)
427 diff = diffs.DiffProcessor(_diff, format='gitdiff')
436 428
437 diff_name = '%s_vs_%s.diff' % (diff1, diff2) 429 diff_name = '%s_vs_%s.diff' % (diff1, diff2)
438 response.content_type = 'text/plain' 430 response.content_type = 'text/plain'
439 response.content_disposition = 'attachment; filename=%s' \ 431 response.content_disposition = 'attachment; filename=%s' \
440 % diff_name 432 % diff_name
441 return diff.raw_diff() 433 return diff.raw_diff()
442 434
443 elif c.action == 'raw': 435 elif c.action == 'raw':
444 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2), 436 _diff = diffs.get_gitdiff(node1, node2,
445 format='gitdiff') 437 ignore_whitespace=ignore_whitespace,
438 context=line_context)
439 diff = diffs.DiffProcessor(_diff, format='gitdiff')
446 response.content_type = 'text/plain' 440 response.content_type = 'text/plain'
447 return diff.raw_diff() 441 return diff.raw_diff()
448 442
449 elif c.action == 'diff':
450 if node1.is_binary or node2.is_binary:
451 c.cur_diff = _('Binary file')
452 elif node1.size > self.cut_off_limit or \
453 node2.size > self.cut_off_limit:
454 c.cur_diff = ''
455 c.big_diff = True
456 else:
457 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2),
458 format='gitdiff')
459 c.cur_diff = diff.as_html()
460 else: 443 else:
461 444 fid = h.FID(diff2, node2.path)
462 #default option 445 line_context_lcl = get_line_ctx(fid, request.GET)
463 if node1.is_binary or node2.is_binary: 446 ign_whitespace_lcl = get_ignore_ws(fid, request.GET)
464 c.cur_diff = _('Binary file') 447
465 elif node1.size > self.cut_off_limit or \ 448 lim = request.GET.get('fulldiff') or self.cut_off_limit
466 node2.size > self.cut_off_limit: 449 _, cs1, cs2, diff, st = wrapped_diff(filenode_old=node1,
467 c.cur_diff = '' 450 filenode_new=node2,
468 c.big_diff = True 451 cut_off_limit=lim,
469 452 ignore_whitespace=ign_whitespace_lcl,
470 else: 453 line_context=line_context_lcl,
471 diff = differ.DiffProcessor(differ.get_gitdiff(node1, node2), 454 enable_comments=False)
472 format='gitdiff') 455
473 c.cur_diff = diff.as_html() 456 c.changes = [('', node2, diff, cs1, cs2, st,)]
474 457
475 if not c.cur_diff and not c.big_diff:
476 c.no_changes = True
477 return render('files/file_diff.html') 458 return render('files/file_diff.html')
478 459
479 def _get_node_history(self, cs, f_path): 460 def _get_node_history(self, cs, f_path):
480 changesets = cs.get_file_history(f_path) 461 changesets = cs.get_file_history(f_path)
481 hist_l = [] 462 hist_l = []
483 changesets_group = ([], _("Changesets")) 464 changesets_group = ([], _("Changesets"))
484 branches_group = ([], _("Branches")) 465 branches_group = ([], _("Branches"))
485 tags_group = ([], _("Tags")) 466 tags_group = ([], _("Tags"))
486 467
487 for chs in changesets: 468 for chs in changesets:
488 n_desc = 'r%s:%s' % (chs.revision, chs.short_id) 469 n_desc = 'r%s:%s (%s)' % (chs.revision, chs.short_id, chs.branch)
489 changesets_group[0].append((chs.raw_id, n_desc,)) 470 changesets_group[0].append((chs.raw_id, n_desc,))
490 471
491 hist_l.append(changesets_group) 472 hist_l.append(changesets_group)
492 473
493 for name, chs in c.rhodecode_repo.branches.items(): 474 for name, chs in c.rhodecode_repo.branches.items():
494 #chs = chs.split(':')[-1]
495 branches_group[0].append((chs, name),) 475 branches_group[0].append((chs, name),)
496 hist_l.append(branches_group) 476 hist_l.append(branches_group)
497 477
498 for name, chs in c.rhodecode_repo.tags.items(): 478 for name, chs in c.rhodecode_repo.tags.items():
499 #chs = chs.split(':')[-1]
500 tags_group[0].append((chs, name),) 479 tags_group[0].append((chs, name),)
501 hist_l.append(tags_group) 480 hist_l.append(tags_group)
502 481
503 return hist_l 482 return hist_l
504 483
506 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', 485 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
507 'repository.admin') 486 'repository.admin')
508 def nodelist(self, repo_name, revision, f_path): 487 def nodelist(self, repo_name, revision, f_path):
509 if request.environ.get('HTTP_X_PARTIAL_XHR'): 488 if request.environ.get('HTTP_X_PARTIAL_XHR'):
510 cs = self.__get_cs_or_redirect(revision, repo_name) 489 cs = self.__get_cs_or_redirect(revision, repo_name)
511 _d, _f = self.__get_paths(cs, f_path) 490 _d, _f = ScmModel().get_nodes(repo_name, cs.raw_id, f_path,
491 flat=False)
512 return _d + _f 492 return _d + _f
513