##// END OF EJS Templates
- Manage User’s Groups: create, delete, rename, add/remove users inside....
- Manage User’s Groups: create, delete, rename, add/remove users inside. by user group admin. In this case, a user's group can be owned by several people thru an owner user's group. Some refactoring of naming, permission handling logic. - remove some code duplicity as well as inconsistent naming

File last commit:

r3430:bbe21df7 beta
r3714:7e3d89d9 beta
Show More
comment.py
284 lines | 10.6 KiB | text/x-python | PythonLexer
#77 code review...
r1670 # -*- coding: utf-8 -*-
"""
rhodecode.model.comment
~~~~~~~~~~~~~~~~~~~~~~~
comments model for RhodeCode
implements #308 rewrote diffs to enable displaying full diff on each file...
r1789
#77 code review...
r1670 :created_on: Nov 11, 2011
:author: marcink
2012 copyrights
r1824 :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com>
#77 code review...
r1670 :license: GPLv3, see COPYING for more details.
"""
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import logging
import traceback
Notification system improvements...
r1712 from pylons.i18n.translation import _
from sqlalchemy.util.compat import defaultdict
Notification fixes...
r2178 from rhodecode.lib.utils2 import extract_mentioned_users, safe_unicode
Notification system improvements...
r1712 from rhodecode.lib import helpers as h
#77 code review...
r1670 from rhodecode.model import BaseModel
- pull request generates overview based on it's params...
r2440 from rhodecode.model.db import ChangesetComment, User, Repository, \
Notification, PullRequest
notification fixes and improvements
r1703 from rhodecode.model.notification import NotificationModel
notifications changes...
r3430 from rhodecode.model.meta import Session
#77 code review...
r1670
log = logging.getLogger(__name__)
class ChangesetCommentsModel(BaseModel):
Added associated classes into child models
r2522 cls = ChangesetComment
Tests updates, Session refactoring
r1713 def __get_changeset_comment(self, changeset_comment):
notification to commit author + gardening
r1716 return self._get_instance(ChangesetComment, changeset_comment)
#77 code review...
r1670
- pull request generates overview based on it's params...
r2440 def __get_pull_request(self, pull_request):
return self._get_instance(PullRequest, pull_request)
Notification system improvements...
r1712 def _extract_mentions(self, s):
Tests updates, Session refactoring
r1713 user_objects = []
for username in extract_mentioned_users(s):
Notification system improvements...
r1712 user_obj = User.get_by_username(username, case_insensitive=True)
if user_obj:
Tests updates, Session refactoring
r1713 user_objects.append(user_obj)
return user_objects
Notification system improvements...
r1712
notifications changes...
r3430 def _get_notification_data(self, repo, comment, user, comment_text,
line_no=None, revision=None, pull_request=None,
status_change=None, closing_pr=False):
"""
Get notification data
:param comment_text:
:param line:
:returns: tuple (subj,body,recipients,notification_type,email_kwargs)
"""
# make notification
body = comment_text # text of the comment
line = ''
if line_no:
line = _('on line %s') % line_no
#changeset
if revision:
notification_type = Notification.TYPE_CHANGESET_COMMENT
cs = repo.scm_instance.get_changeset(revision)
desc = "%s" % (cs.short_id)
_url = h.url('changeset_home',
repo_name=repo.repo_name,
revision=revision,
anchor='comment-%s' % comment.comment_id,
qualified=True,
)
subj = safe_unicode(
h.link_to('Re changeset: %(desc)s %(line)s' % \
{'desc': desc, 'line': line},
_url)
)
email_subject = 'User %s commented on changeset %s' % \
(user.username, h.short_id(revision))
# get the current participants of this changeset
recipients = ChangesetComment.get_users(revision=revision)
# add changeset author if it's in rhodecode system
cs_author = User.get_from_cs_author(cs.author)
if not cs_author:
#use repo owner if we cannot extract the author correctly
cs_author = repo.user
recipients += [cs_author]
email_kwargs = {
'status_change': status_change,
'cs_comment_user': h.person(user.email),
'cs_target_repo': h.url('summary_home', repo_name=repo.repo_name,
qualified=True),
'cs_comment_url': _url,
'raw_id': revision,
'message': cs.message
}
#pull request
elif pull_request:
notification_type = Notification.TYPE_PULL_REQUEST_COMMENT
desc = comment.pull_request.title
_url = h.url('pullrequest_show',
repo_name=pull_request.other_repo.repo_name,
pull_request_id=pull_request.pull_request_id,
anchor='comment-%s' % comment.comment_id,
qualified=True,
)
subj = safe_unicode(
h.link_to('Re pull request #%(pr_id)s: %(desc)s %(line)s' % \
{'desc': desc,
'pr_id': comment.pull_request.pull_request_id,
'line': line},
_url)
)
email_subject = 'User %s commented on pull request #%s' % \
(user.username, comment.pull_request.pull_request_id)
# get the current participants of this pull request
recipients = ChangesetComment.get_users(pull_request_id=
pull_request.pull_request_id)
# add pull request author
recipients += [pull_request.author]
# add the reviewers to notification
recipients += [x.user for x in pull_request.reviewers]
#set some variables for email notification
email_kwargs = {
'pr_id': pull_request.pull_request_id,
'status_change': status_change,
'closing_pr': closing_pr,
'pr_comment_url': _url,
'pr_comment_user': h.person(user.email),
'pr_target_repo': h.url('summary_home',
repo_name=pull_request.other_repo.repo_name,
qualified=True)
}
return subj, body, recipients, notification_type, email_kwargs, email_subject
Added dynamic data loading for other repo we open pull request against...
r2541 def create(self, text, repo, user, revision=None, pull_request=None,
notifications changes...
r3430 f_path=None, line_no=None, status_change=None, closing_pr=False,
send_email=True):
#77 code review...
r1670 """
- added commenting to pull requests...
r2443 Creates new comment for changeset or pull request.
white space cleanup
r2478 IF status_change is not none this comment is associated with a
- added commenting to pull requests...
r2443 status change of changeset or changesets associated with pull request
implements #308 rewrote diffs to enable displaying full diff on each file...
r1789
#77 code review...
r1670 :param text:
Added dynamic data loading for other repo we open pull request against...
r2541 :param repo:
:param user:
code refactoring
r1675 :param revision:
- added commenting to pull requests...
r2443 :param pull_request:
#77 code review...
r1670 :param f_path:
:param line_no:
Add changeset status change into emails
r2296 :param status_change:
notifications changes...
r3430 :param closing_pr:
Don't send notification email for auto-status changes
r3257 :param send_email:
#77 code review...
r1670 """
- added commenting to pull requests...
r2443 if not text:
notifications changes...
r3430 log.warning('Missing text for comment, skipping...')
- added commenting to pull requests...
r2443 return
White space cleanup
r2150
Added dynamic data loading for other repo we open pull request against...
r2541 repo = self._get_repo(repo)
user = self._get_user(user)
- added commenting to pull requests...
r2443 comment = ChangesetComment()
comment.repo = repo
Added dynamic data loading for other repo we open pull request against...
r2541 comment.author = user
- added commenting to pull requests...
r2443 comment.text = text
comment.f_path = f_path
comment.line_no = line_no
if revision:
#71 code-review...
r1677 comment.revision = revision
- added commenting to pull requests...
r2443 elif pull_request:
pull_request = self.__get_pull_request(pull_request)
comment.pull_request = pull_request
else:
raise Exception('Please specify revision or pull_request_id')
#77 code review...
r1670
notifications changes...
r3430 Session().add(comment)
Session().flush()
- added commenting to pull requests...
r2443
Don't send notification email for auto-status changes
r3257 if send_email:
notifications changes...
r3430 (subj, body, recipients, notification_type,
email_kwargs, email_subject) = self._get_notification_data(
repo, comment, user,
comment_text=text,
line_no=line_no,
revision=revision,
pull_request=pull_request,
status_change=status_change,
closing_pr=closing_pr)
Don't send notification email for auto-status changes
r3257 # create notification objects, and emails
code garden
r2077 NotificationModel().create(
Added dynamic data loading for other repo we open pull request against...
r2541 created_by=user, subject=subj, body=body,
Don't send notification email for auto-status changes
r3257 recipients=recipients, type_=notification_type,
notifications changes...
r3430 email_kwargs=email_kwargs, email_subject=email_subject
code garden
r2077 )
notification fixes and improvements
r1703
Don't send notification email for auto-status changes
r3257 mention_recipients = set(self._extract_mentions(body))\
.difference(recipients)
if mention_recipients:
email_kwargs.update({'pr_mention': True})
subj = _('[Mention]') + ' ' + subj
NotificationModel().create(
created_by=user, subject=subj, body=body,
recipients=mention_recipients,
type_=notification_type,
email_kwargs=email_kwargs
)
- added commenting to pull requests...
r2443 return comment
#77 code review...
r1670
Tests updates, Session refactoring
r1713 def delete(self, comment):
#77 code review...
r1670 """
Deletes given comment
implements #308 rewrote diffs to enable displaying full diff on each file...
r1789
#77 code review...
r1670 :param comment_id:
"""
Tests updates, Session refactoring
r1713 comment = self.__get_changeset_comment(comment)
notifications changes...
r3430 Session().delete(comment)
Tests updates, Session refactoring
r1713
#77 code review...
r1670 return comment
code refactoring
r1675
- pull request generates overview based on it's params...
r2440 def get_comments(self, repo_id, revision=None, pull_request=None):
Refactoring of changeset_file_comments for more generic usage. In both It enables sharing code between changeset, and pull requests discussions
r2439 """
Get's main comments based on revision or pull_request_id
:param repo_id:
:param revision:
- pull request generates overview based on it's params...
r2440 :param pull_request:
Refactoring of changeset_file_comments for more generic usage. In both It enables sharing code between changeset, and pull requests discussions
r2439 """
- pull request generates overview based on it's params...
r2440
Refactoring of changeset_file_comments for more generic usage. In both It enables sharing code between changeset, and pull requests discussions
r2439 q = ChangesetComment.query()\
code refactoring
r1675 .filter(ChangesetComment.repo_id == repo_id)\
.filter(ChangesetComment.line_no == None)\
Refactoring of changeset_file_comments for more generic usage. In both It enables sharing code between changeset, and pull requests discussions
r2439 .filter(ChangesetComment.f_path == None)
if revision:
q = q.filter(ChangesetComment.revision == revision)
- pull request generates overview based on it's params...
r2440 elif pull_request:
pull_request = self.__get_pull_request(pull_request)
q = q.filter(ChangesetComment.pull_request == pull_request)
Refactoring of changeset_file_comments for more generic usage. In both It enables sharing code between changeset, and pull requests discussions
r2439 else:
- pull request generates overview based on it's params...
r2440 raise Exception('Please specify revision or pull_request')
Added created_on column to changeset comments for proper ordering.
r2639 q = q.order_by(ChangesetComment.created_on)
Refactoring of changeset_file_comments for more generic usage. In both It enables sharing code between changeset, and pull requests discussions
r2439 return q.all()
code refactoring
r1675
- pull request generates overview based on it's params...
r2440 def get_inline_comments(self, repo_id, revision=None, pull_request=None):
notifications changes...
r3430 q = Session().query(ChangesetComment)\
code refactoring
r1675 .filter(ChangesetComment.repo_id == repo_id)\
fixes inline comments double entries
r1681 .filter(ChangesetComment.line_no != None)\
#415: Adding comment to changeset causes reload...
r2187 .filter(ChangesetComment.f_path != None)\
.order_by(ChangesetComment.comment_id.asc())\
Refactoring of changeset_file_comments for more generic usage. In both It enables sharing code between changeset, and pull requests discussions
r2439
if revision:
q = q.filter(ChangesetComment.revision == revision)
- pull request generates overview based on it's params...
r2440 elif pull_request:
pull_request = self.__get_pull_request(pull_request)
q = q.filter(ChangesetComment.pull_request == pull_request)
Refactoring of changeset_file_comments for more generic usage. In both It enables sharing code between changeset, and pull requests discussions
r2439 else:
raise Exception('Please specify revision or pull_request_id')
comments = q.all()
#71 code-review...
r1677
implements #308 rewrote diffs to enable displaying full diff on each file...
r1789 paths = defaultdict(lambda: defaultdict(list))
code refactoring
r1675
for co in comments:
#71 code-review...
r1677 paths[co.f_path][co.line_no].append(co)
return paths.items()