Exemplo n.º 1
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)
Exemplo n.º 2
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
Exemplo n.º 3
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)
Exemplo n.º 4
0
    def update(parameters, value, values, data):
        critic = parameters.critic

        if parameters.subresource_path:
            assert parameters.subresource_path[0] == "delegates"

            if len(parameters.subresource_path) == 2:
                raise jsonapi.UsageError("can't update specific delegate")

            delegates = jsonapi.convert(parameters, [api.user.User], data)
        else:
            converted = jsonapi.convert(parameters,
                                        {"delegates?": [api.user.User]}, data)

            delegates = converted.get("delegates")

        if value:
            repository_filters = [value]
        else:
            repository_filters = values

        with api.transaction.Transaction(critic) as transaction:
            for repository_filter in repository_filters:
                if delegates is not None:
                    transaction \
                        .modifyUser(repository_filter.subject) \
                        .modifyFilter(repository_filter) \
                        .setDelegates(delegates)

        return value, values
Exemplo n.º 5
0
    def multiple(critic, 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.v1.repositories.Repositories.deduce(
            critic, 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(critic,
                                    repository=repository,
                                    name=name_parameter)
        return api.branch.fetchAll(critic, repository=repository)
Exemplo n.º 6
0
    def update(parameters, value, values, data):
        critic = parameters.critic
        filechanges = [value] if value else values

        reviews = set(filechange.review for filechange in filechanges)
        if len(reviews) > 1:
            raise jsonapi.UsageError("Multiple reviews updated")
        review = reviews.pop()

        converted = jsonapi.convert(parameters, {
            "draft_changes": {
                "new_is_reviewed": bool,
            },
        }, data)

        is_reviewed = converted["draft_changes"]["new_is_reviewed"]

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

            if is_reviewed:
                for filechange in filechanges:
                    modifier.markChangeAsReviewed(filechange)
            else:
                for filechange in filechanges:
                    modifier.markChangeAsPending(filechange)
Exemplo n.º 7
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
Exemplo n.º 8
0
    def multiple(parameters):
        """Retrieve a single named repository or all repositories on this
           system.

           name : SHORT_NAME : string

           Retrieve a repository identified by its unique short-name.  This is
           equivalent to accessing /api/v1/repositories/REPOSITORY_ID with that
           repository's numeric id.  When used, any other parameters are
           ignored.

           filter : highlighted : -

           If specified, retrieve only "highlighted" repositories.  These are
           repositories that are deemed of particular interest for the signed-in
           user.  (If no user is signed in, no repositories are highlighted.)"""

        name_parameter = parameters.getQueryParameter("name")
        if name_parameter:
            return api.repository.fetch(parameters.critic, name=name_parameter)
        filter_parameter = parameters.getQueryParameter("filter")
        if filter_parameter is not None:
            if filter_parameter == "highlighted":
                repositories = api.repository.fetchHighlighted(
                    parameters.critic)
            else:
                raise jsonapi.UsageError(
                    "Invalid repository filter parameter: %r"
                    % filter_parameter)
        else:
            repositories = api.repository.fetchAll(parameters.critic)
        return repositories
Exemplo n.º 9
0
    def multiple(critic, 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.v1.repositories.Repositories.deduce(
            critic, 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(critic, repository=repository, state=state)
Exemplo n.º 10
0
    def delete(parameters, value, values):
        critic = parameters.critic
        path = parameters.subresource_path

        if value:
            profiles = [value]
        else:
            profiles = values

        if len(path) in (2, 3) \
                and path[0] in CATEGORIES \
                and path[1] == "exceptions":
            exception_id = path[2] if len(path) == 3 else None

            with api.transaction.Transaction(critic) as transaction:
                for profile in profiles:
                    modifier = transaction.modifyAccessControlProfile(profile) \
                        .modifyProfile() \
                        .modifyExceptions(path[0])

                    if exception_id is None:
                        modifier.deleteAll()
                    else:
                        modifier.delete(exception_id)

            return value, values

        if path:
            raise jsonapi.UsageError("Invalid DELETE request")

        with api.transaction.Transaction(critic) as transaction:
            for profile in profiles:
                transaction.modifyAccessControlProfile(profile) \
                    .delete()
Exemplo n.º 11
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
    def create(parameters, value, values, data):
        critic = parameters.critic
        user = parameters.context.get("users", critic.actual_user)

        if parameters.subresource_path:
            raise jsonapi.UsageError("Invalid POST request")

        # Create a labeled access control profile selector.
        assert not (value or values)

        converted = jsonapi.convert(
            parameters, {
                "labels": [str],
                "profile": api.accesscontrolprofile.AccessControlProfile
            }, data)

        result = []

        def collectLabeledAccessControlProfile(labeled_profile):
            assert isinstance(
                labeled_profile,
                api.labeledaccesscontrolprofile.LabeledAccessControlProfile)
            result.append(labeled_profile)

        with api.transaction.Transaction(critic) as transaction:
            transaction.createLabeledAccessControlProfile(
                converted["labels"],
                converted["profile"],
                callback=collectLabeledAccessControlProfile)

        assert len(result) == 1
        return result[0], None
Exemplo n.º 13
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
Exemplo n.º 14
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
Exemplo n.º 15
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)
Exemplo n.º 16
0
 def deduce(parameters):
     user = parameters.context.get("users")
     user_parameter = parameters.getQueryParameter("user")
     if user_parameter is not None:
         if user is not None:
             raise jsonapi.UsageError("Redundant query parameter: user=%s" %
                                      user_parameter)
         user = Users.fromParameter(user_parameter, parameters)
     return user
Exemplo n.º 17
0
 def deduce(parameters):
     commit = parameters.context.get(Commits.name)
     commit_parameter = parameters.getQueryParameter("commit")
     if commit_parameter is not None:
         if commit is not None:
             raise jsonapi.UsageError(
                 "Redundant query parameter: commit=%s" % commit_parameter)
         commit = Commits.fromParameter(commit_parameter, parameters)
     return commit
Exemplo n.º 18
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)
Exemplo n.º 19
0
    def multiple(parameters):
        """Retrieve a single named user or all users of this system.

           name : NAME : string

           Retrieve only the user with the given name.  This is equivalent to
           accessing /api/v1/users/USER_ID with that user's numeric id.  When
           used, any other parameters are ignored.

           status : USER_STATUS[,USER_STATUS,...] : string

           Include only users whose status is one of the specified.  Valid
           values are: <code>current</code>, <code>absent</code>,
           <code>retired</code>.

           sort : SORT_KEY : string

           Sort the returned users by the specified key.  Valid values are:
           <code>id</code>, <code>name</code>, <code>fullname</code>,
           <code>email</code>."""

        name_parameter = parameters.getQueryParameter("name")
        if name_parameter:
            return api.user.fetch(parameters.critic, name=name_parameter)
        status_parameter = parameters.getQueryParameter("status")
        if status_parameter:
            status = set(status_parameter.split(","))
            invalid = status - api.user.User.STATUS_VALUES
            if invalid:
                raise jsonapi.UsageError("Invalid user status values: %s" %
                                         ", ".join(map(repr, sorted(invalid))))
        else:
            status = None
        sort_parameter = parameters.getQueryParameter("sort")
        if sort_parameter:
            if sort_parameter not in ("id", "name", "fullname", "email"):
                raise jsonapi.UsageError("Invalid user sort parameter: %r" %
                                         sort_parameter)
            sort_key = lambda user: getattr(user, sort_parameter)
        else:
            sort_key = lambda user: user.id
        return sorted(api.user.fetchAll(parameters.critic, status=status),
                      key=sort_key)
Exemplo n.º 20
0
 def deduce(critic, parameters):
     review = parameters.context.get("reviews")
     review_parameter = parameters.getQueryParameter("review")
     if review_parameter is not None:
         if review is not None:
             raise jsonapi.UsageError(
                 "Redundant query parameter: review=%s" % review_parameter)
         review = api.review.fetch(
             critic, review_id=jsonapi.numeric_id(review_parameter))
     return review
Exemplo n.º 21
0
 def deduce(critic, 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(critic, repository_parameter)
     return repository
Exemplo n.º 22
0
 def deduce(parameters):
     batch = parameters.context.get("batches")
     batch_parameter = parameters.getQueryParameter("batch")
     if batch_parameter is not None:
         if batch is not None:
             raise jsonapi.UsageError(
                 "Redundant query parameter: batch=%s" % batch_parameter)
         batch = api.batch.fetch(
             parameters.critic, jsonapi.numeric_id(batch_parameter))
     return batch
Exemplo n.º 23
0
 def deduce(parameters):
     file_obj = parameters.context.get((Files.name))
     file_parameter = parameters.getQueryParameter("file")
     if file_parameter is not None:
         if file_obj is not None:
             raise jsonapi.UsageError(
                 "Redundant query parameter: file=%s"
                 % file_parameter)
         file_id = Files.fromParameter(file_parameter, parameters)
         file_obj = api.file.fetch(parameters.critic, file_id)
     return file_obj
Exemplo n.º 24
0
 def deduce(parameters):
     profile = parameters.context.get("accesscontrolprofiles")
     profile_parameter = parameters.getQueryParameter("profile")
     if profile_parameter is not None:
         if profile is not None:
             raise jsonapi.UsageError(
                 "Redundant query parameter: profile=%s" %
                 profile_parameter)
         profile_id = jsonapi.numeric_id(profile_parameter)
         profile = api.accesscontrolprofile.fetch(parameters.critic,
                                                  profile_id=profile_id)
     return profile
Exemplo n.º 25
0
    def delete(parameters, value, values):
        critic = parameters.critic

        if value is None:
            raise jsonapi.UsageError(
                "Only one rebase can currently be deleted per request")
        rebase = value

        with api.transaction.Transaction(critic) as transaction:
            transaction \
                .modifyReview(rebase.review) \
                .cancelRebase(rebase)
Exemplo n.º 26
0
 def deduce(parameters):
     comment = parameters.context.get("comments")
     comment_parameter = parameters.getQueryParameter("comment")
     if comment_parameter is not None:
         if comment is not None:
             raise jsonapi.UsageError(
                 "Redundant query parameter: comment=%s" %
                 comment_parameter)
         comment = api.comment.fetch(
             parameters.critic,
             comment_id=jsonapi.numeric_id(comment_parameter))
     return comment
Exemplo n.º 27
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
Exemplo n.º 28
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)
Exemplo n.º 29
0
    def create(parameters, value, values, data):
        critic = parameters.critic
        user = parameters.context.get("users", critic.actual_user)
        profiles = [value] if value else values
        path = parameters.subresource_path

        if 0 < len(path) < 2:
            raise jsonapi.UsageError("Invalid POST request")

        if len(path) == 2 \
                and path[0] in CATEGORIES \
                and path[1] == "exceptions":
            # Create an rule exception.

            if path[0] == "http":
                exception_type = HTTP_EXCEPTION
            elif path[0] == "repositories":
                exception_type = REPOSITORIES_EXCEPTION
            else:
                exception_type = EXTENSION_EXCEPTION

            converted = jsonapi.convert(parameters, exception_type, data)

            with api.transaction.Transaction(critic) as transaction:
                for profile in profiles:
                    modifier = transaction.modifyAccessControlProfile(profile) \
                        .modifyExceptions(path[0]) \
                        .add(**converted)

            return value, values

        # Create an access control profile.
        assert not profiles

        converted = jsonapi.convert(parameters, PROFILE_WITH_TITLE, data)

        result = []

        def collectAccessControlProfile(profile):
            assert isinstance(profile,
                              api.accesscontrolprofile.AccessControlProfile)
            result.append(profile)

        with api.transaction.Transaction(critic) as transaction:
            modifier = transaction.createAccessControlProfile(
                callback=collectAccessControlProfile)
            updateProfile(modifier, converted)

        assert len(result) == 1
        return result[0], None
Exemplo n.º 30
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)