Beispiel #1
0
    def _get_comments(self,
                      repo_id,
                      revision=None,
                      pull_request=None,
                      inline=False):
        """
        Gets comments for either revision or pull_request_id, either inline or general.
        """
        q = Session().query(ChangesetComment)

        if inline:
            q = q.filter(ChangesetComment.line_no != None) \
                .filter(ChangesetComment.f_path != None)
        else:
            q = q.filter(ChangesetComment.line_no == None) \
                .filter(ChangesetComment.f_path == None)

        if revision is not None:
            q = q.filter(ChangesetComment.revision == revision) \
                .filter(ChangesetComment.repo_id == repo_id)
        elif pull_request is not None:
            pull_request = PullRequest.guess_instance(pull_request)
            q = q.filter(ChangesetComment.pull_request == pull_request)
        else:
            raise Exception('Please specify either revision or pull_request')

        return q.order_by(ChangesetComment.created_on).all()
    def set_status(self, repo, status, user, comment, revision=None,
                   pull_request=None, dont_allow_on_closed_pull_request=False):
        """
        Creates new status for changeset or updates the old ones bumping their
        version, leaving the current status at the value of 'status'.

        :param repo:
        :param status:
        :param user:
        :param comment:
        :param revision:
        :param pull_request:
        :param dont_allow_on_closed_pull_request: don't allow a status change
            if last status was for pull request and it's closed. We shouldn't
            mess around this manually
        """
        repo = Repository.guess_instance(repo)

        q = ChangesetStatus.query()
        if revision is not None:
            assert pull_request is None
            q = q.filter(ChangesetStatus.repo == repo)
            q = q.filter(ChangesetStatus.revision == revision)
            revisions = [revision]
        else:
            assert pull_request is not None
            pull_request = PullRequest.guess_instance(pull_request)
            repo = pull_request.org_repo
            q = q.filter(ChangesetStatus.repo == repo)
            q = q.filter(ChangesetStatus.revision.in_(pull_request.revisions))
            revisions = pull_request.revisions
        cur_statuses = q.all()

        #if statuses exists and last is associated with a closed pull request
        # we need to check if we can allow this status change
        if (dont_allow_on_closed_pull_request and cur_statuses
            and getattr(cur_statuses[0].pull_request, 'status', '')
                == PullRequest.STATUS_CLOSED):
            raise StatusChangeOnClosedPullRequestError(
                'Changing status on closed pull request is not allowed'
            )

        #update all current statuses with older version
        for st in cur_statuses:
            st.version += 1

        new_statuses = []
        for rev in revisions:
            new_status = ChangesetStatus()
            new_status.version = 0 # default
            new_status.author = User.guess_instance(user)
            new_status.repo = Repository.guess_instance(repo)
            new_status.status = status
            new_status.comment = comment
            new_status.revision = rev
            new_status.pull_request = pull_request
            new_statuses.append(new_status)
            Session().add(new_status)
        return new_statuses
 def delete(self, pull_request):
     pull_request = PullRequest.guess_instance(pull_request)
     Session().delete(pull_request)
     if pull_request.org_repo.scm_instance.alias == 'git':
         # remove a ref under refs/pull/ so that commits can be garbage-collected
         try:
             del pull_request.org_repo.scm_instance._repo["refs/pull/%d/head" % pull_request.pull_request_id]
         except KeyError:
             pass
    def set_status(self,
                   repo,
                   status,
                   user,
                   comment,
                   revision=None,
                   pull_request=None):
        """
        Creates new status for changeset or updates the old ones bumping their
        version, leaving the current status at the value of 'status'.

        :param repo:
        :param status:
        :param user:
        :param comment:
        :param revision:
        :param pull_request:
        """
        repo = Repository.guess_instance(repo)

        q = ChangesetStatus.query()
        if revision is not None:
            assert pull_request is None
            q = q.filter(ChangesetStatus.repo == repo)
            q = q.filter(ChangesetStatus.revision == revision)
            revisions = [revision]
        else:
            assert pull_request is not None
            pull_request = PullRequest.guess_instance(pull_request)
            repo = pull_request.org_repo
            q = q.filter(ChangesetStatus.repo == repo)
            q = q.filter(ChangesetStatus.revision.in_(pull_request.revisions))
            revisions = pull_request.revisions
        cur_statuses = q.all()

        # update all current statuses with older version
        for st in cur_statuses:
            st.version += 1

        new_statuses = []
        for rev in revisions:
            new_status = ChangesetStatus()
            new_status.version = 0  # default
            new_status.author = User.guess_instance(user)
            new_status.repo = Repository.guess_instance(repo)
            new_status.status = status
            new_status.comment = comment
            new_status.revision = rev
            new_status.pull_request = pull_request
            new_statuses.append(new_status)
            Session().add(new_status)
        return new_statuses
