示例#1
0
    def multiple(parameters):
        """TODO: add documentation"""

        commit = jsonapi.deduce("v1/commits", parameters)
        if commit is None:
            raise jsonapi.UsageError(
                "commit must be specified, ex. &commit=<sha1>")

        file_obj = jsonapi.deduce("v1/files", parameters)

        blob_sha1 = commit.getFileInformation(file_obj).sha1

        return api.filecontent.fetch(
            parameters.critic, commit.repository, blob_sha1, file_obj)
示例#2
0
    def multiple(parameters):
        """TODO: add documentation"""

        changeset = jsonapi.deduce("v1/changesets", parameters)
        if changeset is None:
            raise jsonapi.UsageError(
                "changeset needs to be specified, ex. &changeset=<id>")

        repository = jsonapi.deduce("v1/repositories", parameters)
        if repository is None:
            raise jsonapi.UsageError(
                "repository needs to be specified, "
                "ex. &repository=<id or name>")

        return api.filediff.fetchAll(parameters.critic, changeset)
示例#3
0
    def multiple(parameters):
        """Retrieve all reviews in this system.

           repository : REPOSITORY : -

           Include only reviews in one repository, identified by the
           repository's unique numeric id or short-name.

           state : STATE[,STATE,...] : -

           Include only reviews in the specified state.  Valid values are:
           <code>open</code>, <code>closed</code>, <code>dropped</code>."""

        repository = jsonapi.deduce("v1/repositories", parameters)
        state_parameter = parameters.getQueryParameter("state")
        if state_parameter:
            state = set(state_parameter.split(","))
            invalid = state - api.review.Review.STATE_VALUES
            if invalid:
                raise jsonapi.UsageError("Invalid review state values: %s" %
                                         ", ".join(map(repr, sorted(invalid))))
        else:
            state = None
        return api.review.fetchAll(parameters.critic,
                                   repository=repository,
                                   state=state)
示例#4
0
    def multiple(parameters):
        """Retrieve all branches in the Git repositories.

           repository : REPOSITORY : -

           Include only branches in one repository, identified by the
           repository's unique numeric id or short-name.

           name : NAME : string

           Retrieve only the branch with the specified name.  The name should
           <em>not</em> include the "refs/heads/" prefix.  When this parameter
           is specified a repository must be specified as well, either in the
           resource path or using the <code>repository</code> parameter."""

        repository = jsonapi.deduce("v1/repositories", parameters)
        name_parameter = parameters.getQueryParameter("name")
        if name_parameter:
            if repository is None:
                raise jsonapi.UsageError(
                    "Named branch access must have repository specified.")
            return api.branch.fetch(parameters.critic,
                                    repository=repository,
                                    name=name_parameter)
        return api.branch.fetchAll(parameters.critic, repository=repository)
示例#5
0
    def multiple(parameters):
        """Retrieve a single extension by key or all extensions.

           key : KEY : string

           Retrieve only the extension with the given key.  This is equivalent
           to accessing /api/v1/extensions/EXTENSION_ID with that extension's
           numeric id.  When used, other parameters are ignored.

           installed_by : INSTALLED_BY : integer or string

           Retrieve only extensions installed by the specified user.  The user
           can be identified by numeric id or username."""

        key_parameter = parameters.getQueryParameter("key")
        if key_parameter:
            return api.extension.fetch(parameters.critic, key=key_parameter)

        installed_by = jsonapi.from_parameter(
            "v1/users", "installed_by", parameters)

        return api.extension.fetchAll(
            parameters.critic,
            publisher=jsonapi.deduce("v1/users", parameters),
            installed_by=installed_by)
示例#6
0
文件: reviews.py 项目: jensl/critic
    def multiple(parameters):
        """Retrieve all reviews in this system.

           repository : REPOSITORY : -

           Include only reviews in one repository, identified by the
           repository's unique numeric id or short-name.

           state : STATE[,STATE,...] : -

           Include only reviews in the specified state.  Valid values are:
           <code>open</code>, <code>closed</code>, <code>dropped</code>."""

        repository = jsonapi.deduce("v1/repositories", parameters)
        state_parameter = parameters.getQueryParameter("state")
        if state_parameter:
            state = set(state_parameter.split(","))
            invalid = state - api.review.Review.STATE_VALUES
            if invalid:
                raise jsonapi.UsageError(
                    "Invalid review state values: %s"
                    % ", ".join(map(repr, sorted(invalid))))
        else:
            state = None
        return api.review.fetchAll(
            parameters.critic, repository=repository, state=state)
示例#7
0
    def multiple(parameters):
        """Retrieve a single commit identified by its SHA-1 sum.

           sha1 : COMMIT_SHA1 : string

           Retrieve a commit identified by its SHA-1 sum.  The SHA-1 sum can be
           abbreviated, but must be at least 4 characters long, and must be
           unambigious in the repository.

           repository : REPOSITORY : -

           Specify repository to access, identified by its unique numeric id or
           short-name.  Required unless a repository is specified in the
           resource path."""

        sha1_parameter = parameters.getQueryParameter("sha1")
        if sha1_parameter is None:
            raise jsonapi.UsageError("Missing required SHA-1 parameter.")
        if not re.match("[0-9A-Fa-f]{4,40}$", sha1_parameter):
            raise jsonapi.UsageError("Invalid SHA-1 parameter: %r" %
                                     sha1_parameter)
        repository = jsonapi.deduce("v1/repositories", parameters)
        if repository is None:
            raise jsonapi.UsageError(
                "Commit reference must have repository specified.")
        return api.commit.fetch(repository, sha1=sha1_parameter)
示例#8
0
    def multiple(parameters):
        """Retrieve a single extension by key or all extensions.

           key : KEY : string

           Retrieve only the extension with the given key.  This is equivalent
           to accessing /api/v1/extensions/EXTENSION_ID with that extension's
           numeric id.  When used, other parameters are ignored.

           installed_by : INSTALLED_BY : integer or string

           Retrieve only extensions installed by the specified user.  The user
           can be identified by numeric id or username."""

        key_parameter = parameters.getQueryParameter("key")
        if key_parameter:
            return api.extension.fetch(parameters.critic, key=key_parameter)

        installed_by = jsonapi.from_parameter("v1/users", "installed_by",
                                              parameters)

        return api.extension.fetchAll(parameters.critic,
                                      publisher=jsonapi.deduce(
                                          "v1/users", parameters),
                                      installed_by=installed_by)
