##// END OF EJS Templates
Notification fixes...
marcink -
r2178:989c137f beta
parent child Browse files
Show More
@@ -1,148 +1,151
1 # -*- coding: utf-8 -*-
1 # -*- coding: utf-8 -*-
2 """
2 """
3 rhodecode.model.comment
3 rhodecode.model.comment
4 ~~~~~~~~~~~~~~~~~~~~~~~
4 ~~~~~~~~~~~~~~~~~~~~~~~
5
5
6 comments model for RhodeCode
6 comments model for RhodeCode
7
7
8 :created_on: Nov 11, 2011
8 :created_on: Nov 11, 2011
9 :author: marcink
9 :author: marcink
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
10 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
11 :license: GPLv3, see COPYING for more details.
11 :license: GPLv3, see COPYING for more details.
12 """
12 """
13 # This program is free software: you can redistribute it and/or modify
13 # This program is free software: you can redistribute it and/or modify
14 # it under the terms of the GNU General Public License as published by
14 # it under the terms of the GNU General Public License as published by
15 # the Free Software Foundation, either version 3 of the License, or
15 # the Free Software Foundation, either version 3 of the License, or
16 # (at your option) any later version.
16 # (at your option) any later version.
17 #
17 #
18 # This program is distributed in the hope that it will be useful,
18 # This program is distributed in the hope that it will be useful,
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
19 # but WITHOUT ANY WARRANTY; without even the implied warranty of
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 # GNU General Public License for more details.
21 # GNU General Public License for more details.
22 #
22 #
23 # You should have received a copy of the GNU General Public License
23 # You should have received a copy of the GNU General Public License
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
24 # along with this program. If not, see <http://www.gnu.org/licenses/>.
25
25
26 import logging
26 import logging
27 import traceback
27 import traceback
28
28
29 from pylons.i18n.translation import _
29 from pylons.i18n.translation import _
30 from sqlalchemy.util.compat import defaultdict
30 from sqlalchemy.util.compat import defaultdict
31
31
32 from rhodecode.lib.utils2 import extract_mentioned_users
32 from rhodecode.lib.utils2 import extract_mentioned_users, safe_unicode
33 from rhodecode.lib import helpers as h
33 from rhodecode.lib import helpers as h
34 from rhodecode.model import BaseModel
34 from rhodecode.model import BaseModel
35 from rhodecode.model.db import ChangesetComment, User, Repository, Notification
35 from rhodecode.model.db import ChangesetComment, User, Repository, Notification
36 from rhodecode.model.notification import NotificationModel
36 from rhodecode.model.notification import NotificationModel
37
37
38 log = logging.getLogger(__name__)
38 log = logging.getLogger(__name__)
39
39
40
40
41 class ChangesetCommentsModel(BaseModel):
41 class ChangesetCommentsModel(BaseModel):
42
42
43 def __get_changeset_comment(self, changeset_comment):
43 def __get_changeset_comment(self, changeset_comment):
44 return self._get_instance(ChangesetComment, changeset_comment)
44 return self._get_instance(ChangesetComment, changeset_comment)
45
45
46 def _extract_mentions(self, s):
46 def _extract_mentions(self, s):
47 user_objects = []
47 user_objects = []
48 for username in extract_mentioned_users(s):
48 for username in extract_mentioned_users(s):
49 user_obj = User.get_by_username(username, case_insensitive=True)
49 user_obj = User.get_by_username(username, case_insensitive=True)
50 if user_obj:
50 if user_obj:
51 user_objects.append(user_obj)
51 user_objects.append(user_obj)
52 return user_objects
52 return user_objects
53
53
54 def create(self, text, repo_id, user_id, revision, f_path=None,
54 def create(self, text, repo_id, user_id, revision, f_path=None,
55 line_no=None):
55 line_no=None):
56 """
56 """
57 Creates new comment for changeset
57 Creates new comment for changeset
58
58
59 :param text:
59 :param text:
60 :param repo_id:
60 :param repo_id:
61 :param user_id:
61 :param user_id:
62 :param revision:
62 :param revision:
63 :param f_path:
63 :param f_path:
64 :param line_no:
64 :param line_no:
65 """
65 """
66
66
67 if text:
67 if text:
68 repo = Repository.get(repo_id)
68 repo = Repository.get(repo_id)
69 cs = repo.scm_instance.get_changeset(revision)
69 cs = repo.scm_instance.get_changeset(revision)
70 desc = cs.message
70 desc = "%s - %s" % (cs.short_id, h.shorter(cs.message, 256))
71 author_email = cs.author_email
71 author_email = cs.author_email
72 comment = ChangesetComment()
72 comment = ChangesetComment()
73 comment.repo = repo
73 comment.repo = repo
74 comment.user_id = user_id
74 comment.user_id = user_id
75 comment.revision = revision
75 comment.revision = revision
76 comment.text = text
76 comment.text = text
77 comment.f_path = f_path
77 comment.f_path = f_path
78 comment.line_no = line_no
78 comment.line_no = line_no
79
79
80 self.sa.add(comment)
80 self.sa.add(comment)
81 self.sa.flush()
81 self.sa.flush()
82 # make notification
82 # make notification
83 line = ''
83 line = ''
84 if line_no:
84 if line_no:
85 line = _('on line %s') % line_no
85 line = _('on line %s') % line_no
86 subj = h.link_to('Re commit: %(commit_desc)s %(line)s' % \
86 subj = safe_unicode(
87 {'commit_desc': desc, 'line': line},
87 h.link_to('Re commit: %(commit_desc)s %(line)s' % \
88 h.url('changeset_home', repo_name=repo.repo_name,
88 {'commit_desc': desc, 'line': line},
89 revision=revision,
89 h.url('changeset_home', repo_name=repo.repo_name,
90 anchor='comment-%s' % comment.comment_id,
90 revision=revision,
91 qualified=True,
91 anchor='comment-%s' % comment.comment_id,
92 )
92 qualified=True,
93 )
93 )
94 )
95 )
96
94 body = text
97 body = text
95
98
96 # get the current participants of this changeset
99 # get the current participants of this changeset
97 recipients = ChangesetComment.get_users(revision=revision)
100 recipients = ChangesetComment.get_users(revision=revision)
98
101
99 # add changeset author if it's in rhodecode system
102 # add changeset author if it's in rhodecode system
100 recipients += [User.get_by_email(author_email)]
103 recipients += [User.get_by_email(author_email)]
101
104
102 NotificationModel().create(
105 NotificationModel().create(
103 created_by=user_id, subject=subj, body=body,
106 created_by=user_id, subject=subj, body=body,
104 recipients=recipients, type_=Notification.TYPE_CHANGESET_COMMENT
107 recipients=recipients, type_=Notification.TYPE_CHANGESET_COMMENT
105 )
108 )
106
109
107 mention_recipients = set(self._extract_mentions(body))\
110 mention_recipients = set(self._extract_mentions(body))\
108 .difference(recipients)
111 .difference(recipients)
109 if mention_recipients:
112 if mention_recipients:
110 subj = _('[Mention]') + ' ' + subj
113 subj = _('[Mention]') + ' ' + subj
111 NotificationModel().create(
114 NotificationModel().create(
112 created_by=user_id, subject=subj, body=body,
115 created_by=user_id, subject=subj, body=body,
113 recipients=mention_recipients,
116 recipients=mention_recipients,
114 type_=Notification.TYPE_CHANGESET_COMMENT
117 type_=Notification.TYPE_CHANGESET_COMMENT
115 )
118 )
116
119
117 return comment
120 return comment
118
121
119 def delete(self, comment):
122 def delete(self, comment):
120 """
123 """
121 Deletes given comment
124 Deletes given comment
122
125
123 :param comment_id:
126 :param comment_id:
124 """
127 """
125 comment = self.__get_changeset_comment(comment)
128 comment = self.__get_changeset_comment(comment)
126 self.sa.delete(comment)
129 self.sa.delete(comment)
127
130
128 return comment
131 return comment
129
132
130 def get_comments(self, repo_id, revision):
133 def get_comments(self, repo_id, revision):
131 return ChangesetComment.query()\
134 return ChangesetComment.query()\
132 .filter(ChangesetComment.repo_id == repo_id)\
135 .filter(ChangesetComment.repo_id == repo_id)\
133 .filter(ChangesetComment.revision == revision)\
136 .filter(ChangesetComment.revision == revision)\
134 .filter(ChangesetComment.line_no == None)\
137 .filter(ChangesetComment.line_no == None)\
135 .filter(ChangesetComment.f_path == None).all()
138 .filter(ChangesetComment.f_path == None).all()
136
139
137 def get_inline_comments(self, repo_id, revision):
140 def get_inline_comments(self, repo_id, revision):
138 comments = self.sa.query(ChangesetComment)\
141 comments = self.sa.query(ChangesetComment)\
139 .filter(ChangesetComment.repo_id == repo_id)\
142 .filter(ChangesetComment.repo_id == repo_id)\
140 .filter(ChangesetComment.revision == revision)\
143 .filter(ChangesetComment.revision == revision)\
141 .filter(ChangesetComment.line_no != None)\
144 .filter(ChangesetComment.line_no != None)\
142 .filter(ChangesetComment.f_path != None).all()
145 .filter(ChangesetComment.f_path != None).all()
143
146
144 paths = defaultdict(lambda: defaultdict(list))
147 paths = defaultdict(lambda: defaultdict(list))
145
148
146 for co in comments:
149 for co in comments:
147 paths[co.f_path][co.line_no].append(co)
150 paths[co.f_path][co.line_no].append(co)
148 return paths.items()
151 return paths.items()
General Comments 0
You need to be logged in to leave comments. Login now