##// END OF EJS Templates
i18n: updated translation for Polish...
i18n: updated translation for Polish Currently translated at 56.5% (614 of 1087 strings)

File last commit:

r8081:620c13a3 default
r8092:7fef5132 default
Show More
notification.py
230 lines | 9.4 KiB | text/x-python | PythonLexer
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 # -*- 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.notification
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Model for notifications
Bradley M. Kuhn
RhodeCode GmbH is not the sole author of this work
r4211 This file was forked by the Kallithea project in July 2014.
Original author and date, and relevant copyright and licensing information is below:
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 :created_on: Nov 20, 2011
:author: marcink
Bradley M. Kuhn
RhodeCode GmbH is not the sole author of this work
r4211 :copyright: (c) 2013 RhodeCode GmbH, and others.
Bradley M. Kuhn
Correct licensing information in individual files....
r4208 :license: GPLv3, see LICENSE.md for more details.
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 """
Thomas De Schampheleire
model: remove UI notification feature...
r7367 import datetime
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 import logging
Mads Kiilerich
scripts: initial run of import cleanup using isort
r7718 from tg import app_globals
from tg import tmpl_context as c
Mads Kiilerich
tg: minimize future diff by some mocking and replacing some pylons imports with tg...
r6508 from tg.i18n import ugettext as _
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
import kallithea
from kallithea.lib import helpers as h
Thomas De Schampheleire
model: move notification types from Notification to NotificationModel...
r7368 from kallithea.model.db import User
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Mads Kiilerich
scripts: initial run of import cleanup using isort
r7718
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 log = logging.getLogger(__name__)
Søren Løvborg
model: remove BaseModel class...
r6483 class NotificationModel(object):
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Thomas De Schampheleire
model: move notification types from Notification to NotificationModel...
r7368 TYPE_CHANGESET_COMMENT = u'cs_comment'
TYPE_MESSAGE = u'message'
TYPE_MENTION = u'mention' # not used
TYPE_REGISTRATION = u'registration'
TYPE_PULL_REQUEST = u'pull_request'
TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment'
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 def create(self, created_by, subject, body, recipients=None,
Thomas De Schampheleire
model: move notification types from Notification to NotificationModel...
r7368 type_=TYPE_MESSAGE, with_email=True,
Mads Kiilerich
comments: linkify revision hashes and issue tracker references...
r5643 email_kwargs=None, repo_name=None):
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 """
Creates notification of given type
:param created_by: int, str or User instance. User who created this
notification
:param subject:
:param body:
:param recipients: list of int, str or User objects, when None
is given send to all admins
:param type_: type of notification
:param with_email: send email with this notification
:param email_kwargs: additional dict to pass as args to email template
"""
Mads Kiilerich
celeryd: annotate tasks so they can be run directly without run_task...
r6133 from kallithea.lib.celerylib import tasks
Jiří Suchan
cleanup: stop using mutable default params
r5555 email_kwargs = email_kwargs or {}
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 if recipients and not getattr(recipients, '__iter__', False):
raise Exception('recipients must be a list or iterable')
Søren Løvborg
model: inline BaseModel._get_user calls
r6423 created_by_obj = User.guess_instance(created_by)
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Thomas De Schampheleire
model: notification: don't round-trip via list if you want a set...
r7361 recipients_objs = set()
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 if recipients:
for u in recipients:
Søren Løvborg
model: inline BaseModel._get_user calls
r6423 obj = User.guess_instance(u)
Mads Kiilerich
cleanup: check for None object identity in cases where that is what the 'contract' says...
r5306 if obj is not None:
Thomas De Schampheleire
model: notification: don't round-trip via list if you want a set...
r7361 recipients_objs.add(obj)
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 else:
# TODO: inform user that requested operation couldn't be completed
log.error('cannot email unknown user %r', u)
Mads Kiilerich
cleanup: pass log strings unformatted - avoid unnecessary % formatting when not logging
r5375 log.debug('sending notifications %s to %s',
type_, recipients_objs
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 )
Mads Kiilerich
mail: only bother admins when that really is the intention - not when there just not happens to be other recipients
r4332 elif recipients is None:
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 # empty recipients means to all admins
recipients_objs = User.query().filter(User.admin == True).all()
Mads Kiilerich
cleanup: pass log strings unformatted - avoid unnecessary % formatting when not logging
r5375 log.debug('sending notifications %s to admins: %s',
type_, recipients_objs
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 )
Mads Kiilerich
mail: only bother admins when that really is the intention - not when there just not happens to be other recipients
r4332 #else: silently skip notification mails?
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 if not with_email:
Thomas De Schampheleire
model: remove UI notification feature...
r7367 return
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Thomas De Schampheleire
email: add X-Kallithea-Notification-Type header...
r6238 headers = {}
headers['X-Kallithea-Notification-Type'] = type_
Mads Kiilerich
notifications: insert 'References' mail headers to help MUA threading...
r4384 if 'threading' in email_kwargs:
Thomas De Schampheleire
email: add X-Kallithea-Notification-Type header...
r6238 headers['References'] = ' '.join('<%s>' % x for x in email_kwargs['threading'])
Mads Kiilerich
notifications: insert 'References' mail headers to help MUA threading...
r4384
Thomas De Schampheleire
notification: don't repeat common actions for each email recipient...
r7298 # this is passed into template
Thomas De Schampheleire
model: remove UI notification feature...
r7367 created_on = h.fmt_date(datetime.datetime.now())
Thomas De Schampheleire
notification: don't repeat common actions for each email recipient...
r7298 html_kwargs = {
'subject': subject,
'body': h.render_w_mentions(body, repo_name),
Thomas De Schampheleire
model: remove UI notification feature...
r7367 'when': created_on,
'user': created_by_obj.username,
Thomas De Schampheleire
notification: don't repeat common actions for each email recipient...
r7298 }
txt_kwargs = {
'subject': subject,
'body': body,
Thomas De Schampheleire
model: remove UI notification feature...
r7367 'when': created_on,
'user': created_by_obj.username,
Thomas De Schampheleire
notification: don't repeat common actions for each email recipient...
r7298 }
html_kwargs.update(email_kwargs)
txt_kwargs.update(email_kwargs)
email_subject = EmailNotificationModel() \
.get_email_description(type_, **txt_kwargs)
email_txt_body = EmailNotificationModel() \
.get_email_tmpl(type_, 'txt', **txt_kwargs)
email_html_body = EmailNotificationModel() \
.get_email_tmpl(type_, 'html', **html_kwargs)
# don't send email to person who created this comment
rec_objs = set(recipients_objs).difference(set([created_by_obj]))
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 # send email with notification to all other participants
for rec in rec_objs:
Mads Kiilerich
celeryd: annotate tasks so they can be run directly without run_task...
r6133 tasks.send_email([rec.email], email_subject, email_txt_body,
Thomas De Schampheleire
email: send comment and pullrequest mails with the author's name in 'From'...
r5455 email_html_body, headers, author=created_by_obj)
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Søren Løvborg
model: remove BaseModel class...
r6483 class EmailNotificationModel(object):
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Thomas De Schampheleire
model: move notification types from Notification to NotificationModel...
r7368 TYPE_CHANGESET_COMMENT = NotificationModel.TYPE_CHANGESET_COMMENT
TYPE_MESSAGE = NotificationModel.TYPE_MESSAGE # only used for testing
# NotificationModel.TYPE_MENTION is not used
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 TYPE_PASSWORD_RESET = 'password_link'
Thomas De Schampheleire
model: move notification types from Notification to NotificationModel...
r7368 TYPE_REGISTRATION = NotificationModel.TYPE_REGISTRATION
TYPE_PULL_REQUEST = NotificationModel.TYPE_PULL_REQUEST
TYPE_PULL_REQUEST_COMMENT = NotificationModel.TYPE_PULL_REQUEST_COMMENT
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 TYPE_DEFAULT = 'default'
def __init__(self):
super(EmailNotificationModel, self).__init__()
Alessandro Molina
backend: replace Pylons with TurboGears2...
r6522 self._template_root = kallithea.CONFIG['paths']['templates'][0]
self._tmpl_lookup = app_globals.mako_lookup
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 self.email_types = {
Andrew Shadura
email templates: send text/plain part as well...
r4561 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',
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 }
Mads Kiilerich
notifications: improve Email subjects
r4381 self._subj_map = {
Thomas De Schampheleire <thomas.de.schampheleire at gmail.com>
email: add relevant title to subject of emails...
r6021 self.TYPE_CHANGESET_COMMENT: _('[Comment] %(repo_name)s changeset %(short_id)s "%(message_short)s" on %(branch)s'),
Mads Kiilerich
notifications: improve Email subjects
r4381 self.TYPE_MESSAGE: 'Test Message',
# self.TYPE_PASSWORD_RESET
self.TYPE_REGISTRATION: _('New user %(new_username)s registered'),
# self.TYPE_DEFAULT
Mads Kiilerich
notifications: tweak PR mail subject lines...
r6022 self.TYPE_PULL_REQUEST: _('[Review] %(repo_name)s PR %(pr_nice_id)s "%(pr_title_short)s" from %(pr_source_branch)s by %(pr_owner_username)s'),
self.TYPE_PULL_REQUEST_COMMENT: _('[Comment] %(repo_name)s PR %(pr_nice_id)s "%(pr_title_short)s" from %(pr_source_branch)s by %(pr_owner_username)s'),
Mads Kiilerich
notifications: improve Email subjects
r4381 }
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Mads Kiilerich
notifications: improve Email subjects
r4381 def get_email_description(self, type_, **kwargs):
"""
return subject for email based on given type
"""
tmpl = self._subj_map[type_]
try:
Mads Kiilerich
notifications: append status changes and 'Closing' to email subjects
r4382 subj = tmpl % kwargs
Mads Kiilerich
cleanup: consistently use 'except ... as ...:'...
r5374 except KeyError as e:
Mads Kiilerich
py3: drop .keys when we don't need them...
r7956 log.error('error generating email subject for %r from %s: %s', type_, ', '.join(self._subj_map), e)
Mads Kiilerich
notifications: improve Email subjects
r4381 raise
Mads Kiilerich
model: clean up get_email_description to make it more clear how the [tags] are added ... and why
r7950 # gmail doesn't do proper threading but will ignore leading square
# bracket content ... so that is where we put status info
bracket_tags = []
status_change = kwargs.get('status_change')
if status_change:
Mads Kiilerich
py3: trivial renaming of unicode to str
r8081 bracket_tags.append(str(status_change)) # apply str to evaluate LazyString before .join
Mads Kiilerich
model: clean up get_email_description to make it more clear how the [tags] are added ... and why
r7950 if kwargs.get('closing_pr'):
bracket_tags.append(_('Closing'))
if bracket_tags:
Mads Kiilerich
notifications: use stupid mail static-except-[] subjects to please gmail and its broken threading...
r5111 if subj.startswith('['):
Mads Kiilerich
model: clean up get_email_description to make it more clear how the [tags] are added ... and why
r7950 subj = '[' + ', '.join(bracket_tags) + ': ' + subj[1:]
Mads Kiilerich
notifications: use stupid mail static-except-[] subjects to please gmail and its broken threading...
r5111 else:
Mads Kiilerich
model: clean up get_email_description to make it more clear how the [tags] are added ... and why
r7950 subj = '[' + ', '.join(bracket_tags) + '] ' + subj
Mads Kiilerich
notifications: append status changes and 'Closing' to email subjects
r4382 return subj
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187
Andrew Shadura
email templates: send text/plain part as well...
r4561 def get_email_tmpl(self, type_, content_type, **kwargs):
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 """
return generated template for email based on given type
"""
Andrew Shadura
email templates: send text/plain part as well...
r4561 base = 'email_templates/' + self.email_types.get(type_, self.email_types[self.TYPE_DEFAULT]) + '.' + content_type
Bradley M. Kuhn
Second step in two-part process to rename directories....
r4187 email_template = self._tmpl_lookup.get_template(base)
# translator and helpers inject
_kwargs = {'_': _,
'h': h,
'c': c}
_kwargs.update(kwargs)
Kateryna Musina
notifications: new email templates with html styling...
r6099 if content_type == 'html':
_kwargs.update({
"color_text": "#202020",
"color_emph": "#395fa0",
"color_link": "#395fa0",
"color_border": "#ddd",
"color_background_grey": "#f9f9f9",
"color_button": "#395fa0",
"monospace_style": "font-family:Lucida Console,Consolas,Monaco,Inconsolata,Liberation Mono,monospace",
"sans_style": "font-family:Helvetica,Arial,sans-serif",
})
_kwargs.update({
"default_style": "%(sans_style)s;font-weight:200;font-size:14px;line-height:17px;color:%(color_text)s" % _kwargs,
"comment_style": "%(monospace_style)s;white-space:pre-wrap" % _kwargs,
Thomas De Schampheleire
HTML email templates: don't use link color for non-links...
r7087 "data_style": "border:%(color_border)s 1px solid;background:%(color_background_grey)s" % _kwargs,
Mads Kiilerich
mails: make title in header boxes slightly bolder...
r6405 "emph_style": "font-weight:600;color:%(color_emph)s" % _kwargs,
Thomas De Schampheleire
HTML email templates: introduce link_style variable...
r7085 "link_style": "color:%(color_link)s;text-decoration:none" % _kwargs,
Thomas De Schampheleire
HTML email templates: restrict amount of visible hyperlinks...
r7088 "link_text_style": "color:%(color_text)s;text-decoration:none;border:%(color_border)s 1px solid;background:%(color_background_grey)s" % _kwargs,
Kateryna Musina
notifications: new email templates with html styling...
r6099 })
Mads Kiilerich
cleanup: pass log strings unformatted - avoid unnecessary % formatting when not logging
r5375 log.debug('rendering tmpl %s with kwargs %s', base, _kwargs)
Mads Kiilerich
email: don't crash on sending mails with unicode comments without appropriate environment configuration (Issue #275)...
r6600 return email_template.render_unicode(**_kwargs)