##// END OF EJS Templates
user-groups: fix potential problem with group sync of external plugins....
user-groups: fix potential problem with group sync of external plugins. - when using external plugin we used to check for a parameter that set the sync mode. The problem is we only checked if the flag was there. So toggling sync on and off set the value and then left the key still set but with None. This confused the sync and thought the group should be synced !

File last commit:

r2024:1069b5cc merge default
r2193:20e24a44 stable
Show More
repo.py
281 lines | 8.7 KiB | text/x-python | PythonLexer
license: updated copyright year to 2017
r1271 # Copyright (C) 2016-2017 RhodeCode GmbH
dan
events: add event system for RepoEvents
r375 #
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License, version 3
# (only), as published by the Free Software Foundation.
#
# 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 Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# This program is dual-licensed. If you wish to learn more about the
# RhodeCode Enterprise Edition, including its added features, Support services,
# and proprietary license terms, please see https://rhodecode.com/licenses/
webhook: enable support of extra repo variables as replacement in template url.
r1761 import collections
dan
integrations: add integration support...
r411 import logging
dan
events: add serialization .to_dict() to events based on marshmallow
r379
dan
integrations: add integration support...
r411 from rhodecode.translation import lazy_ugettext
dan
events: fix bugs with serialization of repo/pr events and add tests for those cases
r389 from rhodecode.model.db import User, Repository, Session
dan
events: add serialization .to_dict() to events based on marshmallow
r379 from rhodecode.events.base import RhodecodeEvent
dan
events: change target to source repo for pull request events...
r514 from rhodecode.lib.vcs.exceptions import CommitDoesNotExistError
dan
events: add serialization .to_dict() to events based on marshmallow
r379
Martin Bornhold
logging: Use __name__ when requesting a logger
r504 log = logging.getLogger(__name__)
dan
events: add event system for RepoEvents
r375
events: fixed missing construcors on user based events.
r1422
events: re-organizate events handling....
r1789 def _commits_as_dict(event, commit_ids, repos):
dan
events: change target to source repo for pull request events...
r514 """
Helper function to serialize commit_ids
events: re-organizate events handling....
r1789 :param event: class calling this method
dan
events: change target to source repo for pull request events...
r514 :param commit_ids: commits to get
:param repos: list of repos to check
"""
from rhodecode.lib.utils2 import extract_mentioned_users
slack: updated slack integration to use the attachements for nicer formatting.
r1467 from rhodecode.lib.helpers import (
urlify_commit_message, process_patterns, chop_at_smart)
events: expose permalink urls for different set of object....
r1788 from rhodecode.model.repo import RepoModel
dan
events: change target to source repo for pull request events...
r514
if not repos:
raise Exception('no repo defined')
if not isinstance(repos, (tuple, list)):
repos = [repos]
if not commit_ids:
return []
dan
events: send pushed commit ids in order
r782 needed_commits = list(commit_ids)
dan
events: change target to source repo for pull request events...
r514
commits = []
reviewers = []
for repo in repos:
if not needed_commits:
events: expose permalink urls for different set of object....
r1788 return commits # return early if we have the commits we need
dan
events: change target to source repo for pull request events...
r514
vcs_repo = repo.scm_instance(cache=False)
try:
dan
events: fix bug with _commits_as_dict which was returning only...
r795 # use copy of needed_commits since we modify it while iterating
for commit_id in list(needed_commits):
dan
events: change target to source repo for pull request events...
r514 try:
cs = vcs_repo.get_changeset(commit_id)
except CommitDoesNotExistError:
events: expose permalink urls for different set of object....
r1788 continue # maybe its in next repo
dan
events: change target to source repo for pull request events...
r514
cs_data = cs.__json__()
cs_data['mentions'] = extract_mentioned_users(cs_data['message'])
cs_data['reviewers'] = reviewers
events: expose permalink urls for different set of object....
r1788 cs_data['url'] = RepoModel().get_commit_url(
events: re-organizate events handling....
r1789 repo, cs_data['raw_id'], request=event.request)
events: expose permalink urls for different set of object....
r1788 cs_data['permalink_url'] = RepoModel().get_commit_url(
events: re-organizate events handling....
r1789 repo, cs_data['raw_id'], request=event.request, permalink=True)
dan
events: change target to source repo for pull request events...
r514 urlified_message, issues_data = process_patterns(
cs_data['message'], repo.repo_name)
cs_data['issues'] = issues_data
webhook: enable support of extra repo variables as replacement in template url.
r1761 cs_data['message_html'] = urlify_commit_message(
cs_data['message'], repo.repo_name)
cs_data['message_html_title'] = chop_at_smart(
cs_data['message'], '\n', suffix_if_chopped='...')
dan
events: change target to source repo for pull request events...
r514 commits.append(cs_data)
dan
events: send pushed commit ids in order
r782 needed_commits.remove(commit_id)
dan
events: change target to source repo for pull request events...
r514
except Exception as e:
log.exception(e)
slack: updated slack integration to use the attachements for nicer formatting.
r1467 # we don't send any commits when crash happens, only full list
# matters we short circuit then.
dan
events: change target to source repo for pull request events...
r514 return []
missing_commits = set(commit_ids) - set(c['raw_id'] for c in commits)
if missing_commits:
log.error('missing commits: %s' % ', '.join(missing_commits))
return commits
def _issues_as_dict(commits):
""" Helper function to serialize issues from commits """
issues = {}
for commit in commits:
for issue in commit['issues']:
issues[issue['id']] = issue
return issues
dan
events: add event system for RepoEvents
r375
events: fixed missing construcors on user based events.
r1422
dan
events: add event system for RepoEvents
r375 class RepoEvent(RhodecodeEvent):
"""
Base class for events acting on a repository.
:param repo: a :class:`Repository` instance
"""
dan
events: add serialization .to_dict() to events based on marshmallow
r379
dan
events: add event system for RepoEvents
r375 def __init__(self, repo):
dan
events: add serialization .to_dict() to events based on marshmallow
r379 super(RepoEvent, self).__init__()
dan
events: add event system for RepoEvents
r375 self.repo = repo
dan
integrations: add integration support...
r411 def as_dict(self):
from rhodecode.model.repo import RepoModel
data = super(RepoEvent, self).as_dict()
webhook: enable support of extra repo variables as replacement in template url.
r1761 extra_fields = collections.OrderedDict()
for field in self.repo.extra_fields:
extra_fields[field.field_key] = field.field_value
dan
integrations: add integration support...
r411 data.update({
'repo': {
'repo_id': self.repo.repo_id,
'repo_name': self.repo.repo_name,
dan
events: add repo_type to repo events
r445 'repo_type': self.repo.repo_type,
events: re-organizate events handling....
r1789 'url': RepoModel().get_url(
self.repo, request=self.request),
'permalink_url': RepoModel().get_url(
self.repo, request=self.request, permalink=True),
webhook: enable support of extra repo variables as replacement in template url.
r1761 'extra_fields': extra_fields
dan
integrations: add integration support...
r411 }
})
return data
dan
events: add event system for RepoEvents
r375
class RepoPreCreateEvent(RepoEvent):
"""
An instance of this class is emitted as an :term:`event` before a repo is
created.
"""
name = 'repo-pre-create'
dan
integrations: add integration support...
r411 display_name = lazy_ugettext('repository pre create')
dan
events: add event system for RepoEvents
r375
dan
integrations: add integration support...
r411 class RepoCreateEvent(RepoEvent):
dan
events: add event system for RepoEvents
r375 """
An instance of this class is emitted as an :term:`event` whenever a repo is
created.
"""
dan
integrations: add integration support...
r411 name = 'repo-create'
display_name = lazy_ugettext('repository created')
dan
events: add event system for RepoEvents
r375
class RepoPreDeleteEvent(RepoEvent):
"""
An instance of this class is emitted as an :term:`event` whenever a repo is
created.
"""
name = 'repo-pre-delete'
dan
integrations: add integration support...
r411 display_name = lazy_ugettext('repository pre delete')
dan
events: add event system for RepoEvents
r375
dan
integrations: add integration support...
r411 class RepoDeleteEvent(RepoEvent):
dan
events: add event system for RepoEvents
r375 """
An instance of this class is emitted as an :term:`event` whenever a repo is
created.
"""
dan
integrations: add integration support...
r411 name = 'repo-delete'
display_name = lazy_ugettext('repository deleted')
dan
events: add event system for RepoEvents
r375
class RepoVCSEvent(RepoEvent):
"""
Base class for events triggered by the VCS
"""
def __init__(self, repo_name, extras):
self.repo = Repository.get_by_repo_name(repo_name)
if not self.repo:
raise Exception('repo by this name %s does not exist' % repo_name)
self.extras = extras
super(RepoVCSEvent, self).__init__(self.repo)
dan
events: add serialization .to_dict() to events based on marshmallow
r379 @property
dan
events: fix bugs with serialization of repo/pr events and add tests for those cases
r389 def actor(self):
dan
events: add serialization .to_dict() to events based on marshmallow
r379 if self.extras.get('username'):
dan
events: fix bugs with serialization of repo/pr events and add tests for those cases
r389 return User.get_by_username(self.extras['username'])
dan
events: add serialization .to_dict() to events based on marshmallow
r379
@property
dan
events: fix bugs with serialization of repo/pr events and add tests for those cases
r389 def actor_ip(self):
dan
events: add serialization .to_dict() to events based on marshmallow
r379 if self.extras.get('ip'):
dan
events: fix bugs with serialization of repo/pr events and add tests for those cases
r389 return self.extras['ip']
dan
events: add serialization .to_dict() to events based on marshmallow
r379
events: expose server_url for repo events.
r649 @property
def server_url(self):
if self.extras.get('server_url'):
return self.extras['server_url']
pyramid: ported pyramid routing for events
r2016 @property
def request(self):
return self.extras.get('request') or self.get_request()
dan
events: add event system for RepoEvents
r375
class RepoPrePullEvent(RepoVCSEvent):
"""
An instance of this class is emitted as an :term:`event` before commits
are pulled from a repo.
"""
name = 'repo-pre-pull'
dan
integrations: add integration support...
r411 display_name = lazy_ugettext('repository pre pull')
dan
events: add event system for RepoEvents
r375
class RepoPullEvent(RepoVCSEvent):
"""
An instance of this class is emitted as an :term:`event` after commits
are pulled from a repo.
"""
name = 'repo-pull'
dan
integrations: add integration support...
r411 display_name = lazy_ugettext('repository pull')
dan
events: add event system for RepoEvents
r375
class RepoPrePushEvent(RepoVCSEvent):
"""
An instance of this class is emitted as an :term:`event` before commits
are pushed to a repo.
"""
name = 'repo-pre-push'
dan
integrations: add integration support...
r411 display_name = lazy_ugettext('repository pre push')
dan
events: add event system for RepoEvents
r375
class RepoPushEvent(RepoVCSEvent):
"""
An instance of this class is emitted as an :term:`event` after commits
are pushed to a repo.
:param extras: (optional) dict of data from proxied VCS actions
"""
name = 'repo-push'
dan
integrations: add integration support...
r411 display_name = lazy_ugettext('repository push')
dan
events: add event system for RepoEvents
r375
def __init__(self, repo_name, pushed_commit_ids, extras):
super(RepoPushEvent, self).__init__(repo_name, extras)
self.pushed_commit_ids = pushed_commit_ids
dan
integrations: add integration support...
r411 def as_dict(self):
data = super(RepoPushEvent, self).as_dict()
events: expose permalink urls for different set of object....
r1788
def branch_url(branch_name):
return '{}/changelog?branch={}'.format(
data['repo']['url'], branch_name)
dan
integrations: add integration support...
r411
dan
events: change target to source repo for pull request events...
r514 commits = _commits_as_dict(
events: re-organizate events handling....
r1789 self, commit_ids=self.pushed_commit_ids, repos=[self.repo])
dan
events: use branch from previous commit for repo push event commits...
r815
last_branch = None
for commit in reversed(commits):
commit['branch'] = commit['branch'] or last_branch
last_branch = commit['branch']
dan
events: change target to source repo for pull request events...
r514 issues = _issues_as_dict(commits)
dan
integrations: add integration support...
r411
branches = set(
commit['branch'] for commit in commits if commit['branch'])
branches = [
{
'name': branch,
events: expose permalink urls for different set of object....
r1788 'url': branch_url(branch)
dan
integrations: add integration support...
r411 }
for branch in branches
]
data['push'] = {
'commits': commits,
'issues': issues,
'branches': branches,
}
Martin Bornhold
logging: Use __name__ when requesting a logger
r504 return data