Mercurial > kallithea
comparison rhodecode/controllers/files.py @ 3098:a5f0bc867edc rhodecode-0.0.1.5.0
merge with beta
author | Marcin Kuzminski <marcin@python-works.com> |
---|---|
date | Thu, 13 Dec 2012 22:54:21 +0100 |
parents | 63e58ef80ef1 7727faad5baf |
children | 3563bb7b4b82 |
comparison
equal
deleted
inserted
replaced
2909:52b1c6de19c2 | 3098:a5f0bc867edc |
---|---|
29 import tempfile | 29 import tempfile |
30 | 30 |
31 from pylons import request, response, tmpl_context as c, url | 31 from pylons import request, response, tmpl_context as c, url |
32 from pylons.i18n.translation import _ | 32 from pylons.i18n.translation import _ |
33 from pylons.controllers.util import redirect | 33 from pylons.controllers.util import redirect |
34 from pylons.decorators import jsonify | 34 from rhodecode.lib.utils import jsonify |
35 | 35 |
36 from rhodecode.lib import diffs | 36 from rhodecode.lib import diffs |
37 from rhodecode.lib import helpers as h | 37 from rhodecode.lib import helpers as h |
38 | 38 |
39 from rhodecode.lib.compat import OrderedDict | 39 from rhodecode.lib.compat import OrderedDict |
40 from rhodecode.lib.utils2 import convert_line_endings, detect_mode, safe_str | 40 from rhodecode.lib.utils2 import convert_line_endings, detect_mode, safe_str,\ |
41 str2bool | |
41 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator | 42 from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator |
42 from rhodecode.lib.base import BaseRepoController, render | 43 from rhodecode.lib.base import BaseRepoController, render |
43 from rhodecode.lib.vcs.backends.base import EmptyChangeset | 44 from rhodecode.lib.vcs.backends.base import EmptyChangeset |
44 from rhodecode.lib.vcs.conf import settings | 45 from rhodecode.lib.vcs.conf import settings |
45 from rhodecode.lib.vcs.exceptions import RepositoryError, \ | 46 from rhodecode.lib.vcs.exceptions import RepositoryError, \ |
46 ChangesetDoesNotExistError, EmptyRepositoryError, \ | 47 ChangesetDoesNotExistError, EmptyRepositoryError, \ |
47 ImproperArchiveTypeError, VCSError, NodeAlreadyExistsError | 48 ImproperArchiveTypeError, VCSError, NodeAlreadyExistsError,\ |
49 NodeDoesNotExistError, ChangesetError, NodeError | |
48 from rhodecode.lib.vcs.nodes import FileNode | 50 from rhodecode.lib.vcs.nodes import FileNode |
49 | 51 |
50 from rhodecode.model.repo import RepoModel | 52 from rhodecode.model.repo import RepoModel |
51 from rhodecode.model.scm import ScmModel | 53 from rhodecode.model.scm import ScmModel |
52 from rhodecode.model.db import Repository | 54 from rhodecode.model.db import Repository |
151 # files or dirs | 153 # files or dirs |
152 try: | 154 try: |
153 c.file = c.changeset.get_node(f_path) | 155 c.file = c.changeset.get_node(f_path) |
154 | 156 |
155 if c.file.is_file(): | 157 if c.file.is_file(): |
156 _hist = c.changeset.get_file_history(f_path) | 158 c.load_full_history = False |
157 c.file_history = self._get_node_history(c.changeset, f_path, | 159 file_last_cs = c.file.last_changeset |
158 _hist) | 160 c.file_changeset = (c.changeset |
161 if c.changeset.revision < file_last_cs.revision | |
162 else file_last_cs) | |
163 _hist = [] | |
164 c.file_history = [] | |
165 if c.load_full_history: | |
166 c.file_history, _hist = self._get_node_history(c.changeset, f_path) | |
167 | |
159 c.authors = [] | 168 c.authors = [] |
160 for a in set([x.author for x in _hist]): | 169 for a in set([x.author for x in _hist]): |
161 c.authors.append((h.email(a), h.person(a))) | 170 c.authors.append((h.email(a), h.person(a))) |
162 else: | 171 else: |
163 c.authors = c.file_history = [] | 172 c.authors = c.file_history = [] |
168 | 177 |
169 if request.environ.get('HTTP_X_PARTIAL_XHR'): | 178 if request.environ.get('HTTP_X_PARTIAL_XHR'): |
170 return render('files/files_ypjax.html') | 179 return render('files/files_ypjax.html') |
171 | 180 |
172 return render('files/files.html') | 181 return render('files/files.html') |
182 | |
183 def history(self, repo_name, revision, f_path, annotate=False): | |
184 if request.environ.get('HTTP_X_PARTIAL_XHR'): | |
185 c.changeset = self.__get_cs_or_redirect(revision, repo_name) | |
186 c.f_path = f_path | |
187 c.annotate = annotate | |
188 c.file = c.changeset.get_node(f_path) | |
189 if c.file.is_file(): | |
190 file_last_cs = c.file.last_changeset | |
191 c.file_changeset = (c.changeset | |
192 if c.changeset.revision < file_last_cs.revision | |
193 else file_last_cs) | |
194 c.file_history, _hist = self._get_node_history(c.changeset, f_path) | |
195 c.authors = [] | |
196 for a in set([x.author for x in _hist]): | |
197 c.authors.append((h.email(a), h.person(a))) | |
198 return render('files/files_history_box.html') | |
173 | 199 |
174 @LoginRequired() | 200 @LoginRequired() |
175 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | 201 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
176 'repository.admin') | 202 'repository.admin') |
177 def rawfile(self, repo_name, revision, f_path): | 203 def rawfile(self, repo_name, revision, f_path): |
428 c.anchor_url = anchor_url | 454 c.anchor_url = anchor_url |
429 c.ignorews_url = _ignorews_url | 455 c.ignorews_url = _ignorews_url |
430 c.context_url = _context_url | 456 c.context_url = _context_url |
431 c.changes = OrderedDict() | 457 c.changes = OrderedDict() |
432 c.changes[diff2] = [] | 458 c.changes[diff2] = [] |
459 | |
460 #special case if we want a show rev only, it's impl here | |
461 #to reduce JS and callbacks | |
462 | |
463 if request.GET.get('show_rev'): | |
464 if str2bool(request.GET.get('annotate', 'False')): | |
465 _url = url('files_annotate_home', repo_name=c.repo_name, | |
466 revision=diff1, f_path=c.f_path) | |
467 else: | |
468 _url = url('files_home', repo_name=c.repo_name, | |
469 revision=diff1, f_path=c.f_path) | |
470 | |
471 return redirect(_url) | |
433 try: | 472 try: |
434 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]: | 473 if diff1 not in ['', None, 'None', '0' * 12, '0' * 40]: |
435 c.changeset_1 = c.rhodecode_repo.get_changeset(diff1) | 474 c.changeset_1 = c.rhodecode_repo.get_changeset(diff1) |
436 node1 = c.changeset_1.get_node(f_path) | 475 try: |
476 node1 = c.changeset_1.get_node(f_path) | |
477 except NodeDoesNotExistError: | |
478 c.changeset_1 = EmptyChangeset(cs=diff1, | |
479 revision=c.changeset_1.revision, | |
480 repo=c.rhodecode_repo) | |
481 node1 = FileNode(f_path, '', changeset=c.changeset_1) | |
437 else: | 482 else: |
438 c.changeset_1 = EmptyChangeset(repo=c.rhodecode_repo) | 483 c.changeset_1 = EmptyChangeset(repo=c.rhodecode_repo) |
439 node1 = FileNode('.', '', changeset=c.changeset_1) | 484 node1 = FileNode(f_path, '', changeset=c.changeset_1) |
440 | 485 |
441 if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]: | 486 if diff2 not in ['', None, 'None', '0' * 12, '0' * 40]: |
442 c.changeset_2 = c.rhodecode_repo.get_changeset(diff2) | 487 c.changeset_2 = c.rhodecode_repo.get_changeset(diff2) |
443 node2 = c.changeset_2.get_node(f_path) | 488 try: |
489 node2 = c.changeset_2.get_node(f_path) | |
490 except NodeDoesNotExistError: | |
491 c.changeset_2 = EmptyChangeset(cs=diff2, | |
492 revision=c.changeset_2.revision, | |
493 repo=c.rhodecode_repo) | |
494 node2 = FileNode(f_path, '', changeset=c.changeset_2) | |
444 else: | 495 else: |
445 c.changeset_2 = EmptyChangeset(repo=c.rhodecode_repo) | 496 c.changeset_2 = EmptyChangeset(repo=c.rhodecode_repo) |
446 node2 = FileNode('.', '', changeset=c.changeset_2) | 497 node2 = FileNode(f_path, '', changeset=c.changeset_2) |
447 except RepositoryError: | 498 except (RepositoryError, NodeError): |
499 log.error(traceback.format_exc()) | |
448 return redirect(url('files_home', repo_name=c.repo_name, | 500 return redirect(url('files_home', repo_name=c.repo_name, |
449 f_path=f_path)) | 501 f_path=f_path)) |
450 | 502 |
451 if c.action == 'download': | 503 if c.action == 'download': |
452 _diff = diffs.get_gitdiff(node1, node2, | 504 _diff = diffs.get_gitdiff(node1, node2, |
457 diff_name = '%s_vs_%s.diff' % (diff1, diff2) | 509 diff_name = '%s_vs_%s.diff' % (diff1, diff2) |
458 response.content_type = 'text/plain' | 510 response.content_type = 'text/plain' |
459 response.content_disposition = ( | 511 response.content_disposition = ( |
460 'attachment; filename=%s' % diff_name | 512 'attachment; filename=%s' % diff_name |
461 ) | 513 ) |
462 return diff.raw_diff() | 514 return diff.as_raw() |
463 | 515 |
464 elif c.action == 'raw': | 516 elif c.action == 'raw': |
465 _diff = diffs.get_gitdiff(node1, node2, | 517 _diff = diffs.get_gitdiff(node1, node2, |
466 ignore_whitespace=ignore_whitespace, | 518 ignore_whitespace=ignore_whitespace, |
467 context=line_context) | 519 context=line_context) |
468 diff = diffs.DiffProcessor(_diff, format='gitdiff') | 520 diff = diffs.DiffProcessor(_diff, format='gitdiff') |
469 response.content_type = 'text/plain' | 521 response.content_type = 'text/plain' |
470 return diff.raw_diff() | 522 return diff.as_raw() |
471 | 523 |
472 else: | 524 else: |
473 fid = h.FID(diff2, node2.path) | 525 fid = h.FID(diff2, node2.path) |
474 line_context_lcl = get_line_ctx(fid, request.GET) | 526 line_context_lcl = get_line_ctx(fid, request.GET) |
475 ign_whitespace_lcl = get_ignore_ws(fid, request.GET) | 527 ign_whitespace_lcl = get_ignore_ws(fid, request.GET) |
479 filenode_new=node2, | 531 filenode_new=node2, |
480 cut_off_limit=lim, | 532 cut_off_limit=lim, |
481 ignore_whitespace=ign_whitespace_lcl, | 533 ignore_whitespace=ign_whitespace_lcl, |
482 line_context=line_context_lcl, | 534 line_context=line_context_lcl, |
483 enable_comments=False) | 535 enable_comments=False) |
484 | 536 op = '' |
485 c.changes = [('', node2, diff, cs1, cs2, st,)] | 537 filename = node1.path |
538 cs_changes = { | |
539 'fid': [cs1, cs2, op, filename, diff, st] | |
540 } | |
541 c.changes = cs_changes | |
486 | 542 |
487 return render('files/file_diff.html') | 543 return render('files/file_diff.html') |
488 | 544 |
489 def _get_node_history(self, cs, f_path, changesets=None): | 545 def _get_node_history(self, cs, f_path, changesets=None): |
546 """ | |
547 get changesets history for given node | |
548 | |
549 :param cs: changeset to calculate history | |
550 :param f_path: path for node to calculate history for | |
551 :param changesets: if passed don't calculate history and take | |
552 changesets defined in this list | |
553 """ | |
554 # calculate history based on tip | |
555 tip_cs = c.rhodecode_repo.get_changeset() | |
490 if changesets is None: | 556 if changesets is None: |
491 changesets = cs.get_file_history(f_path) | 557 try: |
558 changesets = tip_cs.get_file_history(f_path) | |
559 except (NodeDoesNotExistError, ChangesetError): | |
560 #this node is not present at tip ! | |
561 changesets = cs.get_file_history(f_path) | |
492 hist_l = [] | 562 hist_l = [] |
493 | 563 |
494 changesets_group = ([], _("Changesets")) | 564 changesets_group = ([], _("Changesets")) |
495 branches_group = ([], _("Branches")) | 565 branches_group = ([], _("Branches")) |
496 tags_group = ([], _("Tags")) | 566 tags_group = ([], _("Tags")) |
497 _hg = cs.repository.alias == 'hg' | 567 _hg = cs.repository.alias == 'hg' |
498 for chs in changesets: | 568 for chs in changesets: |
499 _branch = '(%s)' % chs.branch if _hg else '' | 569 #_branch = '(%s)' % chs.branch if _hg else '' |
500 n_desc = 'r%s:%s %s' % (chs.revision, chs.short_id, _branch) | 570 _branch = chs.branch |
571 n_desc = 'r%s:%s (%s)' % (chs.revision, chs.short_id, _branch) | |
501 changesets_group[0].append((chs.raw_id, n_desc,)) | 572 changesets_group[0].append((chs.raw_id, n_desc,)) |
502 | |
503 hist_l.append(changesets_group) | 573 hist_l.append(changesets_group) |
504 | 574 |
505 for name, chs in c.rhodecode_repo.branches.items(): | 575 for name, chs in c.rhodecode_repo.branches.items(): |
506 branches_group[0].append((chs, name),) | 576 branches_group[0].append((chs, name),) |
507 hist_l.append(branches_group) | 577 hist_l.append(branches_group) |
508 | 578 |
509 for name, chs in c.rhodecode_repo.tags.items(): | 579 for name, chs in c.rhodecode_repo.tags.items(): |
510 tags_group[0].append((chs, name),) | 580 tags_group[0].append((chs, name),) |
511 hist_l.append(tags_group) | 581 hist_l.append(tags_group) |
512 | 582 |
513 return hist_l | 583 return hist_l, changesets |
514 | 584 |
515 @LoginRequired() | 585 @LoginRequired() |
516 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', | 586 @HasRepoPermissionAnyDecorator('repository.read', 'repository.write', |
517 'repository.admin') | 587 'repository.admin') |
518 @jsonify | 588 @jsonify |