Blame pagure/hooks/rtd.py

Pierre-Yves Chibon 6d2f25
# -*- coding: utf-8 -*-
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
"""
Pierre-Yves Chibon 6d2f25
 (c) 2016 - Copyright Red Hat Inc
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
 Authors:
Pierre-Yves Chibon 6d2f25
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
"""
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 5a5352
Pierre-Yves Chibon 67d1cc
from __future__ import unicode_literals, absolute_import
Aurélien Bompard dcf6f6
Pierre-Yves Chibon 6d2f25
import sqlalchemy as sa
Patrick Uiterwijk 4012dc
import requests
Pierre-Yves Chibon 6d2f25
import wtforms
Pierre-Yves Chibon 5a5352
Pierre-Yves Chibon 5a5352
try:
Pierre-Yves Chibon 2011e2
    from flask_wtf import FlaskForm
Pierre-Yves Chibon 5a5352
except ImportError:
Pierre-Yves Chibon 5a5352
    from flask_wtf import Form as FlaskForm
Pierre-Yves Chibon 6d2f25
from sqlalchemy.orm import relation
Pierre-Yves Chibon 6d2f25
from sqlalchemy.orm import backref
Pierre-Yves Chibon 6d2f25
Patrick Uiterwijk 4012dc
import pagure
Patrick Uiterwijk 4012dc
from pagure.hooks import BaseHook, BaseRunner
Pierre-Yves Chibon 6d2f25
from pagure.lib.model import BASE, Project
Patrick Uiterwijk 4012dc
Patrick Uiterwijk 4012dc
_config = pagure.config.config
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
class RtdTable(BASE):
Pierre-Yves Chibon 6d2f25
    """ Stores information about the pagure hook deployed on a project.
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
    Table -- hook_rtd
Pierre-Yves Chibon 6d2f25
    """
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 9c2953
    __tablename__ = "hook_rtd"
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
    id = sa.Column(sa.Integer, primary_key=True)
