Changeset - f23828b00b21
[Not reviewed]
beta
0 6 0
Marcin Kuzminski - 14 years ago 2011-11-20 21:26:55
marcin@python-works.com
notification fixes and improvements
6 files changed with 97 insertions and 17 deletions:
0 comments (0 inline, 0 general)
rhodecode/model/comment.py
Show inline comments
 
@@ -28,8 +28,9 @@ import logging
 
import traceback
 

	
 
from rhodecode.model import BaseModel
 
from rhodecode.model.db import ChangesetComment
 
from rhodecode.model.db import ChangesetComment, User, Notification
 
from sqlalchemy.util.compat import defaultdict
 
from rhodecode.model.notification import NotificationModel
 

	
 
log = logging.getLogger(__name__)
 

	
 
@@ -60,6 +61,17 @@ class ChangesetCommentsModel(BaseModel):
 

	
 
            self.sa.add(comment)
 
            self.sa.commit()
 

	
 
            # make notification
 
            usr = User.get(user_id)
 
            subj = 'User %s commented on %s' % (usr.username, revision)
 
            body = text
 
            recipients = ChangesetComment.get_users(revision=revision)
 
            NotificationModel().create(created_by=user_id, subject=subj,
 
                                   body = body, recipients = recipients,
 
                                   type_ = Notification.TYPE_CHANGESET_COMMENT)
 

	
 

	
 
            return comment
 

	
 
    def delete(self, comment_id):
rhodecode/model/db.py
Show inline comments
 
@@ -1109,18 +1109,40 @@ class ChangesetComment(Base, BaseModel):
 
    text = Column('text', Unicode(25000), nullable=False)
 
    modified_at = Column('modified_at', DateTime(), nullable=False, default=datetime.datetime.now)
 

	
 
    author = relationship('User')
 
    author = relationship('User', lazy='joined')
 
    repo = relationship('Repository')
 

	
 

	
 
    @classmethod
 
    def get_users(cls, revision):
 
        """
 
        Returns user associated with this changesetComment. ie those
 
        who actually commented
 
        
 
        :param cls:
 
        :param revision:
 
        """
 
        return Session.query(User)\
 
                .filter(cls.revision == revision)\
 
                .join(ChangesetComment.author).all()
 

	
 

	
 
class Notification(Base, BaseModel):
 
    __tablename__ = 'notifications'
 
    __table_args__ = ({'extend_existing':True})
 

	
 
    TYPE_CHANGESET_COMMENT = 'cs_comment'
 
    TYPE_MESSAGE = 'message'
 
    TYPE_MENTION = 'mention'
 

	
 
    notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True)
 
    subject = Column('subject', Unicode(512), nullable=True)
 
    body = Column('body', Unicode(50000), nullable=True)
 
    created_by = Column("created_by", Integer(), ForeignKey('users.user_id'), nullable=True)
 
    created_on = Column('created_on', DateTime(timezone=False), nullable=False, default=datetime.datetime.now)
 
    type_ = Column('type', Unicode(256))
 

	
 
    create_by_user = relationship('User')
 
    user_notifications = relationship('UserNotification',
 
        primaryjoin = 'Notification.notification_id==UserNotification.notification_id',
 
        cascade = "all, delete, delete-orphan")
 
@@ -1131,10 +1153,15 @@ class Notification(Base, BaseModel):
 
                .filter(UserNotification.notification == self).all()]
 

	
 
    @classmethod
 
    def create(cls, subject, body, recipients):
 
    def create(cls, created_by, subject, body, recipients, type_=None):
 
        if type_ is None:
 
            type_ = Notification.TYPE_MESSAGE
 

	
 
        notification = cls()
 
        notification.create_by_user = created_by
 
        notification.subject = subject
 
        notification.body = body
 
        notification.type_ = type_
 
        Session.add(notification)
 
        for u in recipients:
 
            u.notifications.append(notification)
 
@@ -1143,10 +1170,12 @@ class Notification(Base, BaseModel):
 

	
 
class UserNotification(Base, BaseModel):
 
    __tablename__ = 'user_to_notification'
 
    __table_args__ = ({'extend_existing':True})
 
    __table_args__ = (UniqueConstraint('user_id', 'notification_id'),
 
                      {'extend_existing':True})
 
    user_to_notification_id = Column("user_to_notification_id", Integer(), nullable=False, unique=True, primary_key=True)
 
    user_id = Column("user_id", Integer(), ForeignKey('users.user_id'), nullable=False, unique=None, default=None)
 
    notification_id = Column("notification_id", Integer(), ForeignKey('notifications.notification_id'), nullable=False)
 
    read = Column('read', Boolean, default=False)
 
    sent_on = Column('sent_on', DateTime(timezone=False), nullable=True, unique=None)
 

	
 
    user = relationship('User', single_parent=True, lazy="joined")
