Mercurial > kallithea
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 |