Beispiel #5
0
    def _get_comments(self,
                      repo_id,
                      revision=None,
                      pull_request=None,
                      inline=False,
                      f_path=None,
                      line_no=None):
        """
        Gets comments for either revision or pull_request_id, either inline or general.
        If a file path and optionally line number are given, return only the matching inline comments.
        """
        if f_path is None and line_no is not None:
            raise Exception("line_no only makes sense if f_path is given.")

        if inline is None and f_path is not None:
            raise Exception("f_path only makes sense for inline comments.")

        q = Session().query(ChangesetComment)

        if inline:
            if f_path is not None:
                # inline comments for a given file...
                q = q.filter(ChangesetComment.f_path == f_path)
                if line_no is None:
                    # ... on any line
                    q = q.filter(ChangesetComment.line_no != None)
                else:
                    # ... on specific line
                    q = q.filter(ChangesetComment.line_no == line_no)
            else:
                # all inline comments
                q = q.filter(ChangesetComment.line_no != None) \
                    .filter(ChangesetComment.f_path != None)
        else:
            # all general comments
            q = q.filter(ChangesetComment.line_no == None) \
                .filter(ChangesetComment.f_path == None)

        if revision is not None:
            q = q.filter(ChangesetComment.revision == revision) \
                .filter(ChangesetComment.repo_id == repo_id)
        elif pull_request is not None:
            pull_request = PullRequest.guess_instance(pull_request)
            q = q.filter(ChangesetComment.pull_request == pull_request)
        else:
            raise Exception('Please specify either revision or pull_request')

        return q.order_by(ChangesetComment.created_on).all()
    def _get_status_query(self, repo, revision, pull_request,
                          with_revisions=False):
        repo = Repository.guess_instance(repo)

        q = ChangesetStatus.query() \
            .filter(ChangesetStatus.repo == repo)
        if not with_revisions:
            # only report the latest vote across all users! TODO: be smarter!
            q = q.filter(ChangesetStatus.version == 0)

        if revision:
            q = q.filter(ChangesetStatus.revision == revision)
        elif pull_request:
            pull_request = PullRequest.guess_instance(pull_request)
            q = q.filter(ChangesetStatus.pull_request == pull_request)
        else:
            raise Exception('Please specify revision or pull_request')
        q = q.order_by(ChangesetStatus.version.asc())
        return q
    def _get_status_query(self,
                          repo,
                          revision,
                          pull_request,
                          with_revisions=False):
        repo = Repository.guess_instance(repo)

        q = ChangesetStatus.query() \
            .filter(ChangesetStatus.repo == repo)
        if not with_revisions:
            # only report the latest vote across all users! TODO: be smarter!
            q = q.filter(ChangesetStatus.version == 0)

        if revision:
            q = q.filter(ChangesetStatus.revision == revision)
        elif pull_request:
            pull_request = PullRequest.guess_instance(pull_request)
            q = q.filter(ChangesetStatus.pull_request == pull_request)
        else:
            raise Exception('Please specify revision or pull_request')
        q = q.order_by(ChangesetStatus.version.asc())
        return q
Beispiel #8
0
    def _get_comments(self, repo_id, revision=None, pull_request=None, inline=False):
        """
        Gets comments for either revision or pull_request_id, either inline or general.
        """
        q = Session().query(ChangesetComment)

        if inline:
            q = q.filter(ChangesetComment.line_no != None) \
                .filter(ChangesetComment.f_path != None)
        else:
            q = q.filter(ChangesetComment.line_no == None) \
                .filter(ChangesetComment.f_path == None)

        if revision is not None:
            q = q.filter(ChangesetComment.revision == revision) \
                .filter(ChangesetComment.repo_id == repo_id)
        elif pull_request is not None:
            pull_request = PullRequest.guess_instance(pull_request)
            q = q.filter(ChangesetComment.pull_request == pull_request)
        else:
            raise Exception('Please specify either revision or pull_request')

        return q.order_by(ChangesetComment.created_on).all()
