<html><head><meta name="color-scheme" content="light dark"></head><body><pre style="word-wrap: break-word; white-space: pre-wrap;">import logging
import re
import subprocess

from rbtools.api.client import RBClient
from rbtools.api.errors import APIError, ServerInterfaceError


SUBMITTED = 'submitted'


class HookError(Exception):
    pass


def _make_api_client(server_url, username, password):
    """Returns an RBClient object for the server.

    The RBClient will be instantiated with the proper arguments
    for talking to the provided Review Board server url.
    """
    return RBClient(server_url, username=username, password=password)

def get_api(server_url, username, password):
    """Returns an RBClient instance and the associated root resource.

    Hooks should use this method to gain access to the API,
    instead of instantianting their own client.
    """
    api_client = _make_api_client(server_url, username, password)

    try:
        api_root = api_client.get_root()
    except ServerInterfaceError, e:
        raise HookError('Could not reach the Review Board server at %s'
                        % server_url)
    except APIError, e:
        raise HookError('Unexpected API Error: %s' % e)

    return api_client, api_root

def execute(command):
    """Executes the specified command and returns the stdout output."""
    process = subprocess.Popen(command, shell=True, stdout=subprocess.PIPE)
    return process.communicate()[0].strip()

def get_review_request_id(regex, commit_message):
    """Returns the review request ID referenced in the commit message.

    We assume there is only one review request to be closed per commit. If a
    matching review request cannot be found, we return None.
    """
    pattern = re.compile(regex, re.IGNORECASE)
    match = pattern.search(commit_message)
    review_request_id = (match and match.group('id')) or None
    return review_request_id

def get_review_request(review_request_id, api_root):
    """Returns the review request resource for the given ID."""
    try:
        review_request = api_root.get_review_request(
            review_request_id=review_request_id)
    except APIError, e:
        raise HookError('Error getting review request: %s' % e)

    return review_request

def close_review_request(server_url, username, password, review_request_id,
                         description):
    """Closes the specified review request as submitted."""
    api_client, api_root = get_api(server_url, username, password)
    review_request = get_review_request(review_request_id, api_root)

    if review_request.status == SUBMITTED:
        logging.warning('Review request #%s is already %s.',
                        review_request_id, SUBMITTED)
        return

    if description:
        review_request = review_request.update(status=SUBMITTED,
                                               description=description)
    else:
        review_request = review_request.update(status=SUBMITTED)

    print('Review request #%s is set to %s.' %
          (review_request_id, review_request.status))

def get_review_request_approval(server_url, username, password,
                                review_request_id):
    """Returns the approval information for the given review request."""
    api_client, api_root = get_api(server_url, username, password)
    review_request = get_review_request(review_request_id, api_root)

    return review_request.approved, review_request.approval_failure</pre></body></html>