Blame pagure/lib/notify.py

Pierre-Yves Chibon 33b534
# -*- coding: utf-8 -*-
Pierre-Yves Chibon d8781e
Pierre-Yves Chibon d8781e
"""
Pierre-Yves Chibon 4b8077
 (c) 2014-2018 - Copyright Red Hat Inc
Pierre-Yves Chibon d8781e
Pierre-Yves Chibon d8781e
 Authors:
Pierre-Yves Chibon d8781e
   Pierre-Yves Chibon <pingou@pingoured.fr></pingou@pingoured.fr>
Pierre-Yves Chibon d8781e
Pierre-Yves Chibon fe5017
pagure notifications.
Pierre-Yves Chibon d8781e
"""
Pierre-Yves Chibon 67d1cc
from __future__ import print_function, unicode_literals, absolute_import
Aurélien Bompard 831553
Pierre-Yves Chibon d8781e
Pierre-Yves Chibon 22a554
# pylint: disable=too-many-branches
Pierre-Yves Chibon 22a554
# pylint: disable=too-many-arguments
Pierre-Yves Chibon f5708b
Pierre-Yves Chibon f5708b
Pierre-Yves Chibon 3aeebc
import datetime
Pierre-Yves Chibon 3bcdaf
import hashlib
Slavek Kabrda 631df5
import json
Pierre-Yves Chibon 4635b5
import logging
Pierre-Yves Chibon 4eda2c
import os
Pierre-Yves Chibon 51c6d4
import re
Pierre-Yves Chibon d8781e
import smtplib
Pierre-Yves Chibon 3aeebc
import time
Aurélien Bompard 831553
import six
Pierre-Yves Chibon 4eda2c
import ssl
Pierre-Yves Chibon 65d42e
from email.header import Header
Pierre-Yves Chibon d8781e
from email.mime.text import MIMEText
Aurélien Bompard 831553
from six.moves.urllib_parse import urljoin
Pierre-Yves Chibon 712198
Pierre-Yves Chibon 4517cd
import blinker
Pierre-Yves Chibon b130e5
import flask
Pierre-Yves Chibon 930073
import pagure.lib.query
Pierre-Yves Chibon 7937d2
import pagure.lib.tasks_services
Pierre-Yves Chibon b130e5
from pagure.config import config as pagure_config
Pierre-Yves Chibon 3ff584
from pagure.pfmarkdown import MENTION_RE
Pierre-Yves Chibon b130e5
Pierre-Yves Chibon 712198
Pierre-Yves Chibon 4635b5
_log = logging.getLogger(__name__)
Pierre-Yves Chibon 4635b5
Pierre-Yves Chibon 4635b5
Pierre-Yves Chibon 9c2953
REPLY_MSG = "To reply, visit the link below"
Pierre-Yves Chibon 9c2953
if pagure_config["EVENTSOURCE_SOURCE"]:
Pierre-Yves Chibon 9c2953
    REPLY_MSG += " or just reply to this email"
Pierre-Yves Chibon a2efa3
Pierre-Yves Chibon 433392
Pierre-Yves Chibon a79c31
def fedmsg_publish(*args, **kwargs):  # pragma: no cover
Pierre-Yves Chibon 9c2953
    """ Try to publish a message on the fedmsg bus. """
Pierre-Yves Chibon 9c2953
    if not pagure_config.get("FEDMSG_NOTIFICATIONS", True):
Pierre-Yves Chibon de6940
        return
Pierre-Yves Chibon de6940
Pierre-Yves Chibon 62e980
    _log.warning(
Pierre-Yves Chibon 62e980
        "fedmsg support is being deprecated in favor of fedora-messaging "
Pierre-Yves Chibon 62e980
        "you likely want to stop relying on it as it will disapear in the "
Pierre-Yves Chibon 62e980
        "future, most likely in the 6.0 release"
Pierre-Yves Chibon 62e980
    )
Pierre-Yves Chibon 62e980
Pierre-Yves Chibon b53eb8
    # We catch Exception if we want :-p
Pierre-Yves Chibon 22a554
    # pylint: disable=broad-except
Pierre-Yves Chibon b53eb8
    # Ignore message about fedmsg import
Pierre-Yves Chibon 22a554
    # pylint: disable=import-error
Pierre-Yves Chibon 9c2953
    kwargs["modname"] = "pagure"
Pierre-Yves Chibon 9c2953
    kwargs["cert_prefix"] = "pagure"
Pierre-Yves Chibon 9c2953
    kwargs["active"] = True
Pierre-Yves Chibon a79c31
    try:
Pierre-Yves Chibon a79c31
        import fedmsg
Pierre-Yves Chibon 9c2953
Pierre-Yves Chibon a79c31
        fedmsg.publish(*args, **kwargs)
Pierre-Yves Chibon a324b4
    except Exception:
Pierre-Yves Chibon 9c2953
        _log.exception("Error sending fedmsg")
Pierre-Yves Chibon a79c31
Pierre-Yves Chibon a79c31
Pierre-Yves Chibon e99662
def fedora_messaging_publish(topic, message):  # pragma: no cover
Pierre-Yves Chibon 8b01fe
    """ Try to publish a message on AMQP using fedora-messaging. """
Pierre-Yves Chibon e99662
    if not pagure_config.get("FEDORA_MESSAGING_NOTIFICATIONS", False):
Pierre-Yves Chibon e99662
        return
Pierre-Yves Chibon e99662
Pierre-Yves Chibon e99662
    try:
Pierre-Yves Chibon e99662
        import fedora_messaging.api
Pierre-Yves Chibon e99662
        import fedora_messaging.exceptions
Pierre-Yves Chibon e99662
Pierre-Yves Chibon e99662
        msg = fedora_messaging.api.Message(
Pierre-Yves Chibon 8b01fe
            topic="pagure.{}".format(topic), body=message
Pierre-Yves Chibon e99662
        )
Pierre-Yves Chibon e99662
        fedora_messaging.api.publish(msg)
Pierre-Yves Chibon ff53f2
    except ImportError:
Pierre-Yves Chibon ff53f2
        _log.warning("Fedora messaging does not appear to be available")
Pierre-Yves Chibon 8b01fe
    except fedora_messaging.exceptions.PublishReturned as e:
Pierre-Yves Chibon 807564
        _log.warning(
Pierre-Yves Chibon 8b01fe
            "Fedora Messaging broker rejected message %s: %s", msg.id, e
Pierre-Yves Chibon e99662
        )
Pierre-Yves Chibon e99662
    except fedora_messaging.exceptions.ConnectionException as e:
Pierre-Yves Chibon 807564
        _log.warning("Error sending message %s: %s", msg.id, e)
Pierre-Yves Chibon e99662
    except Exception:
Pierre-Yves Chibon e99662
        _log.exception("Error sending fedora-messaging message")
Pierre-Yves Chibon e99662
Pierre-Yves Chibon e99662
Slavek Kabrda 631df5
stomp_conn = None
Slavek Kabrda 631df5
Slavek Kabrda 631df5
Slavek Kabrda 631df5
def stomp_publish(topic, message):
Pierre-Yves Chibon 9c2953
    """ Try to publish a message on a Stomp-compliant message bus. """
Pierre-Yves Chibon 8b01fe
    if not pagure_config.get("STOMP_NOTIFICATIONS", False):
Slavek Kabrda 631df5
        return
Slavek Kabrda 631df5
    # We catch Exception if we want :-p
Slavek Kabrda 631df5
    # pylint: disable=broad-except
jingjing 0a2162
    # Ignore message about stomp import
Slavek Kabrda 631df5
    # pylint: disable=import-error
Slavek Kabrda 631df5
    try:
Slavek Kabrda 631df5
        import stomp
Pierre-Yves Chibon 9c2953
Slavek Kabrda 631df5
        global stomp_conn
Slavek Kabrda 511cae
        if not stomp_conn or not stomp_conn.is_connected():
Pierre-Yves Chibon 9c2953
            stomp_conn = stomp.Connection12(pagure_config["STOMP_BROKERS"])
Pierre-Yves Chibon 9c2953
            if pagure_config.get("STOMP_SSL"):
Slavek Kabrda 631df5
                stomp_conn.set_ssl(
Pierre-Yves Chibon 9c2953
                    pagure_config["STOMP_BROKERS"],
Pierre-Yves Chibon 9c2953
                    key_file=pagure_config.get("STOMP_KEY_FILE"),
Pierre-Yves Chibon 9c2953
                    cert_file=pagure_config.get("STOMP_CERT_FILE"),
Pierre-Yves Chibon 9c2953
                    password=pagure_config.get("STOMP_CREDS_PASSWORD"),
Slavek Kabrda 631df5
                )
Slavek Kabrda 631df5
            from stomp import PrintingListener
Pierre-Yves Chibon 9c2953
Pierre-Yves Chibon 9c2953
            stomp_conn.set_listener("", PrintingListener())
Slavek Kabrda 631df5
            stomp_conn.start()
Slavek Kabrda 631df5
            stomp_conn.connect(wait=True)
