Changeset - 8b75085c2c02
[Not reviewed]
default
1 18 6
Mads Kiilerich - 9 years ago 2016-07-28 16:44:24
madski@unity3d.com
mails: restructure notification mail content

* Mention "The Thing" in the header, link to online version
* Show The Thing
* A dense summary of the essentials of the context below it

The html indentation is odd in order to make the next diff smaller.

The text version is based on:

for a in kallithea/templates/email_templates/*.html; do sed -e 's,<\([^%/>]\|/[^%>]\)*>,,g' -e 's,\.html",\.txt",g' -e 's,^ *,,g' -e 's/}/|n,unicode}/g' $a > ${a%%.html}.txt ; done
25 files changed with 911 insertions and 533 deletions:
0 comments (0 inline, 0 general)
kallithea/model/comment.py
Show inline comments
 
# -*- coding: utf-8 -*-
 
# This program is free software: you can redistribute it and/or modify
 
# it under the terms of the GNU General Public License as published by
 
# the Free Software Foundation, either version 3 of the License, or
 
# (at your option) any later version.
 
#
 
# This program is distributed in the hope that it will be useful,
 
# but WITHOUT ANY WARRANTY; without even the implied warranty of
 
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
# GNU General Public License for more details.
 
#
 
# You should have received a copy of the GNU General Public License
 
# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
"""
 
kallithea.model.comment
 
~~~~~~~~~~~~~~~~~~~~~~~
 

	
 
comments model for Kallithea
 

	
 
This file was forked by the Kallithea project in July 2014.
 
Original author and date, and relevant copyright and licensing information is below:
 
:created_on: Nov 11, 2011
 
:author: marcink
 
:copyright: (c) 2013 RhodeCode GmbH, and others.
 
:license: GPLv3, see LICENSE.md for more details.
 
"""
 

	
 
import logging
 

	
 
from pylons.i18n.translation import _
 
from collections import defaultdict
 

	
 
from kallithea.lib.utils2 import extract_mentioned_users, safe_unicode
 
from kallithea.lib import helpers as h
 
from kallithea.model import BaseModel
 
from kallithea.model.db import ChangesetComment, User, \
 
    Notification, PullRequest
 
from kallithea.model.notification import NotificationModel
 
from kallithea.model.meta import Session
 

	
 
log = logging.getLogger(__name__)
 

	
 

	
 
class ChangesetCommentsModel(BaseModel):
 

	
 
    def _get_notification_data(self, repo, comment, user, comment_text,
 
                               line_no=None, revision=None, pull_request=None,
 
                               status_change=None, closing_pr=False):
 
        """
 
        :returns: tuple (subj,body,recipients,notification_type,email_kwargs)
 
        """
 
        # make notification
 
        body = comment_text  # text of the comment
 
        line = ''
 
        if line_no:
 
            line = _('on line %s') % line_no
 

	
 
        #changeset
 
        if revision:
 
            notification_type = Notification.TYPE_CHANGESET_COMMENT
 
            cs = repo.scm_instance.get_changeset(revision)
 
            desc = cs.short_id
 

	
 
            threading = ['%s-rev-%s@%s' % (repo.repo_name, revision, h.canonical_hostname())]
 
            if line_no: # TODO: url to file _and_ line number
 
                threading.append('%s-rev-%s-line-%s@%s' % (repo.repo_name, revision, line_no,
 
                                                           h.canonical_hostname()))
 
            comment_url = h.canonical_url('changeset_home',
 
                repo_name=repo.repo_name,
 
                revision=revision,
 
                anchor='comment-%s' % comment.comment_id)
 
            subj = safe_unicode(
 
                h.link_to('Re changeset: %(desc)s %(line)s' % \
 
                          {'desc': desc, 'line': line},
 
                          comment_url)
 
            )
 
            # get the current participants of this changeset
 
            recipients = ChangesetComment.get_users(revision=revision)
 
            # add changeset author if it's known locally
 
            cs_author = User.get_from_cs_author(cs.author)
 
            if not cs_author:
 
                #use repo owner if we cannot extract the author correctly
 
                # FIXME: just use committer name even if not a user
 
                cs_author = repo.user
 
            recipients += [cs_author]
 
            email_kwargs = {
 
                'status_change': status_change,
 
                'cs_comment_user': user.full_name_and_username,
 
                'cs_target_repo': h.canonical_url('summary_home', repo_name=repo.repo_name),
 
                'cs_comment_url': comment_url,
 
                'cs_url': h.canonical_url('changeset_home', repo_name=repo.repo_name, revision=revision),
 
                'raw_id': revision,
 
                'message': cs.message,
 
                'message_short': h.shorter(cs.message, 50, firstline=True),
 
                'cs_author': cs_author,
 
                'repo_name': repo.repo_name,
 
                'short_id': h.short_id(revision),
 
                'branch': cs.branch,
 
                'comment_username': user.username,
 
                'threading': threading,
 
            }
 
        #pull request
 
        elif pull_request:
 
            notification_type = Notification.TYPE_PULL_REQUEST_COMMENT
 
            desc = comment.pull_request.title
 
            _org_ref_type, org_ref_name, _org_rev = comment.pull_request.org_ref.split(':')
 
            _other_ref_type, other_ref_name, _other_rev = comment.pull_request.other_ref.split(':')
 
            threading = ['%s-pr-%s@%s' % (pull_request.other_repo.repo_name,
 
                                          pull_request.pull_request_id,
 
                                          h.canonical_hostname())]
 
            if line_no: # TODO: url to file _and_ line number
 
                threading.append('%s-pr-%s-line-%s@%s' % (pull_request.other_repo.repo_name,
 
                                                          pull_request.pull_request_id, line_no,
 
                                                          h.canonical_hostname()))
 
            comment_url = pull_request.url(canonical=True,
 
                anchor='comment-%s' % comment.comment_id)
 
            subj = safe_unicode(
 
                h.link_to('Re pull request %(pr_nice_id)s: %(desc)s %(line)s' % \
 
                          {'desc': desc,
 
                           'pr_nice_id': comment.pull_request.nice_id(),
 
                           'line': line},
 
                          comment_url)
 
            )
 
            # get the current participants of this pull request
 
            recipients = ChangesetComment.get_users(pull_request_id=
 
                                                pull_request.pull_request_id)
 
            # add pull request author
 
            recipients += [pull_request.owner]
 

	
 
            # add the reviewers to notification
 
            recipients += pull_request.get_reviewer_users()
 

	
 
            #set some variables for email notification
 
            email_kwargs = {
 
                'pr_title': pull_request.title,
 
                'pr_title_short': h.shorter(pull_request.title, 50),
 
                'pr_nice_id': pull_request.nice_id(),
 
                'status_change': status_change,
 
                'closing_pr': closing_pr,
 
                'pr_comment_url': comment_url,
 
                'pr_url': pull_request.url(canonical=True),
 
                'pr_comment_user': user.full_name_and_username,
 
                'pr_target_repo': h.canonical_url('summary_home',
 
                                   repo_name=pull_request.other_repo.repo_name),
 
                'pr_target_branch': other_ref_name,
 
                'pr_source_repo': h.canonical_url('summary_home',
 
                                   repo_name=pull_request.org_repo.repo_name),
 
                'pr_source_branch': org_ref_name,
 
                'pr_owner': pull_request.owner,
 
                'pr_owner_username': pull_request.owner.username,
 
                'repo_name': pull_request.other_repo.repo_name,
 
                'comment_username': user.username,
 
                'threading': threading,
 
            }
 

	
 
        return subj, body, recipients, notification_type, email_kwargs
 

	
 
    def create(self, text, repo, user, revision=None, pull_request=None,
 
               f_path=None, line_no=None, status_change=None, closing_pr=False,
 
               send_email=True):
 
        """
 
        Creates a new comment for either a changeset or a pull request.
 
        status_change and closing_pr is only for the optional email.
 

	
 
        Returns the created comment.
 
        """
 
        if not status_change and not text:
 
            log.warning('Missing text for comment, skipping...')
 
            return None
 

	
 
        repo = self._get_repo(repo)
 
        user = self._get_user(user)
 
        comment = ChangesetComment()
 
        comment.repo = repo
 
        comment.author = user
 
        comment.text = text
 
        comment.f_path = f_path
 
        comment.line_no = line_no
 

	
 
        if revision is not None:
 
            comment.revision = revision
 
        elif pull_request is not None:
 
            pull_request = PullRequest.guess_instance(pull_request)
 
            comment.pull_request = pull_request
 
        else:
 
            raise Exception('Please specify revision or pull_request_id')
 

	
 
        Session().add(comment)
 
        Session().flush()
 

	
 
        if send_email:
 
            (subj, body, recipients, notification_type,
 
             email_kwargs) = self._get_notification_data(
 
                                repo, comment, user,
 
                                comment_text=text,
 
                                line_no=line_no,
 
                                revision=revision,
 
                                pull_request=pull_request,
 
                                status_change=status_change,
 
                                closing_pr=closing_pr)
 
            email_kwargs['is_mention'] = False
 
            # create notification objects, and emails
 
            NotificationModel().create(
 
                created_by=user, subject=subj, body=body,
 
                recipients=recipients, type_=notification_type,
 
                email_kwargs=email_kwargs,
 
            )
 

	
 
            mention_recipients = extract_mentioned_users(body).difference(recipients)
 
            if mention_recipients:
 
                email_kwargs['is_mention'] = True
 
                subj = _('[Mention]') + ' ' + subj
 
                # FIXME: this subject is wrong and unused!
 
                NotificationModel().create(
 
                    created_by=user, subject=subj, body=body,
 
                    recipients=mention_recipients,
 
                    type_=notification_type,
 
                    email_kwargs=email_kwargs
 
                )
 

	
 
        return comment
 

	
 
    def delete(self, comment):
 
        comment = ChangesetComment.guess_instance(comment)
 
        Session().delete(comment)
 

	
 
        return comment
 

	
 
    def get_comments(self, repo_id, revision=None, pull_request=None):
 
        """
 
        Gets general comments for either revision or pull_request.
 

	
 
        Returns a list, ordered by creation date.
 
        """
 
        return self._get_comments(repo_id, revision=revision, pull_request=pull_request,
 
                                  inline=False)
 

	
kallithea/model/user.py
Show inline comments
 
@@ -105,193 +105,195 @@ class UserModel(BaseModel):
 
        Creates a new instance if not found, or updates current one
 

	
 
        :param username:
 
        :param password:
 
        :param email:
 
        :param active:
 
        :param firstname:
 
        :param lastname:
 
        :param active:
 
        :param admin:
 
        :param extern_name:
 
        :param extern_type:
 
        :param cur_user:
 
        """
 
        if not cur_user:
 
            cur_user = getattr(get_current_authuser(), 'username', None)
 

	
 
        from kallithea.lib.auth import get_crypt_password, check_password
 
        from kallithea.lib.hooks import log_create_user, \
 
            check_allowed_create_user
 
        user_data = {
 
            'username': username, 'password': password,
 
            'email': email, 'firstname': firstname, 'lastname': lastname,
 
            'active': active, 'admin': admin
 
        }
 
        # raises UserCreationError if it's not allowed
 
        check_allowed_create_user(user_data, cur_user)
 

	
 
        log.debug('Checking for %s account in Kallithea database', username)
 
        user = User.get_by_username(username, case_insensitive=True)
 
        if user is None:
 
            log.debug('creating new user %s', username)
 
            new_user = User()
 
            edit = False
 
        else:
 
            log.debug('updating user %s', username)
 
            new_user = user
 
            edit = True
 

	
 
        try:
 
            new_user.username = username
 
            new_user.admin = admin
 
            new_user.email = email
 
            new_user.active = active
 
            new_user.extern_name = safe_str(extern_name) \
 
                if extern_name else None
 
            new_user.extern_type = safe_str(extern_type) \
 
                if extern_type else None
 
            new_user.name = firstname
 
            new_user.lastname = lastname
 

	
 
            if not edit:
 
                new_user.api_key = generate_api_key()
 

	
 
            # set password only if creating an user or password is changed
 
            password_change = new_user.password and \
 
                not check_password(password, new_user.password)
 
            if not edit or password_change:
 
                reason = 'new password' if edit else 'new user'
 
                log.debug('Updating password reason=>%s', reason)
 
                new_user.password = get_crypt_password(password) \
 
                    if password else None
 

	
 
            self.sa.add(new_user)
 

	
 
            if not edit:
 
                log_create_user(new_user.get_dict(), cur_user)
 
            return new_user
 
        except (DatabaseError,):
 
            log.error(traceback.format_exc())
 
            raise
 

	
 
    def create_registration(self, form_data):
 
        from kallithea.model.notification import NotificationModel
 
        import kallithea.lib.helpers as h
 

	
 
        form_data['admin'] = False
 
        form_data['extern_name'] = EXTERN_TYPE_INTERNAL
 
        form_data['extern_type'] = EXTERN_TYPE_INTERNAL
 
        new_user = self.create(form_data)
 

	
 
        self.sa.add(new_user)
 
        self.sa.flush()
 

	
 
        # notification to admins
 
        subject = _('New user registration')
 
        body = (
 
            u'New user registration\n'
 
            '---------------------\n'
 
            '- Username: {user.username}\n'
 
            '- Full Name: {user.full_name}\n'
 
            '- Email: {user.email}\n'
 
            ).format(user=new_user)
 
        edit_url = h.canonical_url('edit_user', id=new_user.user_id)
 
        email_kwargs = {
 
            'registered_user_url': edit_url,
 
            'new_username': new_user.username}
 
            'new_username': new_user.username,
 
            'new_email': new_user.email,
 
            'new_full_name': new_user.full_name}
 
        NotificationModel().create(created_by=new_user, subject=subject,
 
                                   body=body, recipients=None,
 
                                   type_=Notification.TYPE_REGISTRATION,
 
                                   email_kwargs=email_kwargs)
 

	
 
    def update(self, user_id, form_data, skip_attrs=None):
 
        from kallithea.lib.auth import get_crypt_password
 
        skip_attrs = skip_attrs or []
 
        user = self.get(user_id, cache=False)
 
        if user.username == User.DEFAULT_USER:
 
            raise DefaultUserException(
 
                            _("You can't edit this user since it's "
 
                              "crucial for entire application"))
 

	
 
        for k, v in form_data.items():
 
            if k in skip_attrs:
 
                continue
 
            if k == 'new_password' and v:
 
                user.password = get_crypt_password(v)
 
            else:
 
                # old legacy thing orm models store firstname as name,
 
                # need proper refactor to username
 
                if k == 'firstname':
 
                    k = 'name'
 
                setattr(user, k, v)
 
        self.sa.add(user)
 

	
 
    def update_user(self, user, **kwargs):
 
        from kallithea.lib.auth import get_crypt_password
 

	
 
        user = self._get_user(user)
 
        if user.username == User.DEFAULT_USER:
 
            raise DefaultUserException(
 
                _("You can't edit this user since it's"
 
                  " crucial for entire application")
 
            )
 

	
 
        for k, v in kwargs.items():
 
            if k == 'password' and v:
 
                v = get_crypt_password(v)
 

	
 
            setattr(user, k, v)
 
        self.sa.add(user)
 
        return user
 

	
 
    def delete(self, user, cur_user=None):
 
        if cur_user is None:
 
            cur_user = getattr(get_current_authuser(), 'username', None)
 
        user = self._get_user(user)
 

	
 
        if user.username == User.DEFAULT_USER:
 
            raise DefaultUserException(
 
                _("You can't remove this user since it is"
 
                  " crucial for the entire application"))
 
        if user.repositories:
 
            repos = [x.repo_name for x in user.repositories]
 
            raise UserOwnsReposException(
 
                _('User "%s" still owns %s repositories and cannot be '
 
                  'removed. Switch owners or remove those repositories: %s')
 
                % (user.username, len(repos), ', '.join(repos)))
 
        if user.repo_groups:
 
            repogroups = [x.group_name for x in user.repo_groups]
 
            raise UserOwnsReposException(_(
 
                'User "%s" still owns %s repository groups and cannot be '
 
                'removed. Switch owners or remove those repository groups: %s')
 
                % (user.username, len(repogroups), ', '.join(repogroups)))
 
        if user.user_groups:
 
            usergroups = [x.users_group_name for x in user.user_groups]
 
            raise UserOwnsReposException(
 
                _('User "%s" still owns %s user groups and cannot be '
 
                  'removed. Switch owners or remove those user groups: %s')
 
                % (user.username, len(usergroups), ', '.join(usergroups)))
 
        self.sa.delete(user)
 

	
 
        from kallithea.lib.hooks import log_delete_user
 
        log_delete_user(user.get_dict(), cur_user)
 

	
 
    def can_change_password(self, user):
 
        from kallithea.lib import auth_modules
 
        managed_fields = auth_modules.get_managed_fields(user)
 
        return 'password' not in managed_fields
 

	
 
    def get_reset_password_token(self, user, timestamp, session_id):
 
        """
 
        The token is a 40-digit hexstring, calculated as a HMAC-SHA1.
 

	
 
        In a traditional HMAC scenario, an attacker is unable to know or
 
        influence the secret key, but can know or influence the message
 
        and token. This scenario is slightly different (in particular
 
        since the message sender is also the message recipient), but
 
        sufficiently similar to use an HMAC. Benefits compared to a plain
 
        SHA1 hash includes resistance against a length extension attack.
 

	
 
        The HMAC key consists of the following values (known only to the
 
        server and authorized users):
 

	
kallithea/templates/email_templates/button.html
Show inline comments
 
new file 100644
 
<%page args="url,title='',padding_top=True,padding_bottom=True" />\
 
##<!-- button -->
 
<p>
 
            <a href="${url}" target="_blank">
 
                        ${_(title)}
 
            </a>
 
</p>
 
##<!-- /button -->
kallithea/templates/email_templates/button.txt
Show inline comments
 
new file 100644
 
<%page args="url,title" />\
 

	
 
${title|n,unicode}: ${url}
kallithea/templates/email_templates/changeset_comment.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 

	
 
%if is_mention:
 
<p>${_('Comment from %s on %s changeset %s mentioned you') % (cs_comment_user, cs_target_repo, h.short_id(raw_id))}:</p>
 
%else:
 
<p>${_('Comment from %s on %s changeset %s') % (cs_comment_user, cs_target_repo, h.short_id(raw_id))}:</p>
 
%endif
 
<p>${body}</p>
 

	
 
%if status_change:
 
    <p>${_('The changeset status was changed to')}: <b>${status_change}</b></p>
 
%endif
 

	
 
<p>${_('URL')}: <a href="${cs_comment_url}">${cs_comment_url}</a></p>
 

	
 
<p>${_('Changeset')}: ${h.short_id(raw_id)}</p>
 
<p>${_('Description')}:<br/>
 
${h.shorter(message, 256)}
 
</p>
 
<%inherit file="main.html"/>\
 
\
 
<%block name="header">\
 
<% title = _('Mention in Comment on Changeset "%s"') % h.shorter(message, 200, firstline=True) if is_mention else _('Comment on Changeset "%s"') % h.shorter(message, 200, firstline=True) %>\
 
<%include file="header.html" args="title=title,link=cs_comment_url"/>\
 
</%block>\
 
\
 
<%include file="comment.html" args="text=body,author=cs_comment_user,status=status_change"/>\
 
            <p>
 
                ${_('Changeset on')}
 
                <a href="${cs_target_repo}">${cs_target_repo}</a>
 
                ${_('branch')}
 
                ${branch}:
 
                <br/>
 
                "<a href="${cs_url}">${h.shorter(message, 60, firstline=True)}</a>"
 
                ${_('by')}
 
                ${cs_author.full_name_and_username}.
 
            </p>
 
<%include file="button.html" args="url=cs_comment_url,title=_('View Comment'),padding_bottom=False"/>\
kallithea/templates/email_templates/changeset_comment.txt
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.txt"/>
 
<%block name="header">\
 
<% title = _('Mention in Comment on Changeset "%s"') % h.shorter(message, 200, firstline=True) if is_mention else _('Comment on Changeset "%s"') % h.shorter(message, 200, firstline=True) %>\
 
<%include file="header.txt" args="title=title,link=cs_comment_url"/>\
 
</%block>\
 

	
 
%if is_mention:
 
${_('Comment from %s on %s changeset %s mentioned you') % (cs_comment_user, cs_target_repo, h.short_id(raw_id))|n,unicode}:
 
%else:
 
${_('Comment from %s on %s changeset %s') % (cs_comment_user, cs_target_repo, h.short_id(raw_id))|n,unicode}:
 
%endif
 
${body|n,unicode}
 
<%include file="comment.txt" args="text=body,author=cs_comment_user,status=status_change"/>\
 

	
 
%if status_change:
 
${_('The changeset status was changed to')|n,unicode}: ${status_change|n,unicode}
 
%endif
 
${_('Changeset on')|n,unicode} \
 
${cs_target_repo|n,unicode} \
 
${_('branch')|n,unicode} \
 
${branch|n,unicode}:
 
"${h.shorter(message, 60, firstline=True)|n,unicode}" \
 
${_('by')|n,unicode} \
 
${cs_author.full_name_and_username|n,unicode}.
 

	
 
${_('URL')|n,unicode}: ${cs_comment_url|n,unicode}
 

	
 
${_('Changeset')|n,unicode}: ${h.short_id(raw_id)|n,unicode}
 
${_('Description')|n,unicode}:
 
${h.shorter(message, 256)|n,unicode}
 
<%include file="button.txt" args="url=cs_comment_url,title=_('View Comment')"/>\
kallithea/templates/email_templates/comment.html
Show inline comments
 
new file 100644
 
<%page args="author,text,status,close=False" />\
 
\
 
##<!-- comment ->
 
            <h2>${author}</h2>
 
                %if status:
 
                    <p>
 
                        ${_('Status change:')}
 
                        ${status}
 
                    </p>
 
                %endif
 
                %if close:
 
                    <p>
 
                        ${_('The pull request has been closed.')}
 
                    </p>
 
                %endif
 
                <div style="font-family:monospace;white-space:pre-wrap">${text}</div>
 
##<!-- /comment ->
kallithea/templates/email_templates/comment.txt
Show inline comments
 
new file 100644
 
<%page args="author,text,status,close=False" />\
 
${author|n,unicode}:
 

	
 
%if status:
 
${_('Status change:')|n,unicode} \
 
${status|n,unicode}
 

	
 
%endif
 
%if close:
 
${_('The pull request has been closed.')|n,unicode}
 

	
 
%endif
 
${text|n,unicode}
 

	
 
## Trailing empty line
kallithea/templates/email_templates/default.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 

	
 
${body}
 
<%inherit file="main.html"/>\
 
\
 
<%block name="header">\
 
<%include file="header.html" args="title=_('Message'),link=None"/>\
 
</%block>\
 
\
 
        <div style="font-family:monospace;white-space:pre-wrap">${body}</div>
kallithea/templates/email_templates/default.txt
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.txt"/>
 

	
 
${body|n,unicode}
 
<%block name="header">\
 
</%block>\
 
\
 
${body|n,unicode}\
kallithea/templates/email_templates/header.html
Show inline comments
 
new file 100644
 
<%page args="title,link" />\
 
\
 
##<!-- header -->
 
    <h1>
 
        %if link is not None:
 
            <a href="${link}"
 
               target="_blank">${title}</a>
 
        %else:
 
            ${title}
 
        %endif
 
    </h1>
 
##<!-- /header -->
kallithea/templates/email_templates/header.txt
Show inline comments
 
new file 100644
 
<%page args="title,link" />\
 
%if link is not None:
 
${link}
 

	
 
%endif
 
${title|n,unicode}
 

	
 
## Trailing empty line
kallithea/templates/email_templates/main.html
Show inline comments
 
<!doctype html>
 
<html lang="en">
 
<head>
 
    <title></title>
 
    <meta name="viewport" content="width=device-width">
 
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
 
</head>
 
<body>
 
${self.body()}
 
<br/>
 
<br/>
 
-- <br/>
 
${_("This is an automatic notification. Don't reply to this mail.")}
 
                        ##<!-- body -->
 
${self.body()}\
 
                        ##<!-- /body -->
 
</body>
 
</html>
kallithea/templates/email_templates/main.txt
Show inline comments
 
deleted file
kallithea/templates/email_templates/password_reset.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 

	
 
<h4>${_('Hello %s') % user}</h4>
 
<%inherit file="main.html"/>\
 
\
 
<%block name="header">\
 
<%include file="header.html" args="title=_('Password Reset Request'),link=None"/>\
 
</%block>\
 
\
 
            <h2>${_('Hello %s') % user},</h2>
 
            <p>
 
                ${_('We have received a request to reset the password for your account.')}
 
            </p>
 
            <p>
 

	
 
<p>${_('We have received a request to reset the password for your account.')}</p>
 
%if reset_token is None:
 
<p>${_('This account is however managed outside this system and the password cannot be changed here.')}</p>
 
%else:
 
<p>${_('To set a new password, click the following link')}:</p>
 
<p><a href="${reset_url}">${reset_url}</a></p>
 

	
 
<p>${_("Should you not be able to use the link above, please type the following code into the password reset form")}: <code>${reset_token}</code></p>
 
%endif
 

	
 
<p>${_("If it weren't you who requested the password reset, just disregard this message.")}</p>
 
            %if reset_token is None:
 
                ${_('This account is however managed outside this system and the password cannot be changed here.')}
 
            %else:
 
                    ${_('To set a new password, click the following link')}:
 
                    <br/>
 
                    <a href="${reset_url}"
 
                        target="_blank">${reset_url}</a>
 
                    <br/>
 
                    ${_("Should you not be able to use the link above, please type the following code into the password reset form")}:
 
                    <code>${reset_token}</code>
 
            %endif
 
            <p>
 
                ${_("If it weren't you who requested the password reset, just disregard this message.")}
 
            </p>
kallithea/templates/email_templates/password_reset.txt
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.txt"/>
 

	
 
${_('Hello %s') % user|n,unicode}
 
<%block name="header">\
 
<%include file="header.txt" args="title=_('Password Reset Request'),link=None"/>\
 
</%block>\
 
\
 
${_('Hello %s') % user|n,unicode},
 

	
 
${_('We have received a request to reset the password for your account.')|n,unicode}
 

	
 
%if reset_token is None:
 
${_('This account is however managed outside this system and the password cannot be changed here.')|n,unicode}
 
%else:
 
${_('To set a new password, click the following link')|n,unicode}:
 

	
 
${reset_url|n,unicode}
 

	
 
${_("Should you not be able to use the link above, please type the following code into the password reset form")|n,unicode}: ${reset_token|n,unicode}
 
${_("Should you not be able to use the link above, please type the following code into the password reset form")|n,unicode}:
 
${reset_token|n,unicode}
 
%endif
 

	
 
${_("If it weren't you who requested the password reset, just disregard this message.")|n,unicode}
kallithea/templates/email_templates/pull_request.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 

	
 
%if is_mention:
 
<p>${_('%s mentioned you on %s pull request "%s"') % (pr_user_created, repo_name, pr_title)}</p>
 
%else:
 
<p>${_('%s requested your review of %s pull request "%s"') % (pr_user_created, repo_name, pr_title)}</p>
 
%endif
 

	
 
<p>${_('URL')}: <a href="${pr_url}">${pr_url}</a></p>
 

	
 
<p>${_('Description')}:</p>
 
<p style="white-space: pre-wrap; font-family: monospace">${body}</p>
 

	
 
<p>${_('Changesets')}:</p>
 
<p style="white-space: pre-wrap">
 
%for r,r_msg in pr_revisions:
 
<i><a href="${h.canonical_url('changeset_home', repo_name=org_repo_name, revision=r)}">${h.short_id(r)}</a></i>:
 
${h.shorter(r_msg, 256)}
 

	
 
%endfor
 
</p>
 
<%inherit file="main.html"/>\
 
\
 
<%block name="header">\
 
<% title = _('Mention on Pull Request %s "%s" by %s') % (pr_nice_id, pr_title, pr_user_created) if is_mention else _('Added as Reviewer of Pull Request %s "%s" by %s') % (pr_nice_id, pr_title, pr_user_created) %>\
 
<%include file="header.html" args="title=title,link=pr_url"/>\
 
</%block>\
 
\
 
            <p>
 
                ${_('Pull request from')}
 
                <a href="${pr_source_repo}">${pr_source_repo}</a>
 
                ${_('at')}
 
                ${pr_source_branch}
 
                ${_('to')}
 
                <a href="${pr_target_repo}">${pr_target_repo}</a>
 
                ${_('at')}
 
                ${pr_target_branch}:
 
                <br/>
 
                <a href="${pr_url}">${pr_nice_id}</a>
 
                "${pr_title}"
 
                ${_('by')}
 
                ${pr_owner.full_name_and_username}.
 
            </p>
 
            <p>
 
                ${_('Description')}:
 
            </p>
 
            <div style="font-family:monospace;white-space:pre-wrap">${body}</div>
 
            <p>${_('Changesets')}:</p>
 
            <ul>
 
                %for revision, desc in pr_revisions:
 
                    <li>
 
                        <a href="${h.canonical_url('changeset_home', repo_name=org_repo_name, revision=revision)}">
 
                            ${h.shorter(desc, 80, firstline=True)}
 
                        </a>
 
                    </li>
 
                %endfor
 
            </ul>
 
<%include file="button.html" args="url=pr_url,title=_('View Pull Request'),padding_bottom=False"/>\
kallithea/templates/email_templates/pull_request.txt
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.txt"/>
 
<%block name="header">\
 
<% title = _('Mention on Pull Request %s "%s" by %s') % (pr_nice_id, pr_title, pr_user_created) if is_mention else _('Added as Reviewer of Pull Request %s "%s" by %s') % (pr_nice_id, pr_title, pr_user_created) %>\
 
<%include file="header.txt" args="title=title,link=pr_url"/>\
 
</%block>\
 

	
 
%if is_mention:
 
${_('%s mentioned you on %s pull request "%s"') % (pr_user_created, repo_name, pr_title)|n,unicode}
 
%else:
 
${_('%s requested your review of %s pull request "%s"') % (pr_user_created, repo_name, pr_title)|n,unicode}
 
%endif
 
${_('Pull request from')|n,unicode} \
 
${pr_source_repo|n,unicode} \
 
${_('at')|n,unicode} \
 
${pr_source_branch|n,unicode} \
 
${_('to')|n,unicode} \
 
${pr_target_repo|n,unicode} \
 
${_('at')|n,unicode} \
 
${pr_target_branch|n,unicode}:
 
${pr_nice_id|n,unicode} \
 
"${pr_title|n,unicode}" \
 
${_('by')|n,unicode} \
 
${pr_owner.full_name_and_username|n,unicode}.
 

	
 
${_('URL')|n,unicode}: ${pr_url|n,unicode}
 

	
 
${_('Description')|n,unicode}:
 

	
 
${body|n,unicode}
 

	
 

	
 
${_('Changesets')|n,unicode}:
 
%for r,r_msg in pr_revisions:
 
${h.short_id(r)|n,unicode}: ${h.canonical_url('changeset_home', repo_name=org_repo_name, revision=r)}
 
${h.shorter(r_msg, 256)|n,unicode}
 

	
 
%for revision, desc in pr_revisions:
 
${h.shorter(desc, 80, firstline=True)|n,unicode}
 
%endfor
 

	
 
<%include file="button.txt" args="url=pr_url,title='View Pull Request'"/>\
kallithea/templates/email_templates/pull_request_comment.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 

	
 
<p>${_('Comment from %s on %s pull request "%s"') % (pr_comment_user, repo_name, pr_title)}:</p>
 
<p>${body}</p>
 

	
 
%if status_change:
 
    %if closing_pr:
 
       <p>${_('The comment closed the pull request with status')}: <b>${status_change}</b></p>
 
    %else:
 
       <p>${_('The comment was made with status')}: <b>${status_change}</b></p>
 
    %endif
 
%endif
 

	
 
<p>${_('URL')}: <a href="${pr_comment_url}">${pr_comment_url}</a></p>
 
<%inherit file="main.html"/>\
 
\
 
<%block name="header">\
 
<% title = _('Mention in Comment on Pull Request %s "%s"') % (pr_nice_id, pr_title) if is_mention else _('Pull Request %s "%s" Closed') % (pr_nice_id, pr_title) if closing_pr else _('Comment on Pull Request %s "%s"') % (pr_nice_id, pr_title) %>\
 
<%include file="header.html" args="title=title,link=pr_comment_url"/>\
 
</%block>\
 
\
 
<%include file="comment.html" args="text=body,author=pr_comment_user,status=status_change,close=closing_pr"/>\
 
            <p>
 
                ${_('Pull request from')}
 
                <a href="${pr_source_repo}">${pr_source_repo}</a>
 
                ${_('at')}
 
                ${pr_source_branch}
 
                ${_('to')}
 
                <a href="${pr_target_repo}">${pr_target_repo}</a>
 
                ${_('at')}
 
                ${pr_target_branch}:
 
                <br/>
 
                <a href="${pr_url}">${pr_nice_id}</a>
 
                "${pr_title}"
 
                ${_('by')}
 
                ${pr_owner.full_name_and_username}.
 
            </p>
 
<%include file="button.html" args="url=pr_comment_url,title=_('View Comment'),padding_bottom=False"/>\
kallithea/templates/email_templates/pull_request_comment.txt
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.txt"/>
 
<%block name="header">\
 
<% title = _('Mention in Comment on Pull Request %s "%s"') % (pr_nice_id, pr_title) if is_mention else _('Pull Request %s "%s" Closed') % (pr_nice_id, pr_title) if closing_pr else _('Comment on Pull Request %s "%s"') % (pr_nice_id, pr_title) %>\
 
<%include file="header.txt" args="title=title,link=pr_comment_url"/>\
 
</%block>\
 

	
 
${_('Comment from %s on %s pull request "%s"') % (pr_comment_user, repo_name, pr_title)|n,unicode}:
 
${body|n,unicode}
 
<%include file="comment.txt" args="text=body,author=pr_comment_user,status=status_change,close=closing_pr"/>\
 

	
 
%if status_change:
 
    %if closing_pr:
 
${_('The comment closed the pull request with status')|n,unicode}: ${status_change|n,unicode}
 
    %else:
 
${_('The comment was made with status')|n,unicode}: ${status_change|n,unicode}
 
    %endif
 
%endif
 
${_('Pull request from')|n,unicode} \
 
${pr_source_repo|n,unicode} \
 
${_('at')|n,unicode} \
 
${pr_source_branch|n,unicode} \
 
${_('to')|n,unicode} \
 
${pr_target_repo|n,unicode} \
 
${_('at')|n,unicode} \
 
${pr_target_branch|n,unicode}:
 
${pr_nice_id|n,unicode} \
 
"${pr_title|n,unicode}" \
 
${_('by')|n,unicode} \
 
${pr_owner.full_name_and_username|n,unicode}.
 

	
 
${_('URL')|n,unicode}: ${pr_comment_url|n,unicode}
 
<%include file="button.txt" args="url=pr_comment_url,title=_('View Comment')"/>\
kallithea/templates/email_templates/registration.html
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 

	
 
${body}
 

	
 
${_('View this user here')}: <a href="${registered_user_url}">${registered_user_url}</a>
 
<%inherit file="main.html"/>\
 
\
 
<%block name="header">\
 
<%include file="header.html" args="title=_('New User Registration'),link=registered_user_url"/>\
 
</%block>\
 
\
 
        <p>
 
            ${_('Username')}:
 
            <br/>
 
            ${new_username}
 
        </p>
 
        <p>
 
            ${_('Full Name')}:
 
            <br/>
 
            ${new_full_name}
 
        </p>
 
        <p>
 
            ${_('Email')}:
 
            <br/>
 
            ${new_email}
 
        </p>
 
<%include file="button.html" args="url=registered_user_url,title=_('View User Profile'),padding_bottom=False"/>\
kallithea/templates/email_templates/registration.txt
Show inline comments
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.txt"/>
 
<%block name="header">\
 
<%include file="header.txt" args="title=_('New User Registration'),link=registered_user_url"/>\
 
</%block>\
 

	
 
${_('Username')|n,unicode}: ${new_username|n,unicode}
 

	
 
${body|n,unicode}
 
${_('Full Name')|n,unicode}: ${new_full_name|n,unicode}
 

	
 
${_('View this user here')|n,unicode}: ${registered_user_url|n,unicode}
 
${_('Email')|n,unicode}: ${new_email|n,unicode}
 

	
 
<%include file="button.txt" args="url=registered_user_url,title='View User Profile'"/>\
kallithea/tests/models/test_dump_html_mails.ref.html
Show inline comments
 
<!doctype html>
 
<html lang="en">
 
<head><title>Notifications</title><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"></head>
 
<body>
 
<hr/>
 
<h1>cs_comment, is_mention=False, status_change=None</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Comment] repo/name changeset cafe1234 "This changeset did something cl..." on brunch
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://comment.org
 

	
 
Comment on Changeset "This changeset did something clever which is hard to explain"
 

	
 
Comment from Opinionated User (jsmith) on repo_target changeset cafe1234c0ff:
 

	
 
Opinionated User (jsmith):
 

	
 
This is the new comment.
 

	
 
 - and here it ends indented.
 

	
 

	
 
URL: http://comment.org
 

	
 
Changeset: cafe1234c0ff
 
Description:
 
This changeset did something clever which is hard to explain
 
Changeset on repo_target branch brunch:
 
"This changeset did something clever which is hard to explain" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://comment.org
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo_target changeset cafe1234c0ff:</p>
 
<p><div class="formatted-fixed">This is the new comment.
 

	
 
 - and here it ends indented.</div></p>
 

	
 

	
 
<p>URL: <a href="http://comment.org">http://comment.org</a></p>
 
    <h1>
 
            <a href="http://comment.org"
 
               target="_blank">Comment on Changeset &#34;This changeset did something clever which is hard to explain&#34;</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">This is the new comment.
 

	
 
<p>Changeset: cafe1234c0ff</p>
 
<p>Description:<br/>
 
This changeset did something clever which is hard to explain
 
 - and here it ends indented.</div></div>
 
            <p>
 
                Changeset on
 
                <a href="repo_target">repo_target</a>
 
                branch
 
                brunch:
 
                <br/>
 
                "<a href="http://changeset.com">This changeset did something clever which is hard to explain</a>"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://comment.org" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>cs_comment, is_mention=True, status_change=None</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Comment] repo/name changeset cafe1234 "This changeset did something cl..." on brunch
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://comment.org
 

	
 
Mention in Comment on Changeset "This changeset did something clever which is hard to explain"
 

	
 
Comment from Opinionated User (jsmith) on repo_target changeset cafe1234c0ff mentioned you:
 

	
 
Opinionated User (jsmith):
 

	
 
This is the new comment.
 

	
 
 - and here it ends indented.
 

	
 

	
 
URL: http://comment.org
 

	
 
Changeset: cafe1234c0ff
 
Description:
 
This changeset did something clever which is hard to explain
 
Changeset on repo_target branch brunch:
 
"This changeset did something clever which is hard to explain" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://comment.org
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo_target changeset cafe1234c0ff mentioned you:</p>
 
<p><div class="formatted-fixed">This is the new comment.
 

	
 
 - and here it ends indented.</div></p>
 

	
 

	
 
<p>URL: <a href="http://comment.org">http://comment.org</a></p>
 
    <h1>
 
            <a href="http://comment.org"
 
               target="_blank">Mention in Comment on Changeset &#34;This changeset did something clever which is hard to explain&#34;</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">This is the new comment.
 

	
 
<p>Changeset: cafe1234c0ff</p>
 
<p>Description:<br/>
 
This changeset did something clever which is hard to explain
 
 - and here it ends indented.</div></div>
 
            <p>
 
                Changeset on
 
                <a href="repo_target">repo_target</a>
 
                branch
 
                brunch:
 
                <br/>
 
                "<a href="http://changeset.com">This changeset did something clever which is hard to explain</a>"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://comment.org" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>cs_comment, is_mention=False, status_change='Approved'</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Approved: Comment] repo/name changeset cafe1234 "This changeset did something cl..." on brunch
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://comment.org
 

	
 
Comment on Changeset "This changeset did something clever which is hard to explain"
 

	
 

	
 
Comment from Opinionated User (jsmith) on repo_target changeset cafe1234c0ff:
 
Opinionated User (jsmith):
 

	
 
Status change: Approved
 

	
 
This is the new comment.
 

	
 
 - and here it ends indented.
 

	
 
The changeset status was changed to: Approved
 

	
 
URL: http://comment.org
 

	
 
Changeset: cafe1234c0ff
 
Description:
 
This changeset did something clever which is hard to explain
 
Changeset on repo_target branch brunch:
 
"This changeset did something clever which is hard to explain" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://comment.org
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo_target changeset cafe1234c0ff:</p>
 
<p><div class="formatted-fixed">This is the new comment.
 

	
 
 - and here it ends indented.</div></p>
 

	
 
    <p>The changeset status was changed to: <b>Approved</b></p>
 
    <h1>
 
            <a href="http://comment.org"
 
               target="_blank">Comment on Changeset &#34;This changeset did something clever which is hard to explain&#34;</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                    <p>
 
                        Status change:
 
                        Approved
 
                    </p>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">This is the new comment.
 

	
 
<p>URL: <a href="http://comment.org">http://comment.org</a></p>
 

	
 
<p>Changeset: cafe1234c0ff</p>
 
<p>Description:<br/>
 
This changeset did something clever which is hard to explain
 
 - and here it ends indented.</div></div>
 
            <p>
 
                Changeset on
 
                <a href="repo_target">repo_target</a>
 
                branch
 
                brunch:
 
                <br/>
 
                "<a href="http://changeset.com">This changeset did something clever which is hard to explain</a>"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://comment.org" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>cs_comment, is_mention=True, status_change='Approved'</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Approved: Comment] repo/name changeset cafe1234 "This changeset did something cl..." on brunch
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://comment.org
 

	
 
Mention in Comment on Changeset "This changeset did something clever which is hard to explain"
 

	
 

	
 
Comment from Opinionated User (jsmith) on repo_target changeset cafe1234c0ff mentioned you:
 
Opinionated User (jsmith):
 

	
 
Status change: Approved
 

	
 
This is the new comment.
 

	
 
 - and here it ends indented.
 

	
 
The changeset status was changed to: Approved
 

	
 
URL: http://comment.org
 

	
 
Changeset: cafe1234c0ff
 
Description:
 
This changeset did something clever which is hard to explain
 
Changeset on repo_target branch brunch:
 
"This changeset did something clever which is hard to explain" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://comment.org
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo_target changeset cafe1234c0ff mentioned you:</p>
 
<p><div class="formatted-fixed">This is the new comment.
 

	
 
 - and here it ends indented.</div></p>
 

	
 
    <p>The changeset status was changed to: <b>Approved</b></p>
 
    <h1>
 
            <a href="http://comment.org"
 
               target="_blank">Mention in Comment on Changeset &#34;This changeset did something clever which is hard to explain&#34;</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                    <p>
 
                        Status change:
 
                        Approved
 
                    </p>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">This is the new comment.
 

	
 
<p>URL: <a href="http://comment.org">http://comment.org</a></p>
 

	
 
<p>Changeset: cafe1234c0ff</p>
 
<p>Description:<br/>
 
This changeset did something clever which is hard to explain
 
 - and here it ends indented.</div></div>
 
            <p>
 
                Changeset on
 
                <a href="repo_target">repo_target</a>
 
                branch
 
                brunch:
 
                <br/>
 
                "<a href="http://changeset.com">This changeset did something clever which is hard to explain</a>"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://comment.org" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>message</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: Test Message
 
</pre>
 
<hr/>
 
<pre>
 

	
 
This is the body of the test message
 
 - nothing interesting here except indentation.
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
</pre>
 
<pre>This is the body of the test message
 
 - nothing interesting here except indentation.</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<div class="formatted-fixed">This is the body of the test message
 
 - nothing interesting here except indentation.</div>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
    <h1>
 
            Message
 
    </h1>
 
        <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">This is the body of the test message
 
 - nothing interesting here except indentation.</div></div>
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>registration</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: New user newbie registered
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://newbie.org
 

	
 
Registration body
 

	
 
View this user here: http://newbie.org
 
New User Registration
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
Username: newbie
 

	
 
Full Name: New Full Name
 

	
 
Email: new@email.com
 

	
 

	
 
View User Profile: http://newbie.org
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<div class="formatted-fixed">Registration body</div>
 

	
 
View this user here: <a href="http://newbie.org">http://newbie.org</a>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
    <h1>
 
            <a href="http://newbie.org"
 
               target="_blank">New User Registration</a>
 
    </h1>
 
        <p>
 
            Username:
 
            <br/>
 
            newbie
 
        </p>
 
        <p>
 
            Full Name:
 
            <br/>
 
            New Full Name
 
        </p>
 
        <p>
 
            Email:
 
            <br/>
 
            new@email.com
 
        </p>
 
<p>
 
            <a href="http://newbie.org" target="_blank">
 
                        View User Profile
 
            </a>
 
</p>
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>pull_request, is_mention=False</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Review] repo/name PR #7 "The Title" from devbranch by u2
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://pr.org/7
 

	
 
Added as Reviewer of Pull Request #7 "The Title" by Requesting User (root)
 

	
 
Requesting User (root) requested your review of repo/name pull request "The Title"
 

	
 
URL: http://pr.org/7
 
Pull request from https://dev.org/repo at devbranch to http://mainline.com/repo at trunk:
 
#7 "The Title" by u2 u3 (u2).
 

	
 

	
 
Description:
 

	
 
This PR is awesome because it does stuff
 
 - please approve indented!
 

	
 
Changesets:
 
123abc123abc: http://changeset_home/?repo_name=repo_org&amp;revision=123abc123abc123abc123abc123abc123abc123abc
 
Introduce one and two
 

	
 
and that's it
 
Changesets:
 

	
 
567fed567fed: http://changeset_home/?repo_name=repo_org&amp;revision=567fed567fed567fed567fed567fed567fed567fed
 
Introduce one and two
 
Make one plus two equal tree
 

	
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Pull Request: http://pr.org/7
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Requesting User (root) requested your review of repo/name pull request &#34;The Title&#34;</p>
 

	
 
<p>URL: <a href="http://pr.org/7">http://pr.org/7</a></p>
 

	
 
<p>Description:</p>
 
<p style="white-space: pre-wrap; font-family: monospace"><div class="formatted-fixed">This PR is awesome because it does stuff
 
 - please approve indented!</div></p>
 

	
 
<p>Changesets:</p>
 
<p style="white-space: pre-wrap">
 
<i><a href="http://changeset_home/?repo_name=repo_org&amp;revision=123abc123abc123abc123abc123abc123abc123abc">123abc123abc</a></i>:
 
Introduce one and two
 

	
 
and that&#39;s it
 

	
 
<i><a href="http://changeset_home/?repo_name=repo_org&amp;revision=567fed567fed567fed567fed567fed567fed567fed">567fed567fed</a></i>:
 
Make one plus two equal tree
 

	
 
    <h1>
 
            <a href="http://pr.org/7"
 
               target="_blank">Added as Reviewer of Pull Request #7 &#34;The Title&#34; by Requesting User (root)</a>
 
    </h1>
 
            <p>
 
                Pull request from
 
                <a href="https://dev.org/repo">https://dev.org/repo</a>
 
                at
 
                devbranch
 
                to
 
                <a href="http://mainline.com/repo">http://mainline.com/repo</a>
 
                at
 
                trunk:
 
                <br/>
 
                <a href="http://pr.org/7">#7</a>
 
                "The Title"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
            <p>
 
                Description:
 
            </p>
 
            <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">This PR is awesome because it does stuff
 
 - please approve indented!</div></div>
 
            <p>Changesets:</p>
 
            <ul>
 
                    <li>
 
                        <a href="http://changeset_home/?repo_name=repo_org&amp;revision=123abc123abc123abc123abc123abc123abc123abc">
 
                            Introduce one and two
 
                        </a>
 
                    </li>
 
                    <li>
 
                        <a href="http://changeset_home/?repo_name=repo_org&amp;revision=567fed567fed567fed567fed567fed567fed567fed">
 
                            Make one plus two equal tree
 
                        </a>
 
                    </li>
 
            </ul>
 
<p>
 
            <a href="http://pr.org/7" target="_blank">
 
                        View Pull Request
 
            </a>
 
</p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>pull_request, is_mention=True</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Review] repo/name PR #7 "The Title" from devbranch by u2
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://pr.org/7
 

	
 
Mention on Pull Request #7 "The Title" by Requesting User (root)
 

	
 
Requesting User (root) mentioned you on repo/name pull request "The Title"
 

	
 
URL: http://pr.org/7
 
Pull request from https://dev.org/repo at devbranch to http://mainline.com/repo at trunk:
 
#7 "The Title" by u2 u3 (u2).
 

	
 

	
 
Description:
 

	
 
This PR is awesome because it does stuff
 
 - please approve indented!
 

	
 
Changesets:
 
123abc123abc: http://changeset_home/?repo_name=repo_org&amp;revision=123abc123abc123abc123abc123abc123abc123abc
 
Introduce one and two
 

	
 
and that's it
 
Changesets:
 

	
 
567fed567fed: http://changeset_home/?repo_name=repo_org&amp;revision=567fed567fed567fed567fed567fed567fed567fed
 
Introduce one and two
 
Make one plus two equal tree
 

	
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Pull Request: http://pr.org/7
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Requesting User (root) mentioned you on repo/name pull request &#34;The Title&#34;</p>
 

	
 
<p>URL: <a href="http://pr.org/7">http://pr.org/7</a></p>
 

	
 
<p>Description:</p>
 
<p style="white-space: pre-wrap; font-family: monospace"><div class="formatted-fixed">This PR is awesome because it does stuff
 
 - please approve indented!</div></p>
 

	
 
<p>Changesets:</p>
 
<p style="white-space: pre-wrap">
 
<i><a href="http://changeset_home/?repo_name=repo_org&amp;revision=123abc123abc123abc123abc123abc123abc123abc">123abc123abc</a></i>:
 
Introduce one and two
 

	
 
and that&#39;s it
 

	
 
<i><a href="http://changeset_home/?repo_name=repo_org&amp;revision=567fed567fed567fed567fed567fed567fed567fed">567fed567fed</a></i>:
 
Make one plus two equal tree
 

	
 
    <h1>
 
            <a href="http://pr.org/7"
 
               target="_blank">Mention on Pull Request #7 &#34;The Title&#34; by Requesting User (root)</a>
 
    </h1>
 
            <p>
 
                Pull request from
 
                <a href="https://dev.org/repo">https://dev.org/repo</a>
 
                at
 
                devbranch
 
                to
 
                <a href="http://mainline.com/repo">http://mainline.com/repo</a>
 
                at
 
                trunk:
 
                <br/>
 
                <a href="http://pr.org/7">#7</a>
 
                "The Title"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
            <p>
 
                Description:
 
            </p>
 
            <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">This PR is awesome because it does stuff
 
 - please approve indented!</div></div>
 
            <p>Changesets:</p>
 
            <ul>
 
                    <li>
 
                        <a href="http://changeset_home/?repo_name=repo_org&amp;revision=123abc123abc123abc123abc123abc123abc123abc">
 
                            Introduce one and two
 
                        </a>
 
                    </li>
 
                    <li>
 
                        <a href="http://changeset_home/?repo_name=repo_org&amp;revision=567fed567fed567fed567fed567fed567fed567fed">
 
                            Make one plus two equal tree
 
                        </a>
 
                    </li>
 
            </ul>
 
<p>
 
            <a href="http://pr.org/7" target="_blank">
 
                        View Pull Request
 
            </a>
 
</p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>pull_request_comment, is_mention=False, status_change=None, closing_pr=False</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Comment] repo/name PR #7 "The Title" from devbranch by u2
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://pr.org/comment
 

	
 
Comment on Pull Request #7 "The Title"
 

	
 
Comment from Opinionated User (jsmith) on repo/name pull request "The Title":
 

	
 
Opinionated User (jsmith):
 

	
 
Me too!
 

	
 
 - and indented on second line
 

	
 

	
 
URL: http://pr.org/comment
 
Pull request from https://dev.org/repo at devbranch to http://mainline.com/repo at trunk:
 
#7 "The Title" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://pr.org/comment
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo/name pull request &#34;The Title&#34;:</p>
 
<p><div class="formatted-fixed">Me too!
 

	
 
 - and indented on second line</div></p>
 
    <h1>
 
            <a href="http://pr.org/comment"
 
               target="_blank">Comment on Pull Request #7 &#34;The Title&#34;</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">Me too!
 

	
 

	
 
<p>URL: <a href="http://pr.org/comment">http://pr.org/comment</a></p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
 - and indented on second line</div></div>
 
            <p>
 
                Pull request from
 
                <a href="https://dev.org/repo">https://dev.org/repo</a>
 
                at
 
                devbranch
 
                to
 
                <a href="http://mainline.com/repo">http://mainline.com/repo</a>
 
                at
 
                trunk:
 
                <br/>
 
                <a href="http://pr.org/7">#7</a>
 
                "The Title"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://pr.org/comment" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>pull_request_comment, is_mention=True, status_change=None, closing_pr=False</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Comment] repo/name PR #7 "The Title" from devbranch by u2
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://pr.org/comment
 

	
 
Mention in Comment on Pull Request #7 "The Title"
 

	
 
Comment from Opinionated User (jsmith) on repo/name pull request "The Title":
 

	
 
Opinionated User (jsmith):
 

	
 
Me too!
 

	
 
 - and indented on second line
 

	
 

	
 
URL: http://pr.org/comment
 
Pull request from https://dev.org/repo at devbranch to http://mainline.com/repo at trunk:
 
#7 "The Title" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://pr.org/comment
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo/name pull request &#34;The Title&#34;:</p>
 
<p><div class="formatted-fixed">Me too!
 

	
 
 - and indented on second line</div></p>
 
    <h1>
 
            <a href="http://pr.org/comment"
 
               target="_blank">Mention in Comment on Pull Request #7 &#34;The Title&#34;</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">Me too!
 

	
 

	
 
<p>URL: <a href="http://pr.org/comment">http://pr.org/comment</a></p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
 - and indented on second line</div></div>
 
            <p>
 
                Pull request from
 
                <a href="https://dev.org/repo">https://dev.org/repo</a>
 
                at
 
                devbranch
 
                to
 
                <a href="http://mainline.com/repo">http://mainline.com/repo</a>
 
                at
 
                trunk:
 
                <br/>
 
                <a href="http://pr.org/7">#7</a>
 
                "The Title"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://pr.org/comment" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>pull_request_comment, is_mention=False, status_change='Under Review', closing_pr=False</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Under Review: Comment] repo/name PR #7 "The Title" from devbranch by u2
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://pr.org/comment
 

	
 
Comment on Pull Request #7 "The Title"
 

	
 

	
 
Comment from Opinionated User (jsmith) on repo/name pull request "The Title":
 
Opinionated User (jsmith):
 

	
 
Status change: Under Review
 

	
 
Me too!
 

	
 
 - and indented on second line
 

	
 
The comment was made with status: Under Review
 

	
 
URL: http://pr.org/comment
 
Pull request from https://dev.org/repo at devbranch to http://mainline.com/repo at trunk:
 
#7 "The Title" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://pr.org/comment
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo/name pull request &#34;The Title&#34;:</p>
 
<p><div class="formatted-fixed">Me too!
 

	
 
 - and indented on second line</div></p>
 
    <h1>
 
            <a href="http://pr.org/comment"
 
               target="_blank">Comment on Pull Request #7 &#34;The Title&#34;</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                    <p>
 
                        Status change:
 
                        Under Review
 
                    </p>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">Me too!
 

	
 
       <p>The comment was made with status: <b>Under Review</b></p>
 

	
 
<p>URL: <a href="http://pr.org/comment">http://pr.org/comment</a></p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
 - and indented on second line</div></div>
 
            <p>
 
                Pull request from
 
                <a href="https://dev.org/repo">https://dev.org/repo</a>
 
                at
 
                devbranch
 
                to
 
                <a href="http://mainline.com/repo">http://mainline.com/repo</a>
 
                at
 
                trunk:
 
                <br/>
 
                <a href="http://pr.org/7">#7</a>
 
                "The Title"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://pr.org/comment" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>pull_request_comment, is_mention=True, status_change='Under Review', closing_pr=False</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Under Review: Comment] repo/name PR #7 "The Title" from devbranch by u2
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://pr.org/comment
 

	
 
Mention in Comment on Pull Request #7 "The Title"
 

	
 

	
 
Comment from Opinionated User (jsmith) on repo/name pull request "The Title":
 
Opinionated User (jsmith):
 

	
 
Status change: Under Review
 

	
 
Me too!
 

	
 
 - and indented on second line
 

	
 
The comment was made with status: Under Review
 

	
 
URL: http://pr.org/comment
 
Pull request from https://dev.org/repo at devbranch to http://mainline.com/repo at trunk:
 
#7 "The Title" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://pr.org/comment
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo/name pull request &#34;The Title&#34;:</p>
 
<p><div class="formatted-fixed">Me too!
 

	
 
 - and indented on second line</div></p>
 
    <h1>
 
            <a href="http://pr.org/comment"
 
               target="_blank">Mention in Comment on Pull Request #7 &#34;The Title&#34;</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                    <p>
 
                        Status change:
 
                        Under Review
 
                    </p>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">Me too!
 

	
 
       <p>The comment was made with status: <b>Under Review</b></p>
 

	
 
<p>URL: <a href="http://pr.org/comment">http://pr.org/comment</a></p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
 - and indented on second line</div></div>
 
            <p>
 
                Pull request from
 
                <a href="https://dev.org/repo">https://dev.org/repo</a>
 
                at
 
                devbranch
 
                to
 
                <a href="http://mainline.com/repo">http://mainline.com/repo</a>
 
                at
 
                trunk:
 
                <br/>
 
                <a href="http://pr.org/7">#7</a>
 
                "The Title"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://pr.org/comment" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>pull_request_comment, is_mention=False, status_change=None, closing_pr=True</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Closing: Comment] repo/name PR #7 "The Title" from devbranch by u2
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://pr.org/comment
 

	
 
Pull Request #7 "The Title" Closed
 

	
 

	
 
Comment from Opinionated User (jsmith) on repo/name pull request "The Title":
 
Opinionated User (jsmith):
 

	
 
The pull request has been closed.
 

	
 
Me too!
 

	
 
 - and indented on second line
 

	
 

	
 
URL: http://pr.org/comment
 
Pull request from https://dev.org/repo at devbranch to http://mainline.com/repo at trunk:
 
#7 "The Title" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://pr.org/comment
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo/name pull request &#34;The Title&#34;:</p>
 
<p><div class="formatted-fixed">Me too!
 

	
 
 - and indented on second line</div></p>
 
    <h1>
 
            <a href="http://pr.org/comment"
 
               target="_blank">Pull Request #7 &#34;The Title&#34; Closed</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                    <p>
 
                        The pull request has been closed.
 
                    </p>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">Me too!
 

	
 

	
 
<p>URL: <a href="http://pr.org/comment">http://pr.org/comment</a></p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
 - and indented on second line</div></div>
 
            <p>
 
                Pull request from
 
                <a href="https://dev.org/repo">https://dev.org/repo</a>
 
                at
 
                devbranch
 
                to
 
                <a href="http://mainline.com/repo">http://mainline.com/repo</a>
 
                at
 
                trunk:
 
                <br/>
 
                <a href="http://pr.org/7">#7</a>
 
                "The Title"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://pr.org/comment" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>pull_request_comment, is_mention=True, status_change=None, closing_pr=True</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Closing: Comment] repo/name PR #7 "The Title" from devbranch by u2
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://pr.org/comment
 

	
 
Mention in Comment on Pull Request #7 "The Title"
 

	
 

	
 
Comment from Opinionated User (jsmith) on repo/name pull request "The Title":
 
Opinionated User (jsmith):
 

	
 
The pull request has been closed.
 

	
 
Me too!
 

	
 
 - and indented on second line
 

	
 

	
 
URL: http://pr.org/comment
 
Pull request from https://dev.org/repo at devbranch to http://mainline.com/repo at trunk:
 
#7 "The Title" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://pr.org/comment
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo/name pull request &#34;The Title&#34;:</p>
 
<p><div class="formatted-fixed">Me too!
 

	
 
 - and indented on second line</div></p>
 
    <h1>
 
            <a href="http://pr.org/comment"
 
               target="_blank">Mention in Comment on Pull Request #7 &#34;The Title&#34;</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                    <p>
 
                        The pull request has been closed.
 
                    </p>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">Me too!
 

	
 

	
 
<p>URL: <a href="http://pr.org/comment">http://pr.org/comment</a></p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
 - and indented on second line</div></div>
 
            <p>
 
                Pull request from
 
                <a href="https://dev.org/repo">https://dev.org/repo</a>
 
                at
 
                devbranch
 
                to
 
                <a href="http://mainline.com/repo">http://mainline.com/repo</a>
 
                at
 
                trunk:
 
                <br/>
 
                <a href="http://pr.org/7">#7</a>
 
                "The Title"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://pr.org/comment" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>pull_request_comment, is_mention=False, status_change='Under Review', closing_pr=True</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Under Review, Closing: Comment] repo/name PR #7 "The Title" from devbranch by u2
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://pr.org/comment
 

	
 
Pull Request #7 "The Title" Closed
 

	
 

	
 
Comment from Opinionated User (jsmith) on repo/name pull request "The Title":
 
Opinionated User (jsmith):
 

	
 
Status change: Under Review
 

	
 
The pull request has been closed.
 

	
 
Me too!
 

	
 
 - and indented on second line
 

	
 
The comment closed the pull request with status: Under Review
 

	
 
URL: http://pr.org/comment
 
Pull request from https://dev.org/repo at devbranch to http://mainline.com/repo at trunk:
 
#7 "The Title" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://pr.org/comment
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo/name pull request &#34;The Title&#34;:</p>
 
<p><div class="formatted-fixed">Me too!
 

	
 
 - and indented on second line</div></p>
 
    <h1>
 
            <a href="http://pr.org/comment"
 
               target="_blank">Pull Request #7 &#34;The Title&#34; Closed</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                    <p>
 
                        Status change:
 
                        Under Review
 
                    </p>
 
                    <p>
 
                        The pull request has been closed.
 
                    </p>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">Me too!
 

	
 
       <p>The comment closed the pull request with status: <b>Under Review</b></p>
 

	
 
<p>URL: <a href="http://pr.org/comment">http://pr.org/comment</a></p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
 - and indented on second line</div></div>
 
            <p>
 
                Pull request from
 
                <a href="https://dev.org/repo">https://dev.org/repo</a>
 
                at
 
                devbranch
 
                to
 
                <a href="http://mainline.com/repo">http://mainline.com/repo</a>
 
                at
 
                trunk:
 
                <br/>
 
                <a href="http://pr.org/7">#7</a>
 
                "The Title"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://pr.org/comment" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>pull_request_comment, is_mention=True, status_change='Under Review', closing_pr=True</h1>
 
<pre>
 
From: u1
 
To: u2@example.com
 
Subject: [Under Review, Closing: Comment] repo/name PR #7 "The Title" from devbranch by u2
 
</pre>
 
<hr/>
 
<pre>
 
<pre>http://pr.org/comment
 

	
 
Mention in Comment on Pull Request #7 "The Title"
 

	
 

	
 
Comment from Opinionated User (jsmith) on repo/name pull request "The Title":
 
Opinionated User (jsmith):
 

	
 
Status change: Under Review
 

	
 
The pull request has been closed.
 

	
 
Me too!
 

	
 
 - and indented on second line
 

	
 
The comment closed the pull request with status: Under Review
 

	
 
URL: http://pr.org/comment
 
Pull request from https://dev.org/repo at devbranch to http://mainline.com/repo at trunk:
 
#7 "The Title" by u2 u3 (u2).
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
View Comment: http://pr.org/comment
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<p>Comment from Opinionated User (jsmith) on repo/name pull request &#34;The Title&#34;:</p>
 
<p><div class="formatted-fixed">Me too!
 

	
 
 - and indented on second line</div></p>
 
    <h1>
 
            <a href="http://pr.org/comment"
 
               target="_blank">Mention in Comment on Pull Request #7 &#34;The Title&#34;</a>
 
    </h1>
 
            <h2>Opinionated User (jsmith)</h2>
 
                    <p>
 
                        Status change:
 
                        Under Review
 
                    </p>
 
                    <p>
 
                        The pull request has been closed.
 
                    </p>
 
                <div style="font-family:monospace;white-space:pre-wrap"><div class="formatted-fixed">Me too!
 

	
 
       <p>The comment closed the pull request with status: <b>Under Review</b></p>
 

	
 
<p>URL: <a href="http://pr.org/comment">http://pr.org/comment</a></p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
 - and indented on second line</div></div>
 
            <p>
 
                Pull request from
 
                <a href="https://dev.org/repo">https://dev.org/repo</a>
 
                at
 
                devbranch
 
                to
 
                <a href="http://mainline.com/repo">http://mainline.com/repo</a>
 
                at
 
                trunk:
 
                <br/>
 
                <a href="http://pr.org/7">#7</a>
 
                "The Title"
 
                by
 
                u2 u3 (u2).
 
            </p>
 
<p>
 
            <a href="http://pr.org/comment" target="_blank">
 
                        View Comment
 
            </a>
 
</p>
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 
<hr/>
 
<h1>TYPE_PASSWORD_RESET</h1>
 
<pre>
 
From: u1
 
To: john@doe.com
 
Subject: Password reset link
 
</pre>
 
<hr/>
 
<pre>
 
<pre>Password Reset Request
 

	
 
Hello John Doe
 
Hello John Doe,
 

	
 
We have received a request to reset the password for your account.
 

	
 
To set a new password, click the following link:
 

	
 
http://reset.com/decbf64715098db5b0bd23eab44bd792670ab746
 

	
 
Should you not be able to use the link above, please type the following code into the password reset form: decbf64715098db5b0bd23eab44bd792670ab746
 
Should you not be able to use the link above, please type the following code into the password reset form:
 
decbf64715098db5b0bd23eab44bd792670ab746
 

	
 
If it weren't you who requested the password reset, just disregard this message.
 

	
 

	
 
-- 
 
This is an automatic notification. Don't reply to this mail.
 
</pre>
 
<hr/>
 
<!--!doctype html-->
 
<!--html lang="en"-->
 
<!--head-->
 
    <!--title--><!--/title-->
 
    <!--meta name="viewport" content="width=device-width"-->
 
    <!--meta http-equiv="Content-Type" content="text/html; charset=UTF-8"-->
 
<!--/head-->
 
<!--body-->
 

	
 

	
 
<h4>Hello John Doe</h4>
 

	
 
<p>We have received a request to reset the password for your account.</p>
 
<p>To set a new password, click the following link:</p>
 
<p><a href="http://reset.com/decbf64715098db5b0bd23eab44bd792670ab746">http://reset.com/decbf64715098db5b0bd23eab44bd792670ab746</a></p>
 
    <h1>
 
            Password Reset Request
 
    </h1>
 
            <h2>Hello John Doe,</h2>
 
            <p>
 
                We have received a request to reset the password for your account.
 
            </p>
 
            <p>
 

	
 
<p>Should you not be able to use the link above, please type the following code into the password reset form: <code>decbf64715098db5b0bd23eab44bd792670ab746</code></p>
 

	
 
<p>If it weren&#39;t you who requested the password reset, just disregard this message.</p>
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
This is an automatic notification. Don&#39;t reply to this mail.
 
                    To set a new password, click the following link:
 
                    <br/>
 
                    <a href="http://reset.com/decbf64715098db5b0bd23eab44bd792670ab746"
 
                        target="_blank">http://reset.com/decbf64715098db5b0bd23eab44bd792670ab746</a>
 
                    <br/>
 
                    Should you not be able to use the link above, please type the following code into the password reset form:
 
                    <code>decbf64715098db5b0bd23eab44bd792670ab746</code>
 
            <p>
 
                If it weren&#39;t you who requested the password reset, just disregard this message.
 
            </p>
 
<!--/body-->
 
<!--/html-->
 
<hr/>
 

	
 
</body>
 
</html>
kallithea/tests/models/test_notifications.py
Show inline comments
 
import os
 
import re
 

	
 
import mock
 
import routes.util
 

	
 
from kallithea.tests import *
 
from kallithea.lib import helpers as h
 
from kallithea.model.db import User, Notification, UserNotification
 
from kallithea.model.user import UserModel
 
from kallithea.model.meta import Session
 
from kallithea.model.notification import NotificationModel, EmailNotificationModel
 

	
 
import kallithea.lib.celerylib
 
import kallithea.lib.celerylib.tasks
 

	
 

	
 
class TestNotifications(TestController):
 

	
 
    def setup_method(self, method):
 
        Session.remove()
 
        u1 = UserModel().create_or_update(username=u'u1',
 
                                        password=u'qweqwe',
 
                                        email=u'u1@example.com',
 
                                        firstname=u'u1', lastname=u'u1')
 
        Session().commit()
 
        self.u1 = u1.user_id
 

	
 
        u2 = UserModel().create_or_update(username=u'u2',
 
                                        password=u'qweqwe',
 
                                        email=u'u2@example.com',
 
                                        firstname=u'u2', lastname=u'u3')
 
        Session().commit()
 
        self.u2 = u2.user_id
 

	
 
        u3 = UserModel().create_or_update(username=u'u3',
 
                                        password=u'qweqwe',
 
                                        email=u'u3@example.com',
 
                                        firstname=u'u3', lastname=u'u3')
 
        Session().commit()
 
        self.u3 = u3.user_id
 

	
 
        self.remove_all_notifications()
 
        assert [] == Notification.query().all()
 
        assert [] == UserNotification.query().all()
 

	
 
    def test_create_notification(self):
 
        usrs = [self.u1, self.u2]
 
        def send_email(recipients, subject, body='', html_body='', headers=None, author=None):
 
            assert recipients == ['u2@example.com']
 
            assert subject == 'Test Message'
 
            assert body == "\n\nhi there\n\n\n-- \nThis is an automatic notification. Don't reply to this mail.\n"
 
            assert body == u"hi there"
 
            assert '>hi there<' in html_body
 
            assert author.username == 'u1'
 
        with mock.patch.object(kallithea.lib.celerylib.tasks, 'send_email', send_email):
 
            notification = NotificationModel().create(created_by=self.u1,
 
                                               subject=u'subj', body=u'hi there',
 
                                               recipients=usrs)
 
        Session().commit()
 
        u1 = User.get(self.u1)
 
        u2 = User.get(self.u2)
 
        u3 = User.get(self.u3)
 
        notifications = Notification.query().all()
 
        assert len(notifications) == 1
 

	
 
        assert notifications[0].recipients == [u1, u2]
 
        assert notification.notification_id == notifications[0].notification_id
 

	
 
        unotification = UserNotification.query() \
 
            .filter(UserNotification.notification == notification).all()
 

	
 
        assert len(unotification) == len(usrs)
 
        assert set([x.user.user_id for x in unotification]) == set(usrs)
 

	
 
    def test_user_notifications(self):
 
        notification1 = NotificationModel().create(created_by=self.u1,
 
                                            subject=u'subj', body=u'hi there1',
 
                                            recipients=[self.u3])
 
        Session().commit()
 
        notification2 = NotificationModel().create(created_by=self.u1,
 
                                            subject=u'subj', body=u'hi there2',
 
                                            recipients=[self.u3])
 
        Session().commit()
 
        u3 = Session().query(User).get(self.u3)
 

	
 
        assert sorted([x.notification for x in u3.notifications]) == sorted([notification2, notification1])
 

	
 
    def test_delete_notifications(self):
 
        notification = NotificationModel().create(created_by=self.u1,
 
                                           subject=u'title', body=u'hi there3',
 
                                    recipients=[self.u3, self.u1, self.u2])
 
        Session().commit()
 
        notifications = Notification.query().all()
 
        assert notification in notifications
 

	
 
        Notification.delete(notification.notification_id)
 
        Session().commit()
 

	
 
        notifications = Notification.query().all()
 
        assert not notification in notifications
 

	
 
        un = UserNotification.query().filter(UserNotification.notification
 
                                             == notification).all()
 
        assert un == []
 

	
 
    def test_delete_association(self):
 
        notification = NotificationModel().create(created_by=self.u1,
 
                                           subject=u'title', body=u'hi there3',
 
                                    recipients=[self.u3, self.u1, self.u2])
 
        Session().commit()
 

	
 
        unotification = UserNotification.query() \
 
                            .filter(UserNotification.notification ==
 
                                    notification) \
 
                            .filter(UserNotification.user_id == self.u3) \
 
                            .scalar()
 

	
 
        assert unotification.user_id == self.u3
 

	
 
        NotificationModel().delete(self.u3,
 
                                   notification.notification_id)
 
        Session().commit()
 

	
 
        u3notification = UserNotification.query() \
 
                            .filter(UserNotification.notification ==
 
                                    notification) \
 
                            .filter(UserNotification.user_id == self.u3) \
 
                            .scalar()
 

	
 
        assert u3notification == None
 

	
 
        # notification object is still there
 
        assert Notification.query().all() == [notification]
 

	
 
        #u1 and u2 still have assignments
 
        u1notification = UserNotification.query() \
 
                            .filter(UserNotification.notification ==
 
                                    notification) \
 
                            .filter(UserNotification.user_id == self.u1) \
 
                            .scalar()
 
        assert u1notification != None
 
        u2notification = UserNotification.query() \
 
                            .filter(UserNotification.notification ==
 
                                    notification) \
 
                            .filter(UserNotification.user_id == self.u2) \
 
                            .scalar()
 
        assert u2notification != None
 

	
scripts/whitespacecleanup.sh
Show inline comments
 
#!/bin/bash -x
 

	
 
# Enforce some consistency in whitespace - just to avoid spurious whitespaces changes
 

	
 
files=`hg loc '*.py' '*.html' '*.css' '*.rst' '*.txt' '*.js' '*.ini' '*.cfg' CONTRIBUTORS LICENSE.md | egrep -v '/lockfiles.py|LICENSE-MERGELY.html|/codemirror/|/fontello/|(graph|mergely|native.history|select2/select2|yui.flot|yui.2.9|jquery.dataTables)\.js$|test_dump_html_mails.ref.html'`
 
files=`hg loc '*.py' '*.html' '*.css' '*.rst' '*.txt' '*.js' '*.ini' '*.cfg' CONTRIBUTORS LICENSE.md | egrep -v '/lockfiles.py|LICENSE-MERGELY.html|/codemirror/|/fontello/|(graph|mergely|native.history|select2/select2|yui.flot|yui.2.9|jquery.dataTables)\.js$|/email_templates/|/test_dump_html_mails.ref.html'`
 

	
 
sed -i -e "s,`printf '\t'`,    ,g" $files
 
sed -i -e "s,  *$,,g" $files
 
sed -i -e 's,\([^ ]\)\\$,\1 \\,g' -e 's,\(["'"'"']["'"'"']["'"'"']\) \\$,\1\\,g' $files
 
# ensure one trailing newline - remove empty last line and make last line include trailing newline:
 
sed -i -e '$,${/^$/d}' -e '$a\' $files
 

	
 
sed -i -e 's,\([^ /]\){,\1 {,g' `hg loc '*.css'`
 
sed -i -e 's|^\([^ /].*,\)\([^ ]\)|\1 \2|g' `hg loc '*.css'`
 

	
 
sed -i -e 's/^\(    [^: ]*\) *: *\([^/]\)/\1: \2/g' kallithea/public/css/{style,contextbar}.css
 
sed -i -e '1s|, |,|g' kallithea/public/css/{style,contextbar}.css
 
sed -i -e 's/^\([^ ,/]\+ [^,]*[^ ,]\) *, *\(.\)/\1,\n\2/g' kallithea/public/css/{style,contextbar}.css
 
sed -i -e 's/^\([^ ,/].*\)   */\1 /g' kallithea/public/css/{style,contextbar}.css
 
sed -i -e 's,^--$,-- ,g' kallithea/templates/email_templates/main.txt
 
sed -i -e 's,[ 	][ 	]*$,,g' -e 's, 	,	,g' kallithea/public/js/graph.js
 

	
 
hg mani | xargs chmod -x
 
hg loc 'set:!binary()&grep("^#!")&!(**_tmpl.py)&!(**/template**)' | xargs chmod +x
 

	
 
hg diff
0 comments (0 inline, 0 general)