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