comment.py
156 lines
| 5.5 KiB
| text/x-python
|
PythonLexer
r1670 | # -*- coding: utf-8 -*- | |||
""" | ||||
rhodecode.model.comment | ||||
~~~~~~~~~~~~~~~~~~~~~~~ | ||||
comments model for RhodeCode | ||||
r1789 | ||||
r1670 | :created_on: Nov 11, 2011 | |||
:author: marcink | ||||
r1824 | :copyright: (C) 2011-2012 Marcin Kuzminski <marcin@python-works.com> | |||
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 | ||||
r1712 | from pylons.i18n.translation import _ | |||
from sqlalchemy.util.compat import defaultdict | ||||
r2178 | from rhodecode.lib.utils2 import extract_mentioned_users, safe_unicode | |||
r1712 | from rhodecode.lib import helpers as h | |||
r1670 | from rhodecode.model import BaseModel | |||
r1712 | from rhodecode.model.db import ChangesetComment, User, Repository, Notification | |||
r1703 | from rhodecode.model.notification import NotificationModel | |||
r1670 | ||||
log = logging.getLogger(__name__) | ||||
class ChangesetCommentsModel(BaseModel): | ||||
r1713 | def __get_changeset_comment(self, changeset_comment): | |||
r1716 | return self._get_instance(ChangesetComment, changeset_comment) | |||
r1670 | ||||
r1712 | def _extract_mentions(self, s): | |||
r1713 | user_objects = [] | |||
for username in extract_mentioned_users(s): | ||||
r1712 | user_obj = User.get_by_username(username, case_insensitive=True) | |||
if user_obj: | ||||
r1713 | user_objects.append(user_obj) | |||
return user_objects | ||||
r1712 | ||||
r1675 | def create(self, text, repo_id, user_id, revision, f_path=None, | |||
r2296 | line_no=None, status_change=None): | |||
r1670 | """ | |||
r2296 | Creates new comment for changeset. IF status_change is not none | |||
this comment is associated with a status change of changeset | ||||
r1789 | ||||
r1670 | :param text: | |||
:param repo_id: | ||||
:param user_id: | ||||
r1675 | :param revision: | |||
r1670 | :param f_path: | |||
:param line_no: | ||||
r2296 | :param status_change: | |||
r1670 | """ | |||
r2150 | ||||
r1677 | if text: | |||
r1712 | repo = Repository.get(repo_id) | |||
r1716 | cs = repo.scm_instance.get_changeset(revision) | |||
r2178 | desc = "%s - %s" % (cs.short_id, h.shorter(cs.message, 256)) | |||
r2082 | author_email = cs.author_email | |||
r1677 | comment = ChangesetComment() | |||
r1712 | comment.repo = repo | |||
r1677 | comment.user_id = user_id | |||
comment.revision = revision | ||||
comment.text = text | ||||
comment.f_path = f_path | ||||
comment.line_no = line_no | ||||
r1670 | ||||
r1677 | self.sa.add(comment) | |||
r1712 | self.sa.flush() | |||
r1703 | # make notification | |||
r1712 | line = '' | |||
if line_no: | ||||
line = _('on line %s') % line_no | ||||
r2178 | subj = safe_unicode( | |||
h.link_to('Re commit: %(commit_desc)s %(line)s' % \ | ||||
{'commit_desc': desc, 'line': line}, | ||||
h.url('changeset_home', repo_name=repo.repo_name, | ||||
revision=revision, | ||||
anchor='comment-%s' % comment.comment_id, | ||||
qualified=True, | ||||
) | ||||
) | ||||
) | ||||
r1703 | body = text | |||
r2077 | ||||
# get the current participants of this changeset | ||||
r1703 | recipients = ChangesetComment.get_users(revision=revision) | |||
r2077 | ||||
r2082 | # add changeset author if it's in rhodecode system | |||
recipients += [User.get_by_email(author_email)] | ||||
r1716 | ||||
r2077 | NotificationModel().create( | |||
created_by=user_id, subject=subj, body=body, | ||||
r2296 | recipients=recipients, type_=Notification.TYPE_CHANGESET_COMMENT, | |||
email_kwargs={'status_change': status_change} | ||||
r2077 | ) | |||
r1703 | ||||
r1717 | mention_recipients = set(self._extract_mentions(body))\ | |||
.difference(recipients) | ||||
r1716 | if mention_recipients: | |||
subj = _('[Mention]') + ' ' + subj | ||||
r2077 | NotificationModel().create( | |||
created_by=user_id, subject=subj, body=body, | ||||
recipients=mention_recipients, | ||||
type_=Notification.TYPE_CHANGESET_COMMENT | ||||
) | ||||
r1716 | ||||
r1677 | return comment | |||
r1670 | ||||
r1713 | def delete(self, comment): | |||
r1670 | """ | |||
Deletes given comment | ||||
r1789 | ||||
r1670 | :param comment_id: | |||
""" | ||||
r1713 | comment = self.__get_changeset_comment(comment) | |||
r1670 | self.sa.delete(comment) | |||
r1713 | ||||
r1670 | return comment | |||
r1675 | ||||
def get_comments(self, repo_id, revision): | ||||
return ChangesetComment.query()\ | ||||
.filter(ChangesetComment.repo_id == repo_id)\ | ||||
.filter(ChangesetComment.revision == revision)\ | ||||
.filter(ChangesetComment.line_no == None)\ | ||||
.filter(ChangesetComment.f_path == None).all() | ||||
r1677 | def get_inline_comments(self, repo_id, revision): | |||
r1675 | comments = self.sa.query(ChangesetComment)\ | |||
.filter(ChangesetComment.repo_id == repo_id)\ | ||||
r1681 | .filter(ChangesetComment.revision == revision)\ | |||
.filter(ChangesetComment.line_no != None)\ | ||||
r2187 | .filter(ChangesetComment.f_path != None)\ | |||
.order_by(ChangesetComment.comment_id.asc())\ | ||||
.all() | ||||
r1677 | ||||
r1789 | paths = defaultdict(lambda: defaultdict(list)) | |||
r1675 | ||||
for co in comments: | ||||
r1677 | paths[co.f_path][co.line_no].append(co) | |||
return paths.items() | ||||