示例#9
0
文件: commits.py 项目: jensl/critic
    def multiple(parameters):
        """Retrieve a single commit identified by its SHA-1 sum.

           sha1 : COMMIT_SHA1 : string

           Retrieve a commit identified by its SHA-1 sum.  The SHA-1 sum can be
           abbreviated, but must be at least 4 characters long, and must be
           unambigious in the repository.

           repository : REPOSITORY : -

           Specify repository to access, identified by its unique numeric id or
           short-name.  Required unless a repository is specified in the
           resource path."""

        sha1_parameter = parameters.getQueryParameter("sha1")
        if sha1_parameter is None:
            raise jsonapi.UsageError("Missing required SHA-1 parameter.")
        if not re.match("[0-9A-Fa-f]{4,40}$", sha1_parameter):
            raise jsonapi.UsageError(
                "Invalid SHA-1 parameter: %r" % sha1_parameter)
        repository = jsonapi.deduce("v1/repositories", parameters)
        if repository is None:
            raise jsonapi.UsageError(
                "Commit reference must have repository specified.")
        return api.commit.fetch(repository, sha1=sha1_parameter)
示例#10
0
    def multiple(parameters):
        """Retrieve all reviewable file changes in a review.

           review : REVIEW_ID : -

           Retrieve the reviewable changes in the specified review.

           changeset : CHANGESET_ID : -

           Retrieve the reviewable changes in the specified changeset.

           file : FILE : -

           Retrieve the reviewable changes in the specified file only.

           assignee : USER : -

           Retrieve reviewable changes assigned to the specified user only.

           state : STATE : "pending" or "reviewed"

           Retrieve reviewable changes in the specified state only."""

        review = jsonapi.deduce("v1/reviews", parameters)
        changeset = jsonapi.deduce("v1/changesets", parameters)

        if not review:
            raise jsonapi.UsageError("Missing required parameter: review")

        file = jsonapi.from_parameter("v1/files", "file", parameters)
        assignee = jsonapi.from_parameter("v1/users", "assignee", parameters)
        state_parameter = parameters.getQueryParameter("state")

        if state_parameter is None:
            is_reviewed = None
        else:
            if state_parameter not in ("pending", "reviewed"):
                raise jsonapi.UsageError(
                    "Invalid parameter value: state=%r "
                    "(value values are 'pending' and 'reviewed')" %
                    state_parameter)
            is_reviewed = state_parameter == "reviewed"

        return api.reviewablefilechange.fetchAll(parameters.critic, review,
                                                 changeset, file, assignee,
                                                 is_reviewed)
示例#11
0
    def multiple(parameters):
        """Retrieve all reviewable file changes in a review.

           review : REVIEW_ID : -

           Retrieve the reviewable changes in the specified review.

           changeset : CHANGESET_ID : -

           Retrieve the reviewable changes in the specified changeset.

           file : FILE : -

           Retrieve the reviewable changes in the specified file only.

           assignee : USER : -

           Retrieve reviewable changes assigned to the specified user only.

           state : STATE : "pending" or "reviewed"

           Retrieve reviewable changes in the specified state only."""

        review = jsonapi.deduce("v1/reviews", parameters)
        changeset = jsonapi.deduce("v1/changesets", parameters)

        if not review:
            raise jsonapi.UsageError("Missing required parameter: review")

        file = jsonapi.from_parameter("v1/files", "file", parameters)
        assignee = jsonapi.from_parameter("v1/users", "assignee", parameters)
        state_parameter = parameters.getQueryParameter("state")

        if state_parameter is None:
            is_reviewed = None
        else:
            if state_parameter not in ("pending", "reviewed"):
                raise jsonapi.UsageError(
                    "Invalid parameter value: state=%r "
                    "(value values are 'pending' and 'reviewed')"
                    % state_parameter)
            is_reviewed = state_parameter == "reviewed"

        return api.reviewablefilechange.fetchAll(
            parameters.critic, review, changeset, file, assignee, is_reviewed)
示例#12
0
    def single(parameters, argument):
        """TODO: add documentation"""

        changeset = jsonapi.deduce("v1/changesets", parameters)
        if changeset is None:
            raise jsonapi.UsageError(
                "changeset needs to be specified, ex. &changeset=<id>")

        repository = jsonapi.deduce("v1/repositories", parameters)
        if repository is None:
            raise jsonapi.UsageError(
                "repository needs to be specified, "
                "ex. &repository=<id or name>")

        file = api.file.fetch(parameters.critic, jsonapi.numeric_id(argument))
        filechange = api.filechange.fetch(parameters.critic, changeset, file)

        return api.filediff.fetch(parameters.critic, filechange)
    def multiple(parameters):
        """Retrieve all labeled access control profile selectors in the system.

           profile : PROFILE_ID : integer

           Include only selectors selecting the given profile, identified by its
           unique numeric id."""
        profile = jsonapi.deduce("v1/accesscontrolprofiles", parameters)
        return api.labeledaccesscontrolprofile.fetchAll(
            parameters.critic, profile=profile)
示例#14
0
    def multiple(parameters):
        """Retrieve all rebases in this system.

           review : REVIEW_ID : -

           Include only rebases of one review, identified by the review's unique
           numeric id."""

        review = jsonapi.deduce("v1/reviews", parameters)
        return api.log.rebase.fetchAll(parameters.critic, review=review)
    def multiple(parameters):
        """Retrieve all labeled access control profile selectors in the system.

           profile : PROFILE_ID : integer

           Include only selectors selecting the given profile, identified by its
           unique numeric id."""
        profile = jsonapi.deduce("v1/accesscontrolprofiles", parameters)
        return api.labeledaccesscontrolprofile.fetchAll(parameters.critic,
                                                        profile=profile)
示例#16
0
文件: rebases.py 项目: jensl/critic
    def multiple(parameters):
        """Retrieve all rebases in this system.

           review : REVIEW_ID : -

           Include only rebases of one review, identified by the review's unique
           numeric id."""

        review = jsonapi.deduce("v1/reviews", parameters)
        return api.log.rebase.fetchAll(parameters.critic, review=review)