Pierre-Yves Chibon 9c2953
        hierarchy = pagure_config["STOMP_HIERARCHY"]
Slavek Kabrda 631df5
        stomp_conn.send(
Pierre-Yves Chibon 9c2953
            destination=hierarchy + topic, body=json.dumps(message)
Slavek Kabrda 631df5
        )
Slavek Kabrda 631df5
    except Exception:
Pierre-Yves Chibon 9c2953
        _log.exception("Error sending stomp message")
Slavek Kabrda 631df5
Pierre-Yves Chibon 4eda2c
Pierre-Yves Chibon 4517cd
def blinker_publish(topic, message):
Pierre-Yves Chibon 924605
    _log.info("Sending blinker signal to: pagure - topic: %s", topic)
Pierre-Yves Chibon 4517cd
    ready = blinker.signal("pagure")
Pierre-Yves Chibon 4517cd
    ready.send("pagure", topic=topic, message=message)
Pierre-Yves Chibon 4517cd
Pierre-Yves Chibon 4eda2c
jingjing a949ff
def mqtt_publish(topic, message):
jingjing a949ff
    """ Try to publish a message on a MQTT message bus. """
Pierre-Yves Chibon 6cd3e3
    if not pagure_config.get("MQTT_NOTIFICATIONS", False):
jingjing a949ff
        return
Pierre-Yves Chibon 4eda2c
Pierre-Yves Chibon 4eda2c
    mqtt_host = pagure_config.get("MQTT_HOST")
Pierre-Yves Chibon 4eda2c
    mqtt_port = pagure_config.get("MQTT_PORT")
Pierre-Yves Chibon 4eda2c
Pierre-Yves Chibon 4eda2c
    mqtt_username = pagure_config.get("MQTT_USERNAME")
Pierre-Yves Chibon 4eda2c
    mqtt_pass = pagure_config.get("MQTT_PASSWORD")
Pierre-Yves Chibon 4eda2c
Pierre-Yves Chibon 4eda2c
    mqtt_ca_certs = pagure_config.get("MQTT_CA_CERTS")
Pierre-Yves Chibon 4eda2c
    mqtt_certfile = pagure_config.get("MQTT_CERTFILE")
Pierre-Yves Chibon 4eda2c
    mqtt_keyfile = pagure_config.get("MQTT_KEYFILE")
Pierre-Yves Chibon 4eda2c
    mqtt_cert_reqs = pagure_config.get("MQTT_CERT_REQS", ssl.CERT_REQUIRED)
Pierre-Yves Chibon 420b95
    mqtt_tls_version = pagure_config.get(
Pierre-Yves Chibon 420b95
        "MQTT_TLS_VERSION", ssl.PROTOCOL_TLSv1_2
Pierre-Yves Chibon 420b95
    )
Pierre-Yves Chibon 4eda2c
    mqtt_ciphers = pagure_config.get("MQTT_CIPHERS")
Pierre-Yves Chibon 4eda2c
Pierre-Yves Chibon 2a914b
    mqtt_topic_prefix = pagure_config.get("MQTT_TOPIC_PREFIX") or None
Pierre-Yves Chibon 2a914b
    if mqtt_topic_prefix:
Pierre-Yves Chibon 2a914b
        topic = "/".join([mqtt_topic_prefix.rstrip("/"), topic])
Pierre-Yves Chibon 2a914b
jingjing a949ff
    # We catch Exception if we want :-p
jingjing a949ff
    # pylint: disable=broad-except
jingjing a949ff
    # Ignore message about mqtt import
jingjing a949ff
    # pylint: disable=import-error
jingjing a949ff
    try:
jingjing a949ff
        import paho.mqtt.client as mqtt
jingjing a949ff
jingjing a949ff
        client = mqtt.Client(os.uname()[1])
Pierre-Yves Chibon 4eda2c
        client.tls_set(
Pierre-Yves Chibon 4eda2c
            ca_certs=mqtt_ca_certs,
Pierre-Yves Chibon 4eda2c
            certfile=mqtt_certfile,
Pierre-Yves Chibon 4eda2c
            keyfile=mqtt_keyfile,
Pierre-Yves Chibon 4eda2c
            cert_reqs=mqtt_cert_reqs,
Pierre-Yves Chibon 4eda2c
            tls_version=mqtt_tls_version,
Pierre-Yves Chibon 4eda2c
            ciphers=mqtt_ciphers,
Pierre-Yves Chibon 4eda2c
        )
Pierre-Yves Chibon 4eda2c
        if mqtt_username and mqtt_pass:
Pierre-Yves Chibon 4eda2c
            client.username_pw_set(mqtt_username, mqtt_pass)
Pierre-Yves Chibon 4eda2c
jingjing a949ff
        client.connect(mqtt_host, mqtt_port)
jingjing a949ff
        client.publish(topic, json.dumps(message))
jingjing a949ff
        client.disconnect()
jingjing a949ff
jingjing a949ff
    except Exception:
jingjing a949ff
        _log.exception("Error sending mqtt message")
jingjing a949ff
Pierre-Yves Chibon 4517cd
Pierre-Yves Chibon c811a2
def log(project, topic, msg, webhook=True):
Pierre-Yves Chibon 9c2953
    """ This is the place where we send notifications to user about actions
Pierre-Yves Chibon c898e5
    occuring in pagure.
Pierre-Yves Chibon 9c2953
    """
Farhaan Bukhsh 94c9f0
Farhaan Bukhsh 94c9f0
    # Send fedmsg notification (if fedmsg is there and set-up)
Pierre-Yves Chibon 9c2953
    if not project or (
Pierre-Yves Chibon 9c2953
        project.settings.get("fedmsg_notifications", True)
Pierre-Yves Chibon 9c2953
        and not project.private
Pierre-Yves Chibon 9c2953
    ):
Farhaan Bukhsh 94c9f0
        fedmsg_publish(topic, msg)
Pierre-Yves Chibon e99662
        fedora_messaging_publish(topic, msg)
Farhaan Bukhsh 94c9f0
Slavek Kabrda 631df5
    # Send stomp notification (if stomp is there and set-up)
Pierre-Yves Chibon 9c2953
    if not project or (
Pierre-Yves Chibon 9c2953
        project.settings.get("stomp_notifications", True)
Pierre-Yves Chibon 9c2953
        and not project.private
Pierre-Yves Chibon 9c2953
    ):
Slavek Kabrda 631df5
        stomp_publish(topic, msg)
Slavek Kabrda 631df5
Pierre-Yves Chibon 4eda2c
    # Send mqtt notification (if mqtt is there and set-up)
Pierre-Yves Chibon 4eda2c
    if not project or (
Pierre-Yves Chibon 4eda2c
        project.settings.get("mqtt_notifications", True)
Pierre-Yves Chibon 4eda2c
        and not project.private
Pierre-Yves Chibon 4eda2c
    ):
Pierre-Yves Chibon 4eda2c
        mqtt_publish(topic, msg)
Pierre-Yves Chibon 4eda2c
Pierre-Yves Chibon 4517cd
    # Send blink notification to any 3rd party plugins, if there are any
Pierre-Yves Chibon 4517cd
    blinker_publish(topic, msg)
Pierre-Yves Chibon 4517cd
Pierre-Yves Chibon c811a2
    if webhook and project and not project.private:
Pierre-Yves Chibon 7937d2
        pagure.lib.tasks_services.webhook_notification.delay(
Pierre-Yves Chibon 7937d2
            topic=topic,
Pierre-Yves Chibon 7937d2
            msg=msg,
Pierre-Yves Chibon 7937d2
            namespace=project.namespace,
Pierre-Yves Chibon 7937d2
            name=project.name,
Pierre-Yves Chibon 7937d2
            user=project.user.username if project.is_fork else None,
Pierre-Yves Chibon 7937d2
        )
Pierre-Yves Chibon 06af7f
Pierre-Yves Chibon c898e5
Pierre-Yves Chibon 51c6d4
def _add_mentioned_users(emails, comment):
Pierre-Yves Chibon 9c2953
    """ Check the comment to see if an user is mentioned in it and if
Pierre-Yves Chibon 51c6d4
    so add this user to the list of people to notify.
Pierre-Yves Chibon 9c2953
    """
Pierre-Yves Chibon 3ff584
    for username in re.findall(MENTION_RE, comment):
Pierre-Yves Chibon 930073
        user = pagure.lib.query.search_user(flask.g.session, username=username)
Pierre-Yves Chibon 51c6d4
        if user:
Pierre-Yves Chibon 51c6d4
            emails.add(user.default_email)
Pierre-Yves Chibon 51c6d4
    return emails
Pierre-Yves Chibon 51c6d4
Pierre-Yves Chibon 51c6d4
Pierre-Yves Chibon 433392
def _clean_emails(emails, user):
Pierre-Yves Chibon 9c2953
    """ Remove the email of the user doing the action if it is in the list.
Pierre-Yves Chibon 433392
Pierre-Yves Chibon 433392
    This avoids receiving emails about action you do.
Pierre-Yves Chibon 9c2953
    """
