Blame pagure/api/fork.py

Pierre-Yves Chibon 1e1949
# -*- coding: utf-8 -*-
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 1e1949
"""
Pierre-Yves Chibon b130e5
 (c) 2015-2017 - Copyright Red Hat Inc
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 1e1949
 Authors:
Pierre-Yves Chibon 1e1949
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 1e1949
"""
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 67d1cc
from __future__ import unicode_literals, absolute_import
Aurélien Bompard 831553
Pierre-Yves Chibon b130e5
import logging
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 9811e6
import flask
Pierre-Yves Chibon 9811e6
import pygit2
Pierre-Yves Chibon 1e1949
from sqlalchemy.exc import SQLAlchemyError
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 1e1949
import pagure
Pierre-Yves Chibon 1e1949
import pagure.exceptions
Pierre-Yves Chibon 930073
import pagure.lib.query
Patrick Uiterwijk e6f1fd
import pagure.lib.tasks
Pierre-Yves Chibon 9c2953
from pagure.api import (
Pierre-Yves Chibon 9c2953
    API,
Pierre-Yves Chibon 9c2953
    api_method,
Pierre-Yves Chibon 9c2953
    api_login_required,
Pierre-Yves Chibon 9c2953
    APIERROR,
Pierre-Yves Chibon 9c2953
    get_authorized_api_project,
Pierre-Yves Chibon 9c2953
    get_request_data,
Pierre-Yves Chibon 9c2953
    get_page,
Pierre-Yves Chibon 9c2953
    get_per_page,
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon b130e5
from pagure.config import config as pagure_config
Pierre-Yves Chibon 6fdb42
from pagure.utils import is_repo_committer, is_true
Pierre-Yves Chibon 6fdb42
from pagure.api.utils import (
Pierre-Yves Chibon 6fdb42
    _get_repo,
Pierre-Yves Chibon 6fdb42
    _check_token,
Pierre-Yves Chibon 6fdb42
    _get_request,
Pierre-Yves Chibon 6fdb42
    _check_pull_request,
Pierre-Yves Chibon 6fdb42
    _check_pull_request_access,
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon b130e5
_log = logging.getLogger(__name__)
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 9c2953
@API.route("/<repo>/pull-requests")</repo>
Pierre-Yves Chibon 9c2953
@API.route("/<namespace>/<repo>/pull-requests")</repo></namespace>
Pierre-Yves Chibon 9c2953
@API.route("/fork/<username>/<repo>/pull-requests")</repo></username>
Pierre-Yves Chibon 9c2953
@API.route("/fork/<username>/<namespace>/<repo>/pull-requests")</repo></namespace></username>
Pierre-Yves Chibon c0cf15
@api_method
Pierre-Yves Chibon 34ece4
def api_pull_request_views(repo, username=None, namespace=None):
Pierre-Yves Chibon c0cf15
    """
Pierre-Yves Chibon c0cf15
    List project's Pull-Requests
Pierre-Yves Chibon c0cf15
    ----------------------------
Lei Yang 566c51
    Retrieve pull requests of a project.
Pierre-Yves Chibon c0cf15
Pierre-Yves Chibon c0cf15
    ::
Pierre-Yves Chibon c0cf15
Lei Yang 566c51
        GET /api/0/<repo>/pull-requests</repo>
Pierre-Yves Chibon 34ece4
        GET /api/0/<namespace>/<repo>/pull-requests</repo></namespace>
Pierre-Yves Chibon c0cf15
Lei Yang 566c51
    ::
Lei Yang 566c51
Lei Yang 566c51
        GET /api/0/fork/<username>/<repo>/pull-requests</repo></username>
Pierre-Yves Chibon 34ece4
        GET /api/0/fork/<username>/<namespace>/<repo>/pull-requests</repo></namespace></username>
Pierre-Yves Chibon c0cf15
Lei Yang 566c51
    Parameters
Lei Yang 566c51
    ^^^^^^^^^^
Pierre-Yves Chibon c0cf15
Pierre-Yves Chibon e1497f
    +---------------+----------+--------------+----------------------------+
Pierre-Yves Chibon e1497f
    | Key           | Type     | Optionality  | Description                |
Pierre-Yves Chibon e1497f
    +===============+==========+==============+============================+
Pierre-Yves Chibon e68983
    | ``status``    | string   | Optional     | | Filter the status of     |
Pierre-Yves Chibon e1497f
    |               |          |              |   pull requests. Default:  |
Pierre-Yves Chibon e1497f
    |               |          |              |   ``True`` (opened pull    |
Pierre-Yves Chibon e68983
    |               |          |              |   requests), can be ``0``  |
Pierre-Yves Chibon e68983
    |               |          |              |   or ``closed`` for closed |
Pierre-Yves Chibon e68983
    |               |          |              |   requests or ``Merged``   |
Pierre-Yves Chibon e68983
    |               |          |              |   for merged requests.     |
Eric Barbour 395fd2
    |               |          |              |   ``All`` returns closed,  |
Eric Barbour 395fd2
    |               |          |              |   merged and open requests.|
Pierre-Yves Chibon e1497f
    +---------------+----------+--------------+----------------------------+
Pierre-Yves Chibon e1497f
    | ``assignee``  | string   | Optional     | | Filter the assignee of   |
Pierre-Yves Chibon e1497f
    |               |          |              |   pull requests            |
Pierre-Yves Chibon e1497f
    +---------------+----------+--------------+----------------------------+
Pierre-Yves Chibon e1497f
    | ``author``    | string   | Optional     | | Filter the author of     |
Pierre-Yves Chibon e1497f
    |               |          |              |   pull requests            |
Pierre-Yves Chibon e1497f
    +---------------+----------+--------------+----------------------------+
Julen Landa Alustiza 49aa66
    | ``tags``      | string   | Optional     | | A list of tags you       |
Julen Landa Alustiza 49aa66
    |               |          |              |   wish to filter. If you   |
Julen Landa Alustiza 49aa66
    |               |          |              |   want to filter for pull  |
Julen Landa Alustiza 49aa66
    |               |          |              |   requests not having a    |
Julen Landa Alustiza 49aa66
    |               |          |              |   tag, add an exclamation  |
Julen Landa Alustiza 49aa66
    |               |          |              |   mark in front of it      |
Julen Landa Alustiza 49aa66
    +---------------+----------+--------------+----------------------------+
Pierre-Yves Chibon c0cf15
Lei Yang 566c51
    Sample response
Lei Yang 566c51
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon c0cf15
Pierre-Yves Chibon c0cf15
    ::
Pierre-Yves Chibon c0cf15
Pierre-Yves Chibon c0cf15
        {
Pierre-Yves Chibon f3385b
          "args": {
Pierre-Yves Chibon f3385b
            "assignee": null,
Pierre-Yves Chibon f3385b
            "author": null,
Julen Landa Alustiza 49aa66
            "status": true,
Julen Landa Alustiza 49aa66
            "tags": null
Pierre-Yves Chibon f3385b
          },
Pierre-Yves Chibon 7a734f
          "total_requests": 1,
Pierre-Yves Chibon f11edf
          "requests": [
Pierre-Yves Chibon f11edf
            {
Pierre-Yves Chibon f11edf
              "assignee": null,
Pierre-Yves Chibon f11edf
              "branch": "master",
Pierre-Yves Chibon f11edf
              "branch_from": "master",
Pierre-Yves Chibon 15c503
              "closed_at": null,
Pierre-Yves Chibon 15c503
              "closed_by": null,
Pierre-Yves Chibon f11edf
              "comments": [],
Pierre-Yves Chibon f11edf
              "commit_start": null,
Pierre-Yves Chibon f11edf
              "commit_stop": null,
Pierre-Yves Chibon f11edf
              "date_created": "1431414800",
Pierre-Yves Chibon f11edf
              "id": 1,
Pierre-Yves Chibon f11edf
              "project": {
Pierre-Yves Chibon f11edf
                "date_created": "1431414800",
Pierre-Yves Chibon f11edf
                "description": "test project #1",
Pierre-Yves Chibon f11edf
                "id": 1,
Pierre-Yves Chibon f11edf
                "name": "test",
Pierre-Yves Chibon f11edf
                "parent": null,
Pierre-Yves Chibon f11edf
                "user": {
Pierre-Yves Chibon f11edf
                  "fullname": "PY C",
Pierre-Yves Chibon f11edf
                  "name": "pingou"
Pierre-Yves Chibon f11edf
                }
Pierre-Yves Chibon f11edf
              },
Pierre-Yves Chibon f11edf
              "repo_from": {
Pierre-Yves Chibon f11edf
                "date_created": "1431414800",
Pierre-Yves Chibon f11edf
                "description": "test project #1",
Pierre-Yves Chibon f11edf
                "id": 1,
Pierre-Yves Chibon f11edf
                "name": "test",
Pierre-Yves Chibon f11edf
                "parent": null,
Pierre-Yves Chibon f11edf
                "user": {
Pierre-Yves Chibon f11edf
                  "fullname": "PY C",
Pierre-Yves Chibon f11edf
                  "name": "pingou"
Pierre-Yves Chibon f11edf
                }
Pierre-Yves Chibon f11edf
              },
Pierre-Yves Chibon 9e2f39
              "status": "Open",
Pierre-Yves Chibon f11edf
              "title": "test pull-request",
Pierre-Yves Chibon f11edf
              "uid": "1431414800",
Pierre-Yves Chibon e68983
              "updated_on": "1431414800",
Pierre-Yves Chibon f11edf
              "user": {
Pierre-Yves Chibon f11edf
                "fullname": "PY C",
Pierre-Yves Chibon f11edf
                "name": "pingou"
Pierre-Yves Chibon f11edf
              }
Pierre-Yves Chibon c0cf15
            }
Pierre-Yves Chibon f3385b
          ]
Pierre-Yves Chibon c0cf15
        }
Pierre-Yves Chibon c0cf15
Pierre-Yves Chibon c0cf15
    """
Pierre-Yves Chibon c0cf15
Pierre-Yves Chibon 6fdb42
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 6fdb42
    _check_pull_request(repo)
Pierre-Yves Chibon c0cf15
Pierre-Yves Chibon 9c2953
    status = flask.request.args.get("status", True)
Pierre-Yves Chibon 9c2953
    assignee = flask.request.args.get("assignee", None)
Pierre-Yves Chibon 9c2953
    author = flask.request.args.get("author", None)
Julen Landa Alustiza 49aa66
    tags = flask.request.args.getlist("tags")
Julen Landa Alustiza 49aa66
    tags = [tag.strip() for tag in tags if tag.strip()]
Pierre-Yves Chibon c0cf15
Aurélien Bompard 619e2a
    status_text = ("%s" % status).lower()
Pierre-Yves Chibon c0cf15
    requests = []
Lenka Segura 96f2fe
    if status_text in ["0", "false"]:
Pierre-Yves Chibon 930073
        requests = pagure.lib.query.search_pull_requests(
Pierre-Yves Chibon b130e5
            flask.g.session,
Pierre-Yves Chibon c0cf15
            project_id=repo.id,
Pierre-Yves Chibon c0cf15
            status=False,
Pierre-Yves Chibon c0cf15
            assignee=assignee,
Pierre-Yves Chibon 9c2953
            author=author,
Julen Landa Alustiza 49aa66
            tags=tags,
Pierre-Yves Chibon 9c2953
        )
Eric Barbour 395fd2
Pierre-Yves Chibon 9c2953
    elif status_text == "all":
Pierre-Yves Chibon 930073
        requests = pagure.lib.query.search_pull_requests(
Pierre-Yves Chibon b130e5
            flask.g.session,
Eric Barbour 395fd2
            project_id=repo.id,
Eric Barbour 395fd2
            status=None,
Eric Barbour 395fd2
            assignee=assignee,
Pierre-Yves Chibon 9c2953
            author=author,
Julen Landa Alustiza 49aa66
            tags=tags,
Pierre-Yves Chibon 9c2953
        )
Eric Barbour 395fd2
Pierre-Yves Chibon c0cf15
    else:
Pierre-Yves Chibon 930073
        requests = pagure.lib.query.search_pull_requests(
Pierre-Yves Chibon b130e5
            flask.g.session,
Pierre-Yves Chibon c0cf15
            project_id=repo.id,
Pierre-Yves Chibon c0cf15
            assignee=assignee,
Pierre-Yves Chibon c0cf15
            author=author,
Pierre-Yves Chibon 9c2953
            status=status,
Julen Landa Alustiza 49aa66
            tags=tags,
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon c0cf15
Karsten Hopp 566852
    page = get_page()
Karsten Hopp 566852
    per_page = get_per_page()
Karsten Hopp 566852
Pierre-Yves Chibon 930073
    pagination_metadata = pagure.lib.query.get_pagination_metadata(
Pierre-Yves Chibon 9c2953
        flask.request, page, per_page, len(requests)
Pierre-Yves Chibon 9c2953
    )
Karsten Hopp 566852
    start = (page - 1) * per_page
Karsten Hopp 566852
    if start + per_page > len(requests):
Karsten Hopp 566852
        requests_page = requests[start:]
Karsten Hopp 566852
    else:
Pierre-Yves Chibon 9c2953
        requests_page = requests[start : (start + per_page)]
Karsten Hopp 566852
Karsten Hopp 566852
    jsonout = {
Pierre-Yves Chibon 9c2953
        "total_requests": len(requests),
Pierre-Yves Chibon 9c2953
        "requests": [
Pierre-Yves Chibon 9c2953
            request.to_json(public=True, api=True) for request in requests_page
Pierre-Yves Chibon 9c2953
        ],
Julen Landa Alustiza 49aa66
        "args": {
Julen Landa Alustiza 49aa66
            "status": status,
Julen Landa Alustiza 49aa66
            "assignee": assignee,
Julen Landa Alustiza 49aa66
            "author": author,
Julen Landa Alustiza 49aa66
            "tags": tags,
Julen Landa Alustiza 49aa66
        },
Karsten Hopp 566852
    }
Karsten Hopp 566852
    if pagination_metadata:
Pierre-Yves Chibon 9c2953
        jsonout["args"]["page"] = page
Pierre-Yves Chibon 9c2953
        jsonout["args"]["per_page"] = per_page
Pierre-Yves Chibon 9c2953
        jsonout["pagination"] = pagination_metadata
Karsten Hopp 566852
    return flask.jsonify(jsonout)
Pierre-Yves Chibon c0cf15
Pierre-Yves Chibon c0cf15
Slavek Kabrda 1a6e21
@API.route("/pull-requests/<uid>")</uid>
Slavek Kabrda 1a6e21
@api_method
Slavek Kabrda 1a6e21
def api_pull_request_by_uid_view(uid):
Slavek Kabrda 1a6e21
    """
Slavek Kabrda 1a6e21
    Pull-request by UID information
Slavek Kabrda 1a6e21
    -------------------------------
Slavek Kabrda 1a6e21
    Retrieve information of a pull request specified by uid.
Slavek Kabrda 1a6e21
Slavek Kabrda 1a6e21
    ::
Slavek Kabrda 1a6e21
Slavek Kabrda 1a6e21
        GET /api/0/pull-requests/<uid></uid>
Slavek Kabrda 1a6e21
Slavek Kabrda 1a6e21
    Sample response
Slavek Kabrda 1a6e21
    ^^^^^^^^^^^^^^^
Slavek Kabrda 1a6e21
Slavek Kabrda 1a6e21
    ::
Slavek Kabrda 1a6e21
Slavek Kabrda 1a6e21
        {
Slavek Kabrda 1a6e21
          "assignee": null,
Slavek Kabrda 1a6e21
          "branch": "master",
Slavek Kabrda 1a6e21
          "branch_from": "master",
Slavek Kabrda 1a6e21
          "closed_at": null,
Slavek Kabrda 1a6e21
          "closed_by": null,
Slavek Kabrda 1a6e21
          "comments": [],
Slavek Kabrda 1a6e21
          "commit_start": null,
Slavek Kabrda 1a6e21
          "commit_stop": null,
Slavek Kabrda 1a6e21
          "date_created": "1431414800",
Slavek Kabrda 1a6e21
          "id": 1,
Slavek Kabrda 1a6e21
          "project": {
Slavek Kabrda 1a6e21
            "close_status": [],
Slavek Kabrda 1a6e21
            "custom_keys": [],
Slavek Kabrda 1a6e21
            "date_created": "1431414800",
Slavek Kabrda 1a6e21
            "description": "test project #1",
Slavek Kabrda 1a6e21
            "id": 1,
Slavek Kabrda 1a6e21
            "name": "test",
Slavek Kabrda 1a6e21
            "parent": null,
Slavek Kabrda 1a6e21
            "user": {
Slavek Kabrda 1a6e21
              "fullname": "PY C",
Slavek Kabrda 1a6e21
              "name": "pingou"
Slavek Kabrda 1a6e21
            }
Slavek Kabrda 1a6e21
          },
Slavek Kabrda 1a6e21
          "repo_from": {
Slavek Kabrda 1a6e21
            "date_created": "1431414800",
Slavek Kabrda 1a6e21
            "description": "test project #1",
Slavek Kabrda 1a6e21
            "id": 1,
Slavek Kabrda 1a6e21
            "name": "test",
Slavek Kabrda 1a6e21
            "parent": null,
Slavek Kabrda 1a6e21
            "user": {
Slavek Kabrda 1a6e21
              "fullname": "PY C",
Slavek Kabrda 1a6e21
              "name": "pingou"
Slavek Kabrda 1a6e21
            }
Slavek Kabrda 1a6e21
          },
Slavek Kabrda 1a6e21
          "status": "Open",
Slavek Kabrda 1a6e21
          "title": "test pull-request",
Slavek Kabrda 1a6e21
          "uid": "1431414800",
Slavek Kabrda 1a6e21
          "updated_on": "1431414800",
Slavek Kabrda 1a6e21
          "user": {
Slavek Kabrda 1a6e21
            "fullname": "PY C",
Slavek Kabrda 1a6e21
            "name": "pingou"
Slavek Kabrda 1a6e21
          }
Slavek Kabrda 1a6e21
        }
Slavek Kabrda 1a6e21
Slavek Kabrda 1a6e21
    """
Pierre-Yves Chibon 6fdb42
Pierre-Yves Chibon 6fdb42
    request = _get_request(requestuid=uid)
Slavek Kabrda 1a6e21
Slavek Kabrda 1a6e21
    # we don't really need the repo, but we need to make sure
Slavek Kabrda 1a6e21
    # that we're allowed to access it
Slavek Kabrda 1a6e21
    username = request.project.user.user if request.project.is_fork else None
Slavek Kabrda 1a6e21
    repo = get_authorized_api_project(
Patrick Uiterwijk 3f97f6
        flask.g.session,
Patrick Uiterwijk 3f97f6
        request.project.name,
Patrick Uiterwijk 3f97f6
        user=username,
Patrick Uiterwijk 3f97f6
        namespace=request.project.namespace,
Patrick Uiterwijk 3f97f6
    )
Slavek Kabrda 1a6e21
    if repo is None:
Slavek Kabrda 1a6e21
        raise pagure.exceptions.APIError(404, error_code=APIERROR.ENOREQ)
Slavek Kabrda 1a6e21
Slavek Kabrda 1a6e21
    if not repo.settings.get("pull_requests", True):
Slavek Kabrda 1a6e21
        raise pagure.exceptions.APIError(
Slavek Kabrda 1a6e21
            404, error_code=APIERROR.EPULLREQUESTSDISABLED
Slavek Kabrda 1a6e21
        )
Slavek Kabrda 1a6e21
Slavek Kabrda 1a6e21
    jsonout = flask.jsonify(request.to_json(public=True, api=True))
Slavek Kabrda 1a6e21
    return jsonout
Slavek Kabrda 1a6e21
Slavek Kabrda 1a6e21
Pierre-Yves Chibon 9c2953
@API.route("/<repo>/pull-request/<int:requestid>")</int:requestid></repo>
Pierre-Yves Chibon 9c2953
@API.route("/<namespace>/<repo>/pull-request/<int:requestid>")</int:requestid></repo></namespace>
Pierre-Yves Chibon 9c2953
@API.route("/fork/<username>/<repo>/pull-request/<int:requestid>")</int:requestid></repo></username>
Pierre-Yves Chibon 9c2953
@API.route("/fork/<username>/<namespace>/<repo>/pull-request/<int:requestid>")</int:requestid></repo></namespace></username>
Pierre-Yves Chibon bea7bd
@api_method
Pierre-Yves Chibon 34ece4
def api_pull_request_view(repo, requestid, username=None, namespace=None):
Pierre-Yves Chibon a6225b
    """
Pierre-Yves Chibon 1140cc
    Pull-request information
Pierre-Yves Chibon 1140cc
    ------------------------
Lei Yang 566c51
    Retrieve information of a specific pull request.
Pierre-Yves Chibon a6225b
Pierre-Yves Chibon a6225b
    ::
Pierre-Yves Chibon a6225b
Lei Yang 566c51
        GET /api/0/<repo>/pull-request/<request id=""></request></repo>
Pierre-Yves Chibon 34ece4
        GET /api/0/<namespace>/<repo>/pull-request/<request id=""></request></repo></namespace>
Pierre-Yves Chibon a6225b
Lei Yang 566c51
    ::
Pierre-Yves Chibon a6225b
Lei Yang 566c51
        GET /api/0/fork/<username>/<repo>/pull-request/<request id=""></request></repo></username>
Pierre-Yves Chibon 34ece4
        GET /api/0/fork/<username>/<namespace>/<repo>/pull-request/<request id=""></request></repo></namespace></username>
Pierre-Yves Chibon a6225b
Lei Yang 566c51
    Sample response
Lei Yang 566c51
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon a6225b
Pierre-Yves Chibon a6225b
    ::
Pierre-Yves Chibon a6225b
Pierre-Yves Chibon a6225b
        {
Pierre-Yves Chibon a6225b
          "assignee": null,
Pierre-Yves Chibon a6225b
          "branch": "master",
Pierre-Yves Chibon a6225b
          "branch_from": "master",
Pierre-Yves Chibon 15c503
          "closed_at": null,
Pierre-Yves Chibon 15c503
          "closed_by": null,
Pierre-Yves Chibon a6225b
          "comments": [],
Pierre-Yves Chibon a6225b
          "commit_start": null,
Pierre-Yves Chibon a6225b
          "commit_stop": null,
Pierre-Yves Chibon a6225b
          "date_created": "1431414800",
Pierre-Yves Chibon a6225b
          "id": 1,
Pierre-Yves Chibon a6225b
          "project": {
Farhaan Bukhsh ed34e5
            "close_status": [],
Farhaan Bukhsh ed34e5
            "custom_keys": [],
Pierre-Yves Chibon a6225b
            "date_created": "1431414800",
Pierre-Yves Chibon a6225b
            "description": "test project #1",
Pierre-Yves Chibon a6225b
            "id": 1,
Pierre-Yves Chibon a6225b
            "name": "test",
Pierre-Yves Chibon a6225b
            "parent": null,
Pierre-Yves Chibon a6225b
            "user": {
Pierre-Yves Chibon a6225b
              "fullname": "PY C",
Pierre-Yves Chibon a6225b
              "name": "pingou"
Pierre-Yves Chibon a6225b
            }
Pierre-Yves Chibon a6225b
          },
Pierre-Yves Chibon a6225b
          "repo_from": {
Pierre-Yves Chibon a6225b
            "date_created": "1431414800",
Pierre-Yves Chibon a6225b
            "description": "test project #1",
Pierre-Yves Chibon a6225b
            "id": 1,
Pierre-Yves Chibon a6225b
            "name": "test",
Pierre-Yves Chibon a6225b
            "parent": null,
Pierre-Yves Chibon a6225b
            "user": {
Pierre-Yves Chibon a6225b
              "fullname": "PY C",
Pierre-Yves Chibon a6225b
              "name": "pingou"
Pierre-Yves Chibon a6225b
            }
Pierre-Yves Chibon a6225b
          },
Pierre-Yves Chibon 9e2f39
          "status": "Open",
Pierre-Yves Chibon a6225b
          "title": "test pull-request",
Pierre-Yves Chibon a6225b
          "uid": "1431414800",
Pierre-Yves Chibon e68983
          "updated_on": "1431414800",
Pierre-Yves Chibon a6225b
          "user": {
Pierre-Yves Chibon a6225b
            "fullname": "PY C",
Pierre-Yves Chibon a6225b
            "name": "pingou"
Pierre-Yves Chibon a6225b
          }
Pierre-Yves Chibon a6225b
        }
Pierre-Yves Chibon a6225b
Pierre-Yves Chibon bea7bd
    """
Pierre-Yves Chibon bea7bd
Pierre-Yves Chibon 6fdb42
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 6fdb42
    _check_pull_request(repo)
Pierre-Yves Chibon 6fdb42
    request = _get_request(repo, requestid)
Pierre-Yves Chibon bea7bd
Pierre-Yves Chibon 87d805
    jsonout = flask.jsonify(request.to_json(public=True, api=True))
Pierre-Yves Chibon bea7bd
    return jsonout
Pierre-Yves Chibon bea7bd
Pierre-Yves Chibon bea7bd
Pierre-Yves Chibon 5a9017
@API.route("/<repo>/pull-request/<int:requestid>", methods=["POST"])</int:requestid></repo>
Pierre-Yves Chibon 5a9017
@API.route(
Pierre-Yves Chibon 5a9017
    "/<namespace>/<repo>/pull-request/<int:requestid>", methods=["POST"]</int:requestid></repo></namespace>
Pierre-Yves Chibon 5a9017
)
Pierre-Yves Chibon 5a9017
@API.route(
Pierre-Yves Chibon 5a9017
    "/fork/<username>/<repo>/pull-request/<int:requestid>", methods=["POST"]</int:requestid></repo></username>
Pierre-Yves Chibon 5a9017
)
Pierre-Yves Chibon 5a9017
@API.route(
Pierre-Yves Chibon 5a9017
    "/fork/<username>/<namespace>/<repo>/pull-request/<int:requestid>",</int:requestid></repo></namespace></username>
Pierre-Yves Chibon 5a9017
    methods=["POST"],
Pierre-Yves Chibon 5a9017
)
Pierre-Yves Chibon 5a9017
@api_login_required(acls=["pull_request_update"])
Pierre-Yves Chibon 5a9017
@api_method
Pierre-Yves Chibon 5a9017
def api_pull_request_update(repo, requestid, username=None, namespace=None):
Pierre-Yves Chibon 5a9017
    """
Pierre-Yves Chibon 5a9017
    Update pull-request information
Pierre-Yves Chibon 5a9017
    -------------------------------
Pierre-Yves Chibon 5a9017
    Update the title and initial comment of an existing pull-request.
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    ::
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
        POST /api/0/<repo>/pull-request/<request id=""></request></repo>
Pierre-Yves Chibon 5a9017
        POST /api/0/<namespace>/<repo>/pull-request/<request id=""></request></repo></namespace>
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    ::
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
        POST /api/0/fork/<username>/<repo>/pull-request/<request id=""></request></repo></username>
Pierre-Yves Chibon 5a9017
        POST /api/0/fork/<username>/<namespace>/<repo>/pull-request/<request id=""></request></repo></namespace></username>
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    Input
Pierre-Yves Chibon 5a9017
    ^^^^^
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    +---------------------+--------+-------------+-----------------------------+
Pierre-Yves Chibon 5a9017
    | Key                 | Type   | Optionality | Description                 |
Pierre-Yves Chibon 5a9017
    +=====================+========+=============+=============================+
Pierre-Yves Chibon 5a9017
    | ``title``           | string | Mandatory   | | The title to give to the  |
Pierre-Yves Chibon 5a9017
    |                     |        |             |   pull-request              |
Pierre-Yves Chibon 5a9017
    +---------------------+--------+-------------+-----------------------------+
Pierre-Yves Chibon 5a9017
    | ``initial_comment`` | string | Optional    | | The initial comment or    |
Pierre-Yves Chibon 5a9017
    |                     |        |             |   description of the        |
Pierre-Yves Chibon 5a9017
    |                     |        |             |   pull-request              |
Pierre-Yves Chibon 5a9017
    +---------------------+--------+-------------+-----------------------------+
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    Sample response
Pierre-Yves Chibon 5a9017
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    ::
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
        {
Pierre-Yves Chibon 5a9017
          "assignee": null,
Pierre-Yves Chibon 5a9017
          "branch": "master",
Pierre-Yves Chibon 5a9017
          "branch_from": "master",
Pierre-Yves Chibon 5a9017
          "closed_at": null,
Pierre-Yves Chibon 5a9017
          "closed_by": null,
Pierre-Yves Chibon 5a9017
          "comments": [],
Pierre-Yves Chibon 5a9017
          "commit_start": null,
Pierre-Yves Chibon 5a9017
          "commit_stop": null,
Pierre-Yves Chibon 5a9017
          "date_created": "1431414800",
Pierre-Yves Chibon 5a9017
          "id": 1,
Pierre-Yves Chibon 5a9017
          "project": {
Pierre-Yves Chibon 5a9017
            "close_status": [],
Pierre-Yves Chibon 5a9017
            "custom_keys": [],
Pierre-Yves Chibon 5a9017
            "date_created": "1431414800",
Pierre-Yves Chibon 5a9017
            "description": "test project #1",
Pierre-Yves Chibon 5a9017
            "id": 1,
Pierre-Yves Chibon 5a9017
            "name": "test",
Pierre-Yves Chibon 5a9017
            "parent": null,
Pierre-Yves Chibon 5a9017
            "user": {
Pierre-Yves Chibon 5a9017
              "fullname": "PY C",
Pierre-Yves Chibon 5a9017
              "name": "pingou"
Pierre-Yves Chibon 5a9017
            }
Pierre-Yves Chibon 5a9017
          },
Pierre-Yves Chibon 5a9017
          "repo_from": {
Pierre-Yves Chibon 5a9017
            "date_created": "1431414800",
Pierre-Yves Chibon 5a9017
            "description": "test project #1",
Pierre-Yves Chibon 5a9017
            "id": 1,
Pierre-Yves Chibon 5a9017
            "name": "test",
Pierre-Yves Chibon 5a9017
            "parent": null,
Pierre-Yves Chibon 5a9017
            "user": {
Pierre-Yves Chibon 5a9017
              "fullname": "PY C",
Pierre-Yves Chibon 5a9017
              "name": "pingou"
Pierre-Yves Chibon 5a9017
            }
Pierre-Yves Chibon 5a9017
          },
Pierre-Yves Chibon 5a9017
          "status": "Open",
Pierre-Yves Chibon 5a9017
          "title": "test pull-request",
Pierre-Yves Chibon 5a9017
          "uid": "1431414800",
Pierre-Yves Chibon 5a9017
          "updated_on": "1431414800",
Pierre-Yves Chibon 5a9017
          "user": {
Pierre-Yves Chibon 5a9017
            "fullname": "PY C",
Pierre-Yves Chibon 5a9017
            "name": "pingou"
Pierre-Yves Chibon 5a9017
          }
Pierre-Yves Chibon 5a9017
        }
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    """  # noqa
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    _check_pull_request(repo)
Pierre-Yves Chibon 306039
    _check_token(repo, project_token=False)
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    request = _get_request(repo, requestid)
Pierre-Yves Chibon 5a9017
    _check_pull_request_access(request, assignee=True)
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    form = pagure.forms.RequestPullForm(csrf_enabled=False)
Pierre-Yves Chibon 5a9017
    if not form.validate_on_submit():
Pierre-Yves Chibon 5a9017
        raise pagure.exceptions.APIError(
Pierre-Yves Chibon 5a9017
            400, error_code=APIERROR.EINVALIDREQ, errors=form.errors
Pierre-Yves Chibon 5a9017
        )
Pierre-Yves Chibon 5a9017
    else:
Pierre-Yves Chibon 5a9017
        request.title = form.title.data.strip()
Pierre-Yves Chibon 5a9017
        request.initial_comment = form.initial_comment.data.strip()
Pierre-Yves Chibon 5a9017
        flask.g.session.add(request)
Pierre-Yves Chibon 053ab1
        if not request.private and not request.project.private:
Pierre-Yves Chibon 053ab1
            pagure.lib.notify.log(
Pierre-Yves Chibon 053ab1
                request.project,
Pierre-Yves Chibon 053ab1
                topic="pull-request.initial_comment.edited",
Pierre-Yves Chibon 053ab1
                msg={
Pierre-Yves Chibon 053ab1
                    "pullrequest": request.to_json(
Pierre-Yves Chibon 053ab1
                        public=True, with_comments=False
Pierre-Yves Chibon 053ab1
                    ),
Pierre-Yves Chibon 053ab1
                    "project": request.project.to_json(public=True),
Pierre-Yves Chibon 053ab1
                    "agent": flask.g.fas_user.username,
Pierre-Yves Chibon 053ab1
                },
Pierre-Yves Chibon 053ab1
            )
Pierre-Yves Chibon 5a9017
        try:
Pierre-Yves Chibon 2479ca
            # Link the PR to issue(s) if there is such link
Pierre-Yves Chibon 2479ca
            pagure.lib.query.link_pr_to_issue_on_description(
Pierre-Yves Chibon 2479ca
                flask.g.session, request
Pierre-Yves Chibon 2479ca
            )
Pierre-Yves Chibon 5a9017
            flask.g.session.commit()
Pierre-Yves Chibon 5a9017
        except SQLAlchemyError as err:  # pragma: no cover
Pierre-Yves Chibon 5a9017
            flask.g.session.rollback()
Pierre-Yves Chibon 5a9017
            _log.exception(err)
Pierre-Yves Chibon 5a9017
            raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
    request = _get_request(repo, requestid)
Pierre-Yves Chibon 5a9017
    jsonout = flask.jsonify(request.to_json(public=True, api=True))
Pierre-Yves Chibon 5a9017
    return jsonout
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 5a9017
Pierre-Yves Chibon 9c2953
@API.route("/<repo>/pull-request/<int:requestid>/merge", methods=["POST"])</int:requestid></repo>
Pierre-Yves Chibon 34ece4
@API.route(
Pierre-Yves Chibon 9c2953
    "/<namespace>/<repo>/pull-request/<int:requestid>/merge", methods=["POST"]</int:requestid></repo></namespace>
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 34ece4
@API.route(
Pierre-Yves Chibon 9c2953
    "/fork/<username>/<repo>/pull-request/<int:requestid>/merge",</int:requestid></repo></username>
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 9c2953
@API.route(
Pierre-Yves Chibon 9c2953
    "/fork/<username>/<namespace>/<repo>/pull-request/<int:requestid>/merge",</int:requestid></repo></namespace></username>
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 9c2953
@api_login_required(acls=["pull_request_merge"])
Pierre-Yves Chibon 807fce
@api_method
Pierre-Yves Chibon 34ece4
def api_pull_request_merge(repo, requestid, username=None, namespace=None):
Pierre-Yves Chibon be094c
    """
Pierre-Yves Chibon be094c
    Merge a pull-request
Pierre-Yves Chibon be094c
    --------------------
LubomĂ­r SedlĂ¡Å™ f02111
    Instruct Pagure to merge a pull request.
Pierre-Yves Chibon be094c
Patrick Uiterwijk e6f1fd
    This is an asynchronous call.
Patrick Uiterwijk e6f1fd
Pierre-Yves Chibon be094c
    ::
Pierre-Yves Chibon be094c
Lei Yang 566c51
        POST /api/0/<repo>/pull-request/<request id="">/merge</request></repo>
Pierre-Yves Chibon 34ece4
        POST /api/0/<namespace>/<repo>/pull-request/<request id="">/merge</request></repo></namespace>
Pierre-Yves Chibon be094c
Lei Yang 566c51
    ::
Pierre-Yves Chibon be094c
Lei Yang 566c51
        POST /api/0/fork/<username>/<repo>/pull-request/<request id="">/merge</request></repo></username>
Pierre-Yves Chibon 34ece4
        POST /api/0/fork/<username>/<namespace>/<repo>/pull-request/<request id="">/merge</request></repo></namespace></username>
Pierre-Yves Chibon be094c
Lei Yang 566c51
    Sample response
Lei Yang 566c51
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon be094c
Pierre-Yves Chibon be094c
    ::
Pierre-Yves Chibon be094c
Patrick Uiterwijk 0281ff
        wait=False:
Pierre-Yves Chibon be094c
        {
Patrick Uiterwijk e6f1fd
          "message": "Merging queued",
Patrick Uiterwijk e6f1fd
          "taskid": "123-abcd"
Pierre-Yves Chibon be094c
        }
Pierre-Yves Chibon be094c
Patrick Uiterwijk 0281ff
        wait=True:
Patrick Uiterwijk 0281ff
        {
Patrick Uiterwijk 0281ff
          "message": "Changes merged!"
Patrick Uiterwijk 0281ff
        }
Patrick Uiterwijk 0281ff
Pierre-Yves Chibon 4768f2
    """  # noqa
Pierre-Yves Chibon 807fce
    output = {}
Pierre-Yves Chibon 807fce
Pierre-Yves Chibon 6fdb42
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 6fdb42
    _check_pull_request(repo)
Pierre-Yves Chibon 6fdb42
    _check_token(repo, project_token=False)
Pierre-Yves Chibon 6fdb42
    request = _get_request(repo, requestid)
Pierre-Yves Chibon 807fce
Vivek Anand 967335
    if not is_repo_committer(repo):
Pierre-Yves Chibon 23d3ff
        raise pagure.exceptions.APIError(403, error_code=APIERROR.ENOPRCLOSE)
Pierre-Yves Chibon 807fce
Pierre-Yves Chibon 9c2953
    if repo.settings.get("Only_assignee_can_merge_pull-request", False):
Pierre-Yves Chibon 807fce
        if not request.assignee:
Pierre-Yves Chibon 53433f
            raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
                403, error_code=APIERROR.ENOTASSIGNED
Pierre-Yves Chibon 9c2953
            )
Pierre-Yves Chibon 807fce
Pierre-Yves Chibon 807fce
        if request.assignee.username != flask.g.fas_user.username:
Pierre-Yves Chibon 704030
            raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
                403, error_code=APIERROR.ENOTASSIGNEE
Pierre-Yves Chibon 9c2953
            )
Pierre-Yves Chibon 807fce
Pierre-Yves Chibon 9c2953
    threshold = repo.settings.get("Minimum_score_to_merge_pull-request", -1)
Pierre-Yves Chibon 807fce
    if threshold > 0 and int(request.score) < int(threshold):
Pierre-Yves Chibon 23d3ff
        raise pagure.exceptions.APIError(403, error_code=APIERROR.EPRSCORE)
Pierre-Yves Chibon 807fce
Pierre-Yves Chibon 1b3ac8
    task = pagure.lib.tasks.merge_pull_request.delay(
Pierre-Yves Chibon 9c2953
        repo.name, namespace, username, requestid, flask.g.fas_user.username
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 9c2953
    output = {"message": "Merging queued", "taskid": task.id}
Pierre-Yves Chibon 1b3ac8
Pierre-Yves Chibon 9c2953
    if get_request_data().get("wait", True):
Pierre-Yves Chibon 457b8e
        try:
Pierre-Yves Chibon 457b8e
            task.get()
Pierre-Yves Chibon 457b8e
            output = {"message": "Changes merged!"}
Pierre-Yves Chibon 457b8e
        except pagure.exceptions.PagureException:
Pierre-Yves Chibon 457b8e
            raise pagure.exceptions.APIError(
Pierre-Yves Chibon 457b8e
                409, error_code=APIERROR.EPRCONFLICTS
Pierre-Yves Chibon 457b8e
            )
Pierre-Yves Chibon 807fce
Pierre-Yves Chibon 807fce
    jsonout = flask.jsonify(output)
Pierre-Yves Chibon 807fce
    return jsonout
Pierre-Yves Chibon 807fce
Pierre-Yves Chibon 807fce
Pierre-Yves Chibon 5798ff
@API.route("/<repo>/pull-request/<int:requestid>/rebase", methods=["POST"])</int:requestid></repo>
Pierre-Yves Chibon 5798ff
@API.route(
Pierre-Yves Chibon 5798ff
    "/<namespace>/<repo>/pull-request/<int:requestid>/rebase", methods=["POST"]</int:requestid></repo></namespace>
Pierre-Yves Chibon 5798ff
)
Pierre-Yves Chibon 5798ff
@API.route(
Pierre-Yves Chibon 5798ff
    "/fork/<username>/<repo>/pull-request/<int:requestid>/rebase",</int:requestid></repo></username>
Pierre-Yves Chibon 5798ff
    methods=["POST"],
Pierre-Yves Chibon 5798ff
)
Pierre-Yves Chibon 5798ff
@API.route(
Pierre-Yves Chibon 5798ff
    "/fork/<username>/<namespace>/<repo>/pull-request/<int:requestid>/rebase",</int:requestid></repo></namespace></username>
Pierre-Yves Chibon 5798ff
    methods=["POST"],
Pierre-Yves Chibon 5798ff
)
Pierre-Yves Chibon 5798ff
@api_login_required(acls=["pull_request_rebase"])
Pierre-Yves Chibon 5798ff
@api_method
Pierre-Yves Chibon 5798ff
def api_pull_request_rebase(repo, requestid, username=None, namespace=None):
Pierre-Yves Chibon 5798ff
    """
Pierre-Yves Chibon 5798ff
    Rebase a pull-request
Pierre-Yves Chibon d28b70
    ---------------------
Pierre-Yves Chibon 5798ff
    Instruct Pagure to rebase a pull request.
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
    This is an asynchronous call.
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
    ::
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
        POST /api/0/<repo>/pull-request/<request id="">/rebase</request></repo>
Pierre-Yves Chibon 5798ff
        POST /api/0/<namespace>/<repo>/pull-request/<request id="">/rebase</request></repo></namespace>
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
    ::
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
        POST /api/0/fork/<username>/<repo>/pull-request/<request id="">/rebase</request></repo></username>
Pierre-Yves Chibon 5798ff
        POST /api/0/fork/<username>/<namespace>/<repo>/pull-request/<request id="">/rebase</request></repo></namespace></username>
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
    Sample response
Pierre-Yves Chibon 5798ff
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
    ::
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
        wait=False:
Pierre-Yves Chibon 5798ff
        {
Pierre-Yves Chibon 5798ff
          "message": "Rebasing queued",
Pierre-Yves Chibon 5798ff
          "taskid": "123-abcd"
Pierre-Yves Chibon 5798ff
        }
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
        wait=True:
Pierre-Yves Chibon 5798ff
        {
Pierre-Yves Chibon 5798ff
          "message": "Pull-request rebased"
Pierre-Yves Chibon 5798ff
        }
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
    """  # noqa
Pierre-Yves Chibon 5798ff
    output = {}
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 6fdb42
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 6fdb42
    _check_pull_request(repo)
Pierre-Yves Chibon 6fdb42
    _check_token(repo)
Pierre-Yves Chibon b2d897
    request = _get_request(repo, requestid)
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
    if not is_repo_committer(repo):
Pierre-Yves Chibon 5798ff
        raise pagure.exceptions.APIError(403, error_code=APIERROR.ENOPRCLOSE)
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon b2d897
    if not request.allow_rebase:
Pierre-Yves Chibon b2d897
        raise pagure.exceptions.APIError(
Pierre-Yves Chibon b2d897
            403, error_code=APIERROR.EREBASENOTALLOWED
Pierre-Yves Chibon b2d897
        )
Pierre-Yves Chibon b2d897
Pierre-Yves Chibon 5798ff
    task = pagure.lib.tasks.rebase_pull_request.delay(
Pierre-Yves Chibon b983f9
        repo.name,
Pierre-Yves Chibon b983f9
        namespace,
Pierre-Yves Chibon b983f9
        username,
Pierre-Yves Chibon b983f9
        requestid,
Pierre-Yves Chibon b983f9
        user_rebaser=flask.g.fas_user.username,
Pierre-Yves Chibon 5798ff
    )
Pierre-Yves Chibon 5798ff
    output = {"message": "Rebasing queued", "taskid": task.id}
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
    if get_request_data().get("wait", True):
Pierre-Yves Chibon 5798ff
        try:
Pierre-Yves Chibon 5798ff
            task.get()
Pierre-Yves Chibon 5798ff
            output = {"message": "Pull-request rebased"}
Pierre-Yves Chibon 5798ff
        except pagure.exceptions.PagureException as err:
Pierre-Yves Chibon 5798ff
            raise pagure.exceptions.APIError(
Pierre-Yves Chibon 5798ff
                400, error_code=APIERROR.ENOCODE, error=str(err)
Pierre-Yves Chibon 5798ff
            )
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
    jsonout = flask.jsonify(output)
Pierre-Yves Chibon 5798ff
    return jsonout
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 5798ff
Pierre-Yves Chibon 9c2953
@API.route("/<repo>/pull-request/<int:requestid>/close", methods=["POST"])</int:requestid></repo>
Pierre-Yves Chibon 34ece4
@API.route(
Pierre-Yves Chibon 9c2953
    "/<namespace>/<repo>/pull-request/<int:requestid>/close", methods=["POST"]</int:requestid></repo></namespace>
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 34ece4
@API.route(
Pierre-Yves Chibon 9c2953
    "/fork/<username>/<repo>/pull-request/<int:requestid>/close",</int:requestid></repo></username>
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 9c2953
@API.route(
Pierre-Yves Chibon 9c2953
    "/fork/<username>/<namespace>/<repo>/pull-request/<int:requestid>/close",</int:requestid></repo></namespace></username>
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 9c2953
@api_login_required(acls=["pull_request_close"])
Pierre-Yves Chibon 291626
@api_method
Pierre-Yves Chibon 34ece4
def api_pull_request_close(repo, requestid, username=None, namespace=None):
Pierre-Yves Chibon 2da4df
    """
Pierre-Yves Chibon 2da4df
    Close a pull-request
Pierre-Yves Chibon 2da4df
    --------------------
Lei Yang 566c51
    Instruct Pagure to close a pull request.
Pierre-Yves Chibon 2da4df
Pierre-Yves Chibon 2da4df
    ::
Pierre-Yves Chibon 2da4df
Lei Yang 566c51
        POST /api/0/<repo>/pull-request/<request id="">/close</request></repo>
Pierre-Yves Chibon 34ece4
        POST /api/0/<namespace>/<repo>/pull-request/<request id="">/close</request></repo></namespace>
Pierre-Yves Chibon 2da4df
Lei Yang 566c51
    ::
Pierre-Yves Chibon 2da4df
Lei Yang 566c51
        POST /api/0/fork/<username>/<repo>/pull-request/<request id="">/close</request></repo></username>
Pierre-Yves Chibon 34ece4
        POST /api/0/fork/<username>/<namespace>/<repo>/pull-request/<request id="">/close</request></repo></namespace></username>
Pierre-Yves Chibon 2da4df
Lei Yang 566c51
    Sample response
Lei Yang 566c51
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon 2da4df
Pierre-Yves Chibon 2da4df
    ::
Pierre-Yves Chibon 2da4df
Pierre-Yves Chibon 2da4df
        {
Pierre-Yves Chibon 369fd6
          "message": "Pull-request closed!"
Pierre-Yves Chibon 2da4df
        }
Pierre-Yves Chibon 2da4df
Pierre-Yves Chibon 4768f2
    """  # noqa
Pierre-Yves Chibon 291626
    output = {}
Pierre-Yves Chibon 291626
Pierre-Yves Chibon 6fdb42
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 6fdb42
    _check_pull_request(repo)
Pierre-Yves Chibon 6fdb42
    _check_token(repo)
Pierre-Yves Chibon 6fdb42
    request = _get_request(repo, requestid)
Pierre-Yves Chibon 291626
Vivek Anand 967335
    if not is_repo_committer(repo):
Pierre-Yves Chibon 23d3ff
        raise pagure.exceptions.APIError(403, error_code=APIERROR.ENOPRCLOSE)
Pierre-Yves Chibon 291626
Pierre-Yves Chibon 291626
    try:
Pierre-Yves Chibon 930073
        pagure.lib.query.close_pull_request(
Patrick Uiterwijk 3f97f6
            flask.g.session, request, flask.g.fas_user.username, merged=False
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon b130e5
        flask.g.session.commit()
Pierre-Yves Chibon 9c2953
        output["message"] = "Pull-request closed!"
Pierre-Yves Chibon 291626
    except SQLAlchemyError as err:  # pragma: no cover
Pierre-Yves Chibon b130e5
        flask.g.session.rollback()
Pierre-Yves Chibon b130e5
        _log.exception(err)
Pierre-Yves Chibon 23d3ff
        raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
Pierre-Yves Chibon 291626
Pierre-Yves Chibon 291626
    jsonout = flask.jsonify(output)
Pierre-Yves Chibon 291626
    return jsonout
Pierre-Yves Chibon 291626
Pierre-Yves Chibon 291626
Pierre-Yves Chibon 9c2953
@API.route("/<repo>/pull-request/<int:requestid>/comment", methods=["POST"])</int:requestid></repo>
Pierre-Yves Chibon 9c2953
@API.route(
Pierre-Yves Chibon 9c2953
    "/<namespace>/<repo>/pull-request/<int:requestid>/comment",</int:requestid></repo></namespace>
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 9c2953
@API.route(
Pierre-Yves Chibon 9c2953
    "/fork/<username>/<repo>/pull-request/<int:requestid>/comment",</int:requestid></repo></username>
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 34ece4
@API.route(
Pierre-Yves Chibon 9c2953
    "/fork/<username>/<namespace>/<repo>/pull-request/<int:requestid>/comment",</int:requestid></repo></namespace></username>
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 9c2953
@api_login_required(acls=["pull_request_comment"])
Pierre-Yves Chibon 1e1949
@api_method
Pierre-Yves Chibon 34ece4
def api_pull_request_add_comment(
Pierre-Yves Chibon 9c2953
    repo, requestid, username=None, namespace=None
Pierre-Yves Chibon 9c2953
):
Pierre-Yves Chibon e91c31
    """
Pierre-Yves Chibon e91c31
    Comment on a pull-request
Pierre-Yves Chibon 47edc6
    -------------------------
Lei Yang 566c51
    Add comment to a pull request.
Pierre-Yves Chibon e91c31
Pierre-Yves Chibon e91c31
    ::
Pierre-Yves Chibon e91c31
Lei Yang 566c51
        POST /api/0/<repo>/pull-request/<request id="">/comment</request></repo>
Pierre-Yves Chibon 34ece4
        POST /api/0/<namespace>/<repo>/pull-request/<request id="">/comment</request></repo></namespace>
Lei Yang 566c51
Lei Yang 566c51
    ::
Pierre-Yves Chibon e91c31
Lei Yang 566c51
        POST /api/0/fork/<username>/<repo>/pull-request/<request id="">/comment</request></repo></username>
Pierre-Yves Chibon 34ece4
        POST /api/0/fork/<username>/<namespace>/<repo>/pull-request/<request id="">/comment</request></repo></namespace></username>
Pierre-Yves Chibon e91c31
Lei Yang 566c51
    Input
Lei Yang 566c51
    ^^^^^
Pierre-Yves Chibon e91c31
Pierre-Yves Chibon e1497f
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon e1497f
    | Key           | Type    | Optionality  | Description                 |
Pierre-Yves Chibon e1497f
    +===============+=========+==============+=============================+
Pierre-Yves Chibon e1497f
    | ``comment``   | string  | Mandatory    | | The comment to add        |
Pierre-Yves Chibon e1497f
    |               |         |              |   to the pull request       |
Pierre-Yves Chibon e1497f
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon e1497f
    | ``commit``    | string  | Optional     | | The hash of the specific  |
Pierre-Yves Chibon e1497f
    |               |         |              |   commit you wish to        |
Pierre-Yves Chibon e1497f
    |               |         |              |   comment on                |
Pierre-Yves Chibon e1497f
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon e1497f
    | ``filename``  | string  | Optional     | | The filename of the       |
Pierre-Yves Chibon e1497f
    |               |         |              |   specific file you wish    |
Pierre-Yves Chibon e1497f
    |               |         |              |   to comment on             |
Pierre-Yves Chibon e1497f
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon e1497f
    | ``row``       | int     | Optional     | | Used in combination       |
Pierre-Yves Chibon e1497f
    |               |         |              |   with filename to comment  |
Pierre-Yves Chibon e1497f
    |               |         |              |   on a specific row         |
Pierre-Yves Chibon e1497f
    |               |         |              |   of a file                 |
Pierre-Yves Chibon e1497f
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon 626dba
    | ``tree_id``   | string  | Optional     | | The identifier of the     |
Pierre-Yves Chibon 626dba
    |               |         |              |   git tree as it was when   |
Pierre-Yves Chibon 626dba
    |               |         |              |   the comment was added     |
Pierre-Yves Chibon 626dba
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon e91c31
Lei Yang 566c51
    Sample response
Lei Yang 566c51
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon e91c31
Pierre-Yves Chibon e91c31
    ::
Pierre-Yves Chibon e91c31
Pierre-Yves Chibon e91c31
        {
Pierre-Yves Chibon e91c31
          "message": "Comment added"
Pierre-Yves Chibon e91c31
        }
Pierre-Yves Chibon e91c31
Pierre-Yves Chibon 4768f2
    """  # noqa
farhaanbukhsh 44a97a
Pierre-Yves Chibon 1e1949
    output = {}
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 6fdb42
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 6fdb42
    _check_pull_request(repo)
Pierre-Yves Chibon 6fdb42
    _check_token(repo, project_token=False)
Pierre-Yves Chibon 6fdb42
    request = _get_request(repo, requestid)
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 5c561c
    form = pagure.forms.AddPullRequestCommentForm(csrf_enabled=False)
Pierre-Yves Chibon 1e1949
    if form.validate_on_submit():
Pierre-Yves Chibon 1e1949
        comment = form.comment.data
Pierre-Yves Chibon 551952
        commit = form.commit.data or None
Pierre-Yves Chibon 551952
        filename = form.filename.data or None
Pierre-Yves Chibon 626dba
        tree_id = form.tree_id.data or None
Pierre-Yves Chibon 551952
        row = form.row.data or None
Pierre-Yves Chibon 1e1949
        try:
Pierre-Yves Chibon 1e1949
            # New comment
Pierre-Yves Chibon 930073
            message = pagure.lib.query.add_pull_request_comment(
Pierre-Yves Chibon b130e5
                flask.g.session,
Pierre-Yves Chibon 1e1949
                request=request,
Pierre-Yves Chibon 1e1949
                commit=commit,
Pierre-Yves Chibon 626dba
                tree_id=tree_id,
Pierre-Yves Chibon 1e1949
                filename=filename,
Pierre-Yves Chibon 1e1949
                row=row,
Pierre-Yves Chibon 1e1949
                comment=comment,
Pierre-Yves Chibon 1e1949
                user=flask.g.fas_user.username,
Pierre-Yves Chibon 1e1949
            )
Pierre-Yves Chibon b130e5
            flask.g.session.commit()
Pierre-Yves Chibon 9c2953
            output["message"] = message
Pierre-Yves Chibon d47179
        except pagure.exceptions.PagureException as err:
Pierre-Yves Chibon d47179
            raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
                400, error_code=APIERROR.ENOCODE, error=str(err)
Pierre-Yves Chibon 9c2953
            )
Pierre-Yves Chibon fa97f7
        except SQLAlchemyError as err:  # pragma: no cover
Pierre-Yves Chibon b130e5
            _log.exception(err)
Pierre-Yves Chibon b130e5
            flask.g.session.rollback()
Pierre-Yves Chibon 23d3ff
            raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 1e1949
    else:
Pierre-Yves Chibon f7fcaa
        raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
            400, error_code=APIERROR.EINVALIDREQ, errors=form.errors
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 1e1949
Pierre-Yves Chibon 1e1949
    jsonout = flask.jsonify(output)
Pierre-Yves Chibon 1e1949
    return jsonout
Pierre-Yves Chibon e39f18
Pierre-Yves Chibon e39f18
Pierre-Yves Chibon 9c2953
@API.route("/<repo>/pull-request/<int:requestid>/flag", methods=["POST"])</int:requestid></repo>
Pierre-Yves Chibon 34ece4
@API.route(
Pierre-Yves Chibon 9c2953
    "/<namespace>/<repo>/pull-request/<int:requestid>/flag", methods=["POST"]</int:requestid></repo></namespace>
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 9c2953
@API.route(
Pierre-Yves Chibon 9c2953
    "/fork/<username>/<repo>/pull-request/<int:requestid>/flag",</int:requestid></repo></username>
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 9c2953
@API.route(
Pierre-Yves Chibon 9c2953
    "/fork/<username>/<namespace>/<repo>/pull-request/<int:requestid>/flag",</int:requestid></repo></namespace></username>
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 9c2953
@api_login_required(acls=["pull_request_flag"])
Pierre-Yves Chibon e39f18
@api_method
Pierre-Yves Chibon 34ece4
def api_pull_request_add_flag(repo, requestid, username=None, namespace=None):
Pierre-Yves Chibon e39f18
    """
Pierre-Yves Chibon e39f18
    Flag a pull-request
Pierre-Yves Chibon e39f18
    -------------------
Lei Yang 566c51
    Add or edit flags on a pull-request.
Pierre-Yves Chibon e39f18
Pierre-Yves Chibon e39f18
    ::
Pierre-Yves Chibon e39f18
Lei Yang 566c51
        POST /api/0/<repo>/pull-request/<request id="">/flag</request></repo>
Pierre-Yves Chibon 34ece4
        POST /api/0/<namespace>/<repo>/pull-request/<request id="">/flag</request></repo></namespace>
Lei Yang 566c51
Lei Yang 566c51
    ::
Lei Yang 566c51
Lei Yang 566c51
        POST /api/0/fork/<username>/<repo>/pull-request/<request id="">/flag</request></repo></username>
Pierre-Yves Chibon 34ece4
        POST /api/0/fork/<username>/<namespace>/<repo>/pull-request/<request id="">/flag</request></repo></namespace></username>
Lei Yang 566c51
Lei Yang 566c51
    Input
Lei Yang 566c51
    ^^^^^
Lei Yang 566c51
Pierre-Yves Chibon e1497f
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon e1497f
    | Key           | Type    | Optionality  | Description                 |
Pierre-Yves Chibon e1497f
    +===============+=========+==============+=============================+
Pierre-Yves Chibon e1497f
    | ``username``  | string  | Mandatory    | | The name of the           |
Pierre-Yves Chibon e1497f
    |               |         |              |   application to be         |
Pierre-Yves Chibon e1497f
    |               |         |              |   presented to users        |
Pierre-Yves Chibon e1497f
    |               |         |              |   on the pull request page  |
Pierre-Yves Chibon e1497f
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon e1497f
    | ``comment``   | string  | Mandatory    | | A short message           |
Pierre-Yves Chibon e1497f
    |               |         |              |   summarizing the           |
Pierre-Yves Chibon e1497f
    |               |         |              |   presented results         |
Pierre-Yves Chibon e1497f
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon e1497f
    | ``url``       | string  | Mandatory    | | A URL to the result       |
Pierre-Yves Chibon e1497f
    |               |         |              |   of this flag              |
Pierre-Yves Chibon e1497f
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon abcbf7
    | ``status``    | string  | Optional     | | The status of the task,   |
Slavek Kabrda 45252f
    |               |         |              |   can be any of:            |
Slavek Kabrda 45252f
    |               |         |              |   $$FLAG_STATUSES_COMMAS$$  |
Slavek Kabrda 45252f
    |               |         |              |   If not provided it will   |
Slavek Kabrda 45252f
    |               |         |              |   be set to                 |
Slavek Kabrda 45252f
    |               |         |              |   ``$$FLAG_SUCCESS$$`` if   |
Slavek Kabrda 45252f
    |               |         |              |   percent is higher than 0  |
Slavek Kabrda 45252f
    |               |         |              |   ``$$FLAG_FAILURE$$`` if   |
Slavek Kabrda 45252f
    |               |         |              |   it is 0 and               |
Slavek Kabrda 45252f
    |               |         |              |   ``$$FLAG_PENDING$$``      |
Slavek Kabrda 45252f
    |               |         |              |   if percent is not         |
Slavek Kabrda 45252f
    |               |         |              |   specified                 |
Pierre-Yves Chibon abcbf7
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon abcbf7
    | ``percent``   | int     | Optional     | | A percentage of           |
Pierre-Yves Chibon abcbf7
    |               |         |              |   completion compared to    |
Pierre-Yves Chibon abcbf7
    |               |         |              |   the goal. The percentage  |
Pierre-Yves Chibon abcbf7
    |               |         |              |   also determine the        |
Pierre-Yves Chibon abcbf7
    |               |         |              |   background color of the   |
Pierre-Yves Chibon abcbf7
    |               |         |              |   flag on the pull-request  |
Pierre-Yves Chibon abcbf7
    |               |         |              |   page                      |
Pierre-Yves Chibon abcbf7
    +---------------+---------+--------------+-----------------------------+
Pierre-Yves Chibon e1497f
    | ``uid``       | string  | Optional     | | A unique identifier used  |
Pierre-Yves Chibon e1497f
    |               |         |              |   to identify a flag on a   |
Pierre-Yves Chibon e1497f
    |               |         |              |   pull-request. If the      |
Pierre-Yves Chibon e1497f
    |               |         |              |   provided UID matches an   |
Pierre-Yves Chibon e1497f
    |               |         |              |   existing one, then the    |
Pierre-Yves Chibon e1497f
    |               |         |              |   API call will update the  |
Pierre-Yves Chibon e1497f
    |               |         |              |   existing one rather than  |
Pierre-Yves Chibon e1497f
    |               |         |              |   create a new one.         |
Pierre-Yves Chibon e1497f
    |               |         |              |   Maximum Length: 32        |
Pierre-Yves Chibon e1497f
    |               |         |              |   characters. Default: an   |
Pierre-Yves Chibon e1497f
    |               |         |              |   auto generated UID        |
Pierre-Yves Chibon e1497f
    +---------------+---------+--------------+-----------------------------+
Lei Yang 566c51
Lei Yang 566c51
    Sample response
Lei Yang 566c51
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon e39f18
Pierre-Yves Chibon e39f18
    ::
Pierre-Yves Chibon e39f18
Pierre-Yves Chibon e39f18
        {
Pierre-Yves Chibon c27d61
          "flag": {
Pierre-Yves Chibon c27d61
            "comment": "Tests failed",
Pierre-Yves Chibon c27d61
            "date_created": "1510742565",
Pierre-Yves Chibon c27d61
            "percent": 0,
Pierre-Yves Chibon c27d61
            "pull_request_uid": "62b49f00d489452994de5010565fab81",
Pierre-Yves Chibon abcbf7
            "status": "error",
Pierre-Yves Chibon c27d61
            "url": "http://jenkins.cloud.fedoraproject.org/",
Pierre-Yves Chibon c27d61
            "user": {
Pierre-Yves Chibon c27d61
              "default_email": "bar@pingou.com",
Pierre-Yves Chibon c27d61
              "emails": ["bar@pingou.com", "foo@pingou.com"],
Pierre-Yves Chibon c27d61
              "fullname": "PY C",
Pierre-Yves Chibon c27d61
              "name": "pingou"},
Pierre-Yves Chibon c27d61
            "username": "Jenkins"},
Pierre-Yves Chibon c27d61
          "message": u"Flag added",
Pierre-Yves Chibon c27d61
          "uid": u"jenkins_build_pagure_100+seed"
Pierre-Yves Chibon e39f18
        }
Pierre-Yves Chibon e39f18
Lei Yang 566c51
    ::
Lei Yang 566c51
Lei Yang 566c51
        {
Pierre-Yves Chibon c27d61
          "flag": {
Pierre-Yves Chibon c27d61
            "comment": "Tests failed",
Pierre-Yves Chibon c27d61
            "date_created": "1510742565",
Pierre-Yves Chibon c27d61
            "percent": 0,
Pierre-Yves Chibon c27d61
            "pull_request_uid": "62b49f00d489452994de5010565fab81",
Pierre-Yves Chibon abcbf7
            "status": "error",
Pierre-Yves Chibon c27d61
            "url": "http://jenkins.cloud.fedoraproject.org/",
Pierre-Yves Chibon c27d61
            "user": {
Pierre-Yves Chibon c27d61
              "default_email": "bar@pingou.com",
Pierre-Yves Chibon c27d61
              "emails": ["bar@pingou.com", "foo@pingou.com"],
Pierre-Yves Chibon c27d61
              "fullname": "PY C",
Pierre-Yves Chibon c27d61
              "name": "pingou"},
Pierre-Yves Chibon c27d61
            "username": "Jenkins"},
Pierre-Yves Chibon c27d61
          "message": u"Flag updated",
Pierre-Yves Chibon c27d61
          "uid": u"jenkins_build_pagure_100+seed"
Lei Yang 566c51
        }
Lei Yang 566c51
Pierre-Yves Chibon 4768f2
    """  # noqa
farhaanbukhsh 44a97a
Pierre-Yves Chibon e39f18
    output = {}
Pierre-Yves Chibon e39f18
Pierre-Yves Chibon 6fdb42
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 6fdb42
    _check_pull_request(repo)
Pierre-Yves Chibon 6fdb42
    _check_token(repo, project_token=False)
Pierre-Yves Chibon 6fdb42
    request = _get_request(repo, requestid)
Pierre-Yves Chibon e39f18
Pierre-Yves Chibon 9c2953
    if "status" in get_request_data():
Pierre-Yves Chibon 5c561c
        form = pagure.forms.AddPullRequestFlagForm(csrf_enabled=False)
Pierre-Yves Chibon abcbf7
    else:
Pierre-Yves Chibon 5c561c
        form = pagure.forms.AddPullRequestFlagFormV1(csrf_enabled=False)
Pierre-Yves Chibon e39f18
    if form.validate_on_submit():
Pierre-Yves Chibon e39f18
        username = form.username.data
Pierre-Yves Chibon abcbf7
        percent = form.percent.data.strip() or None
Pierre-Yves Chibon e39f18
        comment = form.comment.data.strip()
Pierre-Yves Chibon e39f18
        url = form.url.data.strip()
Pierre-Yves Chibon e39f18
        uid = form.uid.data.strip() if form.uid.data else None
Pierre-Yves Chibon 9c2953
        if "status" in get_request_data():
Pierre-Yves Chibon abcbf7
            status = form.status.data.strip()
Pierre-Yves Chibon abcbf7
        else:
Pierre-Yves Chibon abcbf7
            if percent is None:
Pierre-Yves Chibon 9c2953
                status = pagure_config["FLAG_PENDING"]
Pierre-Yves Chibon abcbf7
            else:
Pierre-Yves Chibon 9c2953
                status = (
Pierre-Yves Chibon 9c2953
                    pagure_config["FLAG_SUCCESS"]
Pierre-Yves Chibon 9c2953
                    if percent != "0"
Pierre-Yves Chibon 9c2953
                    else pagure_config["FLAG_FAILURE"]
Pierre-Yves Chibon 9c2953
                )
Pierre-Yves Chibon e39f18
        try:
Pierre-Yves Chibon e39f18
            # New Flag
Pierre-Yves Chibon 930073
            message, uid = pagure.lib.query.add_pull_request_flag(
Pierre-Yves Chibon b130e5
                flask.g.session,
Pierre-Yves Chibon e39f18
                request=request,
Pierre-Yves Chibon e39f18
                username=username,
Pierre-Yves Chibon abcbf7
                status=status,
Pierre-Yves Chibon e39f18
                percent=percent,
Pierre-Yves Chibon e39f18
                comment=comment,
Pierre-Yves Chibon e39f18
                url=url,
Pierre-Yves Chibon e39f18
                uid=uid,
Pierre-Yves Chibon e39f18
                user=flask.g.fas_user.username,
Pierre-Yves Chibon ba2b1c
                token=flask.g.token.id,
Pierre-Yves Chibon e39f18
            )
Pierre-Yves Chibon b130e5
            flask.g.session.commit()
Pierre-Yves Chibon 930073
            pr_flag = pagure.lib.query.get_pull_request_flag_by_uid(
Pierre-Yves Chibon 9c2953
                flask.g.session, request, uid
Pierre-Yves Chibon 9c2953
            )
Pierre-Yves Chibon 9c2953
            output["message"] = message
Pierre-Yves Chibon 9c2953
            output["uid"] = uid
Pierre-Yves Chibon 9c2953
            output["flag"] = pr_flag.to_json()
Pierre-Yves Chibon e39f18
        except pagure.exceptions.PagureException as err:
Pierre-Yves Chibon e39f18
            raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
                400, error_code=APIERROR.ENOCODE, error=str(err)
Pierre-Yves Chibon 9c2953
            )
Pierre-Yves Chibon fa97f7
        except SQLAlchemyError as err:  # pragma: no cover
Pierre-Yves Chibon b130e5
            _log.exception(err)
Pierre-Yves Chibon b130e5
            flask.g.session.rollback()
Pierre-Yves Chibon e39f18
            raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
Pierre-Yves Chibon e39f18
Pierre-Yves Chibon e39f18
    else:
Pierre-Yves Chibon f7fcaa
        raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
            400, error_code=APIERROR.EINVALIDREQ, errors=form.errors
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon e39f18
Pierre-Yves Chibon 930073
    output["avatar_url"] = pagure.lib.query.avatar_url_from_email(
Pierre-Yves Chibon 9c2953
        flask.g.fas_user.default_email, size=30
Pierre-Yves Chibon 9c2953
    )
Ryan Lerch ccb2e0
Pierre-Yves Chibon 9c2953
    output["user"] = flask.g.fas_user.username
Ryan Lerch ccb2e0
Pierre-Yves Chibon e39f18
    jsonout = flask.jsonify(output)
Pierre-Yves Chibon e39f18
    return jsonout
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 0e98b0
@API.route("/<repo>/pull-request/<int:requestid>/flag", methods=["GET"])</int:requestid></repo>
Pierre-Yves Chibon 0e98b0
@API.route(
Pierre-Yves Chibon 0e98b0
    "/<namespace>/<repo>/pull-request/<int:requestid>/flag", methods=["GET"]</int:requestid></repo></namespace>
Pierre-Yves Chibon 0e98b0
)
Pierre-Yves Chibon 0e98b0
@API.route(
Pierre-Yves Chibon 0e98b0
    "/fork/<username>/<repo>/pull-request/<int:requestid>/flag",</int:requestid></repo></username>
Pierre-Yves Chibon 0e98b0
    methods=["GET"],
Pierre-Yves Chibon 0e98b0
)
Pierre-Yves Chibon 0e98b0
@API.route(
Pierre-Yves Chibon 0e98b0
    "/fork/<username>/<namespace>/<repo>/pull-request/<int:requestid>/flag",</int:requestid></repo></namespace></username>
Pierre-Yves Chibon 0e98b0
    methods=["GET"],
Pierre-Yves Chibon 0e98b0
)
Pierre-Yves Chibon 0e98b0
@api_method
Pierre-Yves Chibon 0e98b0
def api_pull_request_get_flag(repo, requestid, username=None, namespace=None):
Pierre-Yves Chibon 0e98b0
    """
Pierre-Yves Chibon 0e98b0
    Get flag(s) of a pull-request
Pierre-Yves Chibon 0e98b0
    -----------------------------
Pierre-Yves Chibon 0e98b0
    Retrieve the flags on a pull-request.
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
    ::
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
        GET /api/0/<repo>/pull-request/<request id="">/flag</request></repo>
Pierre-Yves Chibon 0e98b0
        GET /api/0/<namespace>/<repo>/pull-request/<request id="">/flag</request></repo></namespace>
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
    ::
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
        GET /api/0/fork/<username>/<repo>/pull-request/<request id="">/flag</request></repo></username>
Pierre-Yves Chibon 0e98b0
        GET /api/0/fork/<username>/<namespace>/<repo>/pull-request/<request id="">/flag</request></repo></namespace></username>
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
    Sample response
Pierre-Yves Chibon 0e98b0
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
    ::
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
        {
Pierre-Yves Chibon 0e98b0
          "flags": [
Pierre-Yves Chibon 0e98b0
            {
Pierre-Yves Chibon 0e98b0
              "comment": "Tests are running in the AtomicCI pipeline",
Pierre-Yves Chibon 0e98b0
              "date_created": "1537560168",
Pierre-Yves Chibon 0e98b0
              "percent": null,
Pierre-Yves Chibon 0e98b0
              "pull_request_uid": "4fb1f8db8f114baeb943b6f10c5de015",
Pierre-Yves Chibon 0e98b0
              "status": "failure",
Pierre-Yves Chibon 0e98b0
              "url": "https://jenkins-continuous-infra.apps.ci.centos.org/job/continuous-infra-ci-pipeline-f26/...",
Pierre-Yves Chibon 0e98b0
              "user": {
Pierre-Yves Chibon 0e98b0
                "fullname": "Pierre-YvesChibon",
Pierre-Yves Chibon 0e98b0
                "name": "pingou"
Pierre-Yves Chibon 0e98b0
              },
Pierre-Yves Chibon 0e98b0
              "username": "AtomicCI"
Pierre-Yves Chibon 0e98b0
            },
Pierre-Yves Chibon 0e98b0
            {
Pierre-Yves Chibon 0e98b0
              "comment": "Built successfully",
Pierre-Yves Chibon 0e98b0
              "date_created": "1517565878",
Pierre-Yves Chibon 0e98b0
              "percent": 100,
Pierre-Yves Chibon 0e98b0
              "pull_request_uid": "4fb1f8db8f114baeb943b6f10c5de015",
Pierre-Yves Chibon 0e98b0
              "status": "success",
Pierre-Yves Chibon 0e98b0
              "url": "https://koji.fedoraproject.org/koji/...",
Pierre-Yves Chibon 0e98b0
              "user": {
Pierre-Yves Chibon 0e98b0
                "fullname": "Pierre-YvesChibon",
Pierre-Yves Chibon 0e98b0
                "name": "pingou"
Pierre-Yves Chibon 0e98b0
              },
Pierre-Yves Chibon 0e98b0
              "username": "simple-koji-ci"
Pierre-Yves Chibon 0e98b0
            }
Pierre-Yves Chibon 0e98b0
          ]
Pierre-Yves Chibon 0e98b0
        }
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
    """  # noqa
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
    output = {}
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 6fdb42
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 6fdb42
    _check_pull_request(repo)
Pierre-Yves Chibon 6fdb42
    request = _get_request(repo, requestid)
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
    output = {"flags": []}
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
    for flag in request.flags:
Pierre-Yves Chibon 0e98b0
        output["flags"].append(flag.to_json(public=True))
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
    jsonout = flask.jsonify(output)
Pierre-Yves Chibon 0e98b0
    return jsonout
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 0e98b0
Pierre-Yves Chibon 9c2953
@API.route("/<repo>/pull-request/<int:requestid>/subscribe", methods=["POST"])</int:requestid></repo>
Pierre-Yves Chibon 4f5301
@API.route(
Pierre-Yves Chibon 9c2953
    "/<namespace>/<repo>/pull-request/<int:requestid>/subscribe",</int:requestid></repo></namespace>
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 4f5301
@API.route(
Pierre-Yves Chibon 9c2953
    "/fork/<username>/<repo>/pull-request/<int:requestid>/subscribe",</int:requestid></repo></username>
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 4f5301
@API.route(
Pierre-Yves Chibon 9c2953
    "/fork/<username>/<namespace>/<repo>/pull-request/<int:requestid>"</int:requestid></repo></namespace></username>
Pierre-Yves Chibon 9c2953
    "/subscribe",
Pierre-Yves Chibon 9c2953
    methods=["POST"],
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 9c2953
@api_login_required(acls=["pull_request_subscribe"])
Pierre-Yves Chibon 4f5301
@api_method
Pierre-Yves Chibon 9c2953
def api_subscribe_pull_request(repo, requestid, username=None, namespace=None):
Pierre-Yves Chibon 4f5301
    """
Pierre-Yves Chibon 4f5301
    Subscribe to an pull-request
Pierre-Yves Chibon 4f5301
    ----------------------------
Pierre-Yves Chibon 4f5301
    Allows someone to subscribe to or unsubscribe from the notifications
Pierre-Yves Chibon 4f5301
    related to a pull-request.
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
    ::
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
        POST /api/0/<repo>/pull-request/<request id="">/subscribe</request></repo>
Pierre-Yves Chibon 4f5301
        POST /api/0/<namespace>/<repo>/pull-request/<request id="">/subscribe</request></repo></namespace>
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
    ::
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
        POST /api/0/fork/<username>/<repo>/pull-request/<request id="">/subscribe</request></repo></username>
Pierre-Yves Chibon 4f5301
        POST /api/0/fork/<username>/<namespace>/<repo>/pull-request/<request id="">/subscribe</request></repo></namespace></username>
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
    Input
Pierre-Yves Chibon 4f5301
    ^^^^^
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
    +--------------+----------+---------------+---------------------------+
Pierre-Yves Chibon 4f5301
    | Key          | Type     | Optionality   | Description               |
Pierre-Yves Chibon 4f5301
    +==============+==========+===============+===========================+
Pierre-Yves Chibon 4f5301
    | ``status``   | boolean  | Mandatory     | The intended subscription |
Pierre-Yves Chibon 4f5301
    |              |          |               | status. ``true`` for      |
Pierre-Yves Chibon 4f5301
    |              |          |               | subscribing, ``false``    |
Pierre-Yves Chibon 4f5301
    |              |          |               | for unsubscribing.        |
Pierre-Yves Chibon 4f5301
    +--------------+----------+---------------+---------------------------+
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
    Sample response
Pierre-Yves Chibon 4f5301
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
    ::
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
        {
Ryan Lerch ccb2e0
          "message": "User subscribed",
Ryan Lerch ccb2e0
          "avatar_url": "https://image.png",
Ryan Lerch ccb2e0
          "user": "pingou"
Pierre-Yves Chibon 4f5301
        }
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
    """  # noqa
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
    output = {}
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 6fdb42
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 6fdb42
    _check_pull_request(repo)
Pierre-Yves Chibon 6fdb42
    _check_token(repo)
Pierre-Yves Chibon 6fdb42
    request = _get_request(repo, requestid)
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 5c561c
    form = pagure.forms.SubscribtionForm(csrf_enabled=False)
Pierre-Yves Chibon 4f5301
    if form.validate_on_submit():
Aurélien Bompard 619e2a
        status = is_true(form.status.data)
Pierre-Yves Chibon 4f5301
        try:
Pierre-Yves Chibon 4f5301
            # Toggle subscribtion
Pierre-Yves Chibon 930073
            message = pagure.lib.query.set_watch_obj(
Pierre-Yves Chibon b130e5
                flask.g.session,
Pierre-Yves Chibon 4f5301
                user=flask.g.fas_user.username,
Pierre-Yves Chibon 4f5301
                obj=request,
Pierre-Yves Chibon 9c2953
                watch_status=status,
Pierre-Yves Chibon 4f5301
            )
Pierre-Yves Chibon b130e5
            flask.g.session.commit()
Pierre-Yves Chibon 9c2953
            output["message"] = message
Pierre-Yves Chibon 930073
            user_obj = pagure.lib.query.get_user(
Pierre-Yves Chibon 9c2953
                flask.g.session, flask.g.fas_user.username
Pierre-Yves Chibon 9c2953
            )
Pierre-Yves Chibon 930073
            output["avatar_url"] = pagure.lib.query.avatar_url_from_email(
Pierre-Yves Chibon 9c2953
                user_obj.default_email, size=30
Pierre-Yves Chibon 9c2953
            )
Pierre-Yves Chibon 9c2953
            output["user"] = flask.g.fas_user.username
Pierre-Yves Chibon 4f5301
        except SQLAlchemyError as err:  # pragma: no cover
Pierre-Yves Chibon b130e5
            flask.g.session.rollback()
Pierre-Yves Chibon b130e5
            _log.logger.exception(err)
Pierre-Yves Chibon 4f5301
            raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
Pierre-Yves Chibon 4f5301
Pierre-Yves Chibon 4f5301
    jsonout = flask.jsonify(output)
Pierre-Yves Chibon 4f5301
    return jsonout
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9c2953
@API.route("/<repo>/pull-request/new", methods=["POST"])</repo>
Pierre-Yves Chibon 9c2953
@API.route("/<namespace>/<repo>/pull-request/new", methods=["POST"])</repo></namespace>
Pierre-Yves Chibon 9c2953
@API.route("/fork/<username>/<repo>/pull-request/new", methods=["POST"])</repo></username>
Pierre-Yves Chibon 9c2953
@API.route(
Pierre-Yves Chibon 9c2953
    "/fork/<username>/<namespace>/<repo>/pull-request/new", methods=["POST"]</repo></namespace></username>
Pierre-Yves Chibon 9c2953
)
Pierre-Yves Chibon 9c2953
@api_login_required(acls=["pull_request_create"])
Pierre-Yves Chibon 9811e6
@api_method
Pierre-Yves Chibon 9811e6
def api_pull_request_create(repo, username=None, namespace=None):
Pierre-Yves Chibon 9811e6
    """
Pierre-Yves Chibon 9811e6
    Create pull-request
Pierre-Yves Chibon 9811e6
    -------------------
Pierre-Yves Chibon 9811e6
    Open a new pull-request from this project to itself or its parent (if
Pierre-Yves Chibon 9811e6
    this project is a fork).
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    ::
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
        POST /api/0/<repo>/pull-request/new</repo>
Pierre-Yves Chibon 9811e6
        POST /api/0/<namespace>/<repo>/pull-request/new</repo></namespace>
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    ::
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
        POST /api/0/fork/<username>/<repo>/pull-request/new</repo></username>
Pierre-Yves Chibon 9811e6
        POST /api/0/fork/<username>/<namespace>/<repo>/pull-request/new</repo></namespace></username>
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    Input
Pierre-Yves Chibon 9811e6
    ^^^^^
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 6fa4b3
    +-----------------------+----------+-------------+------------------------+
Pierre-Yves Chibon 6fa4b3
    | Key                   | Type     | Optionality | Description            |
Pierre-Yves Chibon 6fa4b3
    +=======================+==========+=============+========================+
Pierre-Yves Chibon 6fa4b3
    | ``title``             | string   | Mandatory   | The title to give to   |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | this pull-request      |
Pierre-Yves Chibon 6fa4b3
    +-----------------------+----------+-------------+------------------------+
Pierre-Yves Chibon 6fa4b3
    | ``branch_to``         | string   | Mandatory   | The name of the branch |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | the submitted changes  |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | should be merged into. |
Pierre-Yves Chibon 6fa4b3
    +-----------------------+----------+-------------+------------------------+
Pierre-Yves Chibon 6fa4b3
    | ``branch_from``       | string   | Mandatory   | The name of the branch |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | containing the changes |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | to merge               |
Pierre-Yves Chibon 6fa4b3
    +-----------------------+----------+-------------+------------------------+
Pierre-Yves Chibon 6fa4b3
    | ``repo_from``         | string   | Optional    | The name of the project|
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | the changes originate  |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | from.                  |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | If not specified the   |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | repo_from is assumed   |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | to be the repo_to.     |
Pierre-Yves Chibon 6fa4b3
    +-----------------------+----------+-------------+------------------------+
Pierre-Yves Chibon 6fa4b3
    | ``repo_from_username``| string   | Optional    | The username of the    |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | project the changes    |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | originate from.        |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | If not specified the   |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | repo_from is assumed   |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | to be the repo_to.     |
Pierre-Yves Chibon 6fa4b3
    +-----------------------+----------+-------------+------------------------+
Pierre-Yves Chibon 6fa4b3
    |``repo_from_namespace``| string   | Optional    | The namespace of the   |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | project the changes    |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | originate from.        |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | If not specified the   |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | repo_from is assumed   |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | to be the repo_to.     |
Pierre-Yves Chibon 6fa4b3
    +-----------------------+----------+-------------+------------------------+
Pierre-Yves Chibon 6fa4b3
    | ``initial_comment``   | string   | Optional    | The intial comment     |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | describing what these  |
Pierre-Yves Chibon 6fa4b3
    |                       |          |             | changes are about.     |
Pierre-Yves Chibon 6fa4b3
    +-----------------------+----------+-------------+------------------------+
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    Sample response
Pierre-Yves Chibon 9811e6
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    ::
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
        {
Pierre-Yves Chibon 9811e6
          "assignee": null,
Pierre-Yves Chibon 9811e6
          "branch": "master",
Pierre-Yves Chibon 9811e6
          "branch_from": "master",
Pierre-Yves Chibon 9811e6
          "closed_at": null,
Pierre-Yves Chibon 9811e6
          "closed_by": null,
Pierre-Yves Chibon 9811e6
          "comments": [],
Pierre-Yves Chibon 9811e6
          "commit_start": null,
Pierre-Yves Chibon 9811e6
          "commit_stop": null,
Pierre-Yves Chibon 9811e6
          "date_created": "1431414800",
Pierre-Yves Chibon 9811e6
          "id": 1,
Pierre-Yves Chibon 9811e6
          "project": {
Pierre-Yves Chibon 9811e6
            "close_status": [],
Pierre-Yves Chibon 9811e6
            "custom_keys": [],
Pierre-Yves Chibon 9811e6
            "date_created": "1431414800",
Pierre-Yves Chibon 9811e6
            "description": "test project #1",
Pierre-Yves Chibon 9811e6
            "id": 1,
Pierre-Yves Chibon 9811e6
            "name": "test",
Pierre-Yves Chibon 9811e6
            "parent": null,
Pierre-Yves Chibon 9811e6
            "user": {
Pierre-Yves Chibon 9811e6
              "fullname": "PY C",
Pierre-Yves Chibon 9811e6
              "name": "pingou"
Pierre-Yves Chibon 9811e6
            }
Pierre-Yves Chibon 9811e6
          },
Pierre-Yves Chibon 9811e6
          "repo_from": {
Pierre-Yves Chibon 9811e6
            "date_created": "1431414800",
Pierre-Yves Chibon 9811e6
            "description": "test project #1",
Pierre-Yves Chibon 9811e6
            "id": 1,
Pierre-Yves Chibon 9811e6
            "name": "test",
Pierre-Yves Chibon 9811e6
            "parent": null,
Pierre-Yves Chibon 9811e6
            "user": {
Pierre-Yves Chibon 9811e6
              "fullname": "PY C",
Pierre-Yves Chibon 9811e6
              "name": "pingou"
Pierre-Yves Chibon 9811e6
            }
Pierre-Yves Chibon 9811e6
          },
Pierre-Yves Chibon 9811e6
          "status": "Open",
Pierre-Yves Chibon 9811e6
          "title": "test pull-request",
Pierre-Yves Chibon 9811e6
          "uid": "1431414800",
Pierre-Yves Chibon 9811e6
          "updated_on": "1431414800",
Pierre-Yves Chibon 9811e6
          "user": {
Pierre-Yves Chibon 9811e6
            "fullname": "PY C",
Pierre-Yves Chibon 9811e6
            "name": "pingou"
Pierre-Yves Chibon 9811e6
          }
Pierre-Yves Chibon 9811e6
        }
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 6fa4b3
    """  # noqa
Pierre-Yves Chibon 9811e6
Lenka Segura 98b37a
    repo_to = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 0c2351
Pierre-Yves Chibon 6fa4b3
    req_data = get_request_data()
Pierre-Yves Chibon 6fa4b3
    repo_from = req_data.get("repo_from")
Pierre-Yves Chibon 6fa4b3
    repo_from_username = req_data.get("repo_from_username")
Pierre-Yves Chibon 6fa4b3
    repo_from_namespace = req_data.get("repo_from_namespace")
Pierre-Yves Chibon 6fa4b3
Pierre-Yves Chibon 6fa4b3
    if repo_from:
Pierre-Yves Chibon 0c2351
        repo_from = _get_repo(
Pierre-Yves Chibon 6fa4b3
            repo_from,
Pierre-Yves Chibon 6fa4b3
            username=repo_from_username,
Pierre-Yves Chibon 6fa4b3
            namespace=repo_from_namespace,
Lenka Segura 98b37a
        )
Pierre-Yves Chibon 0c2351
    else:
Pierre-Yves Chibon 0c2351
        repo_from = repo_to
Pierre-Yves Chibon 0c2351
Lenka Segura 98b37a
    _check_pull_request(repo_to)
Pierre-Yves Chibon f74d37
    _check_token(repo_from, project_token=False)
Pierre-Yves Chibon e99858
Pierre-Yves Chibon 5c561c
    form = pagure.forms.RequestPullForm(csrf_enabled=False)
Pierre-Yves Chibon 9811e6
    if not form.validate_on_submit():
Pierre-Yves Chibon 9811e6
        raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
            400, error_code=APIERROR.EINVALIDREQ, errors=form.errors
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 9c2953
    branch_to = get_request_data().get("branch_to")
Pierre-Yves Chibon 9811e6
    if not branch_to:
Pierre-Yves Chibon 9811e6
        raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
            400,
Pierre-Yves Chibon 9c2953
            error_code=APIERROR.EINVALIDREQ,
Pierre-Yves Chibon 9c2953
            errors={"branch_to": ["This field is required."]},
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 9c2953
    branch_from = get_request_data().get("branch_from")
Pierre-Yves Chibon 9811e6
    if not branch_from:
Pierre-Yves Chibon 9811e6
        raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
            400,
Pierre-Yves Chibon 9c2953
            error_code=APIERROR.EINVALIDREQ,
Pierre-Yves Chibon 9c2953
            errors={"branch_from": ["This field is required."]},
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 9811e6
Lenka Segura 98b37a
    if not repo_to.settings.get("pull_requests", True):
Pierre-Yves Chibon 9811e6
        raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
            404, error_code=APIERROR.EPULLREQUESTSDISABLED
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 9811e6
Lenka Segura 98b37a
    repo_committer = pagure.utils.is_repo_committer(repo_from)
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    if not repo_committer:
Pierre-Yves Chibon 9811e6
        raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
            401, error_code=APIERROR.ENOTHIGHENOUGH
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 9811e6
Lenka Segura 98b37a
    git_repo_from = pygit2.Repository(repo_from.repopath("main"))
Lenka Segura 98b37a
    git_repo_to = pygit2.Repository(repo_to.repopath("main"))
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    try:
Pierre-Yves Chibon 9811e6
        diff, diff_commits, orig_commit = pagure.lib.git.get_diff_info(
Lenka Segura 98b37a
            git_repo_from, git_repo_to, branch_from, branch_to
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 9811e6
    except pagure.exceptions.PagureException as err:
Pierre-Yves Chibon 9811e6
        raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
            400, error_code=APIERROR.EINVALIDREQ, errors=str(err)
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 9811e6
Lenka Segura 98b37a
    if repo_to.settings.get(
Pierre-Yves Chibon 9c2953
        "Enforce_signed-off_commits_in_pull-request", False
Pierre-Yves Chibon 9c2953
    ):
Pierre-Yves Chibon 9811e6
        for commit in diff_commits:
Pierre-Yves Chibon 9c2953
            if "signed-off-by" not in commit.message.lower():
Pierre-Yves Chibon 9811e6
                raise pagure.exceptions.APIError(
Pierre-Yves Chibon 9c2953
                    400, error_code=APIERROR.ENOSIGNEDOFF
Pierre-Yves Chibon 9c2953
                )
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    if orig_commit:
Pierre-Yves Chibon 9811e6
        orig_commit = orig_commit.oid.hex
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    initial_comment = form.initial_comment.data.strip() or None
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    commit_start = commit_stop = None
Pierre-Yves Chibon 9811e6
    if diff_commits:
Pierre-Yves Chibon 9811e6
        commit_stop = diff_commits[0].oid.hex
Pierre-Yves Chibon 9811e6
        commit_start = diff_commits[-1].oid.hex
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 930073
    request = pagure.lib.query.new_pull_request(
Pierre-Yves Chibon 9811e6
        flask.g.session,
Lenka Segura 98b37a
        repo_to=repo_to,
Pierre-Yves Chibon 9811e6
        branch_to=branch_to,
Pierre-Yves Chibon 9811e6
        branch_from=branch_from,
Lenka Segura 98b37a
        repo_from=repo_from,
Pierre-Yves Chibon 9811e6
        title=form.title.data,
Pierre-Yves Chibon 9811e6
        initial_comment=initial_comment,
Pierre-Yves Chibon 9811e6
        user=flask.g.fas_user.username,
Pierre-Yves Chibon 9811e6
        commit_start=commit_start,
Pierre-Yves Chibon 9811e6
        commit_stop=commit_stop,
Pierre-Yves Chibon 9811e6
    )
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    try:
Pierre-Yves Chibon 9811e6
        flask.g.session.commit()
Pierre-Yves Chibon 9811e6
    except SQLAlchemyError as err:  # pragma: no cover
Pierre-Yves Chibon 9811e6
        flask.g.session.rollback()
Pierre-Yves Chibon 9811e6
        _log.logger.exception(err)
Pierre-Yves Chibon 9811e6
        raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
Pierre-Yves Chibon 9811e6
Pierre-Yves Chibon 9811e6
    jsonout = flask.jsonify(request.to_json(public=True, api=True))
Pierre-Yves Chibon 9811e6
    return jsonout
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
@API.route("/<repo>/pull-request/<int:requestid>/diffstats")</int:requestid></repo>
Pierre-Yves Chibon c67f41
@API.route("/<namespace>/<repo>/pull-request/<int:requestid>/diffstats")</int:requestid></repo></namespace>
Pierre-Yves Chibon c67f41
@API.route("/fork/<username>/<repo>/pull-request/<int:requestid>/diffstats")</int:requestid></repo></username>
Pierre-Yves Chibon c67f41
@API.route(
Pierre-Yves Chibon c67f41
    "/fork/<username>/<namespace>/<repo>/pull-request/<int:requestid>/"</int:requestid></repo></namespace></username>
Pierre-Yves Chibon c67f41
    "diffstats"
Pierre-Yves Chibon c67f41
)
Pierre-Yves Chibon c67f41
@api_method
Pierre-Yves Chibon c67f41
def api_pull_request_diffstats(repo, requestid, username=None, namespace=None):
Pierre-Yves Chibon c67f41
    """
Pierre-Yves Chibon c67f41
    Pull-request diff statistics
Pierre-Yves Chibon c67f41
    ----------------------------
Pierre-Yves Chibon c67f41
    Retrieve the statistics about the diff of a specific pull request.
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
    ::
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
        GET /api/0/<repo>/pull-request/<request id="">/diffstats</request></repo>
Pierre-Yves Chibon c67f41
        GET /api/0/<namespace>/<repo>/pull-request/<request id="">/diffstats</request></repo></namespace>
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
    ::
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
        GET /api/0/fork/<username>/<repo>/pull-request/<request id="">/diffstats</request></repo></username>
Pierre-Yves Chibon c67f41
        GET /api/0/fork/<username>/<namespace>/<repo>/pull-request/<request id="">/diffstats</request></repo></namespace></username>
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
    Sample response
Pierre-Yves Chibon c67f41
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
    ::
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
        {
Pierre-Yves Chibon c67f41
          "README.rst": {
Pierre-Yves Chibon c67f41
            "lines_added": 1,
Pierre-Yves Chibon c67f41
            "lines_removed": 1,
Pierre-Yves Chibon c67f41
            "old_path": "README.rst",
Pierre-Yves Chibon c67f41
            "status": "M"
Pierre-Yves Chibon c67f41
          },
Pierre-Yves Chibon c67f41
          "blame_file.txt": {
Pierre-Yves Chibon c67f41
            "lines_added": 0,
Pierre-Yves Chibon c67f41
            "lines_removed": 0,
Pierre-Yves Chibon c67f41
            "old_path": "blame_file",
Pierre-Yves Chibon c67f41
            "status": "R"
Pierre-Yves Chibon c67f41
          },
Pierre-Yves Chibon c67f41
          "test": {
Pierre-Yves Chibon c67f41
            "lines_added": 0,
Pierre-Yves Chibon c67f41
            "lines_removed": 8,
Pierre-Yves Chibon c67f41
            "old_path": "test",
Pierre-Yves Chibon c67f41
            "status": "D"
Pierre-Yves Chibon c67f41
          },
Pierre-Yves Chibon c67f41
          "test3": {
Pierre-Yves Chibon c67f41
            "lines_added": 3,
Pierre-Yves Chibon c67f41
            "lines_removed": 0,
Pierre-Yves Chibon c67f41
            "old_path": "test3",
Pierre-Yves Chibon c67f41
            "status": "A"
Pierre-Yves Chibon c67f41
          }
Pierre-Yves Chibon c67f41
        }
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
    """  # noqa
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon 6fdb42
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon 6fdb42
    _check_pull_request(repo)
Pierre-Yves Chibon 6fdb42
    request = _get_request(repo, requestid)
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c8c021
    repopath = None
Pierre-Yves Chibon c8c021
    parentpath = pagure.utils.get_repo_path(request.project)
Pierre-Yves Chibon c67f41
    if request.remote:
Pierre-Yves Chibon c67f41
        repopath = pagure.utils.get_remote_repo_path(
Pierre-Yves Chibon c67f41
            request.remote_git, request.branch_from
Pierre-Yves Chibon c67f41
        )
Pierre-Yves Chibon c8c021
    elif request.project_from:
Pierre-Yves Chibon c8c021
        repopath = pagure.utils.get_repo_path(request.project_from)
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c8c021
    repo_obj = None
Pierre-Yves Chibon c8c021
    if repopath:
Pierre-Yves Chibon c8c021
        repo_obj = pygit2.Repository(repopath)
Pierre-Yves Chibon c67f41
    orig_repo = pygit2.Repository(parentpath)
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
    diff_commits = []
Pierre-Yves Chibon c67f41
    diff = None
Pierre-Yves Chibon c67f41
    # Closed pull-request
Pierre-Yves Chibon c67f41
    if request.status != "Open":
Pierre-Yves Chibon c67f41
        commitid = request.commit_stop
Pierre-Yves Chibon c67f41
        try:
Pierre-Yves Chibon c67f41
            for commit in repo_obj.walk(commitid, pygit2.GIT_SORT_NONE):
Pierre-Yves Chibon c67f41
                diff_commits.append(commit)
Pierre-Yves Chibon c67f41
                if commit.oid.hex == request.commit_start:
Pierre-Yves Chibon c67f41
                    break
Pierre-Yves Chibon c67f41
        except KeyError:
Pierre-Yves Chibon c67f41
            # This happens when repo.walk() cannot find commitid
Pierre-Yves Chibon c67f41
            pass
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
        if diff_commits:
Pierre-Yves Chibon c67f41
            # Ensure the first commit in the PR as a parent, otherwise
Pierre-Yves Chibon c67f41
            # point to it
Pierre-Yves Chibon c67f41
            start = diff_commits[-1].oid.hex
Pierre-Yves Chibon c67f41
            if diff_commits[-1].parents:
Pierre-Yves Chibon c67f41
                start = diff_commits[-1].parents[0].oid.hex
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
            # If the start and the end commits are the same, it means we are,
Pierre-Yves Chibon c67f41
            # dealing with one commit that has no parent, so just diff that
Pierre-Yves Chibon c67f41
            # one commit
Pierre-Yves Chibon c67f41
            if start == diff_commits[0].oid.hex:
Pierre-Yves Chibon c67f41
                diff = diff_commits[0].tree.diff_to_tree(swap=True)
Pierre-Yves Chibon c67f41
            else:
Pierre-Yves Chibon c67f41
                diff = repo_obj.diff(
Pierre-Yves Chibon c67f41
                    repo_obj.revparse_single(start),
Pierre-Yves Chibon c67f41
                    repo_obj.revparse_single(diff_commits[0].oid.hex),
Pierre-Yves Chibon c67f41
                )
Pierre-Yves Chibon c67f41
    else:
Pierre-Yves Chibon c67f41
        try:
Pierre-Yves Chibon c67f41
            diff_commits, diff = pagure.lib.git.diff_pull_request(
Pierre-Yves Chibon c67f41
                flask.g.session, request, repo_obj, orig_repo
Pierre-Yves Chibon c67f41
            )
Pierre-Yves Chibon c67f41
        except pagure.exceptions.PagureException as err:
Pierre-Yves Chibon c67f41
            flask.flash("%s" % err, "error")
Pierre-Yves Chibon c67f41
        except SQLAlchemyError as err:  # pragma: no cover
Pierre-Yves Chibon c67f41
            flask.g.session.rollback()
Pierre-Yves Chibon c67f41
            _log.exception(err)
Pierre-Yves Chibon c67f41
            flask.flash(
Pierre-Yves Chibon c67f41
                "Could not update this pull-request in the database", "error"
Pierre-Yves Chibon c67f41
            )
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
    if diff:
Pierre-Yves Chibon c67f41
        diff.find_similar()
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
    output = {}
Pierre-Yves Chibon c67f41
    if diff:
Pierre-Yves Chibon c67f41
        for patch in diff:
Pierre-Yves Chibon f6a6e0
            stats = pagure.lib.git.get_stats_patch(patch)
Pierre-Yves Chibon f6a6e0
            new_path = stats["new_path"]
Pierre-Yves Chibon 6fa4b3
            del stats["new_path"]
Pierre-Yves Chibon f6a6e0
            output[new_path] = stats
Pierre-Yves Chibon c67f41
    else:
Pierre-Yves Chibon c67f41
        raise pagure.exceptions.APIError(400, error_code=APIERROR.ENOPRSTATS)
Pierre-Yves Chibon c67f41
Pierre-Yves Chibon c67f41
    jsonout = flask.jsonify(output)
Pierre-Yves Chibon c67f41
    return jsonout
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
@API.route("/<repo>/pull-request/<int:requestid>/assign", methods=["POST"])</int:requestid></repo>
Pierre-Yves Chibon bc397c
@API.route(
Pierre-Yves Chibon bc397c
    "/<namespace>/<repo>/pull-request/<int:requestid>/assign", methods=["POST"]</int:requestid></repo></namespace>
Pierre-Yves Chibon bc397c
)
Pierre-Yves Chibon bc397c
@API.route(
Pierre-Yves Chibon bc397c
    "/fork/<username>/<repo>/pull-request/<int:requestid>/assign",</int:requestid></repo></username>
Pierre-Yves Chibon bc397c
    methods=["POST"],
Pierre-Yves Chibon bc397c
)
Pierre-Yves Chibon bc397c
@API.route(
Pierre-Yves Chibon bc397c
    "/fork/<username>/<namespace>/<repo>/pull-request/<int:requestid>/assign",</int:requestid></repo></namespace></username>
Pierre-Yves Chibon bc397c
    methods=["POST"],
Pierre-Yves Chibon bc397c
)
Pierre-Yves Chibon bc397c
@api_login_required(acls=["pull_request_assign", "pull_request_update"])
Pierre-Yves Chibon bc397c
@api_method
Pierre-Yves Chibon bc397c
def api_pull_request_assign(repo, requestid, username=None, namespace=None):
Pierre-Yves Chibon bc397c
    """
Pierre-Yves Chibon bc397c
    Assign a pull-request
Pierre-Yves Chibon bc397c
    ---------------------
Pierre-Yves Chibon bc397c
    Assign a pull-request to someone.
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
    ::
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
        POST /api/0/<repo>/pull-request/<issue id="">/assign</issue></repo>
Pierre-Yves Chibon bc397c
        POST /api/0/<namespace>/<repo>/pull-request/<issue id="">/assign</issue></repo></namespace>
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
    ::
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
        POST /api/0/fork/<username>/<repo>/pull-request/<issue id="">/assign</issue></repo></username>
Pierre-Yves Chibon bc397c
        POST /api/0/fork/<username>/<namespace>/<repo>/pull-request/<issue id="">/assign</issue></repo></namespace></username>
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
    Input
Pierre-Yves Chibon bc397c
    ^^^^^
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
    +--------------+----------+---------------+---------------------------+
Pierre-Yves Chibon bc397c
    | Key          | Type     | Optionality   | Description               |
Pierre-Yves Chibon bc397c
    +==============+==========+===============+===========================+
Pierre-Yves Chibon bc397c
    | ``assignee`` | string   | Mandatory     | | The username of the user|
Pierre-Yves Chibon bc397c
    |              |          |               |   to assign the PR to.    |
Pierre-Yves Chibon bc397c
    +--------------+----------+---------------+---------------------------+
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
    Sample response
Pierre-Yves Chibon bc397c
    ^^^^^^^^^^^^^^^
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
    ::
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
        {
Pierre-Yves Chibon bc397c
          "message": "pull-request assigned"
Pierre-Yves Chibon bc397c
        }
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
    """  # noqa
Pierre-Yves Chibon bc397c
    output = {}
Pierre-Yves Chibon bc397c
    repo = _get_repo(repo, username, namespace)
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
    _check_pull_request(repo)
Pierre-Yves Chibon bc397c
    _check_token(repo)
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
    request = _get_request(repo, requestid)
Pierre-Yves Chibon bc397c
    _check_pull_request_access(request, assignee=True)
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
    form = pagure.forms.AssignIssueForm(csrf_enabled=False)
Pierre-Yves Chibon bc397c
    if form.validate_on_submit():
Pierre-Yves Chibon bc397c
        assignee = form.assignee.data or None
Pierre-Yves Chibon bc397c
        # Create our metadata comment object
Pierre-Yves Chibon bc397c
        try:
Pierre-Yves Chibon bc397c
            # New comment
Pierre-Yves Chibon bc397c
            message = pagure.lib.query.add_pull_request_assignee(
Pierre-Yves Chibon bc397c
                flask.g.session,
Pierre-Yves Chibon bc397c
                request=request,
Pierre-Yves Chibon bc397c
                assignee=assignee,
Pierre-Yves Chibon bc397c
                user=flask.g.fas_user.username,
Pierre-Yves Chibon bc397c
            )
Pierre-Yves Chibon bc397c
            flask.g.session.commit()
Pierre-Yves Chibon bc397c
            if message:
Pierre-Yves Chibon bc397c
                pagure.lib.query.add_metadata_update_notif(
Pierre-Yves Chibon bc397c
                    session=flask.g.session,
Pierre-Yves Chibon bc397c
                    obj=request,
Pierre-Yves Chibon bc397c
                    messages=message,
Pierre-Yves Chibon bc397c
                    user=flask.g.fas_user.username,
Pierre-Yves Chibon bc397c
                )
Pierre-Yves Chibon bc397c
                output["message"] = message
Pierre-Yves Chibon bc397c
            else:
Pierre-Yves Chibon bc397c
                output["message"] = "Nothing to change"
Pierre-Yves Chibon bc397c
        except pagure.exceptions.PagureException as err:  # pragma: no cover
Pierre-Yves Chibon bc397c
            raise pagure.exceptions.APIError(
Pierre-Yves Chibon bc397c
                400, error_code=APIERROR.ENOCODE, error=str(err)
Pierre-Yves Chibon bc397c
            )
Pierre-Yves Chibon bc397c
        except SQLAlchemyError as err:  # pragma: no cover
Pierre-Yves Chibon bc397c
            flask.g.session.rollback()
Pierre-Yves Chibon bc397c
            _log.exception(err)
Pierre-Yves Chibon bc397c
            raise pagure.exceptions.APIError(400, error_code=APIERROR.EDBERROR)
Pierre-Yves Chibon bc397c
Pierre-Yves Chibon bc397c
    jsonout = flask.jsonify(output)
Pierre-Yves Chibon bc397c
    return jsonout