diff --git a/rhodecode/config/routing.py b/rhodecode/config/routing.py
--- a/rhodecode/config/routing.py
+++ b/rhodecode/config/routing.py
@@ -457,6 +457,12 @@ def make_map(config):
action='show_all', conditions=dict(function=check_repo,
method=["GET"]))
+ rmap.connect('pullrequest_comment',
+ '/{repo_name:.*}/pull-request-comment/{pull_request_id}',
+ controller='pullrequests',
+ action='comment', conditions=dict(function=check_repo,
+ method=["POST"]))
+
rmap.connect('summary_home', '/{repo_name:.*}/summary',
controller='summary', conditions=dict(function=check_repo))
diff --git a/rhodecode/controllers/changeset.py b/rhodecode/controllers/changeset.py
--- a/rhodecode/controllers/changeset.py
+++ b/rhodecode/controllers/changeset.py
@@ -390,10 +390,10 @@ class ChangesetController(BaseRepoContro
if status and change_status:
ChangesetStatusModel().set_status(
c.rhodecode_db_repo.repo_id,
- revision,
status,
c.rhodecode_user.user_id,
comm,
+ revision=revision,
)
action_logger(self.rhodecode_user,
'user_commented_revision:%s' % revision,
diff --git a/rhodecode/controllers/pullrequests.py b/rhodecode/controllers/pullrequests.py
--- a/rhodecode/controllers/pullrequests.py
+++ b/rhodecode/controllers/pullrequests.py
@@ -24,19 +24,20 @@
# along with this program. If not, see .
import logging
import traceback
-import binascii
from webob.exc import HTTPNotFound
from pylons import request, response, session, tmpl_context as c, url
from pylons.controllers.util import abort, redirect
from pylons.i18n.translation import _
+from pylons.decorators import jsonify
from rhodecode.lib.base import BaseRepoController, render
from rhodecode.lib.auth import LoginRequired, HasRepoPermissionAnyDecorator
from rhodecode.lib import helpers as h
from rhodecode.lib import diffs
-from rhodecode.model.db import User, PullRequest, Repository, ChangesetStatus
+from rhodecode.lib.utils import action_logger
+from rhodecode.model.db import User, PullRequest, ChangesetStatus
from rhodecode.model.pull_request import PullRequestModel
from rhodecode.model.meta import Session
from rhodecode.model.repo import RepoModel
@@ -208,9 +209,56 @@ class PullrequestsController(BaseRepoCon
.get_comments(c.rhodecode_db_repo.repo_id,
pull_request=pull_request_id)
- # changeset(pull-request) statuse
+ # changeset(pull-request) status
c.current_changeset_status = ChangesetStatusModel()\
- .get_status(c.rhodecode_db_repo.repo_id,
- pull_request=pull_request_id)
+ .get_status(c.pull_request.org_repo,
+ pull_request=c.pull_request)
c.changeset_statuses = ChangesetStatus.STATUSES
return render('/pullrequests/pullrequest_show.html')
+
+ @jsonify
+ def comment(self, repo_name, pull_request_id):
+
+ status = request.POST.get('changeset_status')
+ change_status = request.POST.get('change_changeset_status')
+
+ comm = ChangesetCommentsModel().create(
+ text=request.POST.get('text'),
+ repo_id=c.rhodecode_db_repo.repo_id,
+ user_id=c.rhodecode_user.user_id,
+ pull_request=pull_request_id,
+ f_path=request.POST.get('f_path'),
+ line_no=request.POST.get('line'),
+ status_change=(ChangesetStatus.get_status_lbl(status)
+ if status and change_status else None)
+ )
+
+ # get status if set !
+ if status and change_status:
+ ChangesetStatusModel().set_status(
+ c.rhodecode_db_repo.repo_id,
+ status,
+ c.rhodecode_user.user_id,
+ comm,
+ pull_request=pull_request_id
+ )
+ action_logger(self.rhodecode_user,
+ 'user_commented_pull_request:%s' % pull_request_id,
+ c.rhodecode_db_repo, self.ip_addr, self.sa)
+
+ Session.commit()
+
+ if not request.environ.get('HTTP_X_PARTIAL_XHR'):
+ return redirect(h.url('pullrequest_show', repo_name=repo_name,
+ pull_request_id=pull_request_id))
+
+ data = {
+ 'target_id': h.safeid(h.safe_unicode(request.POST.get('f_path'))),
+ }
+ if comm:
+ c.co = comm
+ data.update(comm.get_dict())
+ data.update({'rendered_text':
+ render('changeset/changeset_comment_block.html')})
+
+ return data
\ No newline at end of file
diff --git a/rhodecode/model/changeset_status.py b/rhodecode/model/changeset_status.py
--- a/rhodecode/model/changeset_status.py
+++ b/rhodecode/model/changeset_status.py
@@ -66,12 +66,15 @@ class ChangesetStatusModel(BaseModel):
else:
raise Exception('Please specify revision or pull_request')
- status = q.scalar()
+ # need to use first here since there can be multiple statuses
+ # returned from pull_request
+ status = q.first()
status = status.status if status else status
st = status or ChangesetStatus.DEFAULT
return str(st)
- def set_status(self, repo, revision, status, user, comment):
+ def set_status(self, repo, status, user, comment, revision=None,
+ pull_request=None):
"""
Creates new status for changeset or updates the old ones bumping their
version, leaving the current status at
@@ -89,20 +92,48 @@ class ChangesetStatusModel(BaseModel):
"""
repo = self._get_repo(repo)
- cur_statuses = ChangesetStatus.query()\
- .filter(ChangesetStatus.repo == repo)\
- .filter(ChangesetStatus.revision == revision)\
- .all()
+ q = ChangesetStatus.query()
+
+ if revision:
+ q = q.filter(ChangesetStatus.repo == repo)
+ q = q.filter(ChangesetStatus.revision == revision)
+ elif pull_request:
+ pull_request = self.__get_pull_request(pull_request)
+ q = q.filter(ChangesetStatus.repo == pull_request.org_repo)
+ q = q.filter(ChangesetStatus.pull_request == pull_request)
+ cur_statuses = q.all()
+
if cur_statuses:
for st in cur_statuses:
st.version += 1
self.sa.add(st)
- new_status = ChangesetStatus()
- new_status.author = self._get_user(user)
- new_status.repo = self._get_repo(repo)
- new_status.status = status
- new_status.revision = revision
- new_status.comment = comment
- self.sa.add(new_status)
- return new_status
+
+ def _create_status(user, repo, status, comment, revision, pull_request):
+ new_status = ChangesetStatus()
+ new_status.author = self._get_user(user)
+ new_status.repo = self._get_repo(repo)
+ new_status.status = status
+ new_status.comment = comment
+ new_status.revision = revision
+ new_status.pull_request = pull_request
+ return new_status
+ if revision:
+ new_status = _create_status(user=user, repo=repo, status=status,
+ comment=comment, revision=revision,
+ pull_request=None)
+ self.sa.add(new_status)
+ return new_status
+ elif pull_request:
+ #pull request can have more than one revision associated to it
+ #we need to create new version for each one
+ new_statuses = []
+ repo = pull_request.org_repo
+ for rev in pull_request.revisions:
+ new_status = _create_status(user=user, repo=repo,
+ status=status, comment=comment,
+ revision=rev,
+ pull_request=pull_request)
+ new_statuses.append(new_status)
+ self.sa.add(new_status)
+ return new_statuses
diff --git a/rhodecode/model/comment.py b/rhodecode/model/comment.py
--- a/rhodecode/model/comment.py
+++ b/rhodecode/model/comment.py
@@ -55,38 +55,54 @@ class ChangesetCommentsModel(BaseModel):
user_objects.append(user_obj)
return user_objects
- def create(self, text, repo_id, user_id, revision, f_path=None,
- line_no=None, status_change=None):
+ def create(self, text, repo_id, user_id, revision=None, pull_request=None,
+ f_path=None, line_no=None, status_change=None):
"""
- Creates new comment for changeset. IF status_change is not none
- this comment is associated with a status change of changeset
+ Creates new comment for changeset or pull request.
+ IF status_change is not none this comment is associated with a
+ status change of changeset or changesets associated with pull request
:param text:
:param repo_id:
:param user_id:
:param revision:
+ :param pull_request:
:param f_path:
:param line_no:
:param status_change:
"""
+ if not text:
+ return
- if text:
- repo = Repository.get(repo_id)
+ repo = Repository.get(repo_id)
+ comment = ChangesetComment()
+ comment.repo = repo
+ comment.user_id = user_id
+ comment.text = text
+ comment.f_path = f_path
+ comment.line_no = line_no
+
+ if revision:
cs = repo.scm_instance.get_changeset(revision)
desc = "%s - %s" % (cs.short_id, h.shorter(cs.message, 256))
author_email = cs.author_email
- comment = ChangesetComment()
- comment.repo = repo
- comment.user_id = user_id
comment.revision = revision
- comment.text = text
- comment.f_path = f_path
- comment.line_no = line_no
+ elif pull_request:
+ pull_request = self.__get_pull_request(pull_request)
+ comment.pull_request = pull_request
+ desc = ''
+ else:
+ raise Exception('Please specify revision or pull_request_id')
- self.sa.add(comment)
- self.sa.flush()
- # make notification
- line = ''
+ self.sa.add(comment)
+ self.sa.flush()
+
+ # make notification
+ line = ''
+ body = text
+
+ #changeset
+ if revision:
if line_no:
line = _('on line %s') % line_no
subj = safe_unicode(
@@ -99,34 +115,41 @@ class ChangesetCommentsModel(BaseModel):
)
)
)
-
- body = text
-
+ notification_type = Notification.TYPE_CHANGESET_COMMENT
# get the current participants of this changeset
recipients = ChangesetComment.get_users(revision=revision)
-
# add changeset author if it's in rhodecode system
recipients += [User.get_by_email(author_email)]
+ #pull request
+ elif pull_request:
+ #TODO: make this something usefull
+ subj = 'commented on pull request something...'
+ notification_type = Notification.TYPE_PULL_REQUEST_COMMENT
+ # 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]
- # create notification objects, and emails
+ # create notification objects, and emails
+ NotificationModel().create(
+ created_by=user_id, subject=subj, body=body,
+ recipients=recipients, type_=notification_type,
+ email_kwargs={'status_change': status_change}
+ )
+
+ mention_recipients = set(self._extract_mentions(body))\
+ .difference(recipients)
+ if mention_recipients:
+ subj = _('[Mention]') + ' ' + subj
NotificationModel().create(
- created_by=user_id, subject=subj, body=body,
- recipients=recipients, type_=Notification.TYPE_CHANGESET_COMMENT,
- email_kwargs={'status_change': status_change}
+ created_by=user_id, subject=subj, body=body,
+ recipients=mention_recipients,
+ type_=notification_type,
+ email_kwargs={'status_change': status_change}
)
- mention_recipients = set(self._extract_mentions(body))\
- .difference(recipients)
- if mention_recipients:
- subj = _('[Mention]') + ' ' + subj
- NotificationModel().create(
- created_by=user_id, subject=subj, body=body,
- recipients=mention_recipients,
- type_=Notification.TYPE_CHANGESET_COMMENT,
- email_kwargs={'status_change': status_change}
- )
-
- return comment
+ return comment
def delete(self, comment):
"""
diff --git a/rhodecode/model/db.py b/rhodecode/model/db.py
--- a/rhodecode/model/db.py
+++ b/rhodecode/model/db.py
@@ -766,7 +766,12 @@ class Repository(Base, BaseModel):
statuses = statuses.filter(ChangesetStatus.revision.in_(revisions))
grouped = {}
for stat in statuses.all():
- grouped[stat.revision] = [str(stat.status), stat.status_lbl]
+ pr_id = pr_repo = None
+ if stat.pull_request:
+ pr_id = stat.pull_request.pull_request_id
+ pr_repo = stat.pull_request.other_repo.repo_name
+ grouped[stat.revision] = [str(stat.status), stat.status_lbl,
+ pr_id, pr_repo]
return grouped
#==========================================================================
@@ -1336,17 +1341,21 @@ class ChangesetComment(Base, BaseModel):
pull_request = relationship('PullRequest', lazy='joined')
@classmethod
- def get_users(cls, revision):
+ def get_users(cls, revision=None, pull_request_id=None):
"""
- Returns user associated with this changesetComment. ie those
+ Returns user associated with this ChangesetComment. ie those
who actually commented
:param cls:
:param revision:
"""
- return Session.query(User)\
- .filter(cls.revision == revision)\
- .join(ChangesetComment.author).all()
+ q = Session.query(User)\
+ .join(ChangesetComment.author)
+ if revision:
+ q = q.filter(cls.revision == revision)
+ elif pull_request_id:
+ q = q.filter(cls.pull_request_id == pull_request_id)
+ return q.all()
class ChangesetStatus(Base, BaseModel):
@@ -1457,6 +1466,7 @@ class Notification(Base, BaseModel):
TYPE_MENTION = u'mention'
TYPE_REGISTRATION = u'registration'
TYPE_PULL_REQUEST = u'pull_request'
+ TYPE_PULL_REQUEST_COMMENT = u'pull_request_comment'
notification_id = Column('notification_id', Integer(), nullable=False, primary_key=True)
subject = Column('subject', Unicode(512), nullable=True)
diff --git a/rhodecode/model/notification.py b/rhodecode/model/notification.py
--- a/rhodecode/model/notification.py
+++ b/rhodecode/model/notification.py
@@ -198,13 +198,15 @@ class NotificationModel(BaseModel):
Creates a human readable description based on properties
of notification object
"""
-
+ #alias
+ _n = notification
_map = {
- notification.TYPE_CHANGESET_COMMENT: _('commented on commit'),
- notification.TYPE_MESSAGE: _('sent message'),
- notification.TYPE_MENTION: _('mentioned you'),
- notification.TYPE_REGISTRATION: _('registered in RhodeCode'),
- notification.TYPE_PULL_REQUEST: _('opened new pull request')
+ _n.TYPE_CHANGESET_COMMENT: _('commented on commit'),
+ _n.TYPE_MESSAGE: _('sent message'),
+ _n.TYPE_MENTION: _('mentioned you'),
+ _n.TYPE_REGISTRATION: _('registered in RhodeCode'),
+ _n.TYPE_PULL_REQUEST: _('opened new pull request'),
+ _n.TYPE_PULL_REQUEST_COMMENT: _('commented on pull request')
}
tmpl = "%(user)s %(action)s %(when)s"
diff --git a/rhodecode/templates/changelog/changelog.html b/rhodecode/templates/changelog/changelog.html
--- a/rhodecode/templates/changelog/changelog.html
+++ b/rhodecode/templates/changelog/changelog.html
@@ -85,7 +85,13 @@
%if c.statuses.get(cs.raw_id):
${c.statuses.get(cs.raw_id)[1]}
-
+
+ %if c.statuses.get(cs.raw_id)[2]:
+
![](${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])})
+ %else:
+
![](${h.url('/images/icons/flag_status_%s.png' % c.statuses.get(cs.raw_id)[0])})
+ %endif
+
%endif
diff --git a/rhodecode/templates/pullrequests/pullrequest_show.html b/rhodecode/templates/pullrequests/pullrequest_show.html
--- a/rhodecode/templates/pullrequests/pullrequest_show.html
+++ b/rhodecode/templates/pullrequests/pullrequest_show.html
@@ -70,8 +70,8 @@
##${comment.comment_inline_form(c.changeset)}
## render comments main comments form and it status
- ##${comment.comments(h.url('pull_request_comment', repo_name=c.repo_name, pull_request_id=c.pull_request.pull_request_id),
- ## c.current_changeset_status)}
+ ${comment.comments(h.url('pullrequest_comment', repo_name=c.repo_name, pull_request_id=c.pull_request.pull_request_id),
+ c.current_changeset_status)}