##// END OF EJS Templates
channelstream: cleanup, and re-organize code for posting comments/pr updated messages....
marcink -
r4505:7d9c5b92 stable
parent child Browse files
Show More
@@ -26,6 +26,7 b' from rhodecode.api.utils import ('
26 26 has_superadmin_permission, Optional, OAttr, get_repo_or_error,
27 27 get_pull_request_or_error, get_commit_or_error, get_user_or_error,
28 28 validate_repo_permissions, resolve_ref_or_error, validate_set_owner_permissions)
29 from rhodecode.lib import channelstream
29 30 from rhodecode.lib.auth import (HasRepoPermissionAnyApi)
30 31 from rhodecode.lib.base import vcs_operation_context
31 32 from rhodecode.lib.utils2 import str2bool
@@ -502,16 +503,19 b' def comment_pull_request('
502 503 },
503 504 error : null
504 505 """
506 _ = request.translate
507
505 508 pull_request = get_pull_request_or_error(pullrequestid)
506 509 if Optional.extract(repoid):
507 510 repo = get_repo_or_error(repoid)
508 511 else:
509 512 repo = pull_request.target_repo
510 513
514 db_repo_name = repo.repo_name
511 515 auth_user = apiuser
512 516 if not isinstance(userid, Optional):
513 517 is_repo_admin = HasRepoPermissionAnyApi('repository.admin')(
514 user=apiuser, repo_name=repo.repo_name)
518 user=apiuser, repo_name=db_repo_name)
515 519 if has_superadmin_permission(apiuser) or is_repo_admin:
516 520 apiuser = get_user_or_error(userid)
517 521 auth_user = apiuser.AuthUser()
@@ -596,6 +600,7 b' def comment_pull_request('
596 600 extra_recipients=extra_recipients,
597 601 send_email=send_email
598 602 )
603 is_inline = bool(comment.f_path and comment.line_no)
599 604
600 605 if allowed_to_change_status and status:
601 606 old_calculated_status = pull_request.calculated_review_status()
@@ -628,6 +633,17 b' def comment_pull_request('
628 633 'comment_id': comment.comment_id if comment else None,
629 634 'status': {'given': status, 'was_changed': status_change},
630 635 }
636
637 comment_broadcast_channel = channelstream.comment_channel(
638 db_repo_name, pull_request_obj=pull_request)
639
640 comment_data = data
641 comment_type = 'inline' if is_inline else 'general'
642 channelstream.comment_channelstream_push(
643 request, comment_broadcast_channel, apiuser,
644 _('posted a new {} comment').format(comment_type),
645 comment_data=comment_data)
646
631 647 return data
632 648
633 649
@@ -881,6 +897,8 b' def update_pull_request('
881 897 description = Optional.extract(description)
882 898 description_renderer = Optional.extract(description_renderer)
883 899
900 # Update title/description
901 title_changed = False
884 902 if title or description:
885 903 PullRequestModel().edit(
886 904 pull_request,
@@ -889,8 +907,12 b' def update_pull_request('
889 907 description_renderer or pull_request.description_renderer,
890 908 apiuser)
891 909 Session().commit()
910 title_changed = True
892 911
893 912 commit_changes = {"added": [], "common": [], "removed": []}
913
914 # Update commits
915 commits_changed = False
894 916 if str2bool(Optional.extract(update_commits)):
895 917
896 918 if pull_request.pull_request_state != PullRequest.STATE_CREATED:
@@ -906,7 +928,10 b' def update_pull_request('
906 928 pull_request, db_user)
907 929 commit_changes = update_response.changes or commit_changes
908 930 Session().commit()
931 commits_changed = True
909 932
933 # Update reviewers
934 reviewers_changed = False
910 935 reviewers_changes = {"added": [], "removed": []}
911 936 if reviewers:
912 937 old_calculated_status = pull_request.calculated_review_status()
@@ -925,6 +950,16 b' def update_pull_request('
925 950 PullRequestModel().trigger_pull_request_hook(
926 951 pull_request, apiuser, 'review_status_change',
927 952 data={'status': calculated_status})
953 reviewers_changed = True
954
955 observers_changed = False
956
957 # push changed to channelstream
958 if commits_changed or reviewers_changed or observers_changed:
959 pr_broadcast_channel = channelstream.pr_channel(pull_request)
960 msg = 'Pull request was updated.'
961 channelstream.pr_update_channelstream_push(
962 request, pr_broadcast_channel, apiuser, msg)
928 963
929 964 data = {
930 965 'msg': 'Updated pull request `{}`'.format(
@@ -29,7 +29,7 b' from rhodecode.api.utils import ('
29 29 get_user_group_or_error, get_user_or_error, validate_repo_permissions,
30 30 get_perm_or_error, parse_args, get_origin, build_commit_data,
31 31 validate_set_owner_permissions)
32 from rhodecode.lib import audit_logger, rc_cache
32 from rhodecode.lib import audit_logger, rc_cache, channelstream
33 33 from rhodecode.lib import repo_maintenance
34 34 from rhodecode.lib.auth import (
35 35 HasPermissionAnyApi, HasUserGroupPermissionAnyApi,
@@ -1597,10 +1597,13 b' def comment_commit('
1597 1597 }
1598 1598
1599 1599 """
1600 _ = request.translate
1601
1600 1602 repo = get_repo_or_error(repoid)
1601 1603 if not has_superadmin_permission(apiuser):
1602 1604 _perms = ('repository.read', 'repository.write', 'repository.admin')
1603 1605 validate_repo_permissions(apiuser, repoid, repo, _perms)
1606 db_repo_name = repo.repo_name
1604 1607
1605 1608 try:
1606 1609 commit = repo.scm_instance().get_commit(commit_id=commit_id)
@@ -1650,6 +1653,8 b' def comment_commit('
1650 1653 extra_recipients=extra_recipients,
1651 1654 send_email=send_email
1652 1655 )
1656 is_inline = bool(comment.f_path and comment.line_no)
1657
1653 1658 if status:
1654 1659 # also do a status change
1655 1660 try:
@@ -1669,6 +1674,17 b' def comment_commit('
1669 1674 data={'comment': comment, 'commit': commit})
1670 1675
1671 1676 Session().commit()
1677
1678 comment_broadcast_channel = channelstream.comment_channel(
1679 db_repo_name, commit_obj=commit)
1680
1681 comment_data = {'comment': comment, 'comment_id': comment.comment_id}
1682 comment_type = 'inline' if is_inline else 'general'
1683 channelstream.comment_channelstream_push(
1684 request, comment_broadcast_channel, apiuser,
1685 _('posted a new {} comment').format(comment_type),
1686 comment_data=comment_data)
1687
1672 1688 return {
1673 1689 'msg': (
1674 1690 'Commented on commit `%s` for repository `%s`' % (
@@ -31,7 +31,7 b' from rhodecode.apps._base import RepoApp'
31 31 from rhodecode.apps.file_store import utils as store_utils
32 32 from rhodecode.apps.file_store.exceptions import FileNotAllowedException, FileOverSizeException
33 33
34 from rhodecode.lib import diffs, codeblocks
34 from rhodecode.lib import diffs, codeblocks, channelstream
35 35 from rhodecode.lib.auth import (
36 36 LoginRequired, HasRepoPermissionAnyDecorator, NotAnonymous, CSRFRequired)
37 37 from rhodecode.lib.ext_json import json
@@ -210,10 +210,7 b' class RepoCommitsView(RepoAppView):'
210 210
211 211 # NOTE(marcink): this uses the same voting logic as in pull-requests
212 212 c.commit_review_status = ChangesetStatusModel().calculate_status(review_statuses)
213 c.commit_broadcast_channel = u'/repo${}$/commit/{}'.format(
214 c.repo_name,
215 commit.raw_id
216 )
213 c.commit_broadcast_channel = channelstream.comment_channel(c.repo_name, commit_obj=commit)
217 214
218 215 diff = None
219 216 # Iterate over ranges (default commit view is always one commit)
@@ -417,6 +414,7 b' class RepoCommitsView(RepoAppView):'
417 414 resolves_comment_id=resolves_comment_id,
418 415 auth_user=self._rhodecode_user
419 416 )
417 is_inline = bool(comment.f_path and comment.line_no)
420 418
421 419 # get status if set !
422 420 if status:
@@ -464,6 +462,16 b' class RepoCommitsView(RepoAppView):'
464 462 data.update(comment.get_dict())
465 463 data.update({'rendered_text': rendered_comment})
466 464
465 comment_broadcast_channel = channelstream.comment_channel(
466 self.db_repo_name, commit_obj=commit)
467
468 comment_data = data
469 comment_type = 'inline' if is_inline else 'general'
470 channelstream.comment_channelstream_push(
471 self.request, comment_broadcast_channel, self._rhodecode_user,
472 _('posted a new {} comment').format(comment_type),
473 comment_data=comment_data)
474
467 475 return data
468 476
469 477 @LoginRequired()
@@ -311,8 +311,7 b' class RepoPullRequestsView(RepoAppView, '
311 311 pull_request_id = pull_request.pull_request_id
312 312
313 313 c.state_progressing = pull_request.is_state_changing()
314 c.pr_broadcast_channel = '/repo${}$/pr/{}'.format(
315 pull_request.target_repo.repo_name, pull_request.pull_request_id)
314 c.pr_broadcast_channel = channelstream.pr_channel(pull_request)
316 315
317 316 _new_state = {
318 317 'created': PullRequest.STATE_CREATED,
@@ -1238,8 +1237,7 b' class RepoPullRequestsView(RepoAppView, '
1238 1237 'redirect_url': redirect_url}
1239 1238
1240 1239 is_state_changing = pull_request.is_state_changing()
1241 c.pr_broadcast_channel = '/repo${}$/pr/{}'.format(
1242 pull_request.target_repo.repo_name, pull_request.pull_request_id)
1240 c.pr_broadcast_channel = channelstream.pr_channel(pull_request)
1243 1241
1244 1242 # only owner or admin can update it
1245 1243 allowed_to_update = PullRequestModel().check_user_update(
@@ -1339,7 +1337,8 b' class RepoPullRequestsView(RepoAppView, '
1339 1337 count_removed=len(resp.changes.removed),
1340 1338 change_source=changed)
1341 1339 h.flash(msg, category='success')
1342 self._pr_update_channelstream_push(c.pr_broadcast_channel, msg)
1340 channelstream.pr_update_channelstream_push(
1341 self.request, c.pr_broadcast_channel, self._rhodecode_user, msg)
1343 1342 else:
1344 1343 msg = PullRequestModel.UPDATE_STATUS_MESSAGES[resp.reason]
1345 1344 warning_reasons = [
@@ -1371,7 +1370,8 b' class RepoPullRequestsView(RepoAppView, '
1371 1370
1372 1371 msg = _('Pull request reviewers updated.')
1373 1372 h.flash(msg, category='success')
1374 self._pr_update_channelstream_push(c.pr_broadcast_channel, msg)
1373 channelstream.pr_update_channelstream_push(
1374 self.request, c.pr_broadcast_channel, self._rhodecode_user, msg)
1375 1375
1376 1376 # trigger status changed if change in reviewers changes the status
1377 1377 calculated_status = pull_request.calculated_review_status()
@@ -1394,7 +1394,8 b' class RepoPullRequestsView(RepoAppView, '
1394 1394 Session().commit()
1395 1395 msg = _('Pull request observers updated.')
1396 1396 h.flash(msg, category='success')
1397 self._pr_update_channelstream_push(c.pr_broadcast_channel, msg)
1397 channelstream.pr_update_channelstream_push(
1398 self.request, c.pr_broadcast_channel, self._rhodecode_user, msg)
1398 1399
1399 1400 @LoginRequired()
1400 1401 @NotAnonymous()
@@ -1588,6 +1589,7 b' class RepoPullRequestsView(RepoAppView, '
1588 1589 resolves_comment_id=resolves_comment_id,
1589 1590 auth_user=self._rhodecode_user
1590 1591 )
1592 is_inline = bool(comment.f_path and comment.line_no)
1591 1593
1592 1594 if allowed_to_change_status:
1593 1595 # calculate old status before we change it
@@ -1636,6 +1638,16 b' class RepoPullRequestsView(RepoAppView, '
1636 1638 data.update(comment.get_dict())
1637 1639 data.update({'rendered_text': rendered_comment})
1638 1640
1641 comment_broadcast_channel = channelstream.comment_channel(
1642 self.db_repo_name, pull_request_obj=pull_request)
1643
1644 comment_data = data
1645 comment_type = 'inline' if is_inline else 'general'
1646 channelstream.comment_channelstream_push(
1647 self.request, comment_broadcast_channel, self._rhodecode_user,
1648 _('posted a new {} comment').format(comment_type),
1649 comment_data=comment_data)
1650
1639 1651 return data
1640 1652
1641 1653 @LoginRequired()
@@ -225,14 +225,26 b' def write_history(config, message):'
225 225
226 226 def get_connection_validators(registry):
227 227 validators = []
228 for k, config in registry.rhodecode_plugins.iteritems():
228 for k, config in registry.rhodecode_plugins.items():
229 229 validator = config.get('channelstream', {}).get('connect_validator')
230 230 if validator:
231 231 validators.append(validator)
232 232 return validators
233 233
234 234
235 def get_channelstream_config(registry=None):
236 if not registry:
237 registry = get_current_registry()
238
239 rhodecode_plugins = getattr(registry, 'rhodecode_plugins', {})
240 channelstream_config = rhodecode_plugins.get('channelstream', {})
241 return channelstream_config
242
243
235 244 def post_message(channel, message, username, registry=None):
245 channelstream_config = get_channelstream_config(registry)
246 if not channelstream_config.get('enabled'):
247 return
236 248
237 249 message_obj = message
238 250 if isinstance(message, basestring):
@@ -242,26 +254,118 b' def post_message(channel, message, usern'
242 254 'topic': '/notifications'
243 255 }
244 256
245 if not registry:
246 registry = get_current_registry()
257 log.debug('Channelstream: sending notification to channel %s', channel)
258 payload = {
259 'type': 'message',
260 'timestamp': datetime.datetime.utcnow(),
261 'user': 'system',
262 'exclude_users': [username],
263 'channel': channel,
264 'message': message_obj
265 }
266
267 try:
268 return channelstream_request(
269 channelstream_config, [payload], '/message',
270 raise_exc=False)
271 except ChannelstreamException:
272 log.exception('Failed to send channelstream data')
273 raise
274
275
276 def _reload_link(label):
277 return (
278 '<a onclick="window.location.reload()">'
279 '<strong>{}</strong>'
280 '</a>'.format(label)
281 )
282
283
284 def pr_channel(pull_request):
285 repo_name = pull_request.target_repo.repo_name
286 pull_request_id = pull_request.pull_request_id
287 channel = '/repo${}$/pr/{}'.format(repo_name, pull_request_id)
288 log.debug('Getting pull-request channelstream broadcast channel: %s', channel)
289 return channel
290
291
292 def comment_channel(repo_name, commit_obj=None, pull_request_obj=None):
293 channel = None
294 if commit_obj:
295 channel = u'/repo${}$/commit/{}'.format(
296 repo_name, commit_obj.raw_id
297 )
298 elif pull_request_obj:
299 channel = u'/repo${}$/pr/{}'.format(
300 repo_name, pull_request_obj.pull_request_id
301 )
302 log.debug('Getting comment channelstream broadcast channel: %s', channel)
303
304 return channel
305
306
307 def pr_update_channelstream_push(request, pr_broadcast_channel, user, msg, **kwargs):
308 """
309 Channel push on pull request update
310 """
311 if not pr_broadcast_channel:
312 return
247 313
248 log.debug('Channelstream: sending notification to channel %s', channel)
249 rhodecode_plugins = getattr(registry, 'rhodecode_plugins', {})
250 channelstream_config = rhodecode_plugins.get('channelstream', {})
251 if channelstream_config.get('enabled'):
252 payload = {
253 'type': 'message',
254 'timestamp': datetime.datetime.utcnow(),
255 'user': 'system',
256 'exclude_users': [username],
257 'channel': channel,
258 'message': message_obj
259 }
314 _ = request.translate
315
316 message = '{} {}'.format(
317 msg,
318 _reload_link(_(' Reload page to load changes')))
319
320 message_obj = {
321 'message': message,
322 'level': 'success',
323 'topic': '/notifications'
324 }
325
326 post_message(
327 pr_broadcast_channel, message_obj, user.username,
328 registry=request.registry)
329
330
331 def comment_channelstream_push(request, comment_broadcast_channel, user, msg, **kwargs):
332 """
333 Channelstream push on comment action, on commit, or pull-request
334 """
335 if not comment_broadcast_channel:
336 return
337
338 _ = request.translate
260 339
261 try:
262 return channelstream_request(
263 channelstream_config, [payload], '/message',
264 raise_exc=False)
265 except ChannelstreamException:
266 log.exception('Failed to send channelstream data')
267 raise
340 comment_data = kwargs.pop('comment_data', {})
341 user_data = kwargs.pop('user_data', {})
342 comment_id = comment_data.get('comment_id')
343
344 message = '<strong>{}</strong> {} #{}, {}'.format(
345 user.username,
346 msg,
347 comment_id,
348 _reload_link(_('Reload page to see new comments')),
349 )
350
351 message_obj = {
352 'message': message,
353 'level': 'success',
354 'topic': '/notifications'
355 }
356
357 post_message(
358 comment_broadcast_channel, message_obj, user.username,
359 registry=request.registry)
360
361 message_obj = {
362 'message': None,
363 'user': user.username,
364 'comment_id': comment_id,
365 'comment_data': comment_data,
366 'user_data': user_data,
367 'topic': '/comment'
368 }
369 post_message(
370 comment_broadcast_channel, message_obj, user.username,
371 registry=request.registry)
@@ -462,55 +462,11 b' class CommentsModel(BaseModel):'
462 462 else:
463 463 action = 'repo.commit.comment.create'
464 464
465 comment_id = comment.comment_id
466 465 comment_data = comment.get_api_data()
467 466
468 467 self._log_audit_action(
469 468 action, {'data': comment_data}, auth_user, comment)
470 469
471 channel = None
472 if commit_obj:
473 repo_name = repo.repo_name
474 channel = u'/repo${}$/commit/{}'.format(
475 repo_name,
476 commit_obj.raw_id
477 )
478 elif pull_request_obj:
479 repo_name = pr_target_repo.repo_name
480 channel = u'/repo${}$/pr/{}'.format(
481 repo_name,
482 pull_request_obj.pull_request_id
483 )
484
485 if channel:
486 username = user.username
487 message = '<strong>{}</strong> {} #{}, {}'
488 message = message.format(
489 username,
490 _('posted a new comment'),
491 comment_id,
492 _('Refresh the page to see new comments.'))
493
494 message_obj = {
495 'message': message,
496 'level': 'success',
497 'topic': '/notifications'
498 }
499
500 channelstream.post_message(
501 channel, message_obj, user.username,
502 registry=get_current_registry())
503
504 message_obj = {
505 'message': None,
506 'user': username,
507 'comment_id': comment_id,
508 'topic': '/comment'
509 }
510 channelstream.post_message(
511 channel, message_obj, user.username,
512 registry=get_current_registry())
513
514 470 return comment
515 471
516 472 def edit(self, comment_id, text, auth_user, version):
General Comments 0
You need to be logged in to leave comments. Login now