Esempio n. 1
0
    def comment(self, repo_name, revision):
        status = request.POST.get('changeset_status')
        change_status = request.POST.get('change_changeset_status')
        text = request.POST.get('text')
        if status and change_status:
            text = text or (_('Status change -> %s')
                            % ChangesetStatus.get_status_lbl(status))

        c.co = comm = ChangesetCommentsModel().create(
            text=text,
            repo=c.rhodecode_db_repo.repo_id,
            user=c.rhodecode_user.user_id,
            revision=revision,
            f_path=request.POST.get('f_path'),
            line_no=request.POST.get('line'),
            status_change=(ChangesetStatus.get_status_lbl(status)
                           if status and change_status else None)
        )

        # get status if set !
        if status and change_status:
            # if latest status was from pull request and it's closed
            # disallow changing status !
            # dont_allow_on_closed_pull_request = True !

            try:
                ChangesetStatusModel().set_status(
                    c.rhodecode_db_repo.repo_id,
                    status,
                    c.rhodecode_user.user_id,
                    comm,
                    revision=revision,
                    dont_allow_on_closed_pull_request=True
                )
            except StatusChangeOnClosedPullRequestError:
                log.error(traceback.format_exc())
                msg = _('Changing status on a changeset associated with '
                        'a closed pull request is not allowed')
                h.flash(msg, category='warning')
                return redirect(h.url('changeset_home', repo_name=repo_name,
                                      revision=revision))
        action_logger(self.rhodecode_user,
                      'user_commented_revision:%s' % revision,
                      c.rhodecode_db_repo, self.ip_addr, self.sa)

        Session().commit()

        if not request.environ.get('HTTP_X_PARTIAL_XHR'):
            return redirect(h.url('changeset_home', repo_name=repo_name,
                                  revision=revision))
        #only ajax below
        data = {
           'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
        }
        if comm:
            data.update(comm.get_dict())
            data.update({'rendered_text':
                         render('changeset/changeset_comment_block.html')})

        return data
Esempio n. 2
0
    def delete_home(self, repo_name, revision, f_path):
        commit_id = revision

        repo = c.rhodecode_db_repo
        if repo.enable_locking and repo.locked[0]:
            h.flash(
                _('This repository has been locked by %s on %s') %
                (h.person_by_id(repo.locked[0]),
                 h.format_date(h.time_to_datetime(repo.locked[1]))), 'warning')
            return redirect(
                h.url('files_home', repo_name=repo_name, revision='tip'))

        if not self._is_valid_head(commit_id, repo.scm_instance()):
            h.flash(_('You can only delete files with revision '
                      'being a valid branch '),
                    category='warning')
            return redirect(
                h.url('files_home',
                      repo_name=repo_name,
                      revision='tip',
                      f_path=f_path))

        c.commit = self.__get_commit_or_redirect(commit_id, repo_name)
        c.file = self.__get_filenode_or_redirect(repo_name, c.commit, f_path)

        c.default_message = _('Deleted file %s via RhodeCode Enterprise') % (
            f_path)
        c.f_path = f_path

        return render('files/files_delete.html')
Esempio n. 3
0
    def create(self, created_by, org_repo, org_ref, other_repo,
               other_ref, revisions, reviewers, title, description=None):

        created_by_user = self._get_user(created_by)
        org_repo = self._get_repo(org_repo)
        other_repo = self._get_repo(other_repo)

        new = PullRequest()
        new.org_repo = org_repo
        new.org_ref = org_ref
        new.other_repo = other_repo
        new.other_ref = other_ref
        new.revisions = revisions
        new.title = title
        new.description = description
        new.author = created_by_user
        self.sa.add(new)
        Session().flush()
        #members
        for member in reviewers:
            _usr = self._get_user(member)
            reviewer = PullRequestReviewers(_usr, new)
            self.sa.add(reviewer)

        #notification to reviewers
        notif = NotificationModel()

        pr_url = h.url('pullrequest_show', repo_name=other_repo.repo_name,
                       pull_request_id=new.pull_request_id,
                       qualified=True,
        )
        subject = safe_unicode(
            h.link_to(
              _('%(user)s wants you to review pull request #%(pr_id)s') % \
                {'user': created_by_user.username,
                 'pr_id': new.pull_request_id},
                pr_url
            )
        )
        body = description
        kwargs = {
            'pr_title': title,
            'pr_user_created': h.person(created_by_user.email),
            'pr_repo_url': h.url('summary_home', repo_name=other_repo.repo_name,
                                 qualified=True,),
            'pr_url': pr_url,
            'pr_revisions': revisions
        }
        notif.create(created_by=created_by_user, subject=subject, body=body,
                     recipients=reviewers,
                     type_=Notification.TYPE_PULL_REQUEST, email_kwargs=kwargs)
        return new
Esempio n. 4
0
    def delete(self, repo_name, revision, f_path):
        commit_id = revision

        repo = c.rhodecode_db_repo
        if repo.enable_locking and repo.locked[0]:
            h.flash(
                _('This repository has been locked by %s on %s') %
                (h.person_by_id(repo.locked[0]),
                 h.format_date(h.time_to_datetime(repo.locked[1]))), 'warning')
            return redirect(
                h.url('files_home', repo_name=repo_name, revision='tip'))

        if not self._is_valid_head(commit_id, repo.scm_instance()):
            h.flash(_('You can only delete files with revision '
                      'being a valid branch '),
                    category='warning')
            return redirect(
                h.url('files_home',
                      repo_name=repo_name,
                      revision='tip',
                      f_path=f_path))

        c.commit = self.__get_commit_or_redirect(commit_id, repo_name)
        c.file = self.__get_filenode_or_redirect(repo_name, c.commit, f_path)

        c.default_message = _('Deleted file %s via RhodeCode Enterprise') % (
            f_path)
        c.f_path = f_path
        node_path = f_path
        author = c.rhodecode_user.full_contact
        message = request.POST.get('message') or c.default_message
        try:
            nodes = {node_path: {'content': ''}}
            self.scm_model.delete_nodes(
                user=c.rhodecode_user.user_id,
                repo=c.rhodecode_db_repo,
                message=message,
                nodes=nodes,
                parent_commit=c.commit,
                author=author,
            )

            h.flash(_('Successfully deleted file %s') % f_path,
                    category='success')
        except Exception:
            msg = _('Error occurred during commit')
            log.exception(msg)
            h.flash(msg, category='error')
        return redirect(
            url('changeset_home', repo_name=c.repo_name, revision='tip'))
Esempio n. 5
0
    def fork_create(self, repo_name):
        self.__load_defaults()
        c.repo_info = Repository.get_by_repo_name(repo_name)
        _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type},
                             repo_groups=c.repo_groups_choices,
                             landing_revs=c.landing_revs_choices)()
        form_result = {}
        try:
            form_result = _form.to_python(dict(request.POST))

            # an approximation that is better than nothing
            if not RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE).ui_active:
                form_result['update_after_clone'] = False

            # create fork is done sometimes async on celery, db transaction
            # management is handled there.
            RepoModel().create_fork(form_result, self.rhodecode_user.user_id)
            fork_url = h.link_to(form_result['repo_name_full'],
                    h.url('summary_home', repo_name=form_result['repo_name_full']))

            h.flash(h.literal(_('Forked repository %s as %s') \
                      % (repo_name, fork_url)),
                    category='success')
        except formencode.Invalid, errors:
            c.new_repo = errors.value['repo_name']

            return htmlfill.render(
                render('forks/fork.html'),
                defaults=errors.value,
                errors=errors.error_dict or {},
                prefix_error=False,
                encoding="UTF-8")
Esempio n. 6
0
def _ignorews_url(GET, fileid=None):
    fileid = str(fileid) if fileid else None
    params = defaultdict(list)
    _update_with_GET(params, GET)
    lbl = _('show white space')
    ig_ws = get_ignore_ws(fileid, GET)
    ln_ctx = get_line_ctx(fileid, GET)
    # global option
    if fileid is None:
        if ig_ws is None:
            params['ignorews'] += [1]
            lbl = _('ignore white space')
        ctx_key = 'context'
        ctx_val = ln_ctx
    # per file options
    else:
        if ig_ws is None:
            params[fileid] += ['WS:1']
            lbl = _('ignore white space')

        ctx_key = fileid
        ctx_val = 'C:%s' % ln_ctx
    # if we have passed in ln_ctx pass it along to our params
    if ln_ctx:
        params[ctx_key] += [ctx_val]

    params['anchor'] = fileid
    img = h.image(h.url('/images/icons/text_strikethrough.png'), lbl, class_='icon')
    return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip')
Esempio n. 7
0
    def fork_create(self, repo_name):
        self.__load_defaults()
        c.repo_info = Repository.get_by_repo_name(repo_name)
        _form = RepoForkForm(old_data={'repo_type': c.repo_info.repo_type},
                             repo_groups=c.repo_groups_choices,
                             landing_revs=c.landing_revs_choices)()
        form_result = {}
        try:
            form_result = _form.to_python(dict(request.POST))

            # an approximation that is better than nothing
            if not RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE).ui_active:
                form_result['update_after_clone'] = False

            # create fork is done sometimes async on celery, db transaction
            # management is handled there.
            RepoModel().create_fork(form_result, self.rhodecode_user.user_id)
            fork_url = h.link_to(
                form_result['repo_name_full'],
                h.url('summary_home', repo_name=form_result['repo_name_full']))

            h.flash(h.literal(_('Forked repository %s as %s') \
                      % (repo_name, fork_url)),
                    category='success')
        except formencode.Invalid, errors:
            c.new_repo = errors.value['repo_name']

            return htmlfill.render(render('forks/fork.html'),
                                   defaults=errors.value,
                                   errors=errors.error_dict or {},
                                   prefix_error=False,
                                   encoding="UTF-8")
