def _render(self, request, view='', error=None): current_user = request.user # TODO: user flash message ticket = self.ticket pullreq = self.pullreq project = self.project commits = self.all_commits try: diff_length = pullreq.get_diff_length() except: # FIXME: more exception detail diff_length = 0 user = request.user has_proj_perm = project.has_push_perm(user.name) if user else False show_merge_guide = (has_proj_perm or user.username == ticket.author) \ if user and not ticket.closed else False if not pullreq.merged and not ticket.closed: # FIXME: 这使得发邮件的时机有点奇怪?没人请求页面就不发吗? delta_commits = self.pullreq.get_delta_commits() if delta_commits: value = ','.join(c.sha for c in delta_commits) author = self.pullreq.from_proj.owner_name if self.ticket.add_commits(value, author): # 补充commits则发送通知邮件给pr参与者 dispatch('new_commits', data={ 'pullreq': self.pullreq, 'ticket': self.ticket, 'deltacommits': delta_commits, }) return st('/pull/ticket.html', **locals())
def add(cls, target_id, from_sha, to_sha, old_path, new_path, from_oid, to_oid, old_linenum, new_linenum, author, content): # TODO: dispatch 放到 view 里 from vilya.models.ticket import Ticket from vilya.libs.signals import codereview_signal from dispatches import dispatch comment = super(PullLineComment, cls).add(target_id, from_sha, to_sha, old_path, new_path, from_oid, to_oid, old_linenum, new_linenum, author, content) ticket = Ticket.get(target_id) # TODO: 重构feed之后取消signal发送 if ticket: codereview_signal.send(comment, content=content, ticket=ticket, author=author, comment=comment) dispatch('codereview', data={ 'comment': comment, 'ticket': ticket, 'sender': author, }) return comment
def create(self, request): if request.method == 'POST': user = request.user if not user: raise AccessError team = self.team if not team: raise TraversalError title = request.get_form_var('title', '').decode('utf-8') description = request.get_form_var('body', '').decode('utf-8') tags = request.get_form_var('issue_tags', []) if isinstance(tags, list): tags = [tag.decode('utf-8') for tag in tags if tag] elif isinstance(tags, basestring): tags = [tags.decode('utf-8')] if not(title and description): return request.redirect('../new?error=empty') tissue = self.cls.add(title, description, user.name, team=team.id) tissue.add_tags(tags, tissue.team_id) # TODO: 重构feed后删除这个signal issue_signal.send(author=user.name, content=description, issue_id=tissue.issue_id) dispatch('issue', data={ 'sender': user.name, 'content': description, 'issue': tissue, }) return request.redirect(tissue.url) return request.redirect(self.team.url + 'issues')
def close_pull(ticket, pullreq, user, content, comment, request): from dispatches import dispatch from vilya.libs.signals import pullrequest_signal project = ticket.project author = user.name ticket.close(author) pullreq.remove_branch_if_temp() # TODO: 重构Feed后取消发送这个信号 pullrequest_signal.send(author, comment=content, pullreq=pullreq, ticket_id=ticket.ticket_id, ticket=ticket, status="closed", new_version=True) dispatch('pullreq', data={ 'sender': author, 'comment': comment, 'ticket': ticket, 'status': 'closed' }) dispatch('pr_actions', data=dict(type='pr_closed', hooks=project.hooks, request=request, author=user, ticket=ticket, pullreq=pullreq, content=content))
def close_pull(ticket, pullreq, user, content, comment, request): from dispatches import dispatch from vilya.libs.signals import pullrequest_signal project = ticket.project author = user.name ticket.close(author) pullreq.remove_branch_if_temp() # TODO: 重构Feed后取消发送这个信号 pullrequest_signal.send(author, comment=content, pullreq=pullreq, ticket_id=ticket.ticket_id, ticket=ticket, status="closed", new_version=True) dispatch('pullreq', data={ 'sender': author, 'comment': comment, 'ticket': ticket, 'status': 'closed'}) dispatch('pr_actions', data=dict( type='pr_closed', hooks=project.hooks, request=request, author=user, ticket=ticket, pullreq=pullreq, content=content))
def create(self, request): if request.method == 'POST': user = request.user if not user: raise AccessError project = request.get_form_var('project') title = request.get_form_var('title', '').decode('utf-8') description = request.get_form_var('body', '').decode('utf-8') tags = request.get_form_var('issue_tags', []) if isinstance(tags, list): tags = [tag.decode('utf-8') for tag in tags if tag] elif isinstance(tags, basestring): tags = [tags.decode('utf-8')] if not project: raise TraversalError if not title.strip(): return request.redirect('/%s/issues/new?error=empty' % project) project = CodeDoubanProject.get_by_name(project) pissue = ProjectIssue.add(title, description, user.name, project=project.id) pissue.add_tags(tags, pissue.project_id) # TODO: 重构feed后取消信号发送 issue_signal.send(author=user.name, content=description, issue_id=pissue.issue_id) dispatch('issue', data={ 'sender': user.name, 'content': description, 'issue': pissue }) return request.redirect(pissue.url) project_name = self.proj_name return request.redirect('/%s/issues' % project_name)
def create(self, request): if request.method == "POST": user = request.user if not user: raise AccessError team = self.team if not team: raise TraversalError title = request.get_form_var("title", "").decode("utf-8") description = request.get_form_var("body", "").decode("utf-8") tags = request.get_form_var("issue_tags", []) if isinstance(tags, list): tags = [tag.decode("utf-8") for tag in tags if tag] elif isinstance(tags, basestring): tags = [tags.decode("utf-8")] if not (title and description): return request.redirect("../new?error=empty") tissue = self.cls.add(title, description, user.name, team=team.id) tissue.add_tags(tags, tissue.team_id) # TODO: 重构feed后删除这个signal issue_signal.send(author=user.name, content=description, issue_id=tissue.issue_id) dispatch("issue", data={"sender": user.name, "content": description, "issue": tissue}) return request.redirect(tissue.url) return request.redirect(self.team.url + "issues")
def add(cls, ticket_id, content, path, position, old, new, from_ref, author, new_path=None): # FIXME: mysql里的content是废的啊,是历史原因么? line_mark = str(old) + '|' + str(new) id = store.execute("insert into codedouban_ticket_codereview " "(ticket_id, content, path, position, line_mark, " "from_ref, author, new_path) " "values (%s, %s, %s, %s, %s, %s, %s, %s)", (ticket_id, content, path, position, line_mark, from_ref, author, new_path)) if not id: store.rollback() raise Exception("Unable to add") store.commit() bdb.set(BDB_TICKET_LINECOMMENT_CONTENT_KEY % id, content) comment = cls.get(id) ticket = Ticket.get(ticket_id) # TODO: 重构feed之后取消signal发送 codereview_signal.send(comment, content=content, ticket=Ticket.get(ticket_id), author=author, comment=comment) dispatch('codereview', data={ 'comment': comment, 'ticket': ticket, 'sender': author, }) return comment
def _push_qaci_noti(self, sha, state, target_url): project = self.project pulls = project.open_family_pulls for p in pulls: if sha in p.get_commits_shas() and state in ('success', 'failure'): dispatch('qaci', data=dict(sha=sha, pull=p, project=project, state=state, url=target_url))
def _q_index(self, request): if request.method != "POST": return json.dumps({'r': 0}) data = request.get_form_var('payload') if not data: return json.dumps({'r': 0}) data = json.loads(data) for ref in data.get('refs', []): push = PushPayload( self.repo, ref.get('old_value'), ref.get('new_value'), ref.get('ref_name'), ref.get('user_name')) dispatch('push_actions', data=push.payload) return json.dumps({'r': 1})
def _q_index(self, request): if request.method != "POST": return json.dumps({'r': 0}) data = request.get_form_var('payload') if not data: return json.dumps({'r': 0}) data = json.loads(data) for ref in data.get('refs', []): push = PushPayload(self.repo, ref.get('old_value'), ref.get('new_value'), ref.get('ref_name'), ref.get('user_name')) dispatch('push_actions', data=push.payload) return json.dumps({'r': 1})
def _add_additional_commits(self): # FIXME: Used in views/api/__init__.py delta_commits = self.pullreq.get_delta_commits() if delta_commits: value = ','.join(c.sha for c in delta_commits) author = self.pullreq.from_proj.owner_name if self.ticket.add_commits(value, author): # 补充commits则发送通知邮件给pr参与者 dispatch('new_commits', data={ 'pullreq': self.pullreq, 'ticket': self.ticket, 'deltacommits': delta_commits, })
def create(self, request): user = request.user if not user: return dict(r=1) project = CodeDoubanProject.get_by_name(self.proj_name) project_id = project.id from_sha = request.get_form_var('from_sha') assert from_sha, "comment from_sha cannot be empty" old_path = request.get_form_var('old_path') assert old_path, "comment old_path cannot be empty" new_path = request.get_form_var('new_path') assert new_path, "comment new path cannot be empty" # position = request.get_form_var('position') # assert position, "comment position cannot be empty" from_oid = request.get_form_var('from_oid') assert from_oid, "comment from_oid cannot be empty" to_oid = request.get_form_var('to_oid') assert to_oid, "comment to_oid cannot be empty" old = request.get_form_var('old_no') old = int(old) if old.isdigit() else LINECOMMENT_INDEX_EMPTY new = request.get_form_var('new_no') new = int(new) if new.isdigit() else LINECOMMENT_INDEX_EMPTY content = request.get_form_var('content', '') # FIXME: commit_author is None commit_author = request.get_form_var('commit_author') if not content.strip(): return {'error': 'Content is empty!'} comment = CommitLineComment.add(project_id, from_sha, '', old_path, new_path, from_oid, to_oid, old, new, user.name, content) dispatch('comment', data={ 'comment': comment, 'commit_author': commit_author, 'is_line_comment': True, }) # TODO: 目前只是回写一个链接,可以多传点信息支持直接回写到pr linecomment # for commit linecomments rewrite to pr dispatch('comment_actions', data={ 'type': 'commit_linecomment', 'comment': comment, 'commit_author': commit_author, }) comment_uid = comment.uid return dict(r=0, html=st('/commit_linecomment.html', **locals()))
def add(cls, from_user, to_user, content): if from_user == to_user: return recommendation_id = store.execute( "insert into codedouban_recommendations " "(from_user, to_user, content) " "values (%s, %s, %s)", (from_user, to_user, content)) if not recommendation_id: store.rollback() raise Exception("Unable to insert new recommendation") store.commit() rec = cls.get(recommendation_id) dispatch('recommend', data={'recommend': rec}) return rec
def add(cls, project, ref, author, content, commit_author=None): new_comment_id = add(project.id, ref, author, content) new_comment = cls.get(new_comment_id) dispatch('comment', data={ 'comment': new_comment, 'commit_author': commit_author, }) # for commit comments rewrite to pr dispatch('comment_actions', data={ 'type': 'commit_comment', 'comment': new_comment, 'commit_author': commit_author, }) return new_comment
def after_create(self, extra_args): from models.ticket import Ticket comment = self TicketNode.add_comment(comment) content = extra_args bdb.set(BDB_TICKET_COMMENT_CONTENT_KEY % self.id, content) ticket = Ticket.get(self.ticket_id) # TODO: 将Feed全部迁移到新的系统后,取消signal发送 codereview_signal.send(comment, content=content, ticket=ticket, author=self.author, comment=comment) dispatch('codereview', data={ 'comment': comment, 'ticket': ticket, 'sender': self.author, })
def after_create(self, extra_args): from vilya.models.ticket import Ticket comment = self TicketNode.add_comment(comment) content = extra_args bdb.set(BDB_TICKET_COMMENT_CONTENT_KEY % self.id, content) ticket = Ticket.get(self.ticket_id) # TODO: 将Feed全部迁移到新的系统后,取消signal发送 codereview_signal.send(comment, content=content, ticket=ticket, author=self.author, comment=comment) dispatch('codereview', data={ 'comment': comment, 'ticket': ticket, 'sender': self.author, })
def comment(self, request): target = self.target issue = self.issue issue_id = self.issue_id current_user = request.user if request.method == 'POST': content = request.get_form_var('content', '').decode('utf-8') user = request.user user = user.name if user else None if user: author = user if content.strip(): comment = issue.add_comment(content, user) issue.add_participant(user) html = st('/widgets/issue/issue_comment.html', **locals()) else: return {'error': 'Content is empty'} if request.get_form_var('comment_and_close'): issue.close(author) # TODO: 重构feed后取消信号发送 issue_signal.send(author=author, content=content, issue_id=issue_id) dispatch('issue', data={ 'sender': author, 'content': content, 'issue': issue, }) return dict(r=0, reload=1, redirect_to=issue.url) elif request.get_form_var('comment_and_open'): issue.open() # TODO: 重构feed后取消信号发送 issue_signal.send(author=author, content=content, issue_id=issue_id) dispatch('issue', data={ 'sender': author, 'content': content, 'issue': issue, }) return dict(r=0, reload=1, redirect_to=issue.url) elif content: issue_comment_signal.send(author=author, content=comment.content, issue_id=comment.issue_id, comment_id=comment.id) dispatch('issue_comment', data={ 'sender': author, 'content': comment.content, 'issue': issue, 'comment': comment}) participants = issue.participants teams = Team.get_all_team_uids() participants_html = st('/widgets/participation.html', **locals()) # FIXME: locals()? return dict( r=0, html=html, participants_html=participants_html) return request.redirect(issue.url)
def add(cls, ticket_id, content, path, position, old, new, from_ref, author, new_path=None): # FIXME: mysql里的content是废的啊,是历史原因么? line_mark = str(old) + '|' + str(new) id = store.execute( "insert into codedouban_ticket_codereview " "(ticket_id, content, path, position, line_mark, " "from_ref, author, new_path) " "values (%s, %s, %s, %s, %s, %s, %s, %s)", (ticket_id, content, path, position, line_mark, from_ref, author, new_path)) if not id: store.rollback() raise Exception("Unable to add") store.commit() bdb.set(BDB_TICKET_LINECOMMENT_CONTENT_KEY % id, content) comment = cls.get(id) ticket = Ticket.get(ticket_id) # TODO: 重构feed之后取消signal发送 codereview_signal.send(comment, content=content, ticket=Ticket.get(ticket_id), author=author, comment=comment) dispatch('codereview', data={ 'comment': comment, 'ticket': ticket, 'sender': author, }) return comment
def add(cls, target_id, from_sha, to_sha, old_path, new_path, from_oid, to_oid, old_linenum, new_linenum, author, content): # TODO: dispatch 放到 view 里 from vilya.models.ticket import Ticket from vilya.libs.signals import codereview_signal from dispatches import dispatch comment = super(PullLineComment, cls).add( target_id, from_sha, to_sha, old_path, new_path, from_oid, to_oid, old_linenum, new_linenum, author, content) ticket = Ticket.get(target_id) # TODO: 重构feed之后取消signal发送 if ticket: codereview_signal.send(comment, content=content, ticket=ticket, author=author, comment=comment) dispatch('codereview', data={ 'comment': comment, 'ticket': ticket, 'sender': author, }) return comment
def add_pull(ticket, pullreq, user): from dispatches import dispatch from vilya.libs.text import get_mentions_from_text from vilya.libs.signals import pullrequest_signal from vilya.models.user import get_author_by_email from vilya.models.user import User from vilya.models.trello.core import process_trello_notify reporter = user.username commits = pullreq.commits # TODO: refactory is! auto number how to? shas = [p.sha for p in commits] ticket_len = Ticket.get_count_by_proj_id(ticket.project_id) if ticket_len == 0: # 检查是否创建过新PR,若未创建过则以旧PR号为基准累加 max_ticket_id = PullRequest.get_max_ticket_id(ticket.project_id) if max_ticket_id >= 0: ticket = Ticket.add(ticket.project_id, ticket.title, ticket.description, ticket.author, max_ticket_id + 1) else: ticket = Ticket.add(ticket.project_id, ticket.title, ticket.description, ticket.author) else: ticket = Ticket.add(ticket.project_id, ticket.title, ticket.description, ticket.author) pullreq = pullreq.insert(ticket.ticket_number) if shas: ticket.add_commits(','.join(shas), reporter) noti_receivers = [committer.name for committer in CodeDoubanProject.get_committers_by_project(pullreq.to_proj.id)] # noqa noti_receivers = noti_receivers + [pullreq.to_proj.owner.name] get_commit_author = lambda u: get_author_by_email(u.email.encode('utf-8')) commit_authors = {get_commit_author(c.author) for c in commits} commit_authors = {a for a in commit_authors if a} noti_receivers.extend(commit_authors) # diffs, author_by_file, authors = pullreq.get_diffs(with_blame=True) # FIXME: diffs没用到? # diffs = pullreq.get_diffs() # blame代码变更的原作者, 也加到at users at_users = get_mentions_from_text(ticket.description) # at_users.extend(authors) at_users.append(pullreq.to_proj.owner_id) at_users = set(at_users) # FIXME: invited_users is used on page /hub/my_pull_requests/ invited_users = [User(u).add_invited_pull_request(ticket.id) for u in at_users] ProjectOwnLRUCounter(user.username).use(pullreq.to_proj.id) ProjectWatchLRUCounter(user.username).use(pullreq.to_proj.id) # TODO: 重构Feed之后取消这个信号的发送 pullrequest_signal.send(user.username, extra_receivers=noti_receivers, pullreq=pullreq, comment=ticket.description, ticket_id=ticket.ticket_id, ticket=ticket, status="unmerge", new_version=True) dispatch('pullreq', data=dict(sender=user.username, content=ticket.description, ticket=ticket, status='unmerge', new_version=True, extra_receivers=noti_receivers)) dispatch('pr_actions', data=dict(type='pr_opened', hooks=pullreq.to_proj.hooks, author=user, title=ticket.title, body=ticket.description, ticket=ticket, pullreq=pullreq)) # FIXME: move to dispatch process_trello_notify(user, ticket) return pullreq
def merge_pull(ticket, pullreq, user, message, request): from dispatches import dispatch from queues_handler import sphinx_builds_add from vilya.libs.signals import pullrequest_signal project = pullreq.to_proj # before # check user permission if not project.has_push_perm(user.name): return 'You do not have merge permission' # check if pull merged if pullreq.merged: return 'This pull was already merged' with MLock.merge_pull(proj_id=pullreq.to_proj.id) as err: if err: return "Merging by someone else ..." # if up-to-date, just close it if pullreq.is_up_to_date(): content = u"Closed due to up-to-date merge" comment = ticket.add_comment(content, user.name) close_pull(ticket, pullreq, user, content, comment, request) return "Closed due to up-to-date merge" # do merge_commit_sha = pullreq.merge(user, message) if merge_commit_sha is None: return "Merge failed" # after ticket_id = ticket.ticket_id # close ticket ticket.close(user.name) # build docs sphinx_builds_add(project.name) # delete tmp branch pullreq.remove_branch_if_temp() # TODO: 重构Feed后取消这个信号的发送 pullrequest_signal.send(user.username, comment='', pullreq=pullreq, ticket_id=ticket_id, ticket=ticket, status="merged", new_version=True) dispatch('pullreq', data=dict(sender=user.username, comment=None, ticket=ticket, status='merged', new_version=True)) # remove argu: request dispatch('pr_actions', data=dict(type='pr_merge', hooks=project.hooks, request=request, commit_message=message, author=user, ticket=ticket, pullreq=pullreq)) return None
def merge_pull(ticket, pullreq, user, message, request): from dispatches import dispatch from queues_handler import sphinx_builds_add from vilya.libs.signals import pullrequest_signal project = pullreq.to_proj # before # check user permission if not project.has_push_perm(user.name): return 'You do not have merge permission' # check if pull merged if pullreq.merged: return 'This pull was already merged' with MLock.merge_pull(proj_id=pullreq.to_proj.id) as err: if err: return "Merging by someone else ..." # if up-to-date, just close it if pullreq.is_up_to_date(): content = u"Closed due to up-to-date merge" comment = ticket.add_comment(content, user.name) close_pull(ticket, pullreq, user, content, comment, request) return "Closed due to up-to-date merge" # do merge_commit_sha = pullreq.merge(user, message) if merge_commit_sha is None: return "Merge failed" # after ticket_id = ticket.ticket_id # close ticket ticket.close(user.name) # build docs sphinx_builds_add(project.name) # delete tmp branch pullreq.remove_branch_if_temp() # TODO: 重构Feed后取消这个信号的发送 pullrequest_signal.send(user.username, comment='', pullreq=pullreq, ticket_id=ticket_id, ticket=ticket, status="merged", new_version=True) dispatch('pullreq', data=dict(sender=user.username, comment=None, ticket=ticket, status='merged', new_version=True) ) # remove argu: request dispatch('pr_actions', data=dict(type='pr_merge', hooks=project.hooks, request=request, commit_message=message, author=user, ticket=ticket, pullreq=pullreq) ) return None
def comment(self, request): target = self.target issue = self.issue issue_id = self.issue_id current_user = request.user if request.method == 'POST': content = request.get_form_var('content', '').decode('utf-8') user = request.user user = user.name if user else None if user: author = user if content.strip(): comment = issue.add_comment(content, user) issue.add_participant(user) html = st('/widgets/issue/issue_comment.html', **locals()) else: return {'error': 'Content is empty'} if request.get_form_var('comment_and_close'): issue.close(author) # TODO: 重构feed后取消信号发送 issue_signal.send(author=author, content=content, issue_id=issue_id) dispatch('issue', data={ 'sender': author, 'content': content, 'issue': issue, }) return dict(r=0, reload=1, redirect_to=issue.url) elif request.get_form_var('comment_and_open'): issue.open() # TODO: 重构feed后取消信号发送 issue_signal.send(author=author, content=content, issue_id=issue_id) dispatch('issue', data={ 'sender': author, 'content': content, 'issue': issue, }) return dict(r=0, reload=1, redirect_to=issue.url) elif content: issue_comment_signal.send(author=author, content=comment.content, issue_id=comment.issue_id, comment_id=comment.id) dispatch('issue_comment', data={ 'sender': author, 'content': comment.content, 'issue': issue, 'comment': comment }) participants = issue.participants teams = Team.get_all_team_uids() participants_html = st('/widgets/participation.html', **locals()) # FIXME: locals()? return dict(r=0, html=html, participants_html=participants_html) return request.redirect(issue.url)
def send_team_week_report(): from dispatches import dispatch for team in get_teams(): if team.weekly: dispatch("weekly", data=dict(team_id=team.id))
def add_pull(ticket, pullreq, user): from dispatches import dispatch from vilya.libs.text import get_mentions_from_text from vilya.libs.signals import pullrequest_signal from vilya.models.user import get_author_by_email from vilya.models.user import User from vilya.models.trello.core import process_trello_notify reporter = user.username commits = pullreq.commits # TODO: refactory is! auto number how to? shas = [p.sha for p in commits] ticket_len = Ticket.get_count_by_proj_id(ticket.project_id) if ticket_len == 0: # 检查是否创建过新PR,若未创建过则以旧PR号为基准累加 max_ticket_id = PullRequest.get_max_ticket_id(ticket.project_id) if max_ticket_id >= 0: ticket = Ticket.add(ticket.project_id, ticket.title, ticket.description, ticket.author, max_ticket_id + 1) else: ticket = Ticket.add(ticket.project_id, ticket.title, ticket.description, ticket.author) else: ticket = Ticket.add(ticket.project_id, ticket.title, ticket.description, ticket.author) pullreq = pullreq.insert(ticket.ticket_number) if shas: ticket.add_commits(','.join(shas), reporter) noti_receivers = [ committer.name for committer in CodeDoubanProject.get_committers_by_project(pullreq.to_proj.id) ] # noqa noti_receivers = noti_receivers + [pullreq.to_proj.owner.name] get_commit_author = lambda u: get_author_by_email(u.email.encode('utf-8')) commit_authors = {get_commit_author(c.author) for c in commits} commit_authors = {a for a in commit_authors if a} noti_receivers.extend(commit_authors) # diffs, author_by_file, authors = pullreq.get_diffs(with_blame=True) # FIXME: diffs没用到? # diffs = pullreq.get_diffs() # blame代码变更的原作者, 也加到at users at_users = get_mentions_from_text(ticket.description) # at_users.extend(authors) at_users.append(pullreq.to_proj.owner_id) at_users = set(at_users) # FIXME: invited_users is used on page /hub/my_pull_requests/ invited_users = [ User(u).add_invited_pull_request(ticket.id) for u in at_users ] ProjectOwnLRUCounter(user.username).use(pullreq.to_proj.id) ProjectWatchLRUCounter(user.username).use(pullreq.to_proj.id) # TODO: 重构Feed之后取消这个信号的发送 pullrequest_signal.send(user.username, extra_receivers=noti_receivers, pullreq=pullreq, comment=ticket.description, ticket_id=ticket.ticket_id, ticket=ticket, status="unmerge", new_version=True) dispatch('pullreq', data=dict(sender=user.username, content=ticket.description, ticket=ticket, status='unmerge', new_version=True, extra_receivers=noti_receivers)) dispatch('pr_actions', data=dict(type='pr_opened', hooks=pullreq.to_proj.hooks, author=user, title=ticket.title, body=ticket.description, ticket=ticket, pullreq=pullreq)) # FIXME: move to dispatch process_trello_notify(user, ticket) return pullreq