##// END OF EJS Templates
comments: check for None instead of boolean checks
Mads Kiilerich -
r5539:87285c50 default
parent child Browse files
Show More
@@ -1,278 +1,278 b''
1 1 # -*- coding: utf-8 -*-
2 2 # This program is free software: you can redistribute it and/or modify
3 3 # it under the terms of the GNU General Public License as published by
4 4 # the Free Software Foundation, either version 3 of the License, or
5 5 # (at your option) any later version.
6 6 #
7 7 # This program is distributed in the hope that it will be useful,
8 8 # but WITHOUT ANY WARRANTY; without even the implied warranty of
9 9 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
10 10 # GNU General Public License for more details.
11 11 #
12 12 # You should have received a copy of the GNU General Public License
13 13 # along with this program. If not, see <http://www.gnu.org/licenses/>.
14 14 """
15 15 kallithea.model.comment
16 16 ~~~~~~~~~~~~~~~~~~~~~~~
17 17
18 18 comments model for Kallithea
19 19
20 20 This file was forked by the Kallithea project in July 2014.
21 21 Original author and date, and relevant copyright and licensing information is below:
22 22 :created_on: Nov 11, 2011
23 23 :author: marcink
24 24 :copyright: (c) 2013 RhodeCode GmbH, and others.
25 25 :license: GPLv3, see LICENSE.md for more details.
26 26 """
27 27
28 28 import logging
29 29
30 30 from pylons.i18n.translation import _
31 31 from collections import defaultdict
32 32
33 33 from kallithea.lib.utils2 import extract_mentioned_users, safe_unicode
34 34 from kallithea.lib import helpers as h
35 35 from kallithea.model import BaseModel
36 36 from kallithea.model.db import ChangesetComment, User, \
37 37 Notification, PullRequest
38 38 from kallithea.model.notification import NotificationModel
39 39 from kallithea.model.meta import Session
40 40
41 41 log = logging.getLogger(__name__)
42 42
43 43
44 44 class ChangesetCommentsModel(BaseModel):
45 45
46 46 cls = ChangesetComment
47 47
48 48 def __get_changeset_comment(self, changeset_comment):
49 49 return self._get_instance(ChangesetComment, changeset_comment)
50 50
51 51 def __get_pull_request(self, pull_request):
52 52 return self._get_instance(PullRequest, pull_request)
53 53
54 54 def _extract_mentions(self, s):
55 55 user_objects = []
56 56 for username in extract_mentioned_users(s):
57 57 user_obj = User.get_by_username(username, case_insensitive=True)
58 58 if user_obj:
59 59 user_objects.append(user_obj)
60 60 return user_objects
61 61
62 62 def _get_notification_data(self, repo, comment, user, comment_text,
63 63 line_no=None, revision=None, pull_request=None,
64 64 status_change=None, closing_pr=False):
65 65 """
66 66 :returns: tuple (subj,body,recipients,notification_type,email_kwargs)
67 67 """
68 68 # make notification
69 69 body = comment_text # text of the comment
70 70 line = ''
71 71 if line_no:
72 72 line = _('on line %s') % line_no
73 73
74 74 #changeset
75 75 if revision:
76 76 notification_type = Notification.TYPE_CHANGESET_COMMENT
77 77 cs = repo.scm_instance.get_changeset(revision)
78 78 desc = cs.short_id
79 79
80 80 threading = ['%s-rev-%s@%s' % (repo.repo_name, revision, h.canonical_hostname())]
81 81 if line_no: # TODO: url to file _and_ line number
82 82 threading.append('%s-rev-%s-line-%s@%s' % (repo.repo_name, revision, line_no,
83 83 h.canonical_hostname()))
84 84 comment_url = h.canonical_url('changeset_home',
85 85 repo_name=repo.repo_name,
86 86 revision=revision,
87 87 anchor='comment-%s' % comment.comment_id)
88 88 subj = safe_unicode(
89 89 h.link_to('Re changeset: %(desc)s %(line)s' % \
90 90 {'desc': desc, 'line': line},
91 91 comment_url)
92 92 )
93 93 # get the current participants of this changeset
94 94 recipients = ChangesetComment.get_users(revision=revision)
95 95 # add changeset author if it's known locally
96 96 cs_author = User.get_from_cs_author(cs.author)
97 97 if not cs_author:
98 98 #use repo owner if we cannot extract the author correctly
99 99 cs_author = repo.user
100 100 recipients += [cs_author]
101 101 email_kwargs = {
102 102 'status_change': status_change,
103 103 'cs_comment_user': user.full_name_and_username,
104 104 'cs_target_repo': h.canonical_url('summary_home', repo_name=repo.repo_name),
105 105 'cs_comment_url': comment_url,
106 106 'raw_id': revision,
107 107 'message': cs.message,
108 108 'repo_name': repo.repo_name,
109 109 'short_id': h.short_id(revision),
110 110 'branch': cs.branch,
111 111 'comment_username': user.username,
112 112 'threading': threading,
113 113 }
114 114 #pull request
115 115 elif pull_request:
116 116 notification_type = Notification.TYPE_PULL_REQUEST_COMMENT
117 117 desc = comment.pull_request.title
118 118 _org_ref_type, org_ref_name, _org_rev = comment.pull_request.org_ref.split(':')
119 119 threading = ['%s-pr-%s@%s' % (pull_request.other_repo.repo_name,
120 120 pull_request.pull_request_id,
121 121 h.canonical_hostname())]
122 122 if line_no: # TODO: url to file _and_ line number
123 123 threading.append('%s-pr-%s-line-%s@%s' % (pull_request.other_repo.repo_name,
124 124 pull_request.pull_request_id, line_no,
125 125 h.canonical_hostname()))
126 126 comment_url = pull_request.url(canonical=True,
127 127 anchor='comment-%s' % comment.comment_id)
128 128 subj = safe_unicode(
129 129 h.link_to('Re pull request %(pr_nice_id)s: %(desc)s %(line)s' % \
130 130 {'desc': desc,
131 131 'pr_nice_id': comment.pull_request.nice_id(),
132 132 'line': line},
133 133 comment_url)
134 134 )
135 135 # get the current participants of this pull request
136 136 recipients = ChangesetComment.get_users(pull_request_id=
137 137 pull_request.pull_request_id)
138 138 # add pull request author
139 139 recipients += [pull_request.owner]
140 140
141 141 # add the reviewers to notification
142 142 recipients += [x.user for x in pull_request.reviewers]
143 143
144 144 #set some variables for email notification
145 145 email_kwargs = {
146 146 'pr_title': pull_request.title,
147 147 'pr_nice_id': pull_request.nice_id(),
148 148 'status_change': status_change,
149 149 'closing_pr': closing_pr,
150 150 'pr_comment_url': comment_url,
151 151 'pr_comment_user': user.full_name_and_username,
152 152 'pr_target_repo': h.canonical_url('summary_home',
153 153 repo_name=pull_request.other_repo.repo_name),
154 154 'repo_name': pull_request.other_repo.repo_name,
155 155 'ref': org_ref_name,
156 156 'comment_username': user.username,
157 157 'threading': threading,
158 158 }
159 159
160 160 return subj, body, recipients, notification_type, email_kwargs
161 161
162 162 def create(self, text, repo, user, revision=None, pull_request=None,
163 163 f_path=None, line_no=None, status_change=None, closing_pr=False,
164 164 send_email=True):
165 165 """
166 166 Creates a new comment for either a changeset or a pull request.
167 167 status_change and closing_pr is only for the optional email.
168 168
169 169 Returns the created comment.
170 170 """
171 171 if not status_change and not text:
172 172 log.warning('Missing text for comment, skipping...')
173 173 return None
174 174
175 175 repo = self._get_repo(repo)
176 176 user = self._get_user(user)
177 177 comment = ChangesetComment()
178 178 comment.repo = repo
179 179 comment.author = user
180 180 comment.text = text
181 181 comment.f_path = f_path
182 182 comment.line_no = line_no
183 183
184 184 if revision is not None:
185 185 comment.revision = revision
186 186 elif pull_request is not None:
187 187 pull_request = self.__get_pull_request(pull_request)
188 188 comment.pull_request = pull_request
189 189 else:
190 190 raise Exception('Please specify revision or pull_request_id')
191 191
192 192 Session().add(comment)
193 193 Session().flush()
194 194
195 195 if send_email:
196 196 (subj, body, recipients, notification_type,
197 197 email_kwargs) = self._get_notification_data(
198 198 repo, comment, user,
199 199 comment_text=text,
200 200 line_no=line_no,
201 201 revision=revision,
202 202 pull_request=pull_request,
203 203 status_change=status_change,
204 204 closing_pr=closing_pr)
205 205 email_kwargs['is_mention'] = False
206 206 # create notification objects, and emails
207 207 NotificationModel().create(
208 208 created_by=user, subject=subj, body=body,
209 209 recipients=recipients, type_=notification_type,
210 210 email_kwargs=email_kwargs,
211 211 )
212 212
213 213 mention_recipients = set(self._extract_mentions(body))\
214 214 .difference(recipients)
215 215 if mention_recipients:
216 216 email_kwargs['is_mention'] = True
217 217 subj = _('[Mention]') + ' ' + subj
218 218 NotificationModel().create(
219 219 created_by=user, subject=subj, body=body,
220 220 recipients=mention_recipients,
221 221 type_=notification_type,
222 222 email_kwargs=email_kwargs
223 223 )
224 224
225 225 return comment
226 226
227 227 def delete(self, comment):
228 228 comment = self.__get_changeset_comment(comment)
229 229 Session().delete(comment)
230 230
231 231 return comment
232 232
233 233 def get_comments(self, repo_id, revision=None, pull_request=None):
234 234 """
235 235 Gets general comments for either revision or pull_request.
236 236
237 237 Returns a list, ordered by creation date.
238 238 """
239 239 return self._get_comments(repo_id, revision=revision, pull_request=pull_request,
240 240 inline=False)
241 241
242 242 def get_inline_comments(self, repo_id, revision=None, pull_request=None):
243 243 """
244 244 Gets inline comments for either revision or pull_request.
245 245
246 246 Returns a list of tuples with file path and list of comments per line number.
247 247 """
248 248 comments = self._get_comments(repo_id, revision=revision, pull_request=pull_request,
249 249 inline=True)
250 250
251 251 paths = defaultdict(lambda: defaultdict(list))
252 252 for co in comments:
253 253 paths[co.f_path][co.line_no].append(co)
254 254 return paths.items()
255 255
256 256 def _get_comments(self, repo_id, revision=None, pull_request=None, inline=False):
257 257 """
258 258 Gets comments for either revision or pull_request_id, either inline or general.
259 259 """
260 260 q = Session().query(ChangesetComment)
261 261
262 262 if inline:
263 263 q = q.filter(ChangesetComment.line_no != None)\
264 264 .filter(ChangesetComment.f_path != None)
265 265 else:
266 266 q = q.filter(ChangesetComment.line_no == None)\
267 267 .filter(ChangesetComment.f_path == None)
268 268
269 if revision:
269 if revision is not None:
270 270 q = q.filter(ChangesetComment.revision == revision)\
271 271 .filter(ChangesetComment.repo_id == repo_id)
272 elif pull_request:
272 elif pull_request is not None:
273 273 pull_request = self.__get_pull_request(pull_request)
274 274 q = q.filter(ChangesetComment.pull_request == pull_request)
275 275 else:
276 276 raise Exception('Please specify either revision or pull_request')
277 277
278 278 return q.order_by(ChangesetComment.created_on).all()
General Comments 0
You need to be logged in to leave comments. Login now