示例#17
0
文件: comments.py 项目: jensl/critic
        def location_json(location):
            if not location:
                return None

            if location.type == "file-version":
                changeset = jsonapi.deduce("v1/changesets", parameters)

                if not changeset:
                    # FileVersionLocation.translateTo() only allows one, so let
                    # a deduced changeset win over a deduced commit.
                    commit = jsonapi.deduce("v1/commits", parameters)
                else:
                    commit = None

                if changeset or commit:
                    location = location.translateTo(changeset=changeset,
                                                    commit=commit)

                    if not location:
                        raise jsonapi.ResourceSkipped(
                            "Comment not present in changeset/commit")

            result = {
                "type": location.type,
                "first_line": location.first_line,
                "last_line": location.last_line
            }

            if location.type == "commit-message":
                result.update({
                    "commit": location.commit
                })
            else:
                result.update({
                    "file": location.file,
                    "changeset": location.changeset,
                    "side": location.side,
                    "commit": location.commit,
                    "is_translated": location.is_translated
                })

            return result
示例#18
0
    def multiple(parameters):
        """All access tokens."""

        user = jsonapi.deduce("v1/users", parameters)

        # Only administrators are allowed to access all access tokens in the
        # system.
        if user is None:
            api.PermissionDenied.raiseUnlessAdministrator(parameters.critic)

        return api.accesstoken.fetchAll(parameters.critic, user=user)
示例#19
0
    def multiple(parameters):
        """All access tokens."""

        user = jsonapi.deduce("v1/users", parameters)

        # Only administrators are allowed to access all access tokens in the
        # system.
        if user is None:
            api.PermissionDenied.raiseUnlessAdministrator(parameters.critic)

        return api.accesstoken.fetchAll(parameters.critic, user=user)
示例#20
0
        def location_json(location):
            if not location:
                return None

            if location.type == "file-version":
                changeset = jsonapi.deduce("v1/changesets", parameters)

                if not changeset:
                    # FileVersionLocation.translateTo() only allows one, so let
                    # a deduced changeset win over a deduced commit.
                    commit = jsonapi.deduce("v1/commits", parameters)
                else:
                    commit = None

                if changeset or commit:
                    location = location.translateTo(changeset=changeset,
                                                    commit=commit)

                    if not location:
                        raise jsonapi.ResourceSkipped(
                            "Comment not present in changeset/commit")

            result = {
                "type": location.type,
                "first_line": location.first_line,
                "last_line": location.last_line
            }

            if location.type == "commit-message":
                result.update({"commit": location.commit})
            else:
                result.update({
                    "file": location.file,
                    "changeset": location.changeset,
                    "side": location.side,
                    "commit": location.commit,
                    "is_translated": location.is_translated
                })

            return result
示例#21
0
文件: replies.py 项目: jensl/critic
    def multiple(parameters):
        """Retrieve replies to a comment.

           comment : COMMENT_ID : integer

           Retrieve all replies to the specified comment."""

        comment = jsonapi.deduce("v1/comments", parameters)

        if not comment:
            raise jsonapi.UsageError("A comment must be identified.")

        return comment.replies
示例#22
0
    def multiple(parameters):
        """Retrieve all filechanges (changed files) from a changeset.

           changeset : CHANGESET : -

           Retrieve the changed from a changeset indentified by its unique numeric id.

           reposititory : REPOSITORY : -

           The repository in which the files exist."""

        changeset = jsonapi.deduce("v1/changesets", parameters)
        return api.filechange.fetchAll(parameters.critic, changeset)
示例#23
0
    def multiple(parameters):
        """Retrieve all filechanges (changed files) from a changeset.

           changeset : CHANGESET : -

           Retrieve the changed from a changeset indentified by its unique numeric id.

           reposititory : REPOSITORY : -

           The repository in which the files exist."""

        changeset = jsonapi.deduce("v1/changesets", parameters)
        return api.filechange.fetchAll(parameters.critic, changeset)
示例#24
0
    def multiple(parameters):
        """Retrieve replies to a comment.

           comment : COMMENT_ID : integer

           Retrieve all replies to the specified comment."""

        comment = jsonapi.deduce("v1/comments", parameters)

        if not comment:
            raise jsonapi.UsageError("A comment must be identified.")

        return comment.replies
示例#25
0
    def create(parameters, value, values, data):
        critic = parameters.critic
        user = parameters.context.get("users", critic.actual_user)

        if value or values:
            raise jsonapi.UsageError("Invalid POST request")

        converted = jsonapi.convert(
            parameters,
            {
                "review?": api.review.Review,
                "comment?": str,
            },
            data)

        review = jsonapi.deduce("v1/reviews", parameters)

        if not review:
            if "review" not in converted:
                raise jsonapi.UsageError("No review specified")
            review = converted["review"]
        elif "review" in converted and review != converted["review"]:
            raise jsonapi.UsageError("Conflicting reviews specified")

        if "comment" in converted:
            comment_text = converted["comment"].strip()
            if not comment_text:
                raise jsonapi.UsageError("Empty comment specified")
        else:
            comment_text = None

        result = []

        def collectBatch(batch):
            assert isinstance(batch, api.batch.Batch)
            result.append(batch)

        with api.transaction.Transaction(critic) as transaction:
            modifier = transaction.modifyReview(review)

            if comment_text:
                note = modifier.createComment(comment_type="note",
                                              author=critic.actual_user,
                                              text=comment_text)
            else:
                note = None

            modifier.submitChanges(note, callback=collectBatch)

        assert len(result) == 1
        return result[0], None