Pierre-Yves Chibon 433392
    # Remove the user doing the action from the list of person to email
Pierre-Yves Chibon 08cf01
    # unless they actively asked for it
Pierre-Yves Chibon 9c2953
    if (
Pierre-Yves Chibon 9c2953
        user
Pierre-Yves Chibon 9c2953
        and user.emails
Pierre-Yves Chibon 9c2953
        and not user.settings.get("cc_me_to_my_actions", False)
Pierre-Yves Chibon 9c2953
    ):
Pierre-Yves Chibon 433392
        for email in user.emails:
Pierre-Yves Chibon d5d345
            if email.email in emails:
Pierre-Yves Chibon 433392
                emails.remove(email.email)
Pierre-Yves Chibon 433392
    return emails
Pierre-Yves Chibon 433392
Pierre-Yves Chibon 433392
Pierre-Yves Chibon 4bd1cb
def _get_emails_for_obj(obj):
Pierre-Yves Chibon 9c2953
    """ Return the list of emails to send notification to when notifying
Pierre-Yves Chibon 4bd1cb
    about the specified issue or pull-request.
Pierre-Yves Chibon 9c2953
    """
Pierre-Yves Chibon 97aef1
    emails = set()
Pierre-Yves Chibon 97aef1
    # Add project creator/owner
Pierre-Yves Chibon 4bd1cb
    if obj.project.user.default_email:
Pierre-Yves Chibon 4bd1cb
        emails.add(obj.project.user.default_email)
Pierre-Yves Chibon 97aef1
Pierre-Yves Chibon b124e7
    # Add committers is object is private, otherwise all contributors
Pierre-Yves Chibon 9c2953
    if obj.isa in ["issue", "pull-request"] and obj.private:
Pierre-Yves Chibon b124e7
        for user in obj.project.committers:
Pierre-Yves Chibon b124e7
            if user.default_email:
Pierre-Yves Chibon b124e7
                emails.add(user.default_email)
Pierre-Yves Chibon b124e7
    else:
Pierre-Yves Chibon b124e7
        for user in obj.project.users:
Pierre-Yves Chibon b124e7
            if user.default_email:
Pierre-Yves Chibon b124e7
                emails.add(user.default_email)
Pierre-Yves Chibon 97aef1
Vivek Anand 967335
    # Add people in groups with any access to the project:
Pierre-Yves Chibon 4bd1cb
    for group in obj.project.groups:
Pierre-Yves Chibon 13d09c
        if group.creator.default_email:
Pierre-Yves Chibon 13d09c
            emails.add(group.creator.default_email)
Pierre-Yves Chibon 13d09c
        for user in group.users:
Pierre-Yves Chibon 13d09c
            if user.default_email:
Pierre-Yves Chibon 13d09c
                emails.add(user.default_email)
Pierre-Yves Chibon 13d09c
Pierre-Yves Chibon 4bd1cb
    # Add people that commented on the issue/PR
Pierre-Yves Chibon 9c2953
    if obj.isa in ["issue", "pull-request"]:
Pierre-Yves Chibon 327b88
        for comment in obj.comments:
Pierre-Yves Chibon 327b88
            if comment.user.default_email:
Pierre-Yves Chibon 327b88
                emails.add(comment.user.default_email)
Pierre-Yves Chibon 97aef1
Pierre-Yves Chibon 080c15
    # Add public notifications to lists/users set project-wide
Pierre-Yves Chibon 9c2953
    if obj.isa == "issue" and not obj.private:
Pierre-Yves Chibon 9c2953
        for notifs in obj.project.notifications.get("issues", []):
Pierre-Yves Chibon 080c15
            emails.add(notifs)
Pierre-Yves Chibon 9c2953
    elif obj.isa == "pull-request":
Pierre-Yves Chibon 9c2953
        for notifs in obj.project.notifications.get("requests", []):
Pierre-Yves Chibon 080c15
            emails.add(notifs)
Pierre-Yves Chibon 080c15
Matt Prahl b49f93
    # Add the person watching this project, if it's a public issue or a
Matt Prahl b49f93
    # pull-request
Pierre-Yves Chibon 9c2953
    if (obj.isa == "issue" and not obj.private) or obj.isa == "pull-request":
Matt Prahl b49f93
        for watcher in obj.project.watchers:
Matt Prahl b49f93
            if watcher.watch_issues:
Matt Prahl b49f93
                emails.add(watcher.user.default_email)
Matt Prahl b49f93
            else:
Matt Prahl b49f93
                # If there is a watch entry and it is false, it means the user
Matt Prahl b49f93
                # explicitly requested to not watch the issue
Matt Prahl b49f93
                if watcher.user.default_email in emails:
Matt Prahl b49f93
                    emails.remove(watcher.user.default_email)
Gaurav Kumar 00f2c8
Pierre-Yves Chibon 7e3cd2
    # Add/Remove people who explicitly asked to be added/removed
Pierre-Yves Chibon 9c2953
    if obj.isa in ["issue", "pull-request"]:
Pierre-Yves Chibon 327b88
        for watcher in obj.watchers:
Pierre-Yves Chibon 327b88
            if not watcher.watch and watcher.user.default_email in emails:
Pierre-Yves Chibon 327b88
                emails.remove(watcher.user.default_email)
Pierre-Yves Chibon 327b88
            elif watcher.watch:
Pierre-Yves Chibon 327b88
                emails.add(watcher.user.default_email)
Pierre-Yves Chibon 7e3cd2
Pierre-Yves Chibon fc71b5
    # Drop the email used by pagure when sending
