##// END OF EJS Templates
Don't do git pull on remote repos since they are bare now, we need to use git fetch on them
Don't do git pull on remote repos since they are bare now, we need to use git fetch on them

File last commit:

r2296:e5c0f201 codereview
r2383:e576410f beta
Show More
notification.py
226 lines | 8.0 KiB | text/x-python | PythonLexer
#302 - basic notification system, models+tests
r1702 # -*- coding: utf-8 -*-
"""
rhodecode.model.notification
docs update
r1839 ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
#302 - basic notification system, models+tests
r1702
Model for notifications
pep8ify
r1800
#302 - basic notification system, models+tests
r1702 :created_on: Nov 20, 2011
:author: marcink
2012 copyrights
r1824 :copyright: (C) 2010-2012 Marcin Kuzminski <marcin@python-works.com>
#302 - basic notification system, models+tests
r1702 :license: GPLv3, see COPYING for more details.
"""
# 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/>.
Notification fixes...
r1717 import os
#302 - basic notification system, models+tests
r1702 import logging
import traceback
Notification fixes...
r1717 import datetime
#302 - basic notification system, models+tests
r1702
from pylons.i18n.translation import _
- refactoring to overcome poor usage of global pylons config...
r1723 import rhodecode
utils/conf...
r2109 from rhodecode.config.conf import DATETIME_FORMAT
Notification fixes...
r1717 from rhodecode.lib import helpers as h
#302 - basic notification system, models+tests
r1702 from rhodecode.model import BaseModel
from rhodecode.model.db import Notification, User, UserNotification
Notification system improvements...
r1712 log = logging.getLogger(__name__)
#302 - basic notification system, models+tests
r1702
notification to commit author + gardening
r1716
#302 - basic notification system, models+tests
r1702 class NotificationModel(BaseModel):
Notification system improvements...
r1712 def __get_user(self, user):
#227 Initial version of repository groups permissions system...
r1982 return self._get_instance(User, user, callback=User.get_by_username)
Notification system improvements...
r1712
def __get_notification(self, notification):
if isinstance(notification, Notification):
return notification
Mysql fixes...
r2149 elif isinstance(notification, (int, long)):
Notification system improvements...
r1712 return Notification.get(notification)
else:
if notification:
Mysql fixes...
r2149 raise Exception('notification must be int, long or Instance'
Notification system improvements...
r1712 ' of Notification got %s' % type(notification))
implements #222 registration feedback...
r1731 def create(self, created_by, subject, body, recipients=None,
type_=Notification.TYPE_MESSAGE, with_email=True,
email_kwargs={}):
notification fixes and improvements
r1703 """
pep8ify
r1800
notification fixes and improvements
r1703 Creates notification of given type
pep8ify
r1800
notification fixes and improvements
r1703 :param created_by: int, str or User instance. User who created this
notification
:param subject:
:param body:
auto white-space removal
r1818 :param recipients: list of int, str or User objects, when None
implements #222 registration feedback...
r1731 is given send to all admins
notification fixes and improvements
r1703 :param type_: type of notification
implements #222 registration feedback...
r1731 :param with_email: send email with this notification
:param email_kwargs: additional dict to pass as args to email template
notification fixes and improvements
r1703 """
#235 forking page repo group selection...
r1722 from rhodecode.lib.celerylib import tasks, run_task
#302 - basic notification system, models+tests
r1702
implements #222 registration feedback...
r1731 if recipients and not getattr(recipients, '__iter__', False):
#302 - basic notification system, models+tests
r1702 raise Exception('recipients must be a list of iterable')
Notification system improvements...
r1712 created_by_obj = self.__get_user(created_by)
#302 - basic notification system, models+tests
r1702
implements #222 registration feedback...
r1731 if recipients:
recipients_objs = []
for u in recipients:
obj = self.__get_user(u)
if obj:
recipients_objs.append(obj)
recipients_objs = set(recipients_objs)
code garden
r2077 log.debug('sending notifications %s to %s' % (
type_, recipients_objs)
)
implements #222 registration feedback...
r1731 else:
# empty recipients means to all admins
recipients_objs = User.query().filter(User.admin == True).all()
code garden
r2077 log.debug('sending notifications %s to admins: %s' % (
type_, recipients_objs)
)
notif = Notification.create(
created_by=created_by_obj, subject=subject,
body=body, recipients=recipients_objs, type_=type_
)
Notification fixes...
r1717
implements #222 registration feedback...
r1731 if with_email is False:
return notif
Notification fixes...
r1717 # send email with notification
for rec in recipients_objs:
email_subject = NotificationModel().make_description(notif, False)
implements #222 registration feedback...
r1731 type_ = type_
Notification fixes...
r1717 email_body = body
pep8ify
r1800 kwargs = {'subject': subject, 'body': h.rst_w_mentions(body)}
implements #222 registration feedback...
r1731 kwargs.update(email_kwargs)
Notification fixes...
r1717 email_body_html = EmailNotificationModel()\
implements #222 registration feedback...
r1731 .get_email_tmpl(type_, **kwargs)
Use __unicode__ instead of __repr__ in models.
r2156
#235 forking page repo group selection...
r1722 run_task(tasks.send_email, rec.email, email_subject, email_body,
Notification fixes...
r1717 email_body_html)
return notif
#302 - basic notification system, models+tests
r1702
Tests updates, Session refactoring
r1713 def delete(self, user, notification):
# we don't want to remove actual notification just the assignment
Notification system improvements...
r1712 try:
Tests updates, Session refactoring
r1713 notification = self.__get_notification(notification)
user = self.__get_user(user)
if notification and user:
Notification fixes...
r1717 obj = UserNotification.query()\
.filter(UserNotification.user == user)\
.filter(UserNotification.notification
== notification)\
.one()
Tests updates, Session refactoring
r1713 self.sa.delete(obj)
Notification system improvements...
r1712 return True
except Exception:
log.error(traceback.format_exc())
raise
#302 - basic notification system, models+tests
r1702
Tests updates, Session refactoring
r1713 def get_for_user(self, user):
user = self.__get_user(user)
return user.notifications
#302 - basic notification system, models+tests
r1702
mark all read button for notifications
r1791 def mark_all_read_for_user(self, user):
user = self.__get_user(user)
UserNotification.query()\
.filter(UserNotification.read==False)\
.update({'read': True})
Tests updates, Session refactoring
r1713 def get_unread_cnt_for_user(self, user):
user = self.__get_user(user)
#302 - basic notification system, models+tests
r1702 return UserNotification.query()\
Notification system improvements...
r1712 .filter(UserNotification.read == False)\
Tests updates, Session refactoring
r1713 .filter(UserNotification.user == user).count()
#302 - basic notification system, models+tests
r1702
Tests updates, Session refactoring
r1713 def get_unread_for_user(self, user):
user = self.__get_user(user)
#302 - basic notification system, models+tests
r1702 return [x.notification for x in UserNotification.query()\
Notification system improvements...
r1712 .filter(UserNotification.read == False)\
Tests updates, Session refactoring
r1713 .filter(UserNotification.user == user).all()]
Notification system improvements...
r1712
def get_user_notification(self, user, notification):
user = self.__get_user(user)
notification = self.__get_notification(notification)
return UserNotification.query()\
.filter(UserNotification.notification == notification)\
.filter(UserNotification.user == user).scalar()
Notification fixes...
r1717 def make_description(self, notification, show_age=True):
Notification system improvements...
r1712 """
Creates a human readable description based on properties
of notification object
"""
code garden
r2082 _map = {
notification.TYPE_CHANGESET_COMMENT: _('commented on commit'),
notification.TYPE_MESSAGE: _('sent message'),
notification.TYPE_MENTION: _('mentioned you'),
notification.TYPE_REGISTRATION: _('registered in RhodeCode')
}
implements #222 registration feedback...
r1731
Notification system improvements...
r1712 tmpl = "%(user)s %(action)s %(when)s"
Notification fixes...
r1717 if show_age:
when = h.age(notification.created_on)
else:
DTF = lambda d: datetime.datetime.strftime(d, DATETIME_FORMAT)
when = DTF(notification.created_on)
Use __unicode__ instead of __repr__ in models.
r2156
code garden
r2082 data = dict(
user=notification.created_by_user.username,
action=_map[notification.type_], when=when,
)
Notification system improvements...
r1712 return tmpl % data
Notification fixes...
r1717
class EmailNotificationModel(BaseModel):
test fixes
r1732 TYPE_CHANGESET_COMMENT = Notification.TYPE_CHANGESET_COMMENT
Notification fixes...
r1717 TYPE_PASSWORD_RESET = 'passoword_link'
test fixes
r1732 TYPE_REGISTRATION = Notification.TYPE_REGISTRATION
Notification fixes...
r1717 TYPE_DEFAULT = 'default'
def __init__(self):
- refactoring to overcome poor usage of global pylons config...
r1723 self._template_root = rhodecode.CONFIG['pylons.paths']['templates'][0]
self._tmpl_lookup = rhodecode.CONFIG['pylons.app_globals'].mako_lookup
Notification fixes...
r1717
self.email_types = {
code garden
r2082 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'
Notification fixes...
r1717 }
def get_email_tmpl(self, type_, **kwargs):
"""
return generated template for email based on given type
auto white-space removal
r1818
Notification fixes...
r1717 :param type_:
"""
- refactoring to overcome poor usage of global pylons config...
r1723
test fixes
r1732 base = self.email_types.get(type_, self.email_types[self.TYPE_DEFAULT])
- refactoring to overcome poor usage of global pylons config...
r1723 email_template = self._tmpl_lookup.get_template(base)
Notification fixes...
r1717 # translator inject
code garden
r2082 _kwargs = {'_': _}
Notification fixes...
r1717 _kwargs.update(kwargs)
log.debug('rendering tmpl %s with kwargs %s' % (base, _kwargs))
return email_template.render(**_kwargs)