Pierre-Yves Chibon 6d2f25
    project_id = sa.Column(
Pierre-Yves Chibon 6d2f25
        sa.Integer,
Pierre-Yves Chibon 9c2953
        sa.ForeignKey("projects.id", onupdate="CASCADE", ondelete="CASCADE"),
Pierre-Yves Chibon 6d2f25
        nullable=False,
Pierre-Yves Chibon 6d2f25
        unique=True,
Pierre-Yves Chibon 9c2953
        index=True,
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
    active = sa.Column(sa.Boolean, nullable=False, default=False)
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
    branches = sa.Column(sa.Text, nullable=True)
Pierre-Yves Chibon 613b67
    api_url = sa.Column(sa.Text, nullable=False)
Pierre-Yves Chibon 613b67
    api_token = sa.Column(sa.Text, nullable=False)
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
    project = relation(
Pierre-Yves Chibon 9c2953
        "Project",
Pierre-Yves Chibon 9c2953
        remote_side=[Project.id],
Pierre-Yves Chibon 6d2f25
        backref=backref(
Pierre-Yves Chibon 9c2953
            "rtd_hook",
Pierre-Yves Chibon 9c2953
            cascade="delete, delete-orphan",
Pierre-Yves Chibon 9c2953
            single_parent=True,
Pierre-Yves Chibon 9c2953
            uselist=False,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 6d2f25
    )
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 5a5352
class RtdForm(FlaskForm):
Pierre-Yves Chibon 9c2953
    """ Form to configure the pagure hook. """
Pierre-Yves Chibon 9c2953
Lenka Segura 643d50
    api_url = wtforms.StringField(
Pierre-Yves Chibon 9c2953
        "URL endpoint used to trigger the builds",
Pierre-Yves Chibon 9c2953
        [wtforms.validators.Optional()],
Pierre-Yves Chibon 613b67
    )
Lenka Segura 643d50
    api_token = wtforms.StringField(
Pierre-Yves Chibon 9c2953
        "API token provided by readthedocs", [wtforms.validators.Optional()]
Pierre-Yves Chibon 6d2f25
    )
Lenka Segura 643d50
    branches = wtforms.StringField(
Pierre-Yves Chibon 9c2953
        "Restrict build to these branches only (comma separated)",
Pierre-Yves Chibon 9c2953
        [wtforms.validators.Optional()],
Pierre-Yves Chibon 6d2f25
    )
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 9c2953
    active = wtforms.BooleanField("Active", [wtforms.validators.Optional()])
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 9c2953
DESCRIPTION = """
Pierre-Yves Chibon 613b67
Git hook to trigger building documentation on the readthedocs.org service
Pierre-Yves Chibon 613b67
when a commit is pushed to the repository.
Pierre-Yves Chibon 613b67
Pierre-Yves Chibon 613b67
If you specify one or more branches (using commas `,` to separate them) only
Pierre-Yves Chibon 613b67
pushes made to these branches will trigger a new build of the documentation.
Pierre-Yves Chibon 613b67
Pierre-Yves Chibon 613b67
To set up this hook, you will need to login to https://readthedocs.org/
Patrick Uiterwijk 4012dc
Go to your project's admin settings, and in the ``Integrations`` section
Pierre-Yves Chibon 613b67
add a new ``Generic API incoming webhook``.
Pierre-Yves Chibon 613b67
Pierre-Yves Chibon 613b67
This will give you access to one URL and one API token, both of which you
Pierre-Yves Chibon 613b67
will have to provide below.
Pierre-Yves Chibon 613b67
Pierre-Yves Chibon 9c2953
"""
Pierre-Yves Chibon 613b67
Pierre-Yves Chibon 613b67
Patrick Uiterwijk 4012dc
class RtdRunner(BaseRunner):
Patrick Uiterwijk 4012dc
    @staticmethod
Patrick Uiterwijk 4012dc
    def post_receive(session, username, project, repotype, repodir, changes):
Patrick Uiterwijk 4012dc
        """ Perform the RTD Post Receive hook.
Patrick Uiterwijk 4012dc
Patrick Uiterwijk 4012dc
        For arguments, see BaseRunner.runhook.
Patrick Uiterwijk 4012dc
        """
Patrick Uiterwijk 4012dc
        # Get the list of branches
Patrick Uiterwijk 4012dc
        branches = [
Patrick Uiterwijk 4012dc
            branch.strip() for branch in project.rtd_hook.branches.split(",")
Patrick Uiterwijk 4012dc
        ]
Patrick Uiterwijk 4012dc
Patrick Uiterwijk 4012dc
        # Remove empty branches
Patrick Uiterwijk 4012dc
        branches = [branch.strip() for branch in branches if branch]
Patrick Uiterwijk 4012dc
Patrick Uiterwijk 4012dc
        url = project.rtd_hook.api_url
Patrick Uiterwijk 4012dc
        if not url:
Patrick Uiterwijk 4012dc
            print(
Patrick Uiterwijk 4012dc
                "No API url specified to trigger the build, please update "
Patrick Uiterwijk 4012dc
                "the configuration"
Patrick Uiterwijk 4012dc
            )
Patrick Uiterwijk 4012dc
        if not project.rtd_hook.api_token:
Patrick Uiterwijk 4012dc
            print(
Patrick Uiterwijk 4012dc
                "No API token specified to trigger the build, please update "
Patrick Uiterwijk 4012dc
                "the configuration"
Patrick Uiterwijk 4012dc
            )
Patrick Uiterwijk 4012dc
Patrick Uiterwijk 4012dc
        for refname in changes:
Patrick Uiterwijk 4012dc
            oldrev, newrev = changes[refname]
Patrick Uiterwijk 4012dc
            if _config.get("HOOK_DEBUG", False):
Patrick Uiterwijk 4012dc
                print("%s: %s -> %s" % (refname, oldrev, newrev))
Patrick Uiterwijk 4012dc
Patrick Uiterwijk 4012dc
            refname = refname.replace("refs/heads/", "")
Patrick Uiterwijk 4012dc
            if branches:
Patrick Uiterwijk 4012dc
                if refname in branches:
Patrick Uiterwijk 4012dc
                    print("Starting RTD build at %s" % (url))
Patrick Uiterwijk 4012dc
                    requests.post(
Patrick Uiterwijk 4012dc
                        url,
Patrick Uiterwijk 4012dc
                        data={
Patrick Uiterwijk 4012dc
                            "branches": refname,
Patrick Uiterwijk 4012dc
                            "token": project.rtd_hook.api_token,
Patrick Uiterwijk 4012dc
                        },
Patrick Uiterwijk 4012dc
                        timeout=60,
Patrick Uiterwijk 4012dc
                    )
Patrick Uiterwijk 4012dc
            else:
Patrick Uiterwijk 4012dc
                print("Starting RTD build at %s" % (url))
Patrick Uiterwijk 4012dc
                requests.post(
Patrick Uiterwijk 4012dc
                    url,
Patrick Uiterwijk 4012dc
                    data={
Patrick Uiterwijk 4012dc
                        "branches": refname,
Patrick Uiterwijk 4012dc
                        "token": project.rtd_hook.api_token,
Patrick Uiterwijk 4012dc
                    },
Patrick Uiterwijk 4012dc
                    timeout=60,
Patrick Uiterwijk 4012dc
                )
Patrick Uiterwijk 4012dc
Patrick Uiterwijk 4012dc
Pierre-Yves Chibon 6d2f25
class RtdHook(BaseHook):
Pierre-Yves Chibon 9c2953
    """ Read The Doc hook. """
Pierre-Yves Chibon 6d2f25
Pierre-Yves Chibon 9c2953
    name = "Read the Doc"
Pierre-Yves Chibon 613b67
    description = DESCRIPTION
Pierre-Yves Chibon 6d2f25
    form = RtdForm
Pierre-Yves Chibon 6d2f25
    db_object = RtdTable
Patrick Uiterwijk 4012dc
    runner = RtdRunner
Pierre-Yves Chibon 9c2953
    backref = "rtd_hook"
Pierre-Yves Chibon 9c2953
    form_fields = ["active", "api_url", "api_token", "branches"]