Esempio n. 8
0
class ChangelogController(BaseRepoController):
    def __before__(self):
        super(ChangelogController, self).__before__()
        c.affected_files_cut_off = 60

    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:
            return c.rhodecode_repo.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('changelog_home', repo_name=repo.repo_name))

        except RepositoryError, e:
            log.error(traceback.format_exc())
            h.flash(safe_str(e), category='warning')
            if not partial:
                redirect(h.url('changelog_home', repo_name=repo.repo_name))
            raise HTTPBadRequest()
Esempio n. 9
0
    def __get_commit_or_redirect(self,
                                 commit_id,
                                 repo,
                                 redirect_after=True,
                                 partial=False):
        """
        This is a safe way to get a commit. If an error occurs it
        redirects to a commit with a proper message. If partial is set
        then it does not do redirect raise and throws an exception instead.

        :param commit_id: commit to fetch
        :param repo: repo instance
        """
        try:
            return c.rhodecode_repo.get_commit(commit_id)
        except EmptyRepositoryError:
            if not redirect_after:
                return None
            h.flash(h.literal(_('There are no commits yet')),
                    category='warning')
            redirect(url('changelog_home', repo_name=repo.repo_name))
        except RepositoryError as e:
            msg = safe_str(e)
            log.exception(msg)
            h.flash(msg, category='warning')
            if not partial:
                redirect(h.url('changelog_home', repo_name=repo.repo_name))
            raise HTTPBadRequest()
    def test_create_subgroup(self, user_util):
        self.log_user()
        repo_group_name = self.NEW_REPO_GROUP
        parent_group = user_util.create_repo_group()
        parent_group_name = parent_group.group_name

        expected_group_name = '{}/{}'.format(parent_group_name,
                                             repo_group_name)
        expected_group_name_unicode = expected_group_name.decode('utf8')

        try:
            response = self.app.post(
                url('repo_groups'),
                fixture._get_group_create_params(
                    group_name=repo_group_name,
                    group_parent_id=parent_group.group_id,
                    group_description='Test desciption',
                    csrf_token=self.csrf_token))

            assert_session_flash(
                response, u'Created repository group <a href="%s">%s</a>' %
                (h.url('repo_group_home', group_name=expected_group_name),
                 expected_group_name_unicode))
        finally:
            RepoGroupModel().delete(expected_group_name_unicode)
            Session().commit()
Esempio n. 11
0
    def index(self, repo_name, revision=None, f_path=None):
        p = safe_int(request.GET.get('page', 1), 1)
        size = safe_int(request.GET.get('size', 20), 20)
        collection = c.rhodecode_repo
        c.file_history = f_path

        def url_generator(**kw):
            if f_path:
                return url('shortlog_file_home',
                           repo_name=repo_name,
                           revision=revision,
                           f_path=f_path,
                           size=size,
                           **kw)
            return url('shortlog_home', repo_name=repo_name, size=size, **kw)

        if f_path:
            log.debug('generating shortlog for path %s' % f_path)
            # get the history for the file !
            tip_cs = c.rhodecode_repo.get_changeset()
            try:
                collection = tip_cs.get_file_history(f_path)
            except (NodeDoesNotExistError, ChangesetError):
                #this node is not present at tip !
                try:
                    cs = self.__get_cs_or_redirect(revision, repo_name)
                    collection = cs.get_file_history(f_path)
                except RepositoryError, e:
                    h.flash(str(e), category='warning')
                    redirect(h.url('shortlog_home', repo_name=repo_name))
            collection = list(reversed(collection))
Esempio n. 12
0
def _ignorews_url(GET, fileid=None):
    fileid = str(fileid) if fileid else None
    params = defaultdict(list)
    _update_with_GET(params, GET)
    lbl = _('show white space')
    ig_ws = get_ignore_ws(fileid, GET)
    ln_ctx = get_line_ctx(fileid, GET)
    # global option
    if fileid is None:
        if ig_ws is None:
            params['ignorews'] += [1]
            lbl = _('ignore white space')
        ctx_key = 'context'
        ctx_val = ln_ctx
    # per file options
    else:
        if ig_ws is None:
            params[fileid] += ['WS:1']
            lbl = _('ignore white space')

        ctx_key = fileid
        ctx_val = 'C:%s' % ln_ctx
    # if we have passed in ln_ctx pass it along to our params
    if ln_ctx:
        params[ctx_key] += [ctx_val]

    params['anchor'] = fileid
    img = h.image(h.url('/images/icons/text_strikethrough.png'),
                  lbl,
                  class_='icon')
    return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip')
Esempio n. 13
0
    def comment(self, repo_name, revision):
        comm = ChangesetCommentsModel().create(
            text=request.POST.get('text'),
            repo_id=c.rhodecode_db_repo.repo_id,
            user_id=c.rhodecode_user.user_id,
            revision=revision,
            f_path=request.POST.get('f_path'),
            line_no=request.POST.get('line'))
        Session.commit()
        if not request.environ.get('HTTP_X_PARTIAL_XHR'):
            return redirect(
                h.url('changeset_home', repo_name=repo_name,
                      revision=revision))

        data = {
            'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
        }
        if comm:
            c.co = comm
            data.update(comm.get_dict())
            data.update({
                'rendered_text':
                render('changeset/changeset_comment_block.html')
            })

        return data
Esempio n. 14
0
class FilesController(BaseRepoController):
    @LoginRequired()
    def __before__(self):
        super(FilesController, self).__before__()
        c.cut_off_limit = self.cut_off_limit

    def __get_cs_or_redirect(self, rev, repo_name, redirect_after=True):
        """
        Safe way to get changeset if error occur it redirects to tip with
        proper message

        :param rev: revision to fetch
        :param repo_name: repo name to redirect after
        """

        try:
            return c.rhodecode_repo.get_changeset(rev)
        except EmptyRepositoryError, e:
            if not redirect_after:
                return None
            url_ = url('files_add_home',
                       repo_name=c.repo_name,
                       revision=0,
                       f_path='')
            add_new = '<a href="%s">[%s]</a>' % (url_, _('add new'))
            h.flash(h.literal(_('There are no files yet %s' % add_new)),
                    category='warning')
            redirect(h.url('summary_home', repo_name=repo_name))

        except RepositoryError, e:
            h.flash(str(e), category='warning')
            redirect(h.url('files_home', repo_name=repo_name, revision='tip'))
Esempio n. 15
0
    def index(self, repo_name, revision=None, f_path=None):
        p = safe_int(request.params.get('page', 1), 1)
        size = safe_int(request.params.get('size', 20), 20)
        collection = c.rhodecode_repo
        c.file_history = f_path

        def url_generator(**kw):
            if f_path:
                return url('shortlog_file_home', repo_name=repo_name,
                           revision=revision, f_path=f_path, size=size, **kw)
            return url('shortlog_home', repo_name=repo_name, size=size, **kw)

        if f_path:
            log.debug('generating shortlog for path %s' % f_path)
            # get the history for the file !
            tip_cs = c.rhodecode_repo.get_changeset()
            try:
                collection = tip_cs.get_file_history(f_path)
            except (NodeDoesNotExistError, ChangesetError):
                #this node is not present at tip !
                try:
                    cs = self.__get_cs_or_redirect(revision, repo_name)
                    collection = cs.get_file_history(f_path)
                except RepositoryError, e:
                    h.flash(str(e), category='warning')
                    redirect(h.url('shortlog_home', repo_name=repo_name))
            collection = list(reversed(collection))
Esempio n. 16
0
    def _get_commit_or_redirect(self,
                                ref,
                                ref_type,
                                repo,
                                redirect_after=True,
                                partial=False):
        """
        This is a safe way to get a commit. If an error occurs it
        redirects to a commit with a proper message. If partial is set
        then it does not do redirect raise and throws an exception instead.
        """
        try:
            return get_commit_from_ref_name(repo, safe_str(ref), ref_type)
        except EmptyRepositoryError:
            if not redirect_after:
                return repo.scm_instance().EMPTY_COMMIT
            h.flash(h.literal(_('There are no commits yet')),
                    category='warning')
            redirect(url('summary_home', repo_name=repo.repo_name))

        except RepositoryError as e:
            msg = safe_str(e)
            log.exception(msg)
            h.flash(msg, category='warning')
            if not partial:
                redirect(h.url('summary_home', repo_name=repo.repo_name))
            raise HTTPBadRequest()
Esempio n. 17
0
 def _create_files_url(self, repo, name, raw_id, is_svn):
     use_commit_id = '/' in name or is_svn
     return h.url('files_home',
                  repo_name=repo.name,
                  f_path=name if is_svn else '',
                  revision=raw_id if use_commit_id else name,
                  at=name)
