Blame pagure/hooks/mail.py

Pierre-Yves Chibon 33b534
# -*- coding: utf-8 -*-
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 82dc5a
"""
Pierre-Yves Chibon 5a5352
 (c) 2014-2016 - Copyright Red Hat Inc
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 82dc5a
 Authors:
Pierre-Yves Chibon 82dc5a
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 82dc5a
"""
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 67d1cc
from __future__ import unicode_literals, absolute_import
Aurélien Bompard dcf6f6
Pierre-Yves Chibon 82dc5a
import sqlalchemy as sa
Patrick Uiterwijk cd5251
import os
Pierre-Yves Chibon 82dc5a
import pygit2
Patrick Uiterwijk cd5251
import subprocess
Pierre-Yves Chibon 362b15
import wtforms
Pierre-Yves Chibon 9c2953
Pierre-Yves Chibon 5a5352
try:
Pierre-Yves Chibon 2011e2
    from flask_wtf import FlaskForm
Pierre-Yves Chibon 2011e2
except ImportError:
Pierre-Yves Chibon 5a5352
    from flask_wtf import Form as FlaskForm
Pierre-Yves Chibon 82dc5a
from sqlalchemy.orm import relation
Pierre-Yves Chibon 848b42
from sqlalchemy.orm import backref
Pierre-Yves Chibon 82dc5a
Patrick Uiterwijk 8b1564
from pagure.config import config as pagure_config
Patrick Uiterwijk cd5251
from pagure.hooks import BaseHook, BaseRunner, RequiredIf
Pierre-Yves Chibon fe5017
from pagure.lib.model import BASE, Project
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 82dc5a
class MailTable(BASE):
Snehal Karale f6d28c
    """ Stores information about the mail hook deployed on a project.
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 82dc5a
    Table -- hook_mail
Pierre-Yves Chibon 82dc5a
    """
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 9c2953
    __tablename__ = "hook_mail"
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 82dc5a
    id = sa.Column(sa.Integer, primary_key=True)