rhodecode/model/notification.py
Show inline comments
 
@@ -38,18 +38,43 @@ from rhodecode.model.db import Notificat
 

	
 
class NotificationModel(BaseModel):
 

	
 
    def create(self, subject, body, recipients):
 
    def create(self, created_by, subject, body, recipients,
 
               type_=Notification.TYPE_MESSAGE):
 
        """
 
        
 
        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
 
        :param type_: type of notification
 
        """
 

	
 
        if not getattr(recipients, '__iter__', False):
 
            raise Exception('recipients must be a list of iterable')
 

	
 
        for x in recipients:
 
            if not isinstance(x, User):
 
                raise Exception('recipient is not instance of %s got %s' % \
 
                                (User, type(x)))
 
        created_by_obj = created_by
 
        if not isinstance(created_by, User):
 
            created_by_obj = User.get(created_by)
 

	
 

	
 
        Notification.create(subject, body, recipients)
 
        recipients_objs = []
 
        for u in recipients:
 
            if isinstance(u, User):
 
                recipients_objs.append(u)
 
            elif isinstance(u, basestring):
 
                recipients_objs.append(User.get_by_username(username=u))
 
            elif isinstance(u, int):
 
                recipients_objs.append(User.get(u))
 
            else:
 
                raise Exception('Unsupported recipient must be one of int,'
 
                                'str or User object')
 

	
 
        Notification.create(created_by=created_by_obj, subject=subject,
 
                            body = body, recipients = recipients_objs,
 
                            type_=type_)
 

	
 

	
 
    def get_for_user(self, user_id):
rhodecode/public/css/diff.css
Show inline comments
 
@@ -7,6 +7,9 @@ div.diffblock {
 
    line-height: 100%;
 
    /* new */
 
    line-height: 125%;
 
        -webkit-border-radius: 6px 6px 0px 0px;
 
    -moz-border-radius: 6px 6px 0px 0px;
 
    border-radius: 6px 6px 0px 0px;     
 
}
 

	
 
div.diffblock.margined{
 
@@ -19,8 +22,9 @@ div.diffblock .code-header{
 
	padding:10px 0 10px 0;
 
}
 
div.diffblock .code-header div{
 
	margin-left:25px;
 
	margin-left:10px;
 
	font-weight: bold;
 
	font-size: 14px;
 
}
 
div.diffblock .code-body{
 
	background: #FFFFFF;
rhodecode/templates/admin/users/notifications.html
Show inline comments
 
@@ -18,11 +18,21 @@
 
    <!-- box / title -->
 
    <div class="title">
 
        ${self.breadcrumbs()}       
 
        <ul class="links">
 
            <li>
 
              <span style="text-transform: uppercase;"><a href="#">${_('Compose message')}</a></span>
 
            </li>          
 
        </ul>            
 
    </div>
 
    % for notification in c.notifications:
 
        ${notification.title}
 
    % if c.notifications:
 
      %for notification in c.notifications:
 
          <div class="table">
 
            <h4>${notification.subject}</h4>
 
            <div>${h.rst(notification.body)}</div>
 
          </div>
 
      %endfor
 
    %else:
 
        <div class="table">${_('No notifications here yet')}</div>
 
    %endfor
 
    %endif
 
</div>    
 
</%def>  
rhodecode/templates/changeset/changeset.html
Show inline comments
 
@@ -34,12 +34,12 @@
 
		<div class="diffblock">
 
			<div class="code-header">
 
				<div>
 
				${_('Changeset')} - r${c.changeset.revision}:${h.short_id(c.changeset.raw_id)}
 
				 &raquo; <span>${h.link_to(_('raw diff'),
 
                <span>${h.link_to(_('raw diff'),
 
				h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='show'))}</span>
 
				 &raquo; <span>${h.link_to(_('download diff'),
 
				h.url('raw_changeset_home',repo_name=c.repo_name,revision=c.changeset.raw_id,diff='download'))}</span>
 
				</div>
 
				<div class="comments-number" style="float:right;padding-right:5px">${len(c.comments)} comment(s) (${c.inline_cnt} ${_('inline')})</div>
 
                </div>
 
			</div>
 
		</div>
 
	    <div id="changeset_content">
0 comments (0 inline, 0 general)