Esempio n. 18
0
    def add(self, repo_name, revision, f_path):

        repo = Repository.get_by_repo_name(repo_name)
        if repo.enable_locking and repo.locked[0]:
            h.flash(_('This repository is has been locked by %s on %s')
                % (h.person_by_id(repo.locked[0]),
                   h.fmt_date(h.time_to_datetime(repo.locked[1]))),
                  'warning')
            return redirect(h.url('files_home',
                                  repo_name=repo_name, revision='tip'))

        r_post = request.POST
        c.cs = self.__get_cs_or_redirect(revision, repo_name,
                                         redirect_after=False)
        if c.cs is None:
            c.cs = EmptyChangeset(alias=c.rhodecode_repo.alias)

        c.f_path = f_path

        if r_post:
            unix_mode = 0
            content = convert_line_endings(r_post.get('content'), unix_mode)

            message = r_post.get('message') or (_('Added %s via RhodeCode')
                                                % (f_path))
            location = r_post.get('location')
            filename = r_post.get('filename')
            file_obj = r_post.get('upload_file', None)

            if file_obj is not None and hasattr(file_obj, 'filename'):
                filename = file_obj.filename
                content = file_obj.file

            node_path = os.path.join(location, filename)
            author = self.rhodecode_user.full_contact

            if not content:
                h.flash(_('No content'), category='warning')
                return redirect(url('changeset_home', repo_name=c.repo_name,
                                    revision='tip'))
            if not filename:
                h.flash(_('No filename'), category='warning')
                return redirect(url('changeset_home', repo_name=c.repo_name,
                                    revision='tip'))

            try:
                self.scm_model.create_node(repo=c.rhodecode_repo,
                                           repo_name=repo_name, cs=c.cs,
                                           user=self.rhodecode_user,
                                           author=author, message=message,
                                           content=content, f_path=node_path)
                h.flash(_('Successfully committed to %s') % node_path,
                        category='success')
            except NodeAlreadyExistsError, e:
                h.flash(_(e), category='error')
            except Exception:
                log.error(traceback.format_exc())
                h.flash(_('Error occurred during commit'), category='error')
Esempio n. 19
0
    def index(self, repo_name, revision, f_path, annotate=False):
        # redirect to given revision from form if given
        post_revision = request.POST.get('at_rev', None)
        if post_revision:
            cs = self.__get_cs_or_redirect(post_revision, repo_name)
            redirect(url('files_home', repo_name=c.repo_name,
                         revision=cs.raw_id, f_path=f_path))

        c.changeset = self.__get_cs_or_redirect(revision, repo_name)
        c.branch = request.GET.get('branch', None)
        c.f_path = f_path
        c.annotate = annotate
        cur_rev = c.changeset.revision

        # prev link
        try:
            prev_rev = c.rhodecode_repo.get_changeset(cur_rev).prev(c.branch)
            c.url_prev = url('files_home', repo_name=c.repo_name,
                         revision=prev_rev.raw_id, f_path=f_path)
            if c.branch:
                c.url_prev += '?branch=%s' % c.branch
        except (ChangesetDoesNotExistError, VCSError):
            c.url_prev = '#'

        # next link
        try:
            next_rev = c.rhodecode_repo.get_changeset(cur_rev).next(c.branch)
            c.url_next = url('files_home', repo_name=c.repo_name,
                     revision=next_rev.raw_id, f_path=f_path)
            if c.branch:
                c.url_next += '?branch=%s' % c.branch
        except (ChangesetDoesNotExistError, VCSError):
            c.url_next = '#'

        # files or dirs
        try:
            c.file = c.changeset.get_node(f_path)

            if c.file.is_file():
                c.load_full_history = False
                file_last_cs = c.file.last_changeset
                c.file_changeset = (c.changeset
                                    if c.changeset.revision < file_last_cs.revision
                                    else file_last_cs)
                _hist = []
                c.file_history = []
                if c.load_full_history:
                    c.file_history, _hist = self._get_node_history(c.changeset, f_path)

                c.authors = []
                for a in set([x.author for x in _hist]):
                    c.authors.append((h.email(a), h.person(a)))
            else:
                c.authors = c.file_history = []
        except RepositoryError, e:
            h.flash(str(e), category='warning')
            redirect(h.url('files_home', repo_name=repo_name,
                           revision='tip'))
Esempio n. 20
0
    def comment(self, repo_name, pull_request_id):
        pull_request = PullRequest.get_or_404(pull_request_id)
        if pull_request.is_closed():
            raise HTTPForbidden()

        status = request.POST.get('changeset_status')
        change_status = request.POST.get('change_changeset_status')
        text = request.POST.get('text')
        if status and change_status:
            text = text or (_('Status change -> %s')
                            % ChangesetStatus.get_status_lbl(status))
        comm = ChangesetCommentsModel().create(
            text=text,
            repo=c.rhodecode_db_repo.repo_id,
            user=c.rhodecode_user.user_id,
            pull_request=pull_request_id,
            f_path=request.POST.get('f_path'),
            line_no=request.POST.get('line'),
            status_change=(ChangesetStatus.get_status_lbl(status)
                           if status and change_status else None)
        )

        # get status if set !
        if status and change_status:
            ChangesetStatusModel().set_status(
                c.rhodecode_db_repo.repo_id,
                status,
                c.rhodecode_user.user_id,
                comm,
                pull_request=pull_request_id
            )
        action_logger(self.rhodecode_user,
                      'user_commented_pull_request:%s' % pull_request_id,
                      c.rhodecode_db_repo, self.ip_addr, self.sa)

        if request.POST.get('save_close'):
            PullRequestModel().close_pull_request(pull_request_id)
            action_logger(self.rhodecode_user,
                      'user_closed_pull_request:%s' % pull_request_id,
                      c.rhodecode_db_repo, self.ip_addr, self.sa)

        Session().commit()

        if not request.environ.get('HTTP_X_PARTIAL_XHR'):
            return redirect(h.url('pullrequest_show', repo_name=repo_name,
                                  pull_request_id=pull_request_id))

        data = {
           'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
        }
        if comm:
            c.co = comm
            data.update(comm.get_dict())
            data.update({'rendered_text':
                         render('changeset/changeset_comment_block.html')})

        return data
Esempio n. 21
0
    def edit(self, repo_name, revision, f_path):
        repo = Repository.get_by_repo_name(repo_name)
        if repo.enable_locking and repo.locked[0]:
            h.flash(_('This repository is has been locked by %s on %s')
                % (h.person_by_id(repo.locked[0]),
                   h.fmt_date(h.time_to_datetime(repo.locked[1]))),
                  'warning')
            return redirect(h.url('files_home',
                                  repo_name=repo_name, revision='tip'))

        r_post = request.POST

        c.cs = self.__get_cs_or_redirect(revision, repo_name)
        c.file = self.__get_filenode_or_redirect(repo_name, c.cs, f_path)

        if c.file.is_binary:
            return redirect(url('files_home', repo_name=c.repo_name,
                         revision=c.cs.raw_id, f_path=f_path))

        c.f_path = f_path

        if r_post:

            old_content = c.file.content
            sl = old_content.splitlines(1)
            first_line = sl[0] if sl else ''
            # modes:  0 - Unix, 1 - Mac, 2 - DOS
            mode = detect_mode(first_line, 0)
            content = convert_line_endings(r_post.get('content'), mode)

            message = r_post.get('message') or (_('Edited %s via RhodeCode')
                                                % (f_path))
            author = self.rhodecode_user.full_contact

            if content == old_content:
                h.flash(_('No changes'),
                    category='warning')
                return redirect(url('changeset_home', repo_name=c.repo_name,
                                    revision='tip'))

            try:
                self.scm_model.commit_change(repo=c.rhodecode_repo,
                                             repo_name=repo_name, cs=c.cs,
                                             user=self.rhodecode_user,
                                             author=author, message=message,
                                             content=content, f_path=f_path)
                h.flash(_('Successfully committed to %s') % f_path,
                        category='success')

            except Exception:
                log.error(traceback.format_exc())
                h.flash(_('Error occurred during commit'), category='error')
            return redirect(url('changeset_home',
                                repo_name=c.repo_name, revision='tip'))

        return render('files/files_edit.html')
Esempio n. 22
0
    def _update_kwargs_for_render(self, kwargs):
        """
        Inject params required for Mako rendering

        :param kwargs:
        :return:
        """
        _kwargs = {'instance_url': h.url('home', qualified=True)}
        _kwargs.update(kwargs)
        return _kwargs
Esempio n. 23
0
    def index(self, repo_name, revision, f_path, annotate=False):
        # redirect to given revision from form if given
        post_revision = request.POST.get('at_rev', None)
        if post_revision:
            cs = self.__get_cs_or_redirect(post_revision, repo_name)
            redirect(
                url('files_home',
                    repo_name=c.repo_name,
                    revision=cs.raw_id,
                    f_path=f_path))

        c.changeset = self.__get_cs_or_redirect(revision, repo_name)
        c.branch = request.GET.get('branch', None)
        c.f_path = f_path
        c.annotate = annotate
        cur_rev = c.changeset.revision

        # prev link
        try:
            prev_rev = c.rhodecode_repo.get_changeset(cur_rev).prev(c.branch)
            c.url_prev = url('files_home',
                             repo_name=c.repo_name,
                             revision=prev_rev.raw_id,
                             f_path=f_path)
            if c.branch:
                c.url_prev += '?branch=%s' % c.branch
        except (ChangesetDoesNotExistError, VCSError):
            c.url_prev = '#'

        # next link
        try:
            next_rev = c.rhodecode_repo.get_changeset(cur_rev).next(c.branch)
            c.url_next = url('files_home',
                             repo_name=c.repo_name,
                             revision=next_rev.raw_id,
                             f_path=f_path)
            if c.branch:
                c.url_next += '?branch=%s' % c.branch
        except (ChangesetDoesNotExistError, VCSError):
            c.url_next = '#'

        # files or dirs
        try:
            c.file = c.changeset.get_node(f_path)

            if c.file.is_file():
                c.file_history = self._get_node_history(c.changeset, f_path)
            else:
                c.file_history = []
        except RepositoryError, e:
            h.flash(str(e), category='warning')
            redirect(
                h.url('files_home', repo_name=repo_name, revision=revision))
 def test_urls_contain_commit_id_if_slash_in_name(self):
     references = {
         'name/with/slash': 'commit_id',
     }
     controller = summary.SummaryController()
     is_svn = False
     result = controller._switcher_reference_data(
         'repo_name', references, is_svn)
     expected_url = h.url(
         'files_home', repo_name='repo_name', revision='commit_id',
         at='name/with/slash')
     assert result[0]['files_url'] == expected_url
 def test_creates_reference_urls_based_on_name(self):
     references = {
         'name': 'commit_id',
     }
     controller = summary.SummaryController()
     is_svn = False
     result = controller._switcher_reference_data(
         'repo_name', references, is_svn)
     expected_url = h.url(
         'files_home', repo_name='repo_name', revision='name',
         at='name')
     assert result[0]['files_url'] == expected_url
 def test_adds_reference_to_path_for_svn(self):
     references = {
         'name/with/slash': 'commit_id',
     }
     controller = summary.SummaryController()
     is_svn = True
     result = controller._switcher_reference_data(
         'repo_name', references, is_svn)
     expected_url = h.url(
         'files_home', repo_name='repo_name', f_path='name/with/slash',
         revision='commit_id', at='name/with/slash')
     assert result[0]['files_url'] == expected_url