Pierre-Yves Chibon 82dc5a
    project_id = sa.Column(
Pierre-Yves Chibon 82dc5a
        sa.Integer,
Pierre-Yves Chibon 9c2953
        sa.ForeignKey("projects.id", onupdate="CASCADE", ondelete="CASCADE"),
Pierre-Yves Chibon 82dc5a
        nullable=False,
Pierre-Yves Chibon 82dc5a
        unique=True,
Pierre-Yves Chibon 9c2953
        index=True,
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 82dc5a
    mail_to = sa.Column(sa.Text, nullable=False)
Pierre-Yves Chibon 82dc5a
    active = sa.Column(sa.Boolean, nullable=False, default=False)
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 82dc5a
    project = relation(
Pierre-Yves Chibon 9c2953
        "Project",
Pierre-Yves Chibon 9c2953
        remote_side=[Project.id],
Pierre-Yves Chibon 848b42
        backref=backref(
Pierre-Yves Chibon 9c2953
            "mail_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
        ),
farhaanbukhsh 9b97b4
    )
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 5a5352
class MailForm(FlaskForm):
Pierre-Yves Chibon 9c2953
    """ Form to configure the mail hook. """
Pierre-Yves Chibon 9c2953
Lenka Segura 643d50
    mail_to = wtforms.StringField("Mail to", [RequiredIf("active")])
Pierre-Yves Chibon 9c2953
    active = wtforms.BooleanField("Active", [wtforms.validators.Optional()])
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 82dc5a
Patrick Uiterwijk cd5251
class MailRunner(BaseRunner):
Patrick Uiterwijk cd5251
    @staticmethod
Patrick Uiterwijk cd5251
    def post_receive(session, username, project, repotype, repodir, changes):
Patrick Uiterwijk cd5251
        """ Run the multimail post-receive hook.
Patrick Uiterwijk cd5251
Patrick Uiterwijk cd5251
        For args, see BaseRunner.runhook.
Patrick Uiterwijk cd5251
        """
Patrick Uiterwijk cd5251
        if repotype != "main":
Patrick Uiterwijk cd5251
            # This hook is only useful on the main repo
Patrick Uiterwijk cd5251
            return
Patrick Uiterwijk cd5251
Patrick Uiterwijk cd5251
        # This may run on a temporary clone, but that doesn't matter.
Patrick Uiterwijk cd5251
        # We set these options every time again anyway
Patrick Uiterwijk cd5251
        repo_obj = pygit2.Repository(repodir)
Patrick Uiterwijk cd5251
        repo_obj.config.set_multivar(
Patrick Uiterwijk 7a66dd
            "multimailhook.mailingList", "", project.mail_hook.mail_to
Patrick Uiterwijk cd5251
        )
Patrick Uiterwijk cd5251
        repo_obj.config.set_multivar(
Patrick Uiterwijk cd5251
            "multimailhook.environment", "", "gitolite"
Patrick Uiterwijk cd5251
        )
Patrick Uiterwijk 8b1564
        repo_obj.config.set_multivar(
Patrick Uiterwijk 8b1564
            "multimailhook.repoName", "", project.fullname
Patrick Uiterwijk 8b1564
        )
Patrick Uiterwijk 8b1564
        repo_obj.config.set_multivar("multimailhook.mailer", "", "smtp")
Patrick Uiterwijk 8b1564
        repo_obj.config.set_multivar(
Patrick Uiterwijk 8b1564
            "multimailhook.smtpServer", "", pagure_config["SMTP_SERVER"]
Patrick Uiterwijk 8b1564
        )
Patrick Uiterwijk 8b1564
        repo_obj.config.set_multivar(
Patrick Uiterwijk d682d5
            "multimailhook.smtpUser", "", pagure_config["SMTP_USERNAME"] or ""
Patrick Uiterwijk 8b1564
        )
Patrick Uiterwijk 8b1564
        repo_obj.config.set_multivar(
Patrick Uiterwijk d682d5
            "multimailhook.smtpPass", "", pagure_config["SMTP_PASSWORD"] or ""
Patrick Uiterwijk 8b1564
        )
Patrick Uiterwijk 8b1564
        repo_obj.config.set_multivar(
Patrick Uiterwijk 8b1564
            "multimailhook.smtpEncryption",
Patrick Uiterwijk 8b1564
            "",
Patrick Uiterwijk d682d5
            "tls" if pagure_config["SMTP_SSL"] else "none",
Patrick Uiterwijk 8b1564
        )
Patrick Uiterwijk 8b1564
        repo_obj.config.set_multivar(
Patrick Uiterwijk 8b1564
            "multimailhook.from", "", pagure_config["FROM_EMAIL"]
Patrick Uiterwijk 8b1564
        )
Patrick Uiterwijk cd5251
Patrick Uiterwijk cd5251
        # Now just run the .py file as a git hook
Patrick Uiterwijk cd5251
        hook_file = os.path.join(
Patrick Uiterwijk cd5251
            os.path.dirname(os.path.realpath(__file__)),
Patrick Uiterwijk cd5251
            "files",
Patrick Uiterwijk cd5251
            "git_multimail_upstream.py",
Patrick Uiterwijk cd5251
        )
Patrick Uiterwijk cd5251
        stdin = (
Patrick Uiterwijk cd5251
            "\n".join(
Patrick Uiterwijk cd5251
                [
Patrick Uiterwijk cd5251
                    "%s %s %s" % (changes[refname] + (refname,))
Patrick Uiterwijk cd5251
                    for refname in changes
Patrick Uiterwijk cd5251
                ]
Patrick Uiterwijk cd5251
            )
Patrick Uiterwijk cd5251
            + "\n"
Patrick Uiterwijk cd5251
        )
Patrick Uiterwijk cd5251
Patrick Uiterwijk cd5251
        proc = subprocess.Popen(
Patrick Uiterwijk cd5251
            [hook_file], cwd=repodir, stdin=subprocess.PIPE
Patrick Uiterwijk cd5251
        )
Patrick Uiterwijk cd5251
        proc.communicate(stdin)
Patrick Uiterwijk cd5251
        ecode = proc.wait()
Patrick Uiterwijk cd5251
        if ecode != 0:
Patrick Uiterwijk cd5251
            print("git_multimail failed")
Patrick Uiterwijk e3347b
            raise Exception("git_multimail failed")
Patrick Uiterwijk cd5251
Patrick Uiterwijk cd5251
Pierre-Yves Chibon 82dc5a
class Mail(BaseHook):
Pierre-Yves Chibon 9c2953
    """ Mail hooks. """
Pierre-Yves Chibon 82dc5a
Pierre-Yves Chibon 9c2953
    name = "Mail"
Pierre-Yves Chibon 9c2953
    description = (
Pierre-Yves Chibon 9c2953
        "Generate notification emails for pushes to a git "
Pierre-Yves Chibon 9c2953
        "repository. This hook sends emails describing changes introduced "
Pierre-Yves Chibon 9c2953
        "by pushes to a git repository."
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 82dc5a
    form = MailForm
Pierre-Yves Chibon 82dc5a
    db_object = MailTable
Pierre-Yves Chibon 9c2953
    backref = "mail_hook"
Pierre-Yves Chibon 9c2953
    form_fields = ["mail_to", "active"]
Patrick Uiterwijk cd5251
    runner = MailRunner