Beispiel #9
0
    def create(self,
               text,
               repo,
               author,
               revision=None,
               pull_request=None,
               f_path=None,
               line_no=None,
               status_change=None,
               closing_pr=False,
               send_email=True):
        """
        Creates a new comment for either a changeset or a pull request.
        status_change and closing_pr is only for the optional email.

        Returns the created comment.
        """
        if not status_change and not text:
            log.warning('Missing text for comment, skipping...')
            return None

        repo = Repository.guess_instance(repo)
        author = User.guess_instance(author)
        comment = ChangesetComment()
        comment.repo = repo
        comment.author = author
        comment.text = text
        comment.f_path = f_path
        comment.line_no = line_no

        if revision is not None:
            comment.revision = revision
        elif pull_request is not None:
            pull_request = PullRequest.guess_instance(pull_request)
            comment.pull_request = pull_request
        else:
            raise Exception('Please specify revision or pull_request_id')

        Session().add(comment)
        Session().flush()

        if send_email:
            (subj, body, recipients, notification_type,
             email_kwargs) = self._get_notification_data(
                 repo,
                 comment,
                 author,
                 comment_text=text,
                 line_no=line_no,
                 revision=revision,
                 pull_request=pull_request,
                 status_change=status_change,
                 closing_pr=closing_pr)
            email_kwargs['is_mention'] = False
            # create notification objects, and emails
            NotificationModel().create(
                created_by=author,
                subject=subj,
                body=body,
                recipients=recipients,
                type_=notification_type,
                email_kwargs=email_kwargs,
            )

            mention_recipients = extract_mentioned_users(body).difference(
                recipients)
            if mention_recipients:
                email_kwargs['is_mention'] = True
                subj = _('[Mention]') + ' ' + subj
                # FIXME: this subject is wrong and unused!
                NotificationModel().create(created_by=author,
                                           subject=subj,
                                           body=body,
                                           recipients=mention_recipients,
                                           type_=notification_type,
                                           email_kwargs=email_kwargs)

        return comment
 def close_pull_request(self, pull_request):
     pull_request = PullRequest.guess_instance(pull_request)
     pull_request.status = PullRequest.STATUS_CLOSED
     pull_request.updated_on = datetime.datetime.now()
Beispiel #11
0
    def create(self, text, repo, author, revision=None, pull_request=None,
               f_path=None, line_no=None, status_change=None, closing_pr=False,
               send_email=True):
        """
        Creates a new comment for either a changeset or a pull request.
        status_change and closing_pr is only for the optional email.

        Returns the created comment.
        """
        if not status_change and not text:
            log.warning('Missing text for comment, skipping...')
            return None

        repo = Repository.guess_instance(repo)
        author = User.guess_instance(author)
        comment = ChangesetComment()
        comment.repo = repo
        comment.author = author
        comment.text = text
        comment.f_path = f_path
        comment.line_no = line_no

        if revision is not None:
            comment.revision = revision
        elif pull_request is not None:
            pull_request = PullRequest.guess_instance(pull_request)
            comment.pull_request = pull_request
        else:
            raise Exception('Please specify revision or pull_request_id')

        Session().add(comment)
        Session().flush()

        if send_email:
            (subj, body, recipients, notification_type,
             email_kwargs) = self._get_notification_data(
                                repo, comment, author,
                                comment_text=text,
                                line_no=line_no,
                                revision=revision,
                                pull_request=pull_request,
                                status_change=status_change,
                                closing_pr=closing_pr)
            email_kwargs['is_mention'] = False
            # create notification objects, and emails
            NotificationModel().create(
                created_by=author, subject=subj, body=body,
                recipients=recipients, type_=notification_type,
                email_kwargs=email_kwargs,
            )

            mention_recipients = extract_mentioned_users(body).difference(recipients)
            if mention_recipients:
                email_kwargs['is_mention'] = True
                subj = _('[Mention]') + ' ' + subj
                # FIXME: this subject is wrong and unused!
                NotificationModel().create(
                    created_by=author, subject=subj, body=body,
                    recipients=mention_recipients,
                    type_=notification_type,
                    email_kwargs=email_kwargs
                )

        return comment