Esempio n. 27
0
    def __get_cs_or_redirect(self, rev, repo_name, redirect_after=True):
        """
        Safe way to get changeset if error occur it redirects to tip with
        proper message

        :param rev: revision to fetch
        :param repo_name: repo name to redirect after
        """

        try:
            return c.rhodecode_repo.get_changeset(rev)
        except RepositoryError, e:
            h.flash(str(e), category='warning')
            redirect(h.url('shortlog_home', repo_name=repo_name))
Esempio n. 28
0
    def __get_cs_or_redirect(self, rev, repo_name, redirect_after=True):
        """
        Safe way to get changeset if error occur it redirects to tip with
        proper message

        :param rev: revision to fetch
        :param repo_name: repo name to redirect after
        """

        try:
            return c.rhodecode_repo.get_changeset(rev)
        except RepositoryError, e:
            h.flash(str(e), category='warning')
            redirect(h.url('shortlog_home', repo_name=repo_name))
Esempio n. 29
0
    def __get_cs_or_redirect(self, rev, repo_name):
        """
        Safe way to get changeset if error occur it redirects to tip with
        proper message

        :param rev: revision to fetch
        :param repo_name: repo name to redirect after
        """

        try:
            return c.rhodecode_repo.get_changeset(rev)
        except EmptyRepositoryError, e:
            h.flash(_('There are no files yet'), category='warning')
            redirect(h.url('summary_home', repo_name=repo_name))
