events: add serialization .to_dict() to events based on marshmallow
This commit is contained in:
parent
a0af559a3d
commit
23d7a947f5
13 changed files with 177 additions and 19 deletions
|
|
@ -831,6 +831,19 @@
|
|||
license = [ pkgs.lib.licenses.bsdOriginal ];
|
||||
};
|
||||
};
|
||||
marshmallow = super.buildPythonPackage {
|
||||
name = "marshmallow-2.8.0";
|
||||
buildInputs = with self; [];
|
||||
doCheck = false;
|
||||
propagatedBuildInputs = with self; [];
|
||||
src = fetchurl {
|
||||
url = "https://pypi.python.org/packages/4f/64/9393d77847d86981c84b88bbea627d30ff71b5ab1402636b366f73737817/marshmallow-2.8.0.tar.gz";
|
||||
md5 = "204513fc123a3d9bdd7b63b9747f02e6";
|
||||
};
|
||||
meta = {
|
||||
license = [ pkgs.lib.licenses.mit ];
|
||||
};
|
||||
};
|
||||
mccabe = super.buildPythonPackage {
|
||||
name = "mccabe-0.3";
|
||||
buildInputs = with self; [];
|
||||
|
|
@ -1355,7 +1368,7 @@
|
|||
name = "rhodecode-enterprise-ce-4.3.0";
|
||||
buildInputs = with self; [WebTest configobj cssselect flake8 lxml mock pytest pytest-cov pytest-runner];
|
||||
doCheck = true;
|
||||
propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments Pylons Pyro4 Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery colander decorator docutils gunicorn infrae.cache ipython iso8601 kombu msgpack-python packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client repoze.lru requests simplejson waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt];
|
||||
propagatedBuildInputs = with self; [Babel Beaker FormEncode Mako Markdown MarkupSafe MySQL-python Paste PasteDeploy PasteScript Pygments Pylons Pyro4 Routes SQLAlchemy Tempita URLObject WebError WebHelpers WebHelpers2 WebOb WebTest Whoosh alembic amqplib anyjson appenlight-client authomatic backport-ipaddress celery colander decorator docutils gunicorn infrae.cache ipython iso8601 kombu marshmallow msgpack-python packaging psycopg2 py-gfm pycrypto pycurl pyparsing pyramid pyramid-debugtoolbar pyramid-mako pyramid-beaker pysqlite python-dateutil python-ldap python-memcached python-pam recaptcha-client repoze.lru requests simplejson waitress zope.cachedescriptors dogpile.cache dogpile.core psutil py-bcrypt];
|
||||
src = ./.;
|
||||
meta = {
|
||||
license = [ { fullName = "AGPLv3, and Commercial License"; } ];
|
||||
|
|
@ -1637,5 +1650,5 @@
|
|||
|
||||
### Test requirements
|
||||
|
||||
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -84,6 +84,7 @@ iso8601==0.1.11
|
|||
itsdangerous==0.24
|
||||
kombu==1.5.1
|
||||
lxml==3.4.4
|
||||
marshmallow==2.8.0
|
||||
mccabe==0.3
|
||||
meld3==1.0.2
|
||||
mock==1.0.1
|
||||
|
|
|
|||
|
|
@ -47,9 +47,14 @@ class TestApiUpdateRepo(object):
|
|||
({'enable_statistics': True}, SAME_AS_UPDATES),
|
||||
({'enable_locking': True}, SAME_AS_UPDATES),
|
||||
({'enable_downloads': True}, SAME_AS_UPDATES),
|
||||
({'name': 'new_repo_name'}, {'repo_name': 'new_repo_name'}),
|
||||
({'group': 'test_group_for_update'},
|
||||
{'repo_name': 'test_group_for_update/%s' % UPDATE_REPO_NAME}),
|
||||
({'name': 'new_repo_name'}, {
|
||||
'repo_name': 'new_repo_name',
|
||||
'url': 'http://test.example.com:80/new_repo_name',
|
||||
}),
|
||||
({'group': 'test_group_for_update'}, {
|
||||
'repo_name': 'test_group_for_update/%s' % UPDATE_REPO_NAME,
|
||||
'url': 'http://test.example.com:80/test_group_for_update/%s' % UPDATE_REPO_NAME
|
||||
}),
|
||||
])
|
||||
def test_api_update_repo(self, updates, expected, backend):
|
||||
repo_name = UPDATE_REPO_NAME
|
||||
|
|
|
|||
|
|
@ -454,6 +454,7 @@ class PullrequestsController(BaseRepoController):
|
|||
h.flash(_('Successfully opened new pull request'),
|
||||
category='success')
|
||||
except Exception as e:
|
||||
raise
|
||||
msg = _('Error occurred during sending pull request')
|
||||
log.exception(msg)
|
||||
h.flash(msg, category='error')
|
||||
|
|
|
|||
|
|
@ -19,12 +19,6 @@
|
|||
from pyramid.threadlocal import get_current_registry
|
||||
|
||||
|
||||
class RhodecodeEvent(object):
|
||||
"""
|
||||
Base event class for all Rhodecode events
|
||||
"""
|
||||
|
||||
|
||||
def trigger(event):
|
||||
"""
|
||||
Helper method to send an event. This wraps the pyramid logic to send an
|
||||
|
|
@ -37,6 +31,8 @@ def trigger(event):
|
|||
registry.notify(event)
|
||||
|
||||
|
||||
from rhodecode.events.base import RhodecodeEvent
|
||||
|
||||
from rhodecode.events.user import (
|
||||
UserPreCreate,
|
||||
UserPreUpdate,
|
||||
|
|
@ -44,6 +40,7 @@ from rhodecode.events.user import (
|
|||
)
|
||||
|
||||
from rhodecode.events.repo import (
|
||||
RepoEvent,
|
||||
RepoPreCreateEvent, RepoCreatedEvent,
|
||||
RepoPreDeleteEvent, RepoDeletedEvent,
|
||||
RepoPrePushEvent, RepoPushEvent,
|
||||
|
|
@ -51,6 +48,7 @@ from rhodecode.events.repo import (
|
|||
)
|
||||
|
||||
from rhodecode.events.pullrequest import (
|
||||
PullRequestEvent,
|
||||
PullRequestCreateEvent,
|
||||
PullRequestUpdateEvent,
|
||||
PullRequestReviewEvent,
|
||||
|
|
|
|||
69
rhodecode/events/base.py
Normal file
69
rhodecode/events/base.py
Normal file
|
|
@ -0,0 +1,69 @@
|
|||
# Copyright (C) 2016-2016 RhodeCode GmbH
|
||||
#
|
||||
# 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/
|
||||
|
||||
from datetime import datetime
|
||||
from marshmallow import Schema, fields
|
||||
from pyramid.threadlocal import get_current_request
|
||||
from rhodecode.lib.utils2 import AttributeDict
|
||||
|
||||
|
||||
SYSTEM_USER = AttributeDict(dict(
|
||||
username='__SYSTEM__'
|
||||
))
|
||||
|
||||
|
||||
class UserSchema(Schema):
|
||||
"""
|
||||
Marshmallow schema for a user
|
||||
"""
|
||||
username = fields.Str()
|
||||
|
||||
|
||||
class RhodecodeEventSchema(Schema):
|
||||
"""
|
||||
Marshmallow schema for a rhodecode event
|
||||
"""
|
||||
utc_timestamp = fields.DateTime()
|
||||
acting_user = fields.Nested(UserSchema)
|
||||
acting_ip = fields.Str()
|
||||
|
||||
|
||||
class RhodecodeEvent(object):
|
||||
"""
|
||||
Base event class for all Rhodecode events
|
||||
"""
|
||||
MarshmallowSchema = RhodecodeEventSchema
|
||||
|
||||
def __init__(self):
|
||||
self.request = get_current_request()
|
||||
self.utc_timestamp = datetime.utcnow()
|
||||
|
||||
@property
|
||||
def acting_user(self):
|
||||
if self.request:
|
||||
return self.request.user.get_instance()
|
||||
return SYSTEM_USER
|
||||
|
||||
@property
|
||||
def acting_ip(self):
|
||||
if self.request:
|
||||
return self.request.user.ip_addr
|
||||
return '<no ip available>'
|
||||
|
||||
def as_dict(self):
|
||||
return self.MarshmallowSchema().dump(self).data
|
||||
|
|
@ -16,15 +16,40 @@
|
|||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
from marshmallow import Schema, fields
|
||||
|
||||
from rhodecode.events.repo import RepoEvent
|
||||
|
||||
|
||||
def get_pull_request_url(pull_request):
|
||||
from rhodecode.model.pull_request import PullRequestModel
|
||||
return PullRequestModel().get_url(pull_request)
|
||||
|
||||
|
||||
class PullRequestSchema(Schema):
|
||||
"""
|
||||
Marshmallow schema for a pull request
|
||||
"""
|
||||
pull_request_id = fields.Integer()
|
||||
url = fields.Function(get_pull_request_url)
|
||||
title = fields.Str()
|
||||
|
||||
|
||||
class PullRequestEventSchema(RepoEvent.MarshmallowSchema):
|
||||
"""
|
||||
Marshmallow schema for a pull request event
|
||||
"""
|
||||
pullrequest = fields.Nested(PullRequestSchema)
|
||||
|
||||
|
||||
class PullRequestEvent(RepoEvent):
|
||||
"""
|
||||
Base class for events acting on a repository.
|
||||
Base class for pull request events.
|
||||
|
||||
:param repo: a :class:`Repository` instance
|
||||
:param pullrequest: a :class:`PullRequest` instance
|
||||
"""
|
||||
MarshmallowSchema = PullRequestEventSchema
|
||||
|
||||
def __init__(self, pullrequest):
|
||||
super(PullRequestEvent, self).__init__(pullrequest.target_repo)
|
||||
self.pullrequest = pullrequest
|
||||
|
|
|
|||
|
|
@ -16,8 +16,31 @@
|
|||
# RhodeCode Enterprise Edition, including its added features, Support services,
|
||||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
from marshmallow import Schema, fields
|
||||
|
||||
from rhodecode.model.db import Repository, Session
|
||||
from rhodecode.events import RhodecodeEvent
|
||||
from rhodecode.events.base import RhodecodeEvent
|
||||
|
||||
|
||||
def get_pull_request_url(repo):
|
||||
from rhodecode.model.repo import RepoModel
|
||||
return RepoModel().get_url(repo)
|
||||
|
||||
|
||||
class RepositorySchema(Schema):
|
||||
"""
|
||||
Marshmallow schema for a repository
|
||||
"""
|
||||
repo_id = fields.Integer()
|
||||
repo_name = fields.Str()
|
||||
url = fields.Function(get_pull_request_url)
|
||||
|
||||
|
||||
class RepoEventSchema(RhodecodeEvent.MarshmallowSchema):
|
||||
"""
|
||||
Marshmallow schema for a repository event
|
||||
"""
|
||||
repository = fields.Nested(RepositorySchema)
|
||||
|
||||
|
||||
class RepoEvent(RhodecodeEvent):
|
||||
|
|
@ -26,7 +49,10 @@ class RepoEvent(RhodecodeEvent):
|
|||
|
||||
:param repo: a :class:`Repository` instance
|
||||
"""
|
||||
MarshmallowSchema = RepoEventSchema
|
||||
|
||||
def __init__(self, repo):
|
||||
super(RepoEvent, self).__init__()
|
||||
self.repo = repo
|
||||
|
||||
|
||||
|
|
@ -73,6 +99,16 @@ class RepoVCSEvent(RepoEvent):
|
|||
self.extras = extras
|
||||
super(RepoVCSEvent, self).__init__(self.repo)
|
||||
|
||||
@property
|
||||
def acting_user(self):
|
||||
if self.extras.get('username'):
|
||||
return User.get_by_username(extras['username'])
|
||||
|
||||
@property
|
||||
def acting_ip(self):
|
||||
if self.extras.get('ip'):
|
||||
return User.get_by_username(extras['ip'])
|
||||
|
||||
|
||||
class RepoPrePullEvent(RepoVCSEvent):
|
||||
"""
|
||||
|
|
|
|||
|
|
@ -17,7 +17,8 @@
|
|||
# and proprietary license terms, please see https://rhodecode.com/licenses/
|
||||
|
||||
from zope.interface import implementer
|
||||
from rhodecode.events import RhodecodeEvent
|
||||
|
||||
from rhodecode.events.base import RhodecodeEvent
|
||||
from rhodecode.events.interfaces import (
|
||||
IUserRegistered, IUserPreCreate, IUserPreUpdate)
|
||||
|
||||
|
|
|
|||
|
|
@ -1641,6 +1641,7 @@ class Repository(Base, BaseModel):
|
|||
'repo_name': repo.repo_name,
|
||||
'repo_type': repo.repo_type,
|
||||
'clone_uri': repo.clone_uri or '',
|
||||
'url': url('summary_home', repo_name=self.repo_name, qualified=True),
|
||||
'private': repo.private,
|
||||
'created_on': repo.created_on,
|
||||
'description': repo.description,
|
||||
|
|
@ -3112,10 +3113,9 @@ class PullRequest(Base, _PullRequestBase):
|
|||
merge_status = PullRequestModel().merge_status(pull_request)
|
||||
data = {
|
||||
'pull_request_id': pull_request.pull_request_id,
|
||||
'url': url('pullrequest_show',
|
||||
repo_name=pull_request.target_repo.repo_name,
|
||||
pull_request_id=pull_request.pull_request_id,
|
||||
qualified=True),
|
||||
'url': url('pullrequest_show', repo_name=self.target_repo.repo_name,
|
||||
pull_request_id=self.pull_request_id,
|
||||
qualified=True),
|
||||
'title': pull_request.title,
|
||||
'description': pull_request.description,
|
||||
'status': pull_request.status,
|
||||
|
|
|
|||
|
|
@ -748,6 +748,11 @@ class PullRequestModel(BaseModel):
|
|||
|
||||
return ids_to_add, ids_to_remove
|
||||
|
||||
def get_url(self, pull_request):
|
||||
return url('pullrequest_show', repo_name=self.target_repo.repo_name,
|
||||
pull_request_id=self.pull_request_id,
|
||||
qualified=True)
|
||||
|
||||
def notify_reviewers(self, pull_request, reviewers_ids):
|
||||
# notification to reviewers
|
||||
if not reviewers_ids:
|
||||
|
|
|
|||
|
|
@ -141,6 +141,9 @@ class RepoModel(BaseModel):
|
|||
|
||||
return None
|
||||
|
||||
def get_url(self, repo):
|
||||
return url('summary_home', repo_name=repo.repo_name, qualified=True)
|
||||
|
||||
def get_users(self, name_contains=None, limit=20, only_active=True):
|
||||
# TODO: mikhail: move this method to the UserModel.
|
||||
query = self.sa.query(User)
|
||||
|
|
|
|||
1
setup.py
1
setup.py
|
|
@ -78,6 +78,7 @@ requirements = [
|
|||
'ipython',
|
||||
'iso8601',
|
||||
'kombu',
|
||||
'marshmallow',
|
||||
'msgpack-python',
|
||||
'packaging',
|
||||
'psycopg2',
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue