Changeset - 25d77aef2729
[Not reviewed]
beta
0 3 0
Marcin Kuzminski - 13 years ago 2012-11-17 17:14:02
marcin@python-works.com
Optimized look of compare view of changesets.
Added cut off limit for compare view
3 files changed with 18 insertions and 4 deletions:
0 comments (0 inline, 0 general)
rhodecode/controllers/compare.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
"""
 
    rhodecode.controllers.compare
 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
    compare controller for pylons showoing differences between two
 
    repos, branches, bookmarks or tips
 

	
 
    :created_on: May 6, 2012
 
    :author: marcink
 
    :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
 
    :license: GPLv3, see COPYING for more details.
 
"""
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
import logging
 
import traceback
 

	
 
from webob.exc import HTTPNotFound
 
from pylons import request, response, session, tmpl_context as c, url
 
from pylons.controllers.util import abort, redirect
 
from pylons.i18n.translation import _
 

	
 
from rhodecode.lib.vcs.exceptions import EmptyRepositoryError, RepositoryError
 
from rhodecode.lib import helpers as h
 
from rhodecode.lib.base import BaseRepoController, render
 
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
 
from rhodecode.lib import diffs
 

	
 
from rhodecode.model.db import Repository
 
from rhodecode.model.pull_request import PullRequestModel
 
from webob.exc import HTTPBadRequest
 
from rhodecode.lib.utils2 import str2bool
 
from rhodecode.lib.diffs import LimitedDiffContainer
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class CompareController(BaseRepoController):
 

	
 
    @LoginRequired()
 
    @HasRepoPermissionAnyDecorator('repository.read', 'repository.write',
 
                                   'repository.admin')
 
    def __before__(self):
 
        super(CompareController, self).__before__()
 

	
 
    def __get_cs_or_redirect(self, rev, repo, redirect_after=True,
 
                             partial=False):
 
        """
 
        Safe way to get changeset if error occur it redirects to changeset with
 
        proper message. If partial is set then don't do redirect raise Exception
 
        instead
 

	
 
        :param rev: revision to fetch
 
        :param repo: repo instance
 
        """
 

	
 
        try:
 
            type_, rev = rev
 
            return repo.scm_instance.get_changeset(rev)
 
        except EmptyRepositoryError, e:
 
            if not redirect_after:
 
                return None
 
            h.flash(h.literal(_('There are no changesets yet')),
 
                    category='warning')
 
            redirect(url('summary_home', repo_name=repo.repo_name))
 

	
 
        except RepositoryError, e:
 
            log.error(traceback.format_exc())
 
            h.flash(str(e), category='warning')
 
            if not partial:
 
                redirect(h.url('summary_home', repo_name=repo.repo_name))
 
            raise HTTPBadRequest()
 

	
 
    def index(self, org_ref_type, org_ref, other_ref_type, other_ref):
 

	
 
        org_repo = c.rhodecode_db_repo.repo_name
 
        org_ref = (org_ref_type, org_ref)
 
        other_ref = (other_ref_type, other_ref)
 
        other_repo = request.GET.get('repo', org_repo)
 
        bundle_compare = str2bool(request.GET.get('bundle', True))
 
        c.fulldiff = fulldiff = request.GET.get('fulldiff')
 

	
 
        c.swap_url = h.url('compare_url', repo_name=other_repo,
 
              org_ref_type=other_ref[0], org_ref=other_ref[1],
 
              other_ref_type=org_ref[0], other_ref=org_ref[1],
 
              repo=org_repo, as_form=request.GET.get('as_form'),
 
              bundle=bundle_compare)
 

	
 
        c.org_repo = org_repo = Repository.get_by_repo_name(org_repo)
 
        c.other_repo = other_repo = Repository.get_by_repo_name(other_repo)
 

	
 
        if c.org_repo is None or c.other_repo is None:
 
            log.error('Could not found repo %s or %s' % (org_repo, other_repo))
 
            raise HTTPNotFound
 

	
 
        if c.org_repo != c.other_repo and h.is_git(c.rhodecode_repo):
 
            log.error('compare of two remote repos not available for GIT REPOS')
 
            raise HTTPNotFound
 

	
 
        if c.org_repo.scm_instance.alias != c.other_repo.scm_instance.alias:
 
            log.error('compare of two different kind of remote repos not available')
 
            raise HTTPNotFound
 

	
 
        partial = request.environ.get('HTTP_X_PARTIAL_XHR')
 
        self.__get_cs_or_redirect(rev=org_ref, repo=org_repo, partial=partial)
 
        self.__get_cs_or_redirect(rev=other_ref, repo=other_repo, partial=partial)
 

	
 
        c.cs_ranges, discovery_data = PullRequestModel().get_compare_data(
 
                                    org_repo, org_ref, other_repo, other_ref
 
                                    )
 

	
 
        c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
 
                                                   c.cs_ranges])
 
        c.target_repo = c.repo_name
 
        # defines that we need hidden inputs with changesets
 
        c.as_form = request.GET.get('as_form', False)
 
        if partial:
 
            return render('compare/compare_cs.html')
 

	
 
        if not bundle_compare and c.cs_ranges:
 
            # case we want a simple diff without incoming changesets, just
 
            # for review purposes. Make the diff on the forked repo, with
 
            # revision that is common ancestor
 
            other_ref = ('rev', c.cs_ranges[-1].parents[0].raw_id)
 
            other_repo = org_repo
 

	
 
        c.org_ref = org_ref[1]
 
        c.other_ref = other_ref[1]
 

	
 
        _diff = diffs.differ(other_repo, other_ref, org_repo, org_ref,
 
                             discovery_data, bundle_compare=bundle_compare)
 
        diff_processor = diffs.DiffProcessor(_diff, format='gitdiff')
 
        diff_limit = self.cut_off_limit if not fulldiff else None
 
        diff_processor = diffs.DiffProcessor(_diff, format='gitdiff',
 
                                             diff_limit=diff_limit)
 
        _parsed = diff_processor.prepare()
 

	
 
        c.limited_diff = False
 
        if isinstance(_parsed, LimitedDiffContainer):
 
            c.limited_diff = True
 

	
 
        c.files = []
 
        c.changes = {}
 

	
 
        for f in _parsed:
 
            fid = h.FID('', f['filename'])
 
            c.files.append([fid, f['operation'], f['filename'], f['stats']])
 
            diff = diff_processor.as_html(enable_comments=False, parsed_lines=[f])
 
            c.changes[fid] = [f['operation'], f['filename'], diff]
 

	
 
        return render('compare/compare_diff.html')
rhodecode/templates/compare/compare_cs.html
Show inline comments
 
## Changesets table !
 
<div class="container">
 
  <table class="compare_view_commits noborder">
 
  %if not c.cs_ranges:
 
    <tr><td>${_('No changesets')}</td></tr>
 
  %else:
 
    %for cnt, cs in enumerate(c.cs_ranges):
 
        <tr>
 
        <td><div class="gravatar"><img alt="gravatar" src="${h.gravatar_url(h.email_or_none(cs.author),14)}"/></div></td>
 
        <td>
 
          %if cs.raw_id in c.statuses:
 
            <div title="${c.statuses[cs.raw_id][1]}" class="changeset-status-ico"><img src="${h.url('/images/icons/flag_status_%s.png' % c.statuses[cs.raw_id][0])}" /></div>
 
          %endif
 
        </td>
 
        <td>${h.link_to('r%s:%s' % (cs.revision,h.short_id(cs.raw_id)),h.url('changeset_home',repo_name=c.target_repo,revision=cs.raw_id))}
 
        %if c.as_form:
 
          ${h.hidden('revisions',cs.raw_id)}
 
        %endif
 
        </td>
 
        <td><div class="author">${h.person(cs.author)}</div></td>
 
        <td><span class="tooltip" title="${h.age(cs.date)}">${cs.date}</span></td>
 
        <td><div class="message">${h.urlify_commit(h.wrap_paragraphs(cs.message),c.repo_name)}</div></td>
 
        <td><span class="tooltip" title="${h.tooltip(h.age(cs.date))}">${cs.date}</span></td>
 
        <td><div class="message tooltip" title="${h.tooltip(cs.message)}" style="white-space:normal">${h.urlify_commit(h.shorter(cs.message, 60),c.repo_name)}</div></td>
 
        </tr>
 
    %endfor
 

	
 
  %endif
 
  </table>
 
</div>
rhodecode/templates/compare/compare_diff.html
Show inline comments
 
@@ -2,76 +2,81 @@
 
<%inherit file="/base/base.html"/>
 

	
 
<%def name="title()">
 
    ${c.repo_name} ${_('Compare')} ${'%s@%s' % (c.org_repo.repo_name, c.org_ref)} -> ${'%s@%s' % (c.other_repo.repo_name, c.other_ref)}
 
</%def>
 

	
 
<%def name="breadcrumbs_links()">
 
    ${h.link_to(_(u'Home'),h.url('/'))}
 
    &raquo;
 
    ${h.link_to(c.repo_name,h.url('summary_home',repo_name=c.repo_name))}
 
    &raquo;
 
    ${_('Compare')}
 
</%def>
 

	
 
<%def name="page_nav()">
 
    ${self.menu('changelog')}
 
</%def>
 

	
 
<%def name="main()">
 
<div class="box">
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}
 
    </div>
 
    <div class="table">
 
        <div id="body" class="diffblock">
 
            <div class="code-header cv">
 
                <h3 class="code-header-title">${_('Compare View')}</h3>
 
                <div>
 
                ${'%s@%s' % (c.org_repo.repo_name, c.org_ref)} -> ${'%s@%s' % (c.other_repo.repo_name, c.other_ref)}  <a href="${c.swap_url}">[swap]</a>
 
                </div>
 
            </div>
 
        </div>
 
        <div id="changeset_compare_view_content">
 
            ##CS
 
            <div style="font-size:1.1em;font-weight: bold;clear:both;padding-top:10px">${_('Outgoing changesets')}</div>
 
            <%include file="compare_cs.html" />
 

	
 
            ## FILES
 
            <div style="font-size:1.1em;font-weight: bold;clear:both;padding-top:10px">${_('Files affected')}</div>
 
            <div class="cs_files">
 
              %for fid, change, f, stat in c.files:
 
                  <div class="cs_${change}">
 
                    <div class="node">${h.link_to(h.safe_unicode(f),h.url.current(anchor=fid))}</div>
 
                    <div class="changes">${h.fancy_file_stats(stat)}</div>
 
                  </div>
 
              %endfor
 
            </div>
 
            % if c.limited_diff:
 
              <h5>${_('Changeset was too big and was cut off...')}</h5>
 
            % endif            
 
        </div>
 
    </div>
 

	
 
    ## diff block
 
    <%namespace name="diff_block" file="/changeset/diff_block.html"/>
 
    %for fid, change, f, stat in c.files:
 
      ${diff_block.diff_block_simple([c.changes[fid]])}
 
    %endfor
 

	
 
    % if c.limited_diff:
 
      <h4>${_('Changeset was too big and was cut off...')}</h4>
 
    % endif
 
     <script type="text/javascript">
 

	
 
      YUE.onDOMReady(function(){
 

	
 
          YUE.on(YUQ('.diff-menu-activate'),'click',function(e){
 
              var act = e.currentTarget.nextElementSibling;
 

	
 
              if(YUD.hasClass(act,'active')){
 
                  YUD.removeClass(act,'active');
 
                  YUD.setStyle(act,'display','none');
 
              }else{
 
                  YUD.addClass(act,'active');
 
                  YUD.setStyle(act,'display','');
 
              }
 
          });
 
      })
 
    </script>
 
    </div>
 
</%def>
0 comments (0 inline, 0 general)