Pierre-Yves Chibon fc71b5
    emails = _clean_emails(
Pierre-Yves Chibon 9c2953
        emails,
Pierre-Yves Chibon 9c2953
        pagure_config.get(
Pierre-Yves Chibon 9c2953
            pagure_config.get("FROM_EMAIL", "pagure@fedoraproject.org")
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon fc71b5
    )
Pierre-Yves Chibon fc71b5
Pierre-Yves Chibon 47a531
    # Add the person that opened the issue/PR
Pierre-Yves Chibon 47a531
    if obj.user.default_email:
Pierre-Yves Chibon 47a531
        emails.add(obj.user.default_email)
Pierre-Yves Chibon 47a531
Pierre-Yves Chibon 47a531
    # Add the person assigned to the issue/PR
Pierre-Yves Chibon 47a531
    if obj.isa in ["issue", "pull-request"]:
Pierre-Yves Chibon 47a531
        if obj.assignee and obj.assignee.default_email:
Pierre-Yves Chibon 47a531
            emails.add(obj.assignee.default_email)
Pierre-Yves Chibon 47a531
Pierre-Yves Chibon 97aef1
    return emails
Pierre-Yves Chibon 97aef1
Pierre-Yves Chibon d8781e
Matt Prahl b49f93
def _get_emails_for_commit_notification(project):
Matt Prahl b49f93
    emails = set()
Matt Prahl b49f93
    for watcher in project.watchers:
Matt Prahl b49f93
        if watcher.watch_commits:
Matt Prahl b49f93
            emails.add(watcher.user.default_email)
Matt Prahl b49f93
Matt Prahl b49f93
    # Drop the email used by pagure when sending
Matt Prahl b49f93
    emails = _clean_emails(
Pierre-Yves Chibon 9c2953
        emails,
Pierre-Yves Chibon 9c2953
        pagure_config.get(
Pierre-Yves Chibon 9c2953
            pagure_config.get("FROM_EMAIL", "pagure@fedoraproject.org")
Pierre-Yves Chibon 9c2953
        ),
Matt Prahl b49f93
    )
Matt Prahl b49f93
Matt Prahl b49f93
    return emails
Matt Prahl b49f93
Matt Prahl b49f93
Pierre-Yves Chibon 6ee231
def _build_url(*args):
Pierre-Yves Chibon 9c2953
    """ Build a URL from a given list of arguments. """
Pierre-Yves Chibon 6ee231
    items = []
Pierre-Yves Chibon 6ee231
    for idx, arg in enumerate(args):
Aurélien Bompard 619e2a
        arg = "%s" % arg
Pierre-Yves Chibon 9c2953
        if arg.startswith("/"):
Pierre-Yves Chibon 6ee231
            arg = arg[1:]
Pierre-Yves Chibon 9c2953
        if arg.endswith("/") and not idx + 1 == len(args):
Pierre-Yves Chibon 6ee231
            arg = arg[:-1]
Pierre-Yves Chibon 6ee231
        items.append(arg)
Pierre-Yves Chibon 6ee231
Pierre-Yves Chibon 9c2953
    return "/".join(items)
Pierre-Yves Chibon 6ee231
Pierre-Yves Chibon 6ee231
Adam Williamson a15f45
def _fullname_to_url(fullname):
Pierre-Yves Chibon 9c2953
    """ For forked projects, fullname is 'forks/user/...' but URL is
Adam Williamson a15f45
    'fork/user/...'. This is why we can't have nice things.
Pierre-Yves Chibon 9c2953
    """
Pierre-Yves Chibon 9c2953
    if fullname.startswith("forks/"):
Pierre-Yves Chibon 9c2953
        fullname = fullname.replace("forks", "fork", 1)
Adam Williamson a15f45
    return fullname
Adam Williamson a15f45
Adam Williamson a15f45
Pierre-Yves Chibon 9c2953
def send_email(
Pierre-Yves Chibon 9c2953
    text,
Pierre-Yves Chibon 9c2953
    subject,
Pierre-Yves Chibon 9c2953
    to_mail,
Pierre-Yves Chibon 9c2953
    mail_id=None,
Pierre-Yves Chibon 9c2953
    in_reply_to=None,
Pierre-Yves Chibon 9c2953
    project_name=None,
Pierre-Yves Chibon 9c2953
    user_from=None,
Lenka Segura 9cb3f3
    reporter=None,
Pierre-Yves Chibon 9ef9df
    assignee=None,
Pierre-Yves Chibon 9c2953
):  # pragma: no cover
Pierre-Yves Chibon 9c2953
    """ Send an email with the specified information.
Pierre-Yves Chibon d8781e
Pierre-Yves Chibon d8781e
    :arg text: the content of the email to send
Adam Williamson a8fef8
    :type text: unicode
Pierre-Yves Chibon d8781e
    :arg subject: the subject of the email
Pierre-Yves Chibon d8781e
    :arg to_mail: a string representing a list of recipient separated by a
René Genz dadd94
        comma
Pierre-Yves Chibon 67cc89
    :kwarg mail_id: if defined, the header `mail-id` is set with this value
Pierre-Yves Chibon 67cc89
    :kwarg in_reply_to: if defined, the header `In-Reply-To` is set with
Pierre-Yves Chibon 67cc89
        this value
Simo Sorce 516e01
    :kwarg project_name: if defined, the name of the project
Pierre-Yves Chibon d8781e
Pierre-Yves Chibon 9c2953
    """
Pierre-Yves Chibon ac631e
    if not to_mail:
Pierre-Yves Chibon ac631e
        return
Pierre-Yves Chibon ac631e
Pierre-Yves Chibon 9c2953
    from_email = pagure_config.get("FROM_EMAIL", "pagure@fedoraproject.org")
Aurélien Bompard 831553
    if isinstance(from_email, bytes):
Pierre-Yves Chibon 9c2953
        from_email = from_email.decode("utf-8")
Pierre-Yves Chibon 9a69ae
    if user_from:
Pierre-Yves Chibon 9c2953
        header = Header(user_from, "utf-8")
Pierre-Yves Chibon 02f40e
        from_email = "%s <%s>" % (header.encode(), from_email)
Pierre-Yves Chibon 9a69ae
Simo Sorce 516e01
    if project_name is not None:
Simo Sorce 516e01
        subject_tag = project_name
Simo Sorce 516e01
    else:
Pierre-Yves Chibon 9c2953
        subject_tag = "Pagure"
Sachin Kamath f01117
    if mail_id:
Pierre-Yves Chibon 9c2953
        mail_id = mail_id + "@%s" % pagure_config["DOMAIN_EMAIL_NOTIFICATIONS"]
Pierre-Yves Chibon 4fb4b5
    if in_reply_to:
Pierre-Yves Chibon 9c2953
        in_reply_to = (
Pierre-Yves Chibon 9c2953
            in_reply_to + "@%s" % pagure_config["DOMAIN_EMAIL_NOTIFICATIONS"]
Pierre-Yves Chibon 9c2953
        )
Simo Sorce 516e01
Pierre-Yves Chibon 62e142
    smtp = None
Pierre-Yves Chibon 9c2953
    for mailto in to_mail.split(","):
Karsten Hopp 5c0db6
        try:
Pierre-Yves Chibon 930073
            pagure.lib.query.allowed_emailaddress(mailto)
Karsten Hopp 5c0db6
        except pagure.exceptions.PagureException:
Karsten Hopp 5c0db6
            continue
Pierre-Yves Chibon 9c2953
        msg = MIMEText(text.encode("utf-8"), "plain", "utf-8")
Pierre-Yves Chibon 9c2953
        msg["Subject"] = Header("[%s] %s" % (subject_tag, subject), "utf-8")
Pierre-Yves Chibon 9c2953
        msg["From"] = from_email
Pierre-Yves Chibon f766cb
Pierre-Yves Chibon f766cb
        if mail_id:
Pierre-Yves Chibon 9c2953
            msg["mail-id"] = mail_id
Pierre-Yves Chibon 9c2953
            msg["Message-Id"] = "<%s>" % mail_id
Pierre-Yves Chibon f766cb
Pierre-Yves Chibon f766cb
        if in_reply_to:
Pierre-Yves Chibon 9c2953
            msg["In-Reply-To"] = "<%s>" % in_reply_to
Pierre-Yves Chibon f766cb
Pierre-Yves Chibon 9c2953
        msg["X-Auto-Response-Suppress"] = "All"
Pierre-Yves Chibon 9c2953
        msg["X-pagure"] = pagure_config["APP_URL"]
Pierre-Yves Chibon b20a30
        if project_name is not None:
Pierre-Yves Chibon 9c2953
            msg["X-pagure-project"] = project_name
Pierre-Yves Chibon 9c2953
            msg["List-ID"] = project_name
Pierre-Yves Chibon 9c2953
            msg["List-Archive"] = _build_url(
Pierre-Yves Chibon 9c2953
                pagure_config["APP_URL"], _fullname_to_url(project_name)
Pierre-Yves Chibon 9c2953
            )
Lenka Segura 9cb3f3
        if reporter is not None:
Lenka Segura 9cb3f3
            msg["X-pagure-reporter"] = reporter
Lenka Segura 9cb3f3
        if assignee is not None:
Lenka Segura 9cb3f3
            msg["X-pagure-assignee"] = assignee
Simo Sorce 516e01
Pierre-Yves Chibon f766cb
        # Send the message via our own SMTP server, but don't include the
Pierre-Yves Chibon f766cb
        # envelope header.
Pierre-Yves Chibon 9c2953
        msg["To"] = mailto
Pierre-Yves Chibon 9c2953
        salt = pagure_config.get("SALT_EMAIL")
Aurélien Bompard 831553
        if salt and not isinstance(salt, bytes):
Pierre-Yves Chibon 9c2953
            salt = salt.encode("utf-8")
Aurélien Bompard 831553
Pierre-Yves Chibon 9c2953
        if mail_id and pagure_config["EVENTSOURCE_SOURCE"]:
Pierre-Yves Chibon ec3e61
Pierre-Yves Chibon 9c2953
            key = (
Pierre-Yves Chibon 9c2953
                b"<"
Pierre-Yves Chibon 9c2953
                + mail_id.encode("utf-8")
Pierre-Yves Chibon 9c2953
                + b">"
Pierre-Yves Chibon 9c2953
                + salt
Pierre-Yves Chibon 9c2953
                + mailto.encode("utf-8")
Pierre-Yves Chibon 9c2953
            )
Karsten Hopp e055c2
            if isinstance(key, six.text_type):
Pierre-Yves Chibon 9c2953
                key = key.encode("utf-8")
Karsten Hopp e055c2
            mhash = hashlib.sha512(key)
Karsten Hopp e055c2
Pierre-Yves Chibon 9c2953
            msg["Reply-To"] = "reply+%s@%s" % (
Karsten Hopp e055c2
                mhash.hexdigest(),
Pierre-Yves Chibon 9c2953
                pagure_config["DOMAIN_EMAIL_NOTIFICATIONS"],
Pierre-Yves Chibon 9c2953
            )
Pierre-Yves Chibon 9c2953
            msg["Mail-Followup-To"] = msg["Reply-To"]
Pierre-Yves Chibon 9c2953
        if not pagure_config.get("EMAIL_SEND", True):
Pierre-Yves Chibon 9c2953
            _log.debug("******EMAIL******")
Pierre-Yves Chibon 9c2953
            _log.debug("From: %s", from_email)
Pierre-Yves Chibon 9c2953
            _log.debug("To: %s", to_mail)
Pierre-Yves Chibon 9c2953
            _log.debug("Subject: %s", subject)
Pierre-Yves Chibon 9c2953
            _log.debug("in_reply_to: %s", in_reply_to)
Pierre-Yves Chibon 9c2953
            _log.debug("mail_id: %s", mail_id)
Pierre-Yves Chibon 9c2953
            _log.debug("Contents:")
Pierre-Yves Chibon 9c2953
            _log.debug("%s" % text)
Pierre-Yves Chibon 9c2953
            _log.debug("*****************")
Farhaan Bukhsh 54719f
            _log.debug(msg.as_string())
Pierre-Yves Chibon 9c2953
            _log.debug("*****/EMAIL******")
Pierre-Yves Chibon d07721
            continue
Pierre-Yves Chibon 3bcdaf
        try:
Pierre-Yves Chibon 859e4c
            if smtp is None:
Pierre-Yves Chibon 9c2953
                if pagure_config["SMTP_SSL"]:
Pierre-Yves Chibon 859e4c
                    smtp = smtplib.SMTP_SSL(
Pierre-Yves Chibon 9c2953
                        pagure_config["SMTP_SERVER"],
Pierre-Yves Chibon 9c2953
                        pagure_config["SMTP_PORT"],
Pierre-Yves Chibon 9c2953
                    )
Pierre-Yves Chibon 859e4c
                else:
Pierre-Yves Chibon 859e4c
                    smtp = smtplib.SMTP(
Pierre-Yves Chibon 9c2953
                        pagure_config["SMTP_SERVER"],
Pierre-Yves Chibon 9c2953
                        pagure_config["SMTP_PORT"],
Pierre-Yves Chibon 9c2953
                    )
Pierre-Yves Chibon 9c2953
            if (
Pierre-Yves Chibon 9c2953
                pagure_config["SMTP_USERNAME"]
Pierre-Yves Chibon 9c2953
                and pagure_config["SMTP_PASSWORD"]
Pierre-Yves Chibon 9c2953
            ):
Pierre-Yves Chibon f610bf
                smtp.login(
Pierre-Yves Chibon 9c2953
                    pagure_config["SMTP_USERNAME"],
Pierre-Yves Chibon 9c2953
                    pagure_config["SMTP_PASSWORD"],
Pierre-Yves Chibon f610bf
                )
vanzhiganov 8c310f
Pierre-Yves Chibon 9c2953
            smtp.sendmail(from_email, [mailto], msg.as_string())
Pierre-Yves Chibon 3bcdaf
        except smtplib.SMTPException as err:
Pierre-Yves Chibon 4635b5
            _log.exception(err)
Pierre-Yves Chibon 859e4c
    if smtp:
Pierre-Yves Chibon 859e4c
        smtp.quit()
Pierre-Yves Chibon d8781e
    return msg
Pierre-Yves Chibon d8781e
Pierre-Yves Chibon d8781e
Pierre-Yves Chibon 433392
def notify_new_comment(comment, user=None):
Pierre-Yves Chibon 9c2953
    """ Notify the people following an issue that a new comment was added
Pierre-Yves Chibon d8781e
    to the issue.
Pierre-Yves Chibon 9c2953
    """
Pierre-Yves Chibon dcc4a5
Aurélien Bompard 831553
    text = """
Pierre-Yves Chibon 728bce
%s added a new comment to an issue you are following:
Pierre-Yves Chibon d8781e
``
Pierre-Yves Chibon d8781e
%s
Pierre-Yves Chibon d8781e
``
Pierre-Yves Chibon d8781e
Pierre-Yves Chibon a2efa3
%s
Pierre-Yves Chibon d8781e
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        comment.user.user,
Pierre-Yves Chibon 9c2953
        comment.comment,
Pierre-Yves Chibon 9c2953
        REPLY_MSG,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(comment.issue.project.fullname),
Pierre-Yves Chibon 9c2953
            "issue",
Pierre-Yves Chibon 9c2953
            comment.issue.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 4bd1cb
    mail_to = _get_emails_for_obj(comment.issue)
Pierre-Yves Chibon c7e252
    if comment.user and comment.user.default_email:
Pierre-Yves Chibon c7e252
        mail_to.add(comment.user.default_email)
Pierre-Yves Chibon 97aef1
Pierre-Yves Chibon 51c6d4
    mail_to = _add_mentioned_users(mail_to, comment.comment)
Pierre-Yves Chibon 433392
    mail_to = _clean_emails(mail_to, user)
Pierre-Yves Chibon 433392
Lenka Segura 9cb3f3
    assignee = comment.issue.assignee.user if comment.issue.assignee else None
Lenka Segura 9cb3f3
Pierre-Yves Chibon d8781e
    send_email(
Pierre-Yves Chibon d8781e
        text,
Pierre-Yves Chibon 9c2953
        "Issue #%s: %s" % (comment.issue.id, comment.issue.title),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 96dfd7
        mail_id=comment.mail_id,
Pierre-Yves Chibon 5d4b74
        in_reply_to=comment.issue.mail_id,
Adam Williamson 05b3f5
        project_name=comment.issue.project.fullname,
Pierre-Yves Chibon 9a69ae
        user_from=comment.user.fullname or comment.user.user,
Lenka Segura 9cb3f3
        reporter=comment.issue.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Pierre-Yves Chibon d8781e
    )
Pierre-Yves Chibon cf312a
Pierre-Yves Chibon cf312a
Pierre-Yves Chibon 433392
def notify_new_issue(issue, user=None):
Pierre-Yves Chibon 9c2953
    """ Notify the people following a project that a new issue was added
Pierre-Yves Chibon cf312a
    to it.
Pierre-Yves Chibon 9c2953
    """
Aurélien Bompard 831553
    text = """
Pierre-Yves Chibon 728bce
%s reported a new issue against the project: `%s` that you are following:
Pierre-Yves Chibon cf312a
``
Pierre-Yves Chibon cf312a
%s
Pierre-Yves Chibon cf312a
``
Pierre-Yves Chibon cf312a
Pierre-Yves Chibon a2efa3
%s
Pierre-Yves Chibon cf312a
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        issue.user.user,
Pierre-Yves Chibon 9c2953
        issue.project.name,
Pierre-Yves Chibon 9c2953
        issue.content,
Pierre-Yves Chibon 9c2953
        REPLY_MSG,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(issue.project.fullname),
Pierre-Yves Chibon 9c2953
            "issue",
Pierre-Yves Chibon 9c2953
            issue.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 4bd1cb
    mail_to = _get_emails_for_obj(issue)
Pierre-Yves Chibon 51c6d4
    mail_to = _add_mentioned_users(mail_to, issue.content)
Pierre-Yves Chibon 433392
    mail_to = _clean_emails(mail_to, user)
Pierre-Yves Chibon a1c51a
Lenka Segura 9cb3f3
    assignee = issue.assignee.user if issue.assignee else None
Lenka Segura 9cb3f3
Pierre-Yves Chibon cf312a
    send_email(
Pierre-Yves Chibon cf312a
        text,
Pierre-Yves Chibon 9c2953
        "Issue #%s: %s" % (issue.id, issue.title),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 6fb585
        mail_id=issue.mail_id,
Adam Williamson 05b3f5
        project_name=issue.project.fullname,
Pierre-Yves Chibon 9a69ae
        user_from=issue.user.fullname or issue.user.user,
Lenka Segura 9cb3f3
        reporter=issue.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Pierre-Yves Chibon cf312a
    )
Pierre-Yves Chibon 4cfb2a
Pierre-Yves Chibon 4cfb2a
Pierre-Yves Chibon 153903
def notify_assigned_issue(issue, new_assignee, user):
Pierre-Yves Chibon 9c2953
    """ Notify the people following an issue that the assignee changed.
Pierre-Yves Chibon 9c2953
    """
Pierre-Yves Chibon 9c2953
    action = "reset"
Pierre-Yves Chibon 186206
    if new_assignee:
Pierre-Yves Chibon 9c2953
        action = "assigned to `%s`" % new_assignee.user
Aurélien Bompard 831553
    text = """
Pierre-Yves Chibon 186206
The issue: `%s` of project: `%s` has been %s by %s.
Pierre-Yves Chibon ff30f1
Pierre-Yves Chibon ff30f1
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        issue.title,
Pierre-Yves Chibon 9c2953
        issue.project.name,
Pierre-Yves Chibon 9c2953
        action,
Pierre-Yves Chibon 9c2953
        user.username,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(issue.project.fullname),
Pierre-Yves Chibon 9c2953
            "issue",
Pierre-Yves Chibon 9c2953
            issue.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 4bd1cb
    mail_to = _get_emails_for_obj(issue)
Pierre-Yves Chibon c7e252
    if new_assignee and new_assignee.default_email:
Pierre-Yves Chibon c7e252
        mail_to.add(new_assignee.default_email)
Pierre-Yves Chibon ff30f1
Pierre-Yves Chibon 433392
    mail_to = _clean_emails(mail_to, user)
Pierre-Yves Chibon 433392
Pierre-Yves Chibon 3aeebc
    uid = time.mktime(datetime.datetime.now().timetuple())
Lenka Segura 9cb3f3
Lenka Segura 9cb3f3
    assignee = issue.assignee.user if issue.assignee else None
Lenka Segura 9cb3f3
Pierre-Yves Chibon ff30f1
    send_email(
Pierre-Yves Chibon ff30f1
        text,
Pierre-Yves Chibon 9c2953
        "Issue #%s: %s" % (issue.id, issue.title),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 9c2953
        mail_id="%s/assigned/%s" % (issue.mail_id, uid),
Pierre-Yves Chibon 3aeebc
        in_reply_to=issue.mail_id,
Adam Williamson 05b3f5
        project_name=issue.project.fullname,
Pierre-Yves Chibon 9a69ae
        user_from=user.fullname or user.user,
Lenka Segura 9cb3f3
        reporter=issue.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Pierre-Yves Chibon ff30f1
    )
Pierre-Yves Chibon ff30f1
Pierre-Yves Chibon ff30f1
Pierre-Yves Chibon e5f996
def notify_status_change_issue(issue, user):
Pierre-Yves Chibon 9c2953
    """ Notify the people following a project that an issue changed status.
Pierre-Yves Chibon 9c2953
    """
Pierre-Yves Chibon e5f996
    status = issue.status
Pierre-Yves Chibon 9c2953
    if status.lower() != "open" and issue.close_status:
Pierre-Yves Chibon 9c2953
        status = "%s as %s" % (status, issue.close_status)
Aurélien Bompard 831553
    text = """
Pierre-Yves Chibon e5f996
The status of the issue: `%s` of project: `%s` has been updated to: %s by %s.
Pierre-Yves Chibon e5f996
Pierre-Yves Chibon e5f996
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        issue.title,
Pierre-Yves Chibon 9c2953
        issue.project.fullname,
Pierre-Yves Chibon 9c2953
        status,
Pierre-Yves Chibon 9c2953
        user.username,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(issue.project.fullname),
Pierre-Yves Chibon 9c2953
            "issue",
Pierre-Yves Chibon 9c2953
            issue.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon e5f996
    mail_to = _get_emails_for_obj(issue)
Pierre-Yves Chibon e5f996
Pierre-Yves Chibon e5f996
    uid = time.mktime(datetime.datetime.now().timetuple())
Lenka Segura 9cb3f3
Lenka Segura 9cb3f3
    assignee = issue.assignee.user if issue.assignee else None
Lenka Segura 9cb3f3
Pierre-Yves Chibon e5f996
    send_email(
Pierre-Yves Chibon e5f996
        text,
Pierre-Yves Chibon 9c2953
        "Issue #%s: %s" % (issue.id, issue.title),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 9c2953
        mail_id="%s/close/%s" % (issue.mail_id, uid),
Pierre-Yves Chibon e5f996
        in_reply_to=issue.mail_id,
Pierre-Yves Chibon e5f996
        project_name=issue.project.fullname,
Pierre-Yves Chibon e5f996
        user_from=user.fullname or user.user,
Lenka Segura 9cb3f3
        reporter=issue.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Pierre-Yves Chibon e5f996
    )
Pierre-Yves Chibon e5f996
Pierre-Yves Chibon e5f996
Mark Reynolds a8f1ac
def notify_meta_change_issue(issue, user, msg):
Pierre-Yves Chibon 9c2953
    """ Notify that a custom field changed
Pierre-Yves Chibon 9c2953
    """
Aurélien Bompard 831553
    text = """
Mark Reynolds a8f1ac
`%s` updated issue.
Mark Reynolds a8f1ac
Mark Reynolds a8f1ac
%s
Mark Reynolds a8f1ac
Mark Reynolds a8f1ac
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        user.username,
Pierre-Yves Chibon 9c2953
        msg,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(issue.project.fullname),
Pierre-Yves Chibon 9c2953
            "issue",
Pierre-Yves Chibon 9c2953
            issue.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Mark Reynolds a8f1ac
    mail_to = _get_emails_for_obj(issue)
Mark Reynolds a8f1ac
    uid = time.mktime(datetime.datetime.now().timetuple())
Lenka Segura 9cb3f3
Lenka Segura 9cb3f3
    assignee = issue.assignee.user if issue.assignee else None
Lenka Segura 9cb3f3
Mark Reynolds a8f1ac
    send_email(
Mark Reynolds a8f1ac
        text,
Pierre-Yves Chibon 9c2953
        "Issue #%s: %s" % (issue.id, issue.title),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 9c2953
        mail_id="%s/close/%s" % (issue.mail_id, uid),
Mark Reynolds a8f1ac
        in_reply_to=issue.mail_id,
Mark Reynolds a8f1ac
        project_name=issue.project.fullname,
Mark Reynolds a8f1ac
        user_from=user.fullname or user.user,
Lenka Segura 9cb3f3
        reporter=issue.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Mark Reynolds a8f1ac
    )
Mark Reynolds a8f1ac
Mark Reynolds a8f1ac
Pierre-Yves Chibon 5bc45e
def notify_assigned_request(request, new_assignee, user):
Pierre-Yves Chibon 9c2953
    """ Notify the people following a pull-request that the assignee changed.
Pierre-Yves Chibon 9c2953
    """
Pierre-Yves Chibon 9c2953
    action = "reset"
Pierre-Yves Chibon 5bc45e
    if new_assignee:
Pierre-Yves Chibon 9c2953
        action = "assigned to `%s`" % new_assignee.user
Aurélien Bompard 831553
    text = """
Pierre-Yves Chibon 5bc45e
The pull-request: `%s` of project: `%s` has been %s by %s.
Pierre-Yves Chibon 5bc45e
Pierre-Yves Chibon 5bc45e
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        request.title,
Pierre-Yves Chibon 9c2953
        request.project.name,
Pierre-Yves Chibon 9c2953
        action,
Pierre-Yves Chibon 9c2953
        user.username,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(request.project.fullname),
Pierre-Yves Chibon 9c2953
            "pull-request",
Pierre-Yves Chibon 9c2953
            request.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 4bd1cb
    mail_to = _get_emails_for_obj(request)
Pierre-Yves Chibon 5bc45e
    if new_assignee and new_assignee.default_email:
Pierre-Yves Chibon 5bc45e
        mail_to.add(new_assignee.default_email)
Pierre-Yves Chibon 5bc45e
Pierre-Yves Chibon 5bc45e
    mail_to = _clean_emails(mail_to, user)
Pierre-Yves Chibon 5bc45e
Pierre-Yves Chibon 5bc45e
    uid = time.mktime(datetime.datetime.now().timetuple())
Lenka Segura 9cb3f3
Lenka Segura 9cb3f3
    assignee = request.assignee.user if request.assignee else None
Lenka Segura 9cb3f3
Pierre-Yves Chibon 5bc45e
    send_email(
Pierre-Yves Chibon 5bc45e
        text,
Pierre-Yves Chibon 9c2953
        "PR #%s: %s" % (request.id, request.title),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 9c2953
        mail_id="%s/assigned/%s" % (request.mail_id, uid),
Pierre-Yves Chibon 5bc45e
        in_reply_to=request.mail_id,
Adam Williamson 05b3f5
        project_name=request.project.fullname,
Pierre-Yves Chibon 9a69ae
        user_from=user.fullname or user.user,
Lenka Segura 9cb3f3
        reporter=request.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Pierre-Yves Chibon 5bc45e
    )
Pierre-Yves Chibon 5bc45e
Pierre-Yves Chibon 5bc45e
Pierre-Yves Chibon f0c222
def notify_new_pull_request(request):
Pierre-Yves Chibon 9c2953
    """ Notify the people following a project that a new pull-request was
Pierre-Yves Chibon 4cfb2a
    added to it.
Pierre-Yves Chibon 9c2953
    """
Aurélien Bompard 831553
    text = """
Pierre-Yves Chibon 728bce
%s opened a new pull-request against the project: `%s` that you are following:
Pierre-Yves Chibon 4cfb2a
``
Pierre-Yves Chibon 4cfb2a
%s
Pierre-Yves Chibon 4cfb2a
``
Pierre-Yves Chibon 4cfb2a
Pierre-Yves Chibon a2efa3
%s
Pierre-Yves Chibon 4cfb2a
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        request.user.user,
Pierre-Yves Chibon 9c2953
        request.project.name,
Pierre-Yves Chibon 9c2953
        request.title,
Pierre-Yves Chibon 9c2953
        REPLY_MSG,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(request.project.fullname),
Pierre-Yves Chibon 9c2953
            "pull-request",
Pierre-Yves Chibon 9c2953
            request.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 4bd1cb
    mail_to = _get_emails_for_obj(request)
Pierre-Yves Chibon 4cfb2a
Lenka Segura 9cb3f3
    assignee = request.assignee.user if request.assignee else None
Lenka Segura 9cb3f3
Pierre-Yves Chibon 4cfb2a
    send_email(
Pierre-Yves Chibon 4cfb2a
        text,
Pierre-Yves Chibon 9c2953
        "PR #%s: %s" % (request.id, request.title),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 4cfb2a
        mail_id=request.mail_id,
Adam Williamson 05b3f5
        project_name=request.project.fullname,
Pierre-Yves Chibon 9a69ae
        user_from=request.user.fullname or request.user.user,
Lenka Segura 9cb3f3
        reporter=request.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Pierre-Yves Chibon 4cfb2a
    )
Pierre-Yves Chibon 688943
Pierre-Yves Chibon 688943
Pierre-Yves Chibon f0c222
def notify_merge_pull_request(request, user):
Pierre-Yves Chibon 9c2953
    """ Notify the people following a project that a pull-request was merged
Pierre-Yves Chibon 688943
    in it.
Pierre-Yves Chibon 9c2953
    """
Aurélien Bompard 831553
    text = """
Pierre-Yves Chibon 688943
%s merged a pull-request against the project: `%s` that you are following.
Pierre-Yves Chibon 688943
Pierre-Yves Chibon 688943
Merged pull-request:
Pierre-Yves Chibon 688943
Pierre-Yves Chibon 688943
``
Pierre-Yves Chibon 688943
%s
Pierre-Yves Chibon 688943
``
Pierre-Yves Chibon 688943
Pierre-Yves Chibon 688943
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        user.username,
Pierre-Yves Chibon 9c2953
        request.project.name,
Pierre-Yves Chibon 9c2953
        request.title,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(request.project.fullname),
Pierre-Yves Chibon 9c2953
            "pull-request",
Pierre-Yves Chibon 9c2953
            request.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 4bd1cb
    mail_to = _get_emails_for_obj(request)
Pierre-Yves Chibon 688943
Pierre-Yves Chibon 3aeebc
    uid = time.mktime(datetime.datetime.now().timetuple())
Lenka Segura 9cb3f3
Lenka Segura 9cb3f3
    assignee = request.assignee.user if request.assignee else None
Lenka Segura 9cb3f3
Pierre-Yves Chibon 688943
    send_email(
Karsten Hopp 130d0e
        text,
Pierre-Yves Chibon 9c2953
        "PR #%s: %s" % (request.id, request.title),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 9c2953
        mail_id="%s/close/%s" % (request.mail_id, uid),
Karsten Hopp 130d0e
        in_reply_to=request.mail_id,
Karsten Hopp 130d0e
        project_name=request.project.fullname,
Karsten Hopp 130d0e
        user_from=user.fullname or user.user,
Lenka Segura 9cb3f3
        reporter=request.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Karsten Hopp 130d0e
    )
Karsten Hopp 130d0e
Karsten Hopp 130d0e
Karsten Hopp 130d0e
def notify_reopen_pull_request(request, user):
Pierre-Yves Chibon 9c2953
    """ Notify the people following a project that a closed pull-request
Karsten Hopp 130d0e
    has been reopened.
Pierre-Yves Chibon 9c2953
    """
Karsten Hopp 130d0e
    text = """
Karsten Hopp 130d0e
%s reopened a pull-request against the project: `%s` that you are following.
Karsten Hopp 130d0e
Karsten Hopp 130d0e
Reopened pull-request:
Karsten Hopp 130d0e
Karsten Hopp 130d0e
``
Karsten Hopp 130d0e
%s
Karsten Hopp 130d0e
``
Karsten Hopp 130d0e
Karsten Hopp 130d0e
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        user.username,
Pierre-Yves Chibon 9c2953
        request.project.name,
Pierre-Yves Chibon 9c2953
        request.title,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(request.project.fullname),
Pierre-Yves Chibon 9c2953
            "pull-request",
Pierre-Yves Chibon 9c2953
            request.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Karsten Hopp 130d0e
    mail_to = _get_emails_for_obj(request)
Karsten Hopp 130d0e
Karsten Hopp 130d0e
    uid = time.mktime(datetime.datetime.now().timetuple())
Lenka Segura 9cb3f3
Lenka Segura 9cb3f3
    assignee = request.assignee.user if request.assignee else None
Lenka Segura 9cb3f3
Karsten Hopp 130d0e
    send_email(
Pierre-Yves Chibon 688943
        text,
Pierre-Yves Chibon 9c2953
        "PR #%s: %s" % (request.id, request.title),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 9c2953
        mail_id="%s/close/%s" % (request.mail_id, uid),
Pierre-Yves Chibon 3aeebc
        in_reply_to=request.mail_id,
Adam Williamson 05b3f5
        project_name=request.project.fullname,
Pierre-Yves Chibon 9a69ae
        user_from=user.fullname or user.user,
Lenka Segura 9cb3f3
        reporter=request.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Pierre-Yves Chibon 688943
    )
Johan Cwiklinski 86d9c4
Johan Cwiklinski 86d9c4
Pierre-Yves Chibon a35061
def notify_closed_pull_request(request, user):
Pierre-Yves Chibon 9c2953
    """ Notify the people following a project that a pull-request was
Pierre-Yves Chibon a35061
    closed in it.
Pierre-Yves Chibon 9c2953
    """
Aurélien Bompard 831553
    text = """
Pierre-Yves Chibon a35061
%s closed without merging a pull-request against the project: `%s` that you
Pierre-Yves Chibon a35061
are following.
Johan Cwiklinski 86d9c4
Pierre-Yves Chibon a35061
Closed pull-request:
Johan Cwiklinski 86d9c4
Johan Cwiklinski 86d9c4
``
Johan Cwiklinski 86d9c4
%s
Johan Cwiklinski 86d9c4
``
Johan Cwiklinski 86d9c4
Johan Cwiklinski 86d9c4
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        user.username,
Pierre-Yves Chibon 9c2953
        request.project.name,
Pierre-Yves Chibon 9c2953
        request.title,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(request.project.fullname),
Pierre-Yves Chibon 9c2953
            "pull-request",
Pierre-Yves Chibon 9c2953
            request.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 4bd1cb
    mail_to = _get_emails_for_obj(request)
Johan Cwiklinski 86d9c4
Pierre-Yves Chibon 3aeebc
    uid = time.mktime(datetime.datetime.now().timetuple())
Lenka Segura 9cb3f3
Lenka Segura 9cb3f3
    assignee = request.assignee.user if request.assignee else None
Lenka Segura 9cb3f3
Johan Cwiklinski 86d9c4
    send_email(
Johan Cwiklinski 86d9c4
        text,
Pierre-Yves Chibon 9c2953
        "PR #%s: %s" % (request.id, request.title),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 9c2953
        mail_id="%s/close/%s" % (request.mail_id, uid),
Pierre-Yves Chibon 3aeebc
        in_reply_to=request.mail_id,
Adam Williamson 05b3f5
        project_name=request.project.fullname,
Pierre-Yves Chibon 9a69ae
        user_from=user.fullname or user.user,
Lenka Segura 9cb3f3
        reporter=request.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Johan Cwiklinski 86d9c4
    )
Pierre-Yves Chibon e43411
Pierre-Yves Chibon e43411
Pierre-Yves Chibon e43411
def notify_pull_request_comment(comment, user):
Pierre-Yves Chibon 9c2953
    """ Notify the people following a pull-request that a new comment was
Pierre-Yves Chibon e43411
    added to it.
Pierre-Yves Chibon 9c2953
    """
Aurélien Bompard 831553
    text = """
Pierre-Yves Chibon 728bce
%s commented on the pull-request: `%s` that you are following:
Pierre-Yves Chibon e43411
``
Pierre-Yves Chibon e43411
%s
Pierre-Yves Chibon e43411
``
Pierre-Yves Chibon e43411
Pierre-Yves Chibon a2efa3
%s
Pierre-Yves Chibon e43411
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        comment.user.user,
Pierre-Yves Chibon 9c2953
        comment.pull_request.title,
Pierre-Yves Chibon 9c2953
        comment.comment,
Pierre-Yves Chibon 9c2953
        REPLY_MSG,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(comment.pull_request.project.fullname),
Pierre-Yves Chibon 9c2953
            "pull-request",
Pierre-Yves Chibon 9c2953
            comment.pull_request.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 4bd1cb
    mail_to = _get_emails_for_obj(comment.pull_request)
Pierre-Yves Chibon 51c6d4
    mail_to = _add_mentioned_users(mail_to, comment.comment)
Pierre-Yves Chibon e43411
    mail_to = _clean_emails(mail_to, user)
Pierre-Yves Chibon e43411
Pierre-Yves Chibon 9ef9df
    assignee = (
Pierre-Yves Chibon 9ef9df
        comment.pull_request.assignee.user
Pierre-Yves Chibon 9ef9df
        if comment.pull_request.assignee
Pierre-Yves Chibon 9ef9df
        else None
Pierre-Yves Chibon 9ef9df
    )
Lenka Segura 9cb3f3
Pierre-Yves Chibon e43411
    send_email(
Pierre-Yves Chibon e43411
        text,
Pierre-Yves Chibon 9c2953
        "PR #%s: %s" % (comment.pull_request.id, comment.pull_request.title),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 96dfd7
        mail_id=comment.mail_id,
Pierre-Yves Chibon 96dfd7
        in_reply_to=comment.pull_request.mail_id,
Adam Williamson 05b3f5
        project_name=comment.pull_request.project.fullname,
Pierre-Yves Chibon 9a69ae
        user_from=comment.user.fullname or comment.user.user,
Lenka Segura 9cb3f3
        reporter=comment.pull_request.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Pierre-Yves Chibon e43411
    )
Pierre-Yves Chibon cab0d9
Pierre-Yves Chibon cab0d9
Pierre-Yves Chibon 4b8077
def notify_pull_request_flag(flag, user):
Pierre-Yves Chibon 9c2953
    """ Notify the people following a pull-request that a new flag was
Pierre-Yves Chibon 4b8077
    added to it.
Pierre-Yves Chibon 9c2953
    """
Aurélien Bompard 831553
    text = """
Pierre-Yves Chibon 4b8077
%s flagged the pull-request `%s` as %s: %s
Pierre-Yves Chibon 4b8077
Pierre-Yves Chibon 4b8077
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        flag.username,
Pierre-Yves Chibon 9c2953
        flag.pull_request.title,
Pierre-Yves Chibon 9c2953
        flag.status,
Pierre-Yves Chibon 9c2953
        flag.comment,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(flag.pull_request.project.fullname),
Pierre-Yves Chibon 9c2953
            "pull-request",
Pierre-Yves Chibon 9c2953
            flag.pull_request.id,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 4b8077
    mail_to = _get_emails_for_obj(flag.pull_request)
Pierre-Yves Chibon 4b8077
Pierre-Yves Chibon 9ef9df
    assignee = (
Pierre-Yves Chibon 9ef9df
        flag.pull_request.assignee.user if flag.pull_request.assignee else None
Pierre-Yves Chibon 9ef9df
    )
Lenka Segura 9cb3f3
Pierre-Yves Chibon 4b8077
    send_email(
Pierre-Yves Chibon 4b8077
        text,
Pierre-Yves Chibon 9c2953
        "PR #%s - %s: %s" % (flag.pull_request.id, flag.username, flag.status),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 4b8077
        mail_id=flag.mail_id,
Pierre-Yves Chibon 4b8077
        in_reply_to=flag.pull_request.mail_id,
Pierre-Yves Chibon 4b8077
        project_name=flag.pull_request.project.fullname,
Pierre-Yves Chibon 4b8077
        user_from=flag.username,
Lenka Segura 9cb3f3
        reporter=flag.pull_request.user.user,
Pierre-Yves Chibon 9ef9df
        assignee=assignee,
Pierre-Yves Chibon 4b8077
    )
Pierre-Yves Chibon 4b8077
Pierre-Yves Chibon 4b8077
Pierre-Yves Chibon cab0d9
def notify_new_email(email, user):
Pierre-Yves Chibon 9c2953
    """ Ask the user to confirm to the email belong to them.
Pierre-Yves Chibon 9c2953
    """
Pierre-Yves Chibon cab0d9
Pierre-Yves Chibon 9c2953
    root_url = pagure_config.get("APP_URL", flask.request.url_root)
Pierre-Yves Chibon cab0d9
Aurélien Bompard 831553
    url = urljoin(
Pierre-Yves Chibon d4589a
        root_url or flask.request.url_root,
Pierre-Yves Chibon 9c2953
        flask.url_for("ui_ns.confirm_email", token=email.token),
Pierre-Yves Chibon cab0d9
    )
Pierre-Yves Chibon cab0d9
Aurélien Bompard 831553
    text = """Dear %(username)s,
Pierre-Yves Chibon cab0d9
Pierre-Yves Chibon d4589a
You have registered a new email on pagure at %(root_url)s.
Pierre-Yves Chibon cab0d9
Pierre-Yves Chibon cab0d9
To finish your validate this registration, please click on the following
Pierre-Yves Chibon cab0d9
link or copy/paste it in your browser, this link will remain valid only 2 days:
Pierre-Yves Chibon cab0d9
  %(url)s
Pierre-Yves Chibon cab0d9
Pierre-Yves Chibon cab0d9
The email will not be activated until you finish this step.
Pierre-Yves Chibon cab0d9
Pierre-Yves Chibon cab0d9
Sincerely,
Pierre-Yves Chibon cab0d9
Your pagure admin.
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        {"username": user.username, "url": url, "root_url": root_url}
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon cab0d9
Pierre-Yves Chibon cab0d9
    send_email(
Pierre-Yves Chibon cab0d9
        text,
Pierre-Yves Chibon 9c2953
        "Confirm new email",
Pierre-Yves Chibon cab0d9
        email.email,
Pierre-Yves Chibon 9a69ae
        user_from=user.fullname or user.user,
Pierre-Yves Chibon cab0d9
    )
Matt Prahl b49f93
Matt Prahl b49f93
Matt Prahl b49f93
def notify_new_commits(abspath, project, branch, commits):
Pierre-Yves Chibon 9c2953
    """ Notify the people following a project's commits that new commits have
Matt Prahl b49f93
    been added.
Pierre-Yves Chibon 9c2953
    """
Adam Williamson a8fef8
    # string note: abspath, project and branch can only contain ASCII
Adam Williamson a8fef8
    # by policy (pagure and/or gitolite)
Matt Prahl b49f93
    commits_info = []
Matt Prahl b49f93
    for commit in commits:
Pierre-Yves Chibon 9c2953
        commits_info.append(
Pierre-Yves Chibon 9c2953
            {
Pierre-Yves Chibon 9c2953
                "commit": commit,
Pierre-Yves Chibon 9c2953
                "author": pagure.lib.git.get_author(commit, abspath),
Pierre-Yves Chibon 9c2953
                "subject": pagure.lib.git.get_commit_subject(commit, abspath),
Pierre-Yves Chibon 9c2953
            }
Pierre-Yves Chibon 9c2953
        )
Matt Prahl b49f93
Adam Williamson a8fef8
    # make sure this is unicode
Pierre-Yves Chibon 9c2953
    commits_string = "\n".join(
Pierre-Yves Chibon 9c2953
        "{0}    {1}    {2}".format(
Pierre-Yves Chibon 9c2953
            commit_info["commit"],
Pierre-Yves Chibon 9c2953
            commit_info["author"],
Pierre-Yves Chibon 9c2953
            commit_info["subject"],
Pierre-Yves Chibon 9c2953
        )
Pierre-Yves Chibon 9c2953
        for commit_info in commits_info
Pierre-Yves Chibon 9c2953
    )
Matt Prahl b49f93
    commit_url = _build_url(
Pierre-Yves Chibon 9c2953
        pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
        _fullname_to_url(project.fullname),
Pierre-Yves Chibon 9c2953
        "commits",
Pierre-Yves Chibon 9c2953
        branch,
Pierre-Yves Chibon 9c2953
    )
Matt Prahl b49f93
Pierre-Yves Chibon 9c2953
    email_body = """
Adam Williamson a8fef8
The following commits were pushed to the repo %s on branch
Adam Williamson a8fef8
%s, which you are following:
Adam Williamson a8fef8
%s
Matt Prahl b49f93
Matt Prahl b49f93
Matt Prahl b49f93
Matt Prahl b49f93
To view more about the commits, visit:
Adam Williamson a8fef8
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        project.fullname,
Pierre-Yves Chibon 9c2953
        branch,
Pierre-Yves Chibon 9c2953
        commits_string,
Pierre-Yves Chibon 9c2953
        commit_url,
Pierre-Yves Chibon 9c2953
    )
