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= |
|
|
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 = |
|
|
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 = |
|
|
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 = |
|
|
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 |
|
|
|
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 |
|
|
|
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 |
|
|
|
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. |
|
|
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,13 +254,7 b' def post_message(channel, message, usern' | |||
|
242 | 254 | 'topic': '/notifications' |
|
243 | 255 | } |
|
244 | 256 | |
|
245 | if not registry: | |
|
246 | registry = get_current_registry() | |
|
247 | ||
|
248 | 257 | 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 | 258 |
|
|
253 | 259 |
|
|
254 | 260 |
|
@@ -265,3 +271,101 b' def post_message(channel, message, usern' | |||
|
265 | 271 |
|
|
266 | 272 |
|
|
267 | 273 |
|
|
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 | |
|
313 | ||
|
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 | |
|
339 | ||
|
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