示例#26
0
    def json(value, parameters):
        """Changeset {
             "id": integer, // the changeset's id
             "type": string, // the changeset type (direct, custom, merge, conflict)
             "from_commit": integer, // commit id for changesets from_commit
             "to_commit": integer, // commit id for changesets to_commit
             "files": integer[], // a list of all files changed in this changeset
             "review_state": ReviewState or null,
           }

           ReviewState {
             "review": integer,
             "comments": integer[],
           }"""

        def review_state(review):
            if not review:
                return None

            comments = api.comment.fetchAll(
                parameters.critic, review=review, changeset=value)

            try:
                reviewablefilechanges = api.reviewablefilechange.fetchAll(
                    parameters.critic, review=review, changeset=value)
            except api.reviewablefilechange.InvalidChangeset:
                reviewablefilechanges = None

            return {
                "review": review,
                "commments": comments,
                "reviewablefilechanges": reviewablefilechanges,
            }

        review = jsonapi.deduce("v1/reviews", parameters)

        contributing_commits = value.contributing_commits
        if contributing_commits:
            contributing_commits = list(contributing_commits.topo_ordered)

        return parameters.filtered(
            "changesets", {
                "id": value.id,
                "type": value.type,
                "from_commit": value.from_commit,
                "to_commit": value.to_commit,
                "files": value.files,
                "contributing_commits": contributing_commits,
                "review_state": review_state(review)
            })
示例#27
0
文件: rebases.py 项目: jensl/critic
    def create(parameters, value, values, data):
        critic = parameters.critic
        user = critic.actual_user

        converted = jsonapi.convert(
            parameters,
            {
                "new_upstream?": str,
                "history_rewrite?": bool
            },
            data)

        new_upstream = converted.get("new_upstream")
        history_rewrite = converted.get("history_rewrite")

        if (new_upstream is None) == (history_rewrite is None):
            raise jsonapi.UsageError(
                "Exactly one of the arguments new_upstream and history_rewrite "
                "must be specified.")

        if history_rewrite == False:
            raise jsonapi.UsageError(
                "history_rewrite must be true, or omitted.")

        review = jsonapi.deduce("v1/reviews", parameters)

        if review is None:
            raise jsonapi.UsageError(
                "review must be specified when preparing a rebase")

        if history_rewrite is not None:
            expected_type = api.log.rebase.HistoryRewrite
        else:
            expected_type = api.log.rebase.MoveRebase

        result = []

        def collectRebase(rebase):
            assert isinstance(rebase, expected_type), repr(rebase)
            result.append(rebase)

        with api.transaction.Transaction(critic) as transaction:
            transaction \
                .modifyReview(review) \
                .prepareRebase(
                    user, new_upstream, history_rewrite,
                    callback=collectRebase)

        assert len(result) == 1, repr(result)
        return result[0], None
示例#28
0
文件: replies.py 项目: jensl/critic
    def create(parameters, value, values, data):
        critic = parameters.critic
        user = parameters.context.get("users", critic.actual_user)

        if value or values:
            raise jsonapi.UsageError("Invalid POST request")

        converted = jsonapi.convert(
            parameters,
            {
                "comment?": api.comment.Comment,
                "author?": api.user.User,
                "text": str
            },
            data)

        comment = jsonapi.deduce("v1/comments", parameters)

        if not comment:
            if "comment" not in converted:
                raise jsonapi.UsageError("No comment specified")
            comment = converted["comment"]
        elif "comment" in converted and comment != converted["comment"]:
            raise jsonapi.UsageError("Conflicting comments specified")

        if "author" in converted:
            author = converted["author"]
        else:
            author = critic.actual_user

        if not converted["text"].strip():
            raise jsonapi.UsageError("Empty reply")

        result = []

        def collectReply(reply):
            assert isinstance(reply, api.reply.Reply)
            result.append(reply)

        with api.transaction.Transaction(critic) as transaction:
            transaction \
                .modifyReview(comment.review) \
                .modifyComment(comment) \
                .addReply(
                    author=author,
                    text=converted["text"],
                    callback=collectReply)

        assert len(result) == 1
        return result[0], None
示例#29
0
    def deduce(parameters):
        repository = parameters.context.get("repositories")
        repository_parameter = parameters.getQueryParameter("repository")
        if repository_parameter is not None:
            if repository is not None:
                raise jsonapi.UsageError(
                    "Redundant query parameter: repository=%s"
                    % repository_parameter)
            repository = from_argument(parameters, repository_parameter)
        if repository is not None:
            return repository

        review = jsonapi.deduce("v1/reviews", parameters)
        if review is not None:
            return review.repository
示例#30
0
 def deduce(parameters):
     repository = jsonapi.deduce("v1/repositories", parameters)
     changeset = parameters.context.get(Changesets.name)
     changeset_parameter = parameters.getQueryParameter("changeset")
     if changeset_parameter is not None:
         if changeset is not None:
             raise jsonapi.UsageError(
                 "Redundant query parameter: changeset=%s"
                 % changeset_parameter)
         if repository is None:
             raise jsonapi.UsageError(
                 "repository needs to be specified, ex. &repository=<id>")
         changeset_id = jsonapi.numeric_id(changeset_parameter)
         changeset = api.changeset.fetch(
             parameters.critic, repository, changeset_id=changeset_id)
     return changeset
示例#31
0
文件: replies.py 项目: jensl/critic
    def single(parameters, argument):
        """Retrieve one (or more) replies to comments.

           REPLY_ID : integer

           Retrieve a reply identified by its unique numeric id."""

        reply = api.reply.fetch(
            parameters.critic, reply_id=jsonapi.numeric_id(argument))

        comment = jsonapi.deduce("v1/comments", parameters)
        if comment and comment != reply.comment:
            raise jsonapi.PathError(
                "Reply does not belong to specified comment")

        return reply
示例#32
0
    def multiple(parameters):
        """All repository filters.

           repository : REPOSITORY : -

           Include only filters for the specified repository, identified by its
           unique numeric id or short-name."""

        user = parameters.context["users"]
        repository = jsonapi.deduce("v1/repositories", parameters)
        if repository:
            repository_filters = user.repository_filters.get(repository, [])
        else:
            repository_filters = itertools.chain(
                *user.repository_filters.values())
        return jsonapi.sorted_by_id(repository_filters)
示例#33
0
 def deduce(parameters):
     changeset = jsonapi.deduce("v1/changesets", parameters)
     if changeset is None:
         raise jsonapi.UsageError(
             "changeset needs to be specified, ex. &changeset=<id>")
     filechange = parameters.context.get(FileChanges.name)
     filechange_parameter = parameters.getQueryParameter("filechange")
     if filechange_parameter is not None:
         if filechange is not None:
             raise jsonapi.UsageError(
                 "Redundant query parameter: filechange=%s" %
                 filechange_parameter)
         filechange_id = jsonapi.numeric_id(filechange_parameter)
         filechange = api.filechange.fetch(parameters.critic, changeset,
                                           filechange_id)
     return filechange