Matt Prahl b49f93
    mail_to = _get_emails_for_commit_notification(project)
Matt Prahl b49f93
Matt Prahl b49f93
    send_email(
Matt Prahl b49f93
        email_body,
Matt Prahl b49f93
        'New Commits To "{0}" ({1})'.format(project.fullname, branch),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 9c2953
        project_name=project.fullname,
Matt Prahl b49f93
    )
Pierre-Yves Chibon 327b88
Pierre-Yves Chibon 327b88
Pierre-Yves Chibon 327b88
def notify_commit_flag(flag, user):
Pierre-Yves Chibon 9c2953
    """ Notify the people following a project that a new flag was added
Pierre-Yves Chibon 327b88
    to one of its commit.
Pierre-Yves Chibon 9c2953
    """
Aurélien Bompard 831553
    text = """
Pierre-Yves Chibon 327b88
%s flagged the commit `%s` as %s: %s
Pierre-Yves Chibon 327b88
Pierre-Yves Chibon 327b88
%s
Pierre-Yves Chibon 9c2953
""" % (
Pierre-Yves Chibon 9c2953
        flag.username,
Pierre-Yves Chibon 9c2953
        flag.commit_hash,
Pierre-Yves Chibon 9c2953
        flag.status,
Pierre-Yves Chibon 9c2953
        flag.comment,
Pierre-Yves Chibon 9c2953
        _build_url(
Pierre-Yves Chibon 9c2953
            pagure_config["APP_URL"],
Pierre-Yves Chibon 9c2953
            _fullname_to_url(flag.project.fullname),
Pierre-Yves Chibon 9c2953
            "c",
Pierre-Yves Chibon 9c2953
            flag.commit_hash,
Pierre-Yves Chibon 9c2953
        ),
Pierre-Yves Chibon 9c2953
    )
Pierre-Yves Chibon 327b88
    mail_to = _get_emails_for_obj(flag)
Pierre-Yves Chibon 327b88
Pierre-Yves Chibon 327b88
    send_email(
Pierre-Yves Chibon 327b88
        text,
Pavel Raiskup ef2dfa
        "Commit #%s - %s: %s" % (flag.commit_hash, flag.username, flag.status),
Pierre-Yves Chibon 9c2953
        ",".join(mail_to),
Pierre-Yves Chibon 327b88
        mail_id=flag.mail_id,
Pierre-Yves Chibon 327b88
        in_reply_to=flag.project.mail_id,
Pierre-Yves Chibon 327b88
        project_name=flag.project.fullname,
Pierre-Yves Chibon 327b88
        user_from=flag.username,
Pierre-Yves Chibon 327b88
    )