Changeset - 3397e3457f9c
[Not reviewed]
default
0 4 7
Andrew Shadura - 11 years ago 2014-10-26 09:53:22
andrew@shadura.me
email templates: send text/plain part as well

This change adds text parts to the email templates, as
HTML and text templates may be way to different to be
handled automatically. Also, use proper dash-dash-space
signature separator, so the email clients recognise it
for sure.
11 files changed with 65 insertions and 56 deletions:
0 comments (0 inline, 0 general)
kallithea/controllers/admin/settings.py
Show inline comments
 
@@ -341,38 +341,41 @@ class SettingsController(BaseController)
 
            defaults=defaults,
 
            encoding="UTF-8",
 
            force_defaults=False)
 

	
 
    @HasPermissionAllDecorator('hg.admin')
 
    def settings_email(self):
 
        """GET /admin/settings/email: All items in the collection"""
 
        # url('admin_settings_email')
 
        c.active = 'email'
 
        if request.POST:
 
            test_email = request.POST.get('test_email')
 
            test_email_subj = 'Kallithea test email'
 
            test_email_body = ('Kallithea Email test, '
 
            test_body = ('Kallithea Email test, '
 
                               'Kallithea version: %s' % c.kallithea_version)
 
            if not test_email:
 
                h.flash(_('Please enter email address'), category='error')
 
                return redirect(url('admin_settings_email'))
 

	
 
            test_email_txt_body = EmailNotificationModel()\
 
                .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
 
                                'txt', body=test_body)
 
            test_email_html_body = EmailNotificationModel()\
 
                .get_email_tmpl(EmailNotificationModel.TYPE_DEFAULT,
 
                                body=test_email_body)
 
                                'html', body=test_body)
 

	
 
            recipients = [test_email] if test_email else None
 

	
 
            run_task(tasks.send_email, recipients, test_email_subj,
 
                     test_email_body, test_email_html_body)
 
                     test_email_txt_body, test_email_html_body)
 

	
 
            h.flash(_('Send email task created'), category='success')
 
            return redirect(url('admin_settings_email'))
 

	
 
        defaults = Setting.get_app_settings()
 
        defaults.update(self._get_hg_ui_settings())
 

	
 
        import kallithea
 
        c.ini = kallithea.CONFIG
 

	
 
        return htmlfill.render(
 
            render('admin/settings/settings.html'),
kallithea/model/notification.py
Show inline comments
 
@@ -109,40 +109,41 @@ class NotificationModel(BaseModel):
 
        if not with_email:
 
            return notif
 

	
 
        #don't send email to person who created this comment
 
        rec_objs = set(recipients_objs).difference(set([created_by_obj]))
 

	
 
        headers = None
 
        if 'threading' in email_kwargs:
 
            headers = {'References': ' '.join('<%s>' % x for x in email_kwargs['threading'])}
 

	
 
        # send email with notification to all other participants
 
        for rec in rec_objs:
 
            email_body = None  # we set body to none, we just send HTML emails
 
            ## this is passed into template
 
            kwargs = {'subject': subject,
 
                      'body': h.rst_w_mentions(body),
 
                      'when': h.fmt_date(notif.created_on),
 
                      'user': notif.created_by_user.username,
 
                      }
 

	
 
            kwargs.update(email_kwargs)
 
            email_subject = EmailNotificationModel()\
 
                                .get_email_description(type_, **kwargs)
 
            email_body_html = EmailNotificationModel()\
 
                                .get_email_tmpl(type_, **kwargs)
 
            email_txt_body = EmailNotificationModel()\
 
                                .get_email_tmpl(type_, 'txt', **kwargs)
 
            email_html_body = EmailNotificationModel()\
 
                                .get_email_tmpl(type_, 'html', **kwargs)
 

	
 
            run_task(tasks.send_email, [rec.email], email_subject, email_body,
 
                     email_body_html, headers)
 
            run_task(tasks.send_email, [rec.email], email_subject, email_txt_body,
 
                     email_html_body, headers)
 

	
 
        return notif
 

	
 
    def delete(self, user, notification):
 
        # we don't want to remove actual notification just the assignment
 
        try:
 
            notification = self.__get_notification(notification)
 
            user = self._get_user(user)
 
            if notification and user:
 
                obj = UserNotification.query()\
 
                        .filter(UserNotification.user == user)\
 
                        .filter(UserNotification.notification
 
@@ -261,30 +262,30 @@ class EmailNotificationModel(BaseModel):
 
    # Notification.TYPE_MENTION is not used
 
    TYPE_PASSWORD_RESET = 'password_link'
 
    TYPE_REGISTRATION = Notification.TYPE_REGISTRATION
 
    TYPE_PULL_REQUEST = Notification.TYPE_PULL_REQUEST
 
    TYPE_PULL_REQUEST_COMMENT = Notification.TYPE_PULL_REQUEST_COMMENT
 
    TYPE_DEFAULT = 'default'
 

	
 
    def __init__(self):
 
        super(EmailNotificationModel, self).__init__()
 
        self._template_root = kallithea.CONFIG['pylons.paths']['templates'][0]
 
        self._tmpl_lookup = kallithea.CONFIG['pylons.app_globals'].mako_lookup
 
        self.email_types = {
 
            self.TYPE_CHANGESET_COMMENT: 'email_templates/changeset_comment.html',
 
            self.TYPE_PASSWORD_RESET: 'email_templates/password_reset.html',
 
            self.TYPE_REGISTRATION: 'email_templates/registration.html',
 
            self.TYPE_DEFAULT: 'email_templates/default.html',
 
            self.TYPE_PULL_REQUEST: 'email_templates/pull_request.html',
 
            self.TYPE_PULL_REQUEST_COMMENT: 'email_templates/pull_request_comment.html',
 
            self.TYPE_CHANGESET_COMMENT: 'changeset_comment',
 
            self.TYPE_PASSWORD_RESET: 'password_reset',
 
            self.TYPE_REGISTRATION: 'registration',
 
            self.TYPE_DEFAULT: 'default',
 
            self.TYPE_PULL_REQUEST: 'pull_request',
 
            self.TYPE_PULL_REQUEST_COMMENT: 'pull_request_comment',
 
        }
 
        self._subj_map = {
 
            self.TYPE_CHANGESET_COMMENT: _('Comment on %(repo_name)s changeset %(short_id)s on %(branch)s by %(comment_username)s'),
 
            self.TYPE_MESSAGE: 'Test Message',
 
            # self.TYPE_PASSWORD_RESET
 
            self.TYPE_REGISTRATION: _('New user %(new_username)s registered'),
 
            # self.TYPE_DEFAULT
 
            self.TYPE_PULL_REQUEST: _('Review request on %(repo_name)s pull request #%(pr_id)s from %(ref)s by %(pr_username)s'),
 
            self.TYPE_PULL_REQUEST_COMMENT: _('Comment on %(repo_name)s pull request #%(pr_id)s from %(ref)s by %(comment_username)s'),
 
        }
 

	
 
    def get_email_description(self, type_, **kwargs):
 
@@ -293,26 +294,26 @@ class EmailNotificationModel(BaseModel):
 
        """
 
        tmpl = self._subj_map[type_]
 
        try:
 
            subj = tmpl % kwargs
 
        except KeyError, e:
 
            log.error('error generating email subject for %r from %s: %s', type_, ','.join(self._subj_map.keys()), e)
 
            raise
 
        l = [str(x) for x in [kwargs.get('status_change'), kwargs.get('closing_pr') and _('Closing')] if x]
 
        if l:
 
            subj += ' (%s)' % (', '.join(l))
 
        return subj
 

	
 
    def get_email_tmpl(self, type_, **kwargs):
 
    def get_email_tmpl(self, type_, content_type, **kwargs):
 
        """
 
        return generated template for email based on given type
 
        """
 

	
 
        base = self.email_types.get(type_, self.email_types[self.TYPE_DEFAULT])
 
        base = 'email_templates/' + self.email_types.get(type_, self.email_types[self.TYPE_DEFAULT]) + '.' + content_type
 
        email_template = self._tmpl_lookup.get_template(base)
 
        # translator and helpers inject
 
        _kwargs = {'_': _,
 
                   'h': h,
 
                   'c': c}
 
        _kwargs.update(kwargs)
 
        log.debug('rendering tmpl %s with kwargs %s' % (base, _kwargs))
 
        return email_template.render(**_kwargs)
kallithea/model/user.py
Show inline comments
 
@@ -288,29 +288,34 @@ class UserModel(BaseModel):
 
        from kallithea.lib.celerylib import tasks, run_task
 
        from kallithea.model.notification import EmailNotificationModel
 
        import kallithea.lib.helpers as h
 

	
 
        user_email = data['email']
 
        try:
 
            user = User.get_by_email(user_email)
 
            if user:
 
                log.debug('password reset user found %s' % user)
 
                link = h.canonical_url('reset_password_confirmation', key=user.api_key)
 
                reg_type = EmailNotificationModel.TYPE_PASSWORD_RESET
 
                body = EmailNotificationModel().get_email_tmpl(reg_type,
 
                                                               'txt',
 
                                                               user=user.short_contact,
 
                                                               reset_url=link)
 
                html_body = EmailNotificationModel().get_email_tmpl(reg_type,
 
                                                               'html',
 
                                                               user=user.short_contact,
 
                                                               reset_url=link)
 
                log.debug('sending email')
 
                run_task(tasks.send_email, [user_email],
 
                         _("Password reset link"), body, body)
 
                         _("Password reset link"), body, html_body)
 
                log.info('send new password mail to %s' % user_email)
 
            else:
 
                log.debug("password reset email %s not found" % user_email)
 
        except Exception:
 
            log.error(traceback.format_exc())
 
            return False
 

	
 
        return True
 

	
 
    def reset_password(self, data):
 
        from kallithea.lib.celerylib import tasks, run_task
 
        from kallithea.lib import auth
kallithea/templates/email_templates/changeset_comment.txt
Show inline comments
 
file copied from kallithea/templates/email_templates/changeset_comment.html to kallithea/templates/email_templates/changeset_comment.txt
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 
<%inherit file="main.txt"/>
 

	
 
%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>
 
${_('Comment from %s on %s changeset %s mentioned you') % (cs_comment_user, cs_target_repo, h.short_id(raw_id))}:
 
%else:
 
<p>${_('Comment from %s on %s changeset %s') % (cs_comment_user, cs_target_repo, h.short_id(raw_id))}:</p>
 
${_('Comment from %s on %s changeset %s') % (cs_comment_user, cs_target_repo, h.short_id(raw_id))}:
 
%endif
 
<p>${body}</p>
 
${body}
 

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

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

	
 
<p>${_('Changeset')}: ${h.short_id(raw_id)}</p>
 
<p>${_('Description')}:<br/>
 
${_('Changeset')}: ${h.short_id(raw_id)}
 
${_('Description')}:
 
${h.shorter(message, 256)}
 
</p>
kallithea/templates/email_templates/default.txt
Show inline comments
 
file copied from kallithea/templates/email_templates/default.html to kallithea/templates/email_templates/default.txt
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 
<%inherit file="main.txt"/>
 

	
 
${body}
kallithea/templates/email_templates/main.html
Show inline comments
 
${self.body()}
 

	
 
<br/>
 
<br/>
 
-- <br/>
 
${_("This is an automatic notification - don't reply to this mail.")}
 
${_("This is an automatic notification. Don't reply to this mail.")}
kallithea/templates/email_templates/main.txt
Show inline comments
 
file copied from kallithea/templates/email_templates/main.html to kallithea/templates/email_templates/main.txt
 
${self.body()}
 
<br/>
 
-- <br/>
 
${_("This is an automatic notification - don't reply to this mail.")}
 

	
 
-- 
 
${_("This is an automatic notification. Don't reply to this mail.")}
kallithea/templates/email_templates/password_reset.txt
Show inline comments
 
file copied from kallithea/templates/email_templates/password_reset.html to kallithea/templates/email_templates/password_reset.txt
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 
<%inherit file="main.txt"/>
 

	
 
<h4>${_('Hello %s') % user}</h4>
 
${_('Hello %s') % user}
 

	
 
<p>${_('We received a request to create a new password for your account.')}</p>
 
<p>${_('You can generate it by clicking following URL')}:</p>
 
<p><a href="${reset_url}">${reset_url}</a></p>
 
${_('We received a request to create a new password for your account.')}
 
${_('You can generate it by clicking following URL')}:
 

	
 
<p>${_("Please ignore this email if you did not request a new password .")}</p>
 
${reset_url}
 

	
 
${_("Please ignore this email if you did not request a new password .")}
kallithea/templates/email_templates/pull_request.txt
Show inline comments
 
file copied from kallithea/templates/email_templates/pull_request.html to kallithea/templates/email_templates/pull_request.txt
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 
<%inherit file="main.txt"/>
 

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

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

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

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

	
 
${_('Changesets')}:
 
%for r,r_msg in pr_revisions:
 
<i>${h.short_id(r)}</i>:
 
${h.short_id(r)}:
 
${h.shorter(r_msg, 256)}
 

	
 
%endfor
 
</p>
kallithea/templates/email_templates/pull_request_comment.txt
Show inline comments
 
file copied from kallithea/templates/email_templates/pull_request_comment.html to kallithea/templates/email_templates/pull_request_comment.txt
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 
<%inherit file="main.txt"/>
 

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

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

	
 
<p>${_('URL')}: <a href="${pr_comment_url}">${pr_comment_url}</a></p>
 
${_('URL')}: ${pr_comment_url}
kallithea/templates/email_templates/registration.txt
Show inline comments
 
file copied from kallithea/templates/email_templates/registration.html to kallithea/templates/email_templates/registration.txt
 
## -*- coding: utf-8 -*-
 
<%inherit file="main.html"/>
 
<%inherit file="main.txt"/>
 

	
 
${body}
 

	
 
${_('View this user here')}: <a href="${registered_user_url}">${registered_user_url}</a>
 
${_('View this user here')}: ${registered_user_url}
0 comments (0 inline, 0 general)