Esempio n. 30
0
class CompareController(BaseRepoController):
    def __before__(self):
        super(CompareController, self).__before__()

    def __get_rev_or_redirect(self,
                              ref,
                              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
        """

        rev = ref[1]  # default and used for git
        if repo.scm_instance.alias == 'hg':
            # lookup up the exact node id
            _revset_predicates = {
                'branch': 'branch',
                'book': 'bookmark',
                'tag': 'tag',
                'rev': 'id',
            }
            rev_spec = "max(%s(%%s))" % _revset_predicates[ref[0]]
            revs = repo.scm_instance._repo.revs(rev_spec, safe_str(ref[1]))
            if revs:
                rev = revs[-1]
            # else: TODO: just report 'not found'

        try:
            return repo.scm_instance.get_changeset(rev).raw_id
        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(safe_str(e), category='warning')
            if not partial:
                redirect(h.url('summary_home', repo_name=repo.repo_name))
            raise HTTPBadRequest()
Esempio n. 31
0
    def create(self):
        """POST /repo_groups: Create a new item"""
        # url('repo_groups')

        parent_group_id = safe_int(request.POST.get('group_parent_id'))
        can_create = self._can_create_repo_group(parent_group_id)

        self.__load_defaults()
        # permissions for can create group based on parent_id are checked
        # here in the Form
        available_groups = map(lambda k: unicode(k[0]), c.repo_groups)
        repo_group_form = RepoGroupForm(available_groups=available_groups,
                                        can_create_in_root=can_create)()
        try:
            owner = c.rhodecode_user
            form_result = repo_group_form.to_python(dict(request.POST))
            RepoGroupModel().create(
                group_name=form_result['group_name_full'],
                group_description=form_result['group_description'],
                owner=owner.user_id,
                copy_permissions=form_result['group_copy_permissions'])
            Session().commit()
            _new_group_name = form_result['group_name_full']
            repo_group_url = h.link_to(
                _new_group_name,
                h.url('repo_group_home', group_name=_new_group_name))
            h.flash(h.literal(
                _('Created repository group %s') % repo_group_url),
                    category='success')
            # TODO: in futureaction_logger(, '', '', '', self.sa)
        except formencode.Invalid as errors:
            return htmlfill.render(
                render('admin/repo_groups/repo_group_add.html'),
                defaults=errors.value,
                errors=errors.error_dict or {},
                prefix_error=False,
                encoding="UTF-8",
                force_defaults=False)
        except Exception:
            log.exception("Exception during creation of repository group")
            h.flash(
                _('Error occurred during creation of repository group %s') %
                request.POST.get('group_name'),
                category='error')

        # TODO: maybe we should get back to the main view, not the admin one
        return redirect(url('repo_groups', parent_group=parent_group_id))
Esempio n. 32
0
    def index(self, repo_name, revision, f_path):
        # redirect to given revision from form if given
        post_revision = request.POST.get('at_rev', None)
        if post_revision:
            cs = self.__get_cs_or_redirect(post_revision, repo_name)
            redirect(url('files_home', repo_name=c.repo_name,
                         revision=cs.raw_id, f_path=f_path))

        c.changeset = self.__get_cs_or_redirect(revision, repo_name)
        c.branch = request.GET.get('branch', None)
        c.f_path = f_path

        cur_rev = c.changeset.revision

        # prev link
        try:
            prev_rev = c.rhodecode_repo.get_changeset(cur_rev).prev(c.branch)
            c.url_prev = url('files_home', repo_name=c.repo_name,
                         revision=prev_rev.raw_id, f_path=f_path)
            if c.branch:
                c.url_prev += '?branch=%s' % c.branch
        except (ChangesetDoesNotExistError, VCSError):
            c.url_prev = '#'

        # next link
        try:
            next_rev = c.rhodecode_repo.get_changeset(cur_rev).next(c.branch)
            c.url_next = url('files_home', repo_name=c.repo_name,
                     revision=next_rev.raw_id, f_path=f_path)
            if c.branch:
                c.url_next += '?branch=%s' % c.branch
        except (ChangesetDoesNotExistError, VCSError):
            c.url_next = '#'

        # files or dirs
        try:
            c.files_list = c.changeset.get_node(f_path)

            if c.files_list.is_file():
                c.file_history = self._get_node_history(c.changeset, f_path)
            else:
                c.file_history = []
        except RepositoryError, e:
            h.flash(str(e), category='warning')
            redirect(h.url('files_home', repo_name=repo_name,
                           revision=revision))
Esempio n. 33
0
 def _switcher_reference_data(self, repo_name, references, is_svn):
     """Prepare reference data for given `references`"""
     items = []
     for name, commit_id in references.items():
         use_commit_id = '/' in name or is_svn
         items.append({
             'name':
             name,
             'commit_id':
             commit_id,
             'files_url':
             h.url('files_home',
                   repo_name=repo_name,
                   f_path=name if is_svn else '',
                   revision=commit_id if use_commit_id else name,
                   at=name)
         })
     return items
Esempio n. 34
0
    def __get_filenode_or_redirect(self, repo_name, cs, path):
        """
        Returns file_node, if error occurs or given path is directory,
        it'll redirect to top level path

        :param repo_name: repo_name
        :param cs: given changeset
        :param path: path to lookup
        """

        try:
            file_node = cs.get_node(path)
            if file_node.is_dir():
                raise RepositoryError('given path is a directory')
        except RepositoryError, e:
            h.flash(str(e), category='warning')
            redirect(
                h.url('files_home', repo_name=repo_name, revision=cs.raw_id))
Esempio n. 35
0
    def __get_cs_or_redirect(self, rev, repo_name, redirect_after=True):
        """
        Safe way to get changeset if error occur it redirects to tip with
        proper message

        :param rev: revision to fetch
        :param repo_name: repo name to redirect after
        """

        try:
            return c.rhodecode_repo.get_changeset(rev)
        except EmptyRepositoryError, e:
            if not redirect_after:
                return None
            url_ = url("files_add_home", repo_name=c.repo_name, revision=0, f_path="")
            add_new = h.link_to(_("Click here to add new file"), url_)
            h.flash(h.literal(_("There are no files yet %s") % add_new), category="warning")
            redirect(h.url("summary_home", repo_name=repo_name))
Esempio n. 36
0
    def __get_filenode_or_redirect(self, repo_name, cs, path):
        """
        Returns file_node, if error occurs or given path is directory,
        it'll redirect to top level path

        :param repo_name: repo_name
        :param cs: given changeset
        :param path: path to lookup
        """

        try:
            file_node = cs.get_node(path)
            if file_node.is_dir():
                raise RepositoryError('given path is a directory')
        except RepositoryError, e:
            h.flash(str(e), category='warning')
            redirect(h.url('files_home', repo_name=repo_name,
                           revision=cs.raw_id))
Esempio n. 37
0
    def create(self):
        """
        POST /repos: Create a new item"""
        # url('repos')

        self.__load_defaults()
        form_result = {}
        try:
            form_result = RepoForm(repo_groups=c.repo_groups_choices,
                                   landing_revs=c.landing_revs_choices)()\
                            .to_python(dict(request.POST))

            new_repo = RepoModel().create(form_result,
                                          self.rhodecode_user.user_id)
            if form_result['clone_uri']:
                h.flash(_('Created repository %s from %s') \
                    % (form_result['repo_name'], form_result['clone_uri']),
                    category='success')
            else:
                repo_url = h.link_to(
                    form_result['repo_name'],
                    h.url('summary_home',
                          repo_name=form_result['repo_name_full']))
                h.flash(h.literal(_('Created repository %s') % repo_url),
                        category='success')

            if request.POST.get('user_created'):
                # created by regular non admin user
                action_logger(self.rhodecode_user, 'user_created_repo',
                              form_result['repo_name_full'], self.ip_addr,
                              self.sa)
            else:
                action_logger(self.rhodecode_user, 'admin_created_repo',
                              form_result['repo_name_full'], self.ip_addr,
                              self.sa)
            Session().commit()
        except formencode.Invalid, errors:
            return htmlfill.render(render('admin/repos/repo_add.html'),
                                   defaults=errors.value,
                                   errors=errors.error_dict or {},
                                   prefix_error=False,
                                   encoding="UTF-8")
    def test_create(self):
        self.log_user()
        repo_group_name = self.NEW_REPO_GROUP
        repo_group_name_unicode = repo_group_name.decode('utf8')
        description = 'description for newly created repo group'

        response = self.app.post(
            url('repo_groups'),
            fixture._get_group_create_params(group_name=repo_group_name,
                                             group_description=description,
                                             csrf_token=self.csrf_token))

        # run the check page that triggers the flash message
        # response = self.app.get(url('repo_check_home', repo_name=repo_name))
        # assert response.json == {u'result': True}
        assert_session_flash(
            response, u'Created repository group <a href="%s">%s</a>' %
            (h.url('repo_group_home',
                   group_name=repo_group_name), repo_group_name_unicode))

        # # test if the repo group was created in the database
        new_repo_group = RepoGroupModel()._get_repo_group(
            repo_group_name_unicode)
        assert new_repo_group is not None

        assert new_repo_group.group_name == repo_group_name_unicode
        assert new_repo_group.group_description == description

        #
        # # test if the repository is visible in the list ?
        response = self.app.get(
            url('repo_group_home', group_name=repo_group_name))
        response.mustcontain(repo_group_name)

        # test if the repository group was created on filesystem
        is_on_filesystem = os.path.isdir(
            os.path.join(TESTS_TMP_PATH, repo_group_name))
        if not is_on_filesystem:
            self.fail('no repo group %s in filesystem' % repo_group_name)

        RepoGroupModel().delete(repo_group_name_unicode)
        Session().commit()
Esempio n. 39
0
    def add_home(self, repo_name, revision, f_path):

        repo = Repository.get_by_repo_name(repo_name)
        if repo.enable_locking and repo.locked[0]:
            h.flash(
                _('This repository has been locked by %s on %s') %
                (h.person_by_id(repo.locked[0]),
                 h.format_date(h.time_to_datetime(repo.locked[1]))), 'warning')
            return redirect(
                h.url('files_home', repo_name=repo_name, revision='tip'))

        c.commit = self.__get_commit_or_redirect(revision,
                                                 repo_name,
                                                 redirect_after=False)
        if c.commit is None:
            c.commit = EmptyCommit(alias=c.rhodecode_repo.alias)
        c.default_message = (_('Added file via RhodeCode Enterprise'))
        c.f_path = f_path

        return render('files/files_add.html')
Esempio n. 40
0
    def create(self):
        """
        POST /repos: Create a new item"""
        # url('repos')

        self.__load_defaults()
        form_result = {}
        try:
            form_result = RepoForm(repo_groups=c.repo_groups_choices,
                                   landing_revs=c.landing_revs_choices)()\
                            .to_python(dict(request.POST))

            new_repo = RepoModel().create(form_result,
                                          self.rhodecode_user.user_id)
            if form_result['clone_uri']:
                h.flash(_('Created repository %s from %s') \
                    % (form_result['repo_name'], form_result['clone_uri']),
                    category='success')
            else:
                repo_url = h.link_to(form_result['repo_name'],
                    h.url('summary_home', repo_name=form_result['repo_name_full']))
                h.flash(h.literal(_('Created repository %s') % repo_url),
                        category='success')

            if request.POST.get('user_created'):
                # created by regular non admin user
                action_logger(self.rhodecode_user, 'user_created_repo',
                              form_result['repo_name_full'], self.ip_addr,
                              self.sa)
            else:
                action_logger(self.rhodecode_user, 'admin_created_repo',
                              form_result['repo_name_full'], self.ip_addr,
                              self.sa)
            Session().commit()
        except formencode.Invalid, errors:
            return htmlfill.render(
                render('admin/repos/repo_add.html'),
                defaults=errors.value,
                errors=errors.error_dict or {},
                prefix_error=False,
                encoding="UTF-8")
Esempio n. 41
0
    def index(self, repo_name, revision=None, f_path=None):
        limit = 100
        default = 20
        if request.GET.get('size'):
            c.size = max(min(safe_int(request.GET.get('size')), limit), 1)
            session['changelog_size'] = c.size
            session.save()
        else:
            c.size = int(session.get('changelog_size', default))
        # min size must be 1
        c.size = max(c.size, 1)
        p = safe_int(request.GET.get('page', 1), 1)
        branch_name = request.GET.get('branch', None)
        if (branch_name and branch_name not in c.rhodecode_repo.branches
                and branch_name not in c.rhodecode_repo.closed_branches
                and not revision):
            return redirect(
                url('changelog_file_home',
                    repo_name=c.repo_name,
                    revision=branch_name,
                    f_path=f_path or ''))

        c.changelog_for_path = f_path
        try:

            if f_path:
                log.debug('generating changelog for path %s' % f_path)
                # get the history for the file !
                tip_cs = c.rhodecode_repo.get_changeset()
                try:
                    collection = tip_cs.get_file_history(f_path)
                except (NodeDoesNotExistError, ChangesetError):
                    #this node is not present at tip !
                    try:
                        cs = self.__get_cs_or_redirect(revision, repo_name)
                        collection = cs.get_file_history(f_path)
                    except RepositoryError, e:
                        h.flash(safe_str(e), category='warning')
                        redirect(h.url('changelog_home', repo_name=repo_name))
                collection = list(reversed(collection))
            else:
Esempio n. 42
0
    def index(self):
        _render = PartialRenderer(self.partials_template)
        _data = []
        pre_load = ["author", "date", "message"]
        repo = c.rhodecode_repo
        is_svn = h.is_svn(repo)
        format_ref_id = utils.get_format_ref_id(repo)

        for ref_name, commit_id in self._get_reference_items(repo):
            commit = repo.get_commit(commit_id=commit_id, pre_load=pre_load)

            # TODO: johbo: Unify generation of reference links
            use_commit_id = '/' in ref_name or is_svn
            files_url = h.url(
                'files_home',
                repo_name=c.repo_name,
                f_path=ref_name if is_svn else '',
                revision=commit_id if use_commit_id else ref_name,
                at=ref_name)

            _data.append({
                "name":
                _render('name', ref_name, files_url),
                "name_raw":
                ref_name,
                "date":
                _render('date', commit.date),
                "date_raw":
                datetime_to_time(commit.date),
                "author":
                _render('author', commit.author),
                "commit":
                _render('commit', commit.message, commit.raw_id, commit.idx),
                "commit_raw":
                commit.idx,
                "compare":
                _render('compare', format_ref_id(ref_name, commit.raw_id)),
            })
        c.has_references = bool(_data)
        c.data = json.dumps(_data)
        return render(self.template)
Esempio n. 43
0
    def __get_cs_or_redirect(self, rev, repo_name, redirect_after=True):
        """
        Safe way to get changeset if error occur it redirects to tip with
        proper message

        :param rev: revision to fetch
        :param repo_name: repo name to redirect after
        """

        try:
            return c.rhodecode_repo.get_changeset(rev)
        except EmptyRepositoryError, e:
            if not redirect_after:
                return None
            url_ = url('files_add_home',
                       repo_name=c.repo_name,
                       revision=0, f_path='')
            add_new = h.link_to(_('Click here to add new file'), url_)
            h.flash(h.literal(_('There are no files yet %s') % add_new),
                    category='warning')
            redirect(h.url('summary_home', repo_name=repo_name))
Esempio n. 44
0
    def __get_cs_or_redirect(self, rev, repo_name, redirect_after=True):
        """
        Safe way to get changeset if error occur it redirects to tip with
        proper message

        :param rev: revision to fetch
        :param repo_name: repo name to redirect after
        """

        try:
            return c.rhodecode_repo.get_changeset(rev)
        except EmptyRepositoryError, e:
            if not redirect_after:
                return None
            url_ = url('files_add_home',
                       repo_name=c.repo_name,
                       revision=0, f_path='')
            add_new = '<a href="%s">[%s]</a>' % (url_, _('click here to add new file'))
            h.flash(h.literal(_('There are no files yet %s') % add_new),
                    category='warning')
            redirect(h.url('summary_home', repo_name=repo_name))
Esempio n. 45
0
    def create(self):
        """
        POST /repos: Create a new item"""
        # url('repos')

        self.__load_defaults()
        form_result = {}
        task_id = None
        try:
            # CanWriteToGroup validators checks permissions of this POST
            form_result = RepoForm(repo_groups=c.repo_groups_choices,
                                   landing_revs=c.landing_revs_choices)()\
                            .to_python(dict(request.POST))

            # create is done sometimes async on celery, db transaction
            # management is handled there.
            task = RepoModel().create(form_result, c.rhodecode_user.user_id)
            from celery.result import BaseAsyncResult
            if isinstance(task, BaseAsyncResult):
                task_id = task.task_id
        except formencode.Invalid as errors:
            c.personal_repo_group = RepoGroup.get_by_group_name(
                c.rhodecode_user.username)
            return htmlfill.render(render('admin/repos/repo_add.html'),
                                   defaults=errors.value,
                                   errors=errors.error_dict or {},
                                   prefix_error=False,
                                   encoding="UTF-8",
                                   force_defaults=False)

        except Exception as e:
            msg = self._log_creation_exception(e, form_result.get('repo_name'))
            h.flash(msg, category='error')
            return redirect(url('home'))

        return redirect(
            h.url('repo_creating_home',
                  repo_name=form_result['repo_name_full'],
                  task_id=task_id))
Esempio n. 46
0
    def index(self, repo_name, revision=None, f_path=None):
        limit = 100
        default = 20
        if request.GET.get('size'):
            c.size = max(min(safe_int(request.GET.get('size')), limit), 1)
            session['changelog_size'] = c.size
            session.save()
        else:
            c.size = int(session.get('changelog_size', default))
        # min size must be 1
        c.size = max(c.size, 1)
        p = safe_int(request.GET.get('page', 1), 1)
        branch_name = request.GET.get('branch', None)
        if (branch_name and
            branch_name not in c.rhodecode_repo.branches and
            branch_name not in c.rhodecode_repo.closed_branches and
            not revision):
            return redirect(url('changelog_file_home', repo_name=c.repo_name,
                                    revision=branch_name, f_path=f_path or ''))

        c.changelog_for_path = f_path
        try:

            if f_path:
                log.debug('generating changelog for path %s' % f_path)
                # get the history for the file !
                tip_cs = c.rhodecode_repo.get_changeset()
                try:
                    collection = tip_cs.get_file_history(f_path)
                except (NodeDoesNotExistError, ChangesetError):
                    #this node is not present at tip !
                    try:
                        cs = self.__get_cs_or_redirect(revision, repo_name)
                        collection = cs.get_file_history(f_path)
                    except RepositoryError, e:
                        h.flash(safe_str(e), category='warning')
                        redirect(h.url('changelog_home', repo_name=repo_name))
                collection = list(reversed(collection))
            else:
Esempio n. 47
0
def _context_url(GET, fileid=None):
    """
    Generates url for context lines

    :param fileid:
    """

    fileid = str(fileid) if fileid else None
    ig_ws = get_ignore_ws(fileid, GET)
    ln_ctx = (get_line_ctx(fileid, GET) or 3) * 2

    params = defaultdict(list)
    _update_with_GET(params, GET)

    # global option
    if fileid is None:
        if ln_ctx > 0:
            params['context'] += [ln_ctx]

        if ig_ws:
            ig_ws_key = 'ignorews'
            ig_ws_val = 1

    # per file option
    else:
        params[fileid] += ['C:%s' % ln_ctx]
        ig_ws_key = fileid
        ig_ws_val = 'WS:%s' % 1

    if ig_ws:
        params[ig_ws_key] += [ig_ws_val]

    lbl = _('%s line context') % ln_ctx

    params['anchor'] = fileid
    img = h.image(h.url('/images/icons/table_add.png'), lbl, class_='icon')
    return h.link_to(img, h.url.current(**params), title=lbl, class_='tooltip')
Esempio n. 48
0
    def comment(self, repo_name, revision):
        comm = ChangesetCommentsModel().create(
            text=request.POST.get('text'),
            repo_id=c.rhodecode_db_repo.repo_id,
            user_id=c.rhodecode_user.user_id,
            revision=revision,
            f_path=request.POST.get('f_path'),
            line_no=request.POST.get('line')
        )
        Session.commit()
        if not request.environ.get('HTTP_X_PARTIAL_XHR'):
            return redirect(h.url('changeset_home', repo_name=repo_name,
                                  revision=revision))

        data = {
           'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
        }
        if comm:
            c.co = comm
            data.update(comm.get_dict())
            data.update({'rendered_text':
                         render('changeset/changeset_comment_block.html')})

        return data
Esempio n. 49
0
    def edit(self, repo_name, revision, f_path):
        repo = c.rhodecode_db_repo
        if repo.enable_locking and repo.locked[0]:
            h.flash(_('This repository is has been locked by %s on %s')
                % (h.person_by_id(repo.locked[0]),
                   h.fmt_date(h.time_to_datetime(repo.locked[1]))),
                'warning')
            return redirect(h.url('files_home',
                                  repo_name=repo_name, revision='tip'))

        # check if revision is a branch identifier- basically we cannot
        # create multiple heads via file editing
        _branches = repo.scm_instance.branches
        # check if revision is a branch name or branch hash
        if revision not in _branches.keys() + _branches.values():
            h.flash(_('You can only edit files with revision '
                      'being a valid branch '), category='warning')
            return redirect(h.url('files_home',
                                  repo_name=repo_name, revision='tip',
                                  f_path=f_path))

        r_post = request.POST

        c.cs = self.__get_cs_or_redirect(revision, repo_name)
        c.file = self.__get_filenode_or_redirect(repo_name, c.cs, f_path)

        if c.file.is_binary:
            return redirect(url('files_home', repo_name=c.repo_name,
                            revision=c.cs.raw_id, f_path=f_path))
        c.default_message = _('Edited file %s via RhodeCode') % (f_path)
        c.f_path = f_path

        if r_post:

            old_content = c.file.content
            sl = old_content.splitlines(1)
            first_line = sl[0] if sl else ''
            # modes:  0 - Unix, 1 - Mac, 2 - DOS
            mode = detect_mode(first_line, 0)
            content = convert_line_endings(r_post.get('content', ''), mode)

            message = r_post.get('message') or c.default_message
            author = self.rhodecode_user.full_contact

            if content == old_content:
                h.flash(_('No changes'), category='warning')
                return redirect(url('changeset_home', repo_name=c.repo_name,
                                    revision='tip'))
            try:
                self.scm_model.commit_change(repo=c.rhodecode_repo,
                                             repo_name=repo_name, cs=c.cs,
                                             user=self.rhodecode_user.user_id,
                                             author=author, message=message,
                                             content=content, f_path=f_path)
                h.flash(_('Successfully committed to %s') % f_path,
                        category='success')
            except Exception:
                log.error(traceback.format_exc())
                h.flash(_('Error occurred during commit'), category='error')
            return redirect(url('changeset_home',
                                repo_name=c.repo_name, revision='tip'))

        return render('files/files_edit.html')
Esempio n. 50
0
    def create(self, created_by, org_repo, org_ref, other_repo, other_ref,
               revisions, reviewers, title, description=None):
        from rhodecode.model.changeset_status import ChangesetStatusModel

        created_by_user = self._get_user(created_by)
        org_repo = self._get_repo(org_repo)
        other_repo = self._get_repo(other_repo)

        new = PullRequest()
        new.org_repo = org_repo
        new.org_ref = org_ref
        new.other_repo = other_repo
        new.other_ref = other_ref
        new.revisions = revisions
        new.title = title
        new.description = description
        new.author = created_by_user
        Session().add(new)
        Session().flush()
        #members
        for member in set(reviewers):
            _usr = self._get_user(member)
            reviewer = PullRequestReviewers(_usr, new)
            Session().add(reviewer)

        #reset state to under-review
        ChangesetStatusModel().set_status(
            repo=org_repo,
            status=ChangesetStatus.STATUS_UNDER_REVIEW,
            user=created_by_user,
            pull_request=new
        )
        revision_data = [(x.raw_id, x.message)
                         for x in map(org_repo.get_changeset, revisions)]
        #notification to reviewers
        pr_url = h.url('pullrequest_show', repo_name=other_repo.repo_name,
                       pull_request_id=new.pull_request_id,
                       qualified=True,
        )
        subject = safe_unicode(
            h.link_to(
              _('%(user)s wants you to review pull request #%(pr_id)s: %(pr_title)s') % \
                {'user': created_by_user.username,
                 'pr_title': new.title,
                 'pr_id': new.pull_request_id},
                pr_url
            )
        )
        body = description
        kwargs = {
            'pr_title': title,
            'pr_user_created': h.person(created_by_user.email),
            'pr_repo_url': h.url('summary_home', repo_name=other_repo.repo_name,
                                 qualified=True,),
            'pr_url': pr_url,
            'pr_revisions': revision_data
        }

        NotificationModel().create(created_by=created_by_user, subject=subject, body=body,
                                   recipients=reviewers,
                                   type_=Notification.TYPE_PULL_REQUEST, email_kwargs=kwargs)
        return new
Esempio n. 51
0
    def add(self, repo_name, revision, f_path):

        repo = Repository.get_by_repo_name(repo_name)
        if repo.enable_locking and repo.locked[0]:
            h.flash(_('This repository is has been locked by %s on %s')
                % (h.person_by_id(repo.locked[0]),
                   h.fmt_date(h.time_to_datetime(repo.locked[1]))),
                  'warning')
            return redirect(h.url('files_home',
                                  repo_name=repo_name, revision='tip'))

        r_post = request.POST
        c.cs = self.__get_cs_or_redirect(revision, repo_name,
                                         redirect_after=False)
        if c.cs is None:
            c.cs = EmptyChangeset(alias=c.rhodecode_repo.alias)
        c.default_message = (_('Added file via RhodeCode'))
        c.f_path = f_path

        if r_post:
            unix_mode = 0
            content = convert_line_endings(r_post.get('content', ''), unix_mode)

            message = r_post.get('message') or c.default_message
            filename = r_post.get('filename')
            location = r_post.get('location', '')
            file_obj = r_post.get('upload_file', None)

            if file_obj is not None and hasattr(file_obj, 'filename'):
                filename = file_obj.filename
                content = file_obj.file

                if hasattr(content, 'file'):
                    # non posix systems store real file under file attr
                    content = content.file

            if not content:
                h.flash(_('No content'), category='warning')
                return redirect(url('changeset_home', repo_name=c.repo_name,
                                    revision='tip'))
            if not filename:
                h.flash(_('No filename'), category='warning')
                return redirect(url('changeset_home', repo_name=c.repo_name,
                                    revision='tip'))
            #strip all crap out of file, just leave the basename
            filename = os.path.basename(filename)
            node_path = os.path.join(location, filename)
            author = self.rhodecode_user.full_contact

            try:
                nodes = {
                    node_path: {
                        'content': content
                    }
                }
                self.scm_model.create_nodes(
                    user=c.rhodecode_user.user_id, repo=c.rhodecode_db_repo,
                    message=message,
                    nodes=nodes,
                    parent_cs=c.cs,
                    author=author,
                )

                h.flash(_('Successfully committed to %s') % node_path,
                        category='success')
            except NonRelativePathError, e:
                h.flash(_('Location must be relative path and must not '
                          'contain .. in path'), category='warning')
                return redirect(url('changeset_home', repo_name=c.repo_name,
                                    revision='tip'))
            except (NodeError, NodeAlreadyExistsError), e:
                h.flash(_(e), category='error')
Esempio n. 52
0
    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.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.scm_instance.alias != 'hg':
            log.error('Review not available for GIT REPOS')
            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')
        _parsed = diff_processor.prepare()

        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, diff_lines=[f])
            c.changes[fid] = [f['operation'], f['filename'], diff]

        return render('compare/compare_diff.html')
Esempio n. 53
0
            form_result = _form.to_python(dict(request.POST))

            # an approximation that is better than nothing
            if not RhodeCodeUi.get_by_key(RhodeCodeUi.HOOK_UPDATE).ui_active:
                form_result['update_after_clone'] = False

            # create fork is done sometimes async on celery, db transaction
            # management is handled there.
            RepoModel().create_fork(form_result, self.rhodecode_user.user_id)
            fork_url = h.link_to(form_result['repo_name_full'],
                    h.url('summary_home', repo_name=form_result['repo_name_full']))

            h.flash(h.literal(_('Forked repository %s as %s') \
                      % (repo_name, fork_url)),
                    category='success')
        except formencode.Invalid, errors:
            c.new_repo = errors.value['repo_name']

            return htmlfill.render(
                render('forks/fork.html'),
                defaults=errors.value,
                errors=errors.error_dict or {},
                prefix_error=False,
                encoding="UTF-8")
        except Exception:
            log.error(traceback.format_exc())
            h.flash(_('An error occurred during repository forking %s') %
                    repo_name, category='error')

        return redirect(h.url('summary_home', repo_name=repo_name))
Esempio n. 54
0
    def add(self, repo_name, revision, f_path):

        repo = Repository.get_by_repo_name(repo_name)
        if repo.enable_locking and repo.locked[0]:
            h.flash(
                _("This repository is has been locked by %s on %s")
                % (h.person_by_id(repo.locked[0]), h.fmt_date(h.time_to_datetime(repo.locked[1]))),
                "warning",
            )
            return redirect(h.url("files_home", repo_name=repo_name, revision="tip"))

        r_post = request.POST
        c.cs = self.__get_cs_or_redirect(revision, repo_name, redirect_after=False)
        if c.cs is None:
            c.cs = EmptyChangeset(alias=c.rhodecode_repo.alias)
        c.default_message = _("Added file via RhodeCode")
        c.f_path = f_path

        if r_post:
            unix_mode = 0
            content = convert_line_endings(r_post.get("content"), unix_mode)

            message = r_post.get("message") or c.default_message
            filename = r_post.get("filename")
            location = r_post.get("location")
            file_obj = r_post.get("upload_file", None)

            if file_obj is not None and hasattr(file_obj, "filename"):
                filename = file_obj.filename
                content = file_obj.file

            if not content:
                h.flash(_("No content"), category="warning")
                return redirect(url("changeset_home", repo_name=c.repo_name, revision="tip"))
            if not filename:
                h.flash(_("No filename"), category="warning")
                return redirect(url("changeset_home", repo_name=c.repo_name, revision="tip"))
            if location.startswith("/") or location.startswith(".") or "../" in location:
                h.flash(_("Location must be relative path and must not " "contain .. in path"), category="warning")
                return redirect(url("changeset_home", repo_name=c.repo_name, revision="tip"))
            if location:
                location = os.path.normpath(location)
            filename = os.path.basename(filename)
            node_path = os.path.join(location, filename)
            author = self.rhodecode_user.full_contact

            try:
                self.scm_model.create_node(
                    repo=c.rhodecode_repo,
                    repo_name=repo_name,
                    cs=c.cs,
                    user=self.rhodecode_user.user_id,
                    author=author,
                    message=message,
                    content=content,
                    f_path=node_path,
                )
                h.flash(_("Successfully committed to %s") % node_path, category="success")
            except (NodeError, NodeAlreadyExistsError), e:
                h.flash(_(e), category="error")
            except Exception:
                log.error(traceback.format_exc())
                h.flash(_("Error occurred during commit"), category="error")
Esempio n. 55
0
    def index(self, org_ref_type, org_ref, other_ref_type, other_ref):
        # org_ref will be evaluated in org_repo
        org_repo = c.rhodecode_db_repo.repo_name
        org_ref = (org_ref_type, org_ref)
        # other_ref will be evaluated in other_repo
        other_ref = (other_ref_type, other_ref)
        other_repo = request.GET.get('other_repo', org_repo)
        # If merge is True:
        #   Show what org would get if merged with other:
        #   List changesets that are ancestors of other but not of org.
        #   New changesets in org is thus ignored.
        #   Diff will be from common ancestor, and merges of org to other will thus be ignored.
        # If merge is False:
        #   Make a raw diff from org to other, no matter if related or not.
        #   Changesets in one and not in the other will be ignored
        merge = bool(request.GET.get('merge'))
        # fulldiff disables cut_off_limit
        c.fulldiff = request.GET.get('fulldiff')
        # partial uses compare_cs.html template directly
        partial = request.environ.get('HTTP_X_PARTIAL_XHR')
        # as_form puts hidden input field with changeset revisions
        c.as_form = partial and request.GET.get('as_form')
        # swap url for compare_diff page - never partial and never as_form
        c.swap_url = h.url('compare_url',
            repo_name=other_repo,
            org_ref_type=other_ref[0], org_ref=other_ref[1],
            other_repo=org_repo,
            other_ref_type=org_ref[0], other_ref=org_ref[1],
            merge=merge or '')

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

        if org_repo is None:
            log.error('Could not find org repo %s' % org_repo)
            raise HTTPNotFound
        if other_repo is None:
            log.error('Could not find other repo %s' % other_repo)
            raise HTTPNotFound

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

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

        org_rev = self.__get_rev_or_redirect(ref=org_ref, repo=org_repo, partial=partial)
        other_rev = self.__get_rev_or_redirect(ref=other_ref, repo=other_repo, partial=partial)

        c.org_repo = org_repo
        c.other_repo = other_repo
        c.org_ref = org_ref[1]
        c.other_ref = other_ref[1]
        c.org_ref_type = org_ref[0]
        c.other_ref_type = other_ref[0]

        c.cs_ranges, c.ancestor = self._get_changesets(org_repo.scm_instance.alias,
                                                       org_repo.scm_instance, org_rev,
                                                       other_repo.scm_instance, other_rev,
                                                       merge)

        c.statuses = c.rhodecode_db_repo.statuses([x.raw_id for x in
                                                   c.cs_ranges])
        if merge and not c.ancestor:
            log.error('Unable to find ancestor revision')

        if partial:
            return render('compare/compare_cs.html')

        if c.ancestor:
            assert merge
            # case we want a simple diff without incoming changesets,
            # previewing what will be merged.
            # Make the diff on the other repo (which is known to have other_ref)
            log.debug('Using ancestor %s as org_ref instead of %s'
                      % (c.ancestor, org_ref))
            org_rev = c.ancestor
            org_repo = other_repo

        diff_limit = self.cut_off_limit if not c.fulldiff else None

        log.debug('running diff between %s and %s in %s'
                  % (org_rev, other_rev, org_repo.scm_instance.path))
        txtdiff = org_repo.scm_instance.get_diff(rev1=org_rev, rev2=other_rev)

        diff_processor = diffs.DiffProcessor(txtdiff or '', 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 = {}
        c.lines_added = 0
        c.lines_deleted = 0
        for f in _parsed:
            st = f['stats']
            if not st['binary']:
                c.lines_added += st['added']
                c.lines_deleted += st['deleted']
            fid = h.FID('', f['filename'])
            c.files.append([fid, f['operation'], f['filename'], f['stats']])
            htmldiff = diff_processor.as_html(enable_comments=False, parsed_lines=[f])
            c.changes[fid] = [f['operation'], f['filename'], htmldiff]

        return render('compare/compare_diff.html')
Esempio n. 56
0
    def _get_notification_data(self, repo, comment, user, comment_text,
                               line_no=None, revision=None, pull_request=None,
                               status_change=None, closing_pr=False):
        """
        Get notification data

        :param comment_text:
        :param line:
        :returns: tuple (subj,body,recipients,notification_type,email_kwargs)
        """
        # make notification
        body = comment_text  # text of the comment
        line = ''
        if line_no:
            line = _('on line %s') % line_no

        #changeset
        if revision:
            notification_type = Notification.TYPE_CHANGESET_COMMENT
            cs = repo.scm_instance.get_changeset(revision)
            desc = "%s" % (cs.short_id)

            _url = h.url('changeset_home',
                repo_name=repo.repo_name,
                revision=revision,
                anchor='comment-%s' % comment.comment_id,
                qualified=True,
            )
            subj = safe_unicode(
                h.link_to('Re changeset: %(desc)s %(line)s' % \
                          {'desc': desc, 'line': line},
                          _url)
            )
            email_subject = '%s commented on changeset %s' % \
                (user.username, h.short_id(revision))
            # get the current participants of this changeset
            recipients = ChangesetComment.get_users(revision=revision)
            # add changeset author if it's in rhodecode system
            cs_author = User.get_from_cs_author(cs.author)
            if not cs_author:
                #use repo owner if we cannot extract the author correctly
                cs_author = repo.user
            recipients += [cs_author]
            email_kwargs = {
                'status_change': status_change,
                'cs_comment_user': h.person(user.email),
                'cs_target_repo': h.url('summary_home', repo_name=repo.repo_name,
                                        qualified=True),
                'cs_comment_url': _url,
                'raw_id': revision,
                'message': cs.message
            }
        #pull request
        elif pull_request:
            notification_type = Notification.TYPE_PULL_REQUEST_COMMENT
            desc = comment.pull_request.title
            _url = h.url('pullrequest_show',
                repo_name=pull_request.other_repo.repo_name,
                pull_request_id=pull_request.pull_request_id,
                anchor='comment-%s' % comment.comment_id,
                qualified=True,
            )
            subj = safe_unicode(
                h.link_to('Re pull request #%(pr_id)s: %(desc)s %(line)s' % \
                          {'desc': desc,
                           'pr_id': comment.pull_request.pull_request_id,
                           'line': line},
                          _url)
            )
            email_subject = '%s commented on pull request #%s' % \
                    (user.username, comment.pull_request.pull_request_id)
            # get the current participants of this pull request
            recipients = ChangesetComment.get_users(pull_request_id=
                                                pull_request.pull_request_id)
            # add pull request author
            recipients += [pull_request.author]

            # add the reviewers to notification
            recipients += [x.user for x in pull_request.reviewers]

            #set some variables for email notification
            email_kwargs = {
                'pr_title': pull_request.title,
                'pr_id': pull_request.pull_request_id,
                'status_change': status_change,
                'closing_pr': closing_pr,
                'pr_comment_url': _url,
                'pr_comment_user': h.person(user.email),
                'pr_target_repo': h.url('summary_home',
                                   repo_name=pull_request.other_repo.repo_name,
                                   qualified=True)
            }

        return subj, body, recipients, notification_type, email_kwargs, email_subject
Esempio n. 57
0
    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)
        incoming_changesets = str2bool(request.GET.get('bundle', False))
        c.fulldiff = fulldiff = request.GET.get('fulldiff')
        rev_start = request.GET.get('rev_start')
        rev_end = request.GET.get('rev_end')

        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=incoming_changesets)

        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)

        if rev_start and rev_end:
            #replace our org_ref with given CS
            org_ref = ('rev', rev_start)
            other_ref = ('rev', rev_end)

        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')

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

        if not incoming_changesets and c.cs_ranges and c.org_repo != c.other_repo:
            # 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
            _org_ref = org_ref
            org_ref = ('rev', getattr(c.cs_ranges[0].parents[0]
                                      if c.cs_ranges[0].parents
                                      else EmptyChangeset(), 'raw_id'))
            log.debug('Changed org_ref from %s to %s' % (_org_ref, org_ref))
            other_repo = org_repo

        diff_limit = self.cut_off_limit if not fulldiff else None

        _diff = diffs.differ(org_repo, org_ref, other_repo, other_ref,
                             discovery_data,
                             remote_compare=incoming_changesets)

        diff_processor = diffs.DiffProcessor(_diff or '', 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 = {}
        c.lines_added = 0
        c.lines_deleted = 0
        for f in _parsed:
            st = f['stats']
            if st[0] != 'b':
                c.lines_added += st[0]
                c.lines_deleted += st[1]
            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')
Esempio n. 58
0
    def create(self, text, repo, user, revision=None, pull_request=None,
               f_path=None, line_no=None, status_change=None):
        """
        Creates new comment for changeset or pull request.
        IF status_change is not none this comment is associated with a
        status change of changeset or changesets associated with pull request

        :param text:
        :param repo:
        :param user:
        :param revision:
        :param pull_request:
        :param f_path:
        :param line_no:
        :param status_change:
        """
        if not text:
            return

        repo = self._get_repo(repo)
        user = self._get_user(user)
        comment = ChangesetComment()
        comment.repo = repo
        comment.author = user
        comment.text = text
        comment.f_path = f_path
        comment.line_no = line_no

        if revision:
            cs = repo.scm_instance.get_changeset(revision)
            desc = "%s - %s" % (cs.short_id, h.shorter(cs.message, 256))
            author_email = cs.author_email
            comment.revision = revision
        elif pull_request:
            pull_request = self.__get_pull_request(pull_request)
            comment.pull_request = pull_request
            desc = pull_request.pull_request_id
        else:
            raise Exception('Please specify revision or pull_request_id')

        self.sa.add(comment)
        self.sa.flush()

        # make notification
        line = ''
        body = text

        #changeset
        if revision:
            if line_no:
                line = _('on line %s') % line_no
            subj = safe_unicode(
                h.link_to('Re commit: %(desc)s %(line)s' % \
                          {'desc': desc, 'line': line},
                          h.url('changeset_home', repo_name=repo.repo_name,
                                revision=revision,
                                anchor='comment-%s' % comment.comment_id,
                                qualified=True,
                          )
                )
            )
            notification_type = Notification.TYPE_CHANGESET_COMMENT
            # get the current participants of this changeset
            recipients = ChangesetComment.get_users(revision=revision)
            # add changeset author if it's in rhodecode system
            recipients += [User.get_by_email(author_email)]
            email_kwargs = {
                'status_change': status_change,
            }
        #pull request
        elif pull_request:
            _url = h.url('pullrequest_show',
                repo_name=pull_request.other_repo.repo_name,
                pull_request_id=pull_request.pull_request_id,
                anchor='comment-%s' % comment.comment_id,
                qualified=True,
            )
            subj = safe_unicode(
                h.link_to('Re pull request: %(desc)s %(line)s' % \
                          {'desc': desc, 'line': line}, _url)
            )

            notification_type = Notification.TYPE_PULL_REQUEST_COMMENT
            # get the current participants of this pull request
            recipients = ChangesetComment.get_users(pull_request_id=
                                                pull_request.pull_request_id)
            # add pull request author
            recipients += [pull_request.author]

            # add the reviewers to notification
            recipients += [x.user for x in pull_request.reviewers]

            #set some variables for email notification
            email_kwargs = {
                'pr_id': pull_request.pull_request_id,
                'status_change': status_change,
                'pr_comment_url': _url,
                'pr_comment_user': h.person(user.email),
                'pr_target_repo': h.url('summary_home',
                                   repo_name=pull_request.other_repo.repo_name,
                                   qualified=True)
            }
        # create notification objects, and emails
        NotificationModel().create(
            created_by=user, subject=subj, body=body,
            recipients=recipients, type_=notification_type,
            email_kwargs=email_kwargs
        )

        mention_recipients = set(self._extract_mentions(body))\
                                .difference(recipients)
        if mention_recipients:
            email_kwargs.update({'pr_mention': True})
            subj = _('[Mention]') + ' ' + subj
            NotificationModel().create(
                created_by=user, subject=subj, body=body,
                recipients=mention_recipients,
                type_=notification_type,
                email_kwargs=email_kwargs
            )

        return comment
Esempio n. 59
0
    def comment(self, repo_name, pull_request_id):
        pull_request = PullRequest.get_or_404(pull_request_id)
        if pull_request.is_closed():
            raise HTTPForbidden()

        status = request.POST.get('changeset_status')
        change_status = request.POST.get('change_changeset_status')
        text = request.POST.get('text')
        close_pr = request.POST.get('save_close')

        allowed_to_change_status = self._get_is_allowed_change_status(pull_request)
        if status and change_status and allowed_to_change_status:
            _def = (_('Status change -> %s')
                            % ChangesetStatus.get_status_lbl(status))
            if close_pr:
                _def = _('Closing with') + ' ' + _def
            text = text or _def
        comm = ChangesetCommentsModel().create(
            text=text,
            repo=c.rhodecode_db_repo.repo_id,
            user=c.rhodecode_user.user_id,
            pull_request=pull_request_id,
            f_path=request.POST.get('f_path'),
            line_no=request.POST.get('line'),
            status_change=(ChangesetStatus.get_status_lbl(status)
                           if status and change_status
                           and allowed_to_change_status else None),
            closing_pr=close_pr
        )

        action_logger(self.rhodecode_user,
                      'user_commented_pull_request:%s' % pull_request_id,
                      c.rhodecode_db_repo, self.ip_addr, self.sa)

        if allowed_to_change_status:
            # get status if set !
            if status and change_status:
                ChangesetStatusModel().set_status(
                    c.rhodecode_db_repo.repo_id,
                    status,
                    c.rhodecode_user.user_id,
                    comm,
                    pull_request=pull_request_id
                )

            if close_pr:
                if status in ['rejected', 'approved']:
                    PullRequestModel().close_pull_request(pull_request_id)
                    action_logger(self.rhodecode_user,
                              'user_closed_pull_request:%s' % pull_request_id,
                              c.rhodecode_db_repo, self.ip_addr, self.sa)
                else:
                    h.flash(_('Closing pull request on other statuses than '
                              'rejected or approved forbidden'),
                            category='warning')

        Session().commit()

        if not request.environ.get('HTTP_X_PARTIAL_XHR'):
            return redirect(h.url('pullrequest_show', repo_name=repo_name,
                                  pull_request_id=pull_request_id))

        data = {
           'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
        }
        if comm:
            c.co = comm
            data.update(comm.get_dict())
            data.update({'rendered_text':
                         render('changeset/changeset_comment_block.html')})

        return data