events: ported pylons part to pyramid.

- fix lack of request context in VCS type events
  we now use a dummy request but it's sufficient for routes generation
- cleanup and re-organized some code
- removed all pylons stuff from the events code
This commit is contained in:
Marcin Kuzminski 2017-07-26 12:41:14 +02:00
parent ab16b87482
commit 2656338a0d
5 changed files with 66 additions and 23 deletions

View file

@ -16,9 +16,11 @@
# RhodeCode Enterprise Edition, including its added features, Support services,
# and proprietary license terms, please see https://rhodecode.com/licenses/
import logging
import datetime
from datetime import datetime
from zope.cachedescriptors.property import Lazy as LazyProperty
from pyramid.threadlocal import get_current_request
from rhodecode.lib.utils2 import AttributeDict
@ -36,10 +38,20 @@ class RhodecodeEvent(object):
Base event class for all RhodeCode events
"""
name = "RhodeCodeEvent"
no_url_set = '<no server_url available>'
def __init__(self, request=None):
self.request = request or get_current_request()
self.utc_timestamp = datetime.utcnow()
self._request = request
self.utc_timestamp = datetime.datetime.utcnow()
def get_request(self):
if self._request:
return self._request
return get_current_request()
@LazyProperty
def request(self):
return self.get_request()
@property
def auth_user(self):
@ -57,7 +69,6 @@ class RhodecodeEvent(object):
@property
def actor(self):
auth_user = self.auth_user
if auth_user:
instance = auth_user.get_instance()
if not instance:
@ -78,15 +89,14 @@ class RhodecodeEvent(object):
@property
def server_url(self):
default = '<no server_url available>'
if self.request:
try:
return self.request.route_url('home')
except Exception:
log.exception('Failed to fetch URL for server')
return default
return self.no_url_set
return default
return self.no_url_set
def as_dict(self):
data = {

View file

@ -52,9 +52,10 @@ class PullRequestEvent(RepoEvent):
'title': self.pullrequest.title,
'issues': issues,
'pull_request_id': self.pullrequest.pull_request_id,
'url': PullRequestModel().get_url(self.pullrequest),
'url': PullRequestModel().get_url(
self.pullrequest, request=self.request),
'permalink_url': PullRequestModel().get_url(
self.pullrequest, permalink=True),
self.pullrequest, request=self.request, permalink=True),
'status': self.pullrequest.calculated_review_status(),
'commits': commits,
}
@ -134,9 +135,10 @@ class PullRequestCommentEvent(PullRequestEvent):
'type': self.comment.comment_type,
'file': self.comment.f_path,
'line': self.comment.line_no,
'url': CommentsModel().get_url(self.comment),
'url': CommentsModel().get_url(
self.comment, request=self.request),
'permalink_url': CommentsModel().get_url(
self.comment, permalink=True),
self.comment, request=self.request, permalink=True),
}
})
return data

View file

@ -120,6 +120,7 @@ class RepoEvent(RhodecodeEvent):
def as_dict(self):
from rhodecode.model.repo import RepoModel
data = super(RepoEvent, self).as_dict()
extra_fields = collections.OrderedDict()
for field in self.repo.extra_fields:
extra_fields[field.field_key] = field.field_value
@ -201,6 +202,10 @@ class RepoVCSEvent(RepoEvent):
if self.extras.get('server_url'):
return self.extras['server_url']
@property
def request(self):
return self.extras.get('request') or self.get_request()
class RepoPrePullEvent(RepoVCSEvent):
"""

View file

@ -582,6 +582,36 @@ def h_filter(s):
return markupsafe.escape(s)
def add_events_routes(config):
"""
Adds routing that can be used in events. Because some events are triggered
outside of pyramid context, we need to bootstrap request with some
routing registered
"""
config.add_route(name='home', pattern='/')
config.add_route(name='repo_summary', pattern='/{repo_name}')
config.add_route(name='repo_summary_explicit', pattern='/{repo_name}/summary')
config.add_route(name='repo_group_home', pattern='/{repo_group_name}')
config.add_route(name='pullrequest_show',
pattern='/{repo_name}/pull-request/{pull_request_id}')
config.add_route(name='pull_requests_global',
pattern='/pull-request/{pull_request_id}')
config.add_route(name='repo_commit',
pattern='/{repo_name}/changeset/{commit_id}')
config.add_route(name='repo_files',
pattern='/{repo_name}/files/{commit_id}/{f_path}')
def bootstrap_request():
import pyramid.testing
request = pyramid.testing.DummyRequest()
config = pyramid.testing.setUp(request=request)
add_events_routes(config)
class BaseRepoController(BaseController):
"""
Base class for controllers responsible for loading all needed data for

View file

@ -25,13 +25,11 @@ import threading
from BaseHTTPServer import BaseHTTPRequestHandler
from SocketServer import TCPServer
import pylons
import rhodecode
from rhodecode.model import meta
from rhodecode.lib.base import bootstrap_request
from rhodecode.lib import hooks_base
from rhodecode.lib.utils2 import (
AttributeDict, safe_str, get_routes_generator_for_server_url)
from rhodecode.lib.utils2 import AttributeDict
log = logging.getLogger(__name__)
@ -188,29 +186,28 @@ class Hooks(object):
"""
def repo_size(self, extras):
log.debug("Called repo_size of Hooks object")
log.debug("Called repo_size of %s object", self)
return self._call_hook(hooks_base.repo_size, extras)
def pre_pull(self, extras):
log.debug("Called pre_pull of Hooks object")
log.debug("Called pre_pull of %s object", self)
return self._call_hook(hooks_base.pre_pull, extras)
def post_pull(self, extras):
log.debug("Called post_pull of Hooks object")
log.debug("Called post_pull of %s object", self)
return self._call_hook(hooks_base.post_pull, extras)
def pre_push(self, extras):
log.debug("Called pre_push of Hooks object")
log.debug("Called pre_push of %s object", self)
return self._call_hook(hooks_base.pre_push, extras)
def post_push(self, extras):
log.debug("Called post_push of Hooks object")
log.debug("Called post_push of %s object", self)
return self._call_hook(hooks_base.post_push, extras)
def _call_hook(self, hook, extras):
extras = AttributeDict(extras)
pylons_router = get_routes_generator_for_server_url(extras.server_url)
pylons.url._push_object(pylons_router)
extras.request = bootstrap_request()
try:
result = hook(extras)
@ -226,7 +223,6 @@ class Hooks(object):
'exception_args': error_args,
}
finally:
pylons.url._pop_object()
meta.Session.remove()
return {