示例#34
0
    def single(parameters, argument):
        """Retrieve one (or more) comments in reviews.

           COMMENT_ID : integer

           Retrieve a comment identified by its unique numeric id."""

        comment = api.comment.fetch(parameters.critic,
                                    comment_id=jsonapi.numeric_id(argument))

        review = jsonapi.deduce("v1/reviews", parameters)
        if review and review != comment.review:
            raise jsonapi.PathError(
                "Comment does not belong to specified review")

        return Comments.setAsContext(parameters, comment)
示例#35
0
    def single(parameters, argument):
        """Retrieve one (or more) batches in reviews.

           BATCH_ID : integer

           Retrieve a batch identified by its unique numeric id."""

        batch = api.batch.fetch(
            parameters.critic, batch_id=jsonapi.numeric_id(argument))

        review = jsonapi.deduce("v1/reviews", parameters)
        if review and review != batch.review:
            raise jsonapi.PathError(
                "Batch does not belong to specified review")

        return Batches.setAsContext(parameters, batch)
示例#36
0
 def deduce(parameters):
     changeset = jsonapi.deduce("v1/changesets", parameters)
     if changeset is None:
         raise jsonapi.UsageError(
             "changeset needs to be specified, ex. &changeset=<id>")
     filechange = parameters.context.get(FileChanges.name)
     filechange_parameter = parameters.getQueryParameter("filechange")
     if filechange_parameter is not None:
         if filechange is not None:
             raise jsonapi.UsageError(
                 "Redundant query parameter: filechange=%s"
                 % filechange_parameter)
         filechange_id = jsonapi.numeric_id(filechange_parameter)
         filechange = api.filechange.fetch(
             parameters.critic, changeset, filechange_id)
     return filechange
示例#37
0
文件: comments.py 项目: jensl/critic
    def single(parameters, argument):
        """Retrieve one (or more) comments in reviews.

           COMMENT_ID : integer

           Retrieve a comment identified by its unique numeric id."""

        comment = api.comment.fetch(
            parameters.critic, comment_id=jsonapi.numeric_id(argument))

        review = jsonapi.deduce("v1/reviews", parameters)
        if review and review != comment.review:
            raise jsonapi.PathError(
                "Comment does not belong to specified review")

        return Comments.setAsContext(parameters, comment)
示例#38
0
    def single(parameters, argument):
        """Retrieve one (or more) replies to comments.

           REPLY_ID : integer

           Retrieve a reply identified by its unique numeric id."""

        reply = api.reply.fetch(parameters.critic,
                                reply_id=jsonapi.numeric_id(argument))

        comment = jsonapi.deduce("v1/comments", parameters)
        if comment and comment != reply.comment:
            raise jsonapi.PathError(
                "Reply does not belong to specified comment")

        return reply
示例#39
0
    def create(parameters, value, values, data):
        critic = parameters.critic
        user = parameters.context.get("users", critic.actual_user)

        if value or values:
            raise jsonapi.UsageError("Invalid POST request")

        converted = jsonapi.convert(parameters, {
            "comment?": api.comment.Comment,
            "author?": api.user.User,
            "text": str
        }, data)

        comment = jsonapi.deduce("v1/comments", parameters)

        if not comment:
            if "comment" not in converted:
                raise jsonapi.UsageError("No comment specified")
            comment = converted["comment"]
        elif "comment" in converted and comment != converted["comment"]:
            raise jsonapi.UsageError("Conflicting comments specified")

        if "author" in converted:
            author = converted["author"]
        else:
            author = critic.actual_user

        if not converted["text"].strip():
            raise jsonapi.UsageError("Empty reply")

        result = []

        def collectReply(reply):
            assert isinstance(reply, api.reply.Reply)
            result.append(reply)

        with api.transaction.Transaction(critic) as transaction:
            transaction \
                .modifyReview(comment.review) \
                .modifyComment(comment) \
                .addReply(
                    author=author,
                    text=converted["text"],
                    callback=collectReply)

        assert len(result) == 1
        return result[0], None
示例#40
0
    def create(parameters, value, values, data):
        critic = parameters.critic
        user = critic.actual_user

        converted = jsonapi.convert(parameters, {
            "new_upstream?": str,
            "history_rewrite?": bool
        }, data)

        new_upstream = converted.get("new_upstream")
        history_rewrite = converted.get("history_rewrite")

        if (new_upstream is None) == (history_rewrite is None):
            raise jsonapi.UsageError(
                "Exactly one of the arguments new_upstream and history_rewrite "
                "must be specified.")

        if history_rewrite == False:
            raise jsonapi.UsageError(
                "history_rewrite must be true, or omitted.")

        review = jsonapi.deduce("v1/reviews", parameters)

        if review is None:
            raise jsonapi.UsageError(
                "review must be specified when preparing a rebase")

        if history_rewrite is not None:
            expected_type = api.log.rebase.HistoryRewrite
        else:
            expected_type = api.log.rebase.MoveRebase

        result = []

        def collectRebase(rebase):
            assert isinstance(rebase, expected_type), repr(rebase)
            result.append(rebase)

        with api.transaction.Transaction(critic) as transaction:
            transaction \
                .modifyReview(review) \
                .prepareRebase(
                    user, new_upstream, history_rewrite,
                    callback=collectRebase)

        assert len(result) == 1, repr(result)
        return result[0], None
示例#41
0
文件: users.py 项目: jensl/critic
    def multiple(parameters):
        """All repository filters.

           repository : REPOSITORY : -

           Include only filters for the specified repository, identified by its
           unique numeric id or short-name."""

        user = parameters.context["users"]
        repository = jsonapi.deduce("v1/repositories", parameters)
        if repository:
            repository_filters = user.repository_filters.get(
                repository, [])
        else:
            repository_filters = itertools.chain(
                *user.repository_filters.values())
        return jsonapi.sorted_by_id(repository_filters)
示例#42
0
文件: commits.py 项目: jensl/critic
    def single(parameters, argument):
        """Retrieve one (or more) commits from a Git repository.

           COMMIT_ID : integer

           Retrieve a commit identified by its unique numeric id.

           repository : REPOSITORY : -

           Specify repository to access, identified by its unique numeric id or
           short-name.  Required unless a repository is specified in the
           resource path."""

        repository = jsonapi.deduce("v1/repositories", parameters)
        if repository is None:
            raise jsonapi.UsageError(
                "Commit reference must have repository specified.")
        return Commits.setAsContext(parameters, api.commit.fetch(
            repository, commit_id=jsonapi.numeric_id(argument)))
示例#43
0
    def single(parameters, argument):
        """Retrieve one (or more) filechanges (changed files).

           FILE_ID : integer

           Retrieve the changes to a file identified by its unique numeric id.

           changeset : CHANGESET : -

           Retrieve the changes from a changeset identified by its unique numeric id.

           reposititory : REPOSITORY : -

           The repository in which the files exist."""

        changeset = jsonapi.deduce("v1/changesets", parameters)
        file = api.file.fetch(parameters.critic, jsonapi.numeric_id(argument))

        return FileChanges.setAsContext(
            parameters, api.filechange.fetch(parameters.critic, changeset,
                                             file))
示例#44
0
    def single(parameters, argument):
        """Retrieve one (or more) filechanges (changed files).

           FILE_ID : integer

           Retrieve the changes to a file identified by its unique numeric id.

           changeset : CHANGESET : -

           Retrieve the changes from a changeset identified by its unique numeric id.

           reposititory : REPOSITORY : -

           The repository in which the files exist."""

        changeset = jsonapi.deduce("v1/changesets", parameters)
        file = api.file.fetch(parameters.critic, jsonapi.numeric_id(argument))

        return FileChanges.setAsContext(
            parameters, api.filechange.fetch(
                parameters.critic, changeset, file))
示例#45
0
    def single(parameters, argument):
        """Retrieve one (or more) commits from a Git repository.

           COMMIT_ID : integer

           Retrieve a commit identified by its unique numeric id.

           repository : REPOSITORY : -

           Specify repository to access, identified by its unique numeric id or
           short-name.  Required unless a repository is specified in the
           resource path."""

        repository = jsonapi.deduce("v1/repositories", parameters)
        if repository is None:
            raise jsonapi.UsageError(
                "Commit reference must have repository specified.")
        return Commits.setAsContext(
            parameters,
            api.commit.fetch(repository,
                             commit_id=jsonapi.numeric_id(argument)))
示例#46
0
    def single(parameters, argument):
        """Retrieve one (or more) changesets.

           CHANGESET_ID : integer

           Retrieve a changeset identified by its unique numeric id.

           repository : REPOSITORY : -

           Specify repository to access, identified by its unique numeric id or
           short-name.  Required unless a repository is specified in the
           resource path."""

        repository = jsonapi.deduce("v1/repositories", parameters)
        if repository is None:
            raise jsonapi.UsageError(
                "repository needs to be specified, ex. &repository=<id>")
        return Changesets.setAsContext(parameters,
                                       api.changeset.fetch(
                                           parameters.critic,
                                           repository,
                                           jsonapi.numeric_id(argument)))
示例#47
0
    def multiple(parameters):
        """Retrieve all batches in the system (or review.)

           review : REVIEW_ID : integer

           Retrieve only batches in the specified review.  Can only be used if a
           review is not specified in the resource path.

           author : AUTHOR : integer or string

           Retrieve only batches authored by the specified user, identified by
           the user's unique numeric id or user name.

           unpublished : UNPUBLISHED : 'yes'

           Retrieve a single batch representing the current user's unpublished
           changes to a review. Must be combined with `review` and cannot be
           combined with `author`."""

        critic = parameters.critic

        review = jsonapi.deduce("v1/reviews", parameters)
        author = jsonapi.from_parameter("v1/users", "author", parameters)

        unpublished_parameter = parameters.getQueryParameter("unpublished")
        if unpublished_parameter is not None:
            if unpublished_parameter == "yes":
                if author is not None:
                    raise jsonapi.UsageError(
                        "Parameters 'author' and 'unpublished' cannot be "
                        "combined")
                return api.batch.fetchUnpublished(critic, review)
            else:
                raise jsonapi.UsageError(
                    "Invalid 'unpublished' parameter: %r (must be 'yes')"
                    % unpublished_parameter)

        return api.batch.fetchAll(critic, review=review, author=author)
示例#48
0
文件: branches.py 项目: jensl/critic
    def multiple(parameters):
        """Retrieve all branches in the Git repositories.

           repository : REPOSITORY : -

           Include only branches in one repository, identified by the
           repository's unique numeric id or short-name.

           name : NAME : string

           Retrieve only the branch with the specified name.  The name should
           <em>not</em> include the "refs/heads/" prefix.  When this parameter
           is specified a repository must be specified as well, either in the
           resource path or using the <code>repository</code> parameter."""

        repository = jsonapi.deduce("v1/repositories", parameters)
        name_parameter = parameters.getQueryParameter("name")
        if name_parameter:
            if repository is None:
                raise jsonapi.UsageError(
                    "Named branch access must have repository specified.")
            return api.branch.fetch(
                parameters.critic, repository=repository, name=name_parameter)
        return api.branch.fetchAll(parameters.critic, repository=repository)
示例#49
0
文件: commits.py 项目: jensl/critic
 def fromParameter(value, parameters):
     repository = jsonapi.deduce("v1/repositories", parameters)
     commit_id, ref = jsonapi.id_or_name(value)
     return api.commit.fetch(repository, commit_id, ref=ref)
示例#50
0
文件: comments.py 项目: jensl/critic
    def multiple(parameters):
        """Retrieve all comments in the system (or review.)

           with_reply : REPLY_ID : integer

           Retrieve only the comment to which the specified reply is a reply.
           This is equivalent to accessing /api/v1/comments/COMMENT_ID with that
           comment's numeric id.  When used, any other parameters are ignored.

           review : REVIEW_ID : integer

           Retrieve only comments in the specified review.  Can only be used if
           a review is not specified in the resource path.

           author : AUTHOR : integer or string

           Retrieve only comments authored by the specified user, identified by
           the user's unique numeric id or user name.

           comment_type : TYPE : -

           Retrieve only comments of the specified type.  Valid values are:
           <code>issue</code> and <code>note</code>.

           state : STATE : -

           Retrieve only issues in the specified state.  Valid values are:
           <code>open</code>, <code>addressed</code> and <code>resolved</code>.

           location_type : LOCATION : -

           Retrieve only comments in the specified type of location.  Valid
           values are: <code>general</code>, <code>commit-message</code> and
           <code>file-version</code>.

           changeset : CHANGESET_ID : integer

           Retrieve only comments visible in the specified changeset. Can not be
           combined with the <code>commit</code> parameter.

           commit : COMMIT : integer or string

           Retrieve only comments visible in the specified commit, either in its
           commit message or in the commit's version of a file. Combine with the
           <code>location_type</code> parameter to select only one of those
           possibilities. Can not be combined with the <code>changeset</code>
           parameter."""

        critic = parameters.critic

        reply = jsonapi.from_parameter("v1/replies", "with_reply", parameters)
        if reply:
            return reply.comment

        review = jsonapi.deduce("v1/reviews", parameters)
        author = jsonapi.from_parameter("v1/users", "author", parameters)

        comment_type_parameter = parameters.getQueryParameter("comment_type")
        if comment_type_parameter:
            if comment_type_parameter not in api.comment.Comment.TYPE_VALUES:
                raise jsonapi.UsageError("Invalid comment-type parameter: %r"
                                         % comment_type_parameter)
            comment_type = comment_type_parameter
        else:
            comment_type = None

        state_parameter = parameters.getQueryParameter("state")
        if state_parameter:
            if state_parameter not in api.comment.Issue.STATE_VALUES:
                raise jsonapi.UsageError(
                    "Invalid state parameter: %r" % state_parameter)
            state = state_parameter
        else:
            state = None

        location_type_parameter = parameters.getQueryParameter("location_type")
        if location_type_parameter:
            if location_type_parameter not in api.comment.Location.TYPE_VALUES:
                raise jsonapi.UsageError("Invalid location-type parameter: %r"
                                         % location_type_parameter)
            location_type = location_type_parameter
        else:
            location_type = None

        changeset = jsonapi.deduce("v1/changesets", parameters)
        commit = jsonapi.deduce("v1/commits", parameters)

        if changeset and commit:
            raise jsonapi.UsageError(
                "Incompatible parameters: changeset and commit")

        return api.comment.fetchAll(critic, review=review, author=author,
                                    comment_type=comment_type, state=state,
                                    location_type=location_type,
                                    changeset=changeset, commit=commit)
示例#51
0
文件: comments.py 项目: jensl/critic
    def create(parameters, value, values, data):
        critic = parameters.critic
        user = parameters.context.get("users", critic.actual_user)
        path = parameters.subresource_path

        if value and path == ["replies"]:
            assert isinstance(value, api.comment.Comment)
            Comments.setAsContext(parameters, value)
            raise jsonapi.InternalRedirect("v1/replies")

        if value or values or path:
            raise jsonapi.UsageError("Invalid POST request")

        converted = jsonapi.convert(
            parameters,
            {
                "type": api.comment.Comment.TYPE_VALUES,
                "review!?": api.review.Review,
                "author?": api.user.User,
                "location?": {
                    # Note: "general" not included here; |location| should be
                    #       omitted instead.
                    "type": frozenset(["commit-message", "file-version"]),
                    "first_line": int,
                    "last_line": int,
                    "commit?": api.commit.Commit,
                    "file?": api.file.File,
                    "changeset?": api.changeset.Changeset,
                    "side?": frozenset(["old", "new"]),
                },
                "text": str
            },
            data)

        review = jsonapi.deduce("v1/reviews", parameters)

        if not review:
            if "review" not in converted:
                raise jsonapi.UsageError("No review specified")
            review = converted["review"]
        elif "review" in converted and review != converted["review"]:
            raise jsonapi.UsageError("Conflicting reviews specified")

        if "author" in converted:
            author = converted["author"]
        else:
            author = critic.actual_user

        if converted["type"] == "issue":
            expected_class = api.comment.Issue
        else:
            expected_class = api.comment.Note

        converted_location = converted.get("location")
        if converted_location:
            location_type = converted_location.pop("type")
            if location_type == "commit-message":
                required_fields = set(("first_line", "last_line", "commit"))
                optional_fields = set()
            else:
                required_fields = set(("first_line", "last_line", "file"))
                optional_fields = set(("commit", "changeset", "side"))
            accepted_fields = required_fields | optional_fields

            for required_field in required_fields:
                if required_field not in converted_location:
                    raise jsonapi.InputError(
                        "data.location.%s: missing attribute" % required_field)
            for actual_field in converted_location.keys():
                if actual_field not in accepted_fields:
                    raise jsonapi.InputError(
                        "data.location.%s: unexpected attribute" % actual_field)

            if location_type == "commit-message":
                max_line = len(
                    converted_location["commit"].message.splitlines())
            else:
                if "commit" in converted_location:
                    if "changeset" in converted_location:
                        raise jsonapi.InputError(
                            "data.location: only one of commit and changeset "
                            "can be specified")
                    changeset = None
                    side = None
                    commit = converted_location["commit"]
                elif "changeset" not in converted_location:
                    raise jsonapi.InputError(
                        "data.location: one of commit and changeset must be "
                        "specified")
                elif "side" not in converted_location:
                    raise jsonapi.InputError(
                        "data.location.side: missing attribute (required when "
                        "changeset is specified)")
                else:
                    changeset = converted_location["changeset"]
                    side = converted_location["side"]
                    commit = None

            first_line = converted_location["first_line"]
            last_line = converted_location["last_line"]

            if location_type == "commit-message":
                location = api.comment.CommitMessageLocation.make(
                    critic, first_line, last_line, converted_location["commit"])
            else:
                location = api.comment.FileVersionLocation.make(
                    critic, first_line, last_line, converted_location["file"],
                    changeset, side, commit)
        else:
            location = None

        result = []

        def collectComment(comment):
            assert isinstance(comment, expected_class), repr(comment)
            result.append(comment)

        with api.transaction.Transaction(critic) as transaction:
            transaction \
                .modifyReview(review) \
                .createComment(
                    comment_type=converted["type"],
                    author=author,
                    text=converted["text"],
                    location=location,
                    callback=collectComment)

        assert len(result) == 1, repr(result)
        return result[0], None
示例#52
0
    def create(parameters, value, values, data):
        critic = parameters.critic
        user = parameters.context.get("users", critic.actual_user)
        path = parameters.subresource_path

        if value and path == ["replies"]:
            assert isinstance(value, api.comment.Comment)
            Comments.setAsContext(parameters, value)
            raise jsonapi.InternalRedirect("v1/replies")

        if value or values or path:
            raise jsonapi.UsageError("Invalid POST request")

        converted = jsonapi.convert(
            parameters,
            {
                "type": api.comment.Comment.TYPE_VALUES,
                "review!?": api.review.Review,
                "author?": api.user.User,
                "location?": {
                    # Note: "general" not included here; |location| should be
                    #       omitted instead.
                    "type": frozenset(["commit-message", "file-version"]),
                    "first_line": int,
                    "last_line": int,
                    "commit?": api.commit.Commit,
                    "file?": api.file.File,
                    "changeset?": api.changeset.Changeset,
                    "side?": frozenset(["old", "new"]),
                },
                "text": str
            },
            data)

        review = jsonapi.deduce("v1/reviews", parameters)

        if not review:
            if "review" not in converted:
                raise jsonapi.UsageError("No review specified")
            review = converted["review"]
        elif "review" in converted and review != converted["review"]:
            raise jsonapi.UsageError("Conflicting reviews specified")

        if "author" in converted:
            author = converted["author"]
        else:
            author = critic.actual_user

        if converted["type"] == "issue":
            expected_class = api.comment.Issue
        else:
            expected_class = api.comment.Note

        converted_location = converted.get("location")
        if converted_location:
            location_type = converted_location.pop("type")
            if location_type == "commit-message":
                required_fields = set(("first_line", "last_line", "commit"))
                optional_fields = set()
            else:
                required_fields = set(("first_line", "last_line", "file"))
                optional_fields = set(("commit", "changeset", "side"))
            accepted_fields = required_fields | optional_fields

            for required_field in required_fields:
                if required_field not in converted_location:
                    raise jsonapi.InputError(
                        "data.location.%s: missing attribute" % required_field)
            for actual_field in converted_location.keys():
                if actual_field not in accepted_fields:
                    raise jsonapi.InputError(
                        "data.location.%s: unexpected attribute" %
                        actual_field)

            if location_type == "commit-message":
                max_line = len(
                    converted_location["commit"].message.splitlines())
            else:
                if "commit" in converted_location:
                    if "changeset" in converted_location:
                        raise jsonapi.InputError(
                            "data.location: only one of commit and changeset "
                            "can be specified")
                    changeset = None
                    side = None
                    commit = converted_location["commit"]
                elif "changeset" not in converted_location:
                    raise jsonapi.InputError(
                        "data.location: one of commit and changeset must be "
                        "specified")
                elif "side" not in converted_location:
                    raise jsonapi.InputError(
                        "data.location.side: missing attribute (required when "
                        "changeset is specified)")
                else:
                    changeset = converted_location["changeset"]
                    side = converted_location["side"]
                    commit = None

            first_line = converted_location["first_line"]
            last_line = converted_location["last_line"]

            if location_type == "commit-message":
                location = api.comment.CommitMessageLocation.make(
                    critic, first_line, last_line,
                    converted_location["commit"])
            else:
                location = api.comment.FileVersionLocation.make(
                    critic, first_line, last_line, converted_location["file"],
                    changeset, side, commit)
        else:
            location = None

        result = []

        def collectComment(comment):
            assert isinstance(comment, expected_class), repr(comment)
            result.append(comment)

        with api.transaction.Transaction(critic) as transaction:
            transaction \
                .modifyReview(review) \
                .createComment(
                    comment_type=converted["type"],
                    author=author,
                    text=converted["text"],
                    location=location,
                    callback=collectComment)

        assert len(result) == 1, repr(result)
        return result[0], None
示例#53
0
文件: filediffs.py 项目: jensl/critic
    def json(value, parameters):
        """TODO: add documentation"""

        def part_as_dict(part):
            if not part.type and not part.state:
                return part.content
            dict_part = {
                "content": part.content
            }
            if part.type:
                dict_part["type"] = part.type
            if part.state:
                dict_part["state"] = part.state
            return dict_part

        def line_as_dict(line):
            dict_line = {
                "type": line.type_string,
                "old_offset": line.old_offset,
                "new_offset": line.new_offset,
            }
            dict_line["content"] = [part_as_dict(part) for
                                    part in line.content]
            return dict_line

        def chunk_as_dict(chunk):
            return {
                "content": [line_as_dict(line) for line in chunk.lines],
                "old_offset": chunk.old_offset,
                "old_count": chunk.old_count,
                "new_offset": chunk.new_offset,
                "new_count": chunk.new_count
            }

        context_lines = parameters.getQueryParameter(
            "context_lines", int, ValueError)
        if context_lines is not None:
            if context_lines < 0:
                raise jsonapi.UsageError(
                    "Negative number of context lines not supported")
        else:
            # TODO: load this from the user's config (or make it mandatory and
            # let the client handle config loading).
            context_lines = 3

        comment = jsonapi.deduce("v1/comments", parameters)
        if comment is not None:
            comments = [comment]
            ignore_chunks = True
        else:
            review = jsonapi.deduce("v1/reviews", parameters)
            if review is not None:
                comments = api.comment.fetchAll(
                    parameters.critic, review=review,
                    changeset=value.filechange.changeset)
            else:
                comments = None
            ignore_chunks = False

        macro_chunks = value.getMacroChunks(
            context_lines, comments, ignore_chunks)

        dict_chunks = [chunk_as_dict(chunk) for chunk in macro_chunks]
        return parameters.filtered(
            "filediffs", {
                "file": value.filechange,
                "changeset": value.filechange.changeset,
                "macro_chunks": dict_chunks,
                "old_count": value.old_count,
                "new_count": value.new_count
            })