Added support for signals
This commit is contained in:
parent
a59dfe4a77
commit
e0712b47c6
10 changed files with 212 additions and 4 deletions
|
|
@ -24,6 +24,10 @@ from .globals import current_app, g, request, session, _request_ctx_stack
|
|||
from .module import Module
|
||||
from .templating import render_template, render_template_string
|
||||
|
||||
# the signals
|
||||
from .signals import signals_available, template_rendered, request_started, \
|
||||
request_finished, got_request_exception
|
||||
|
||||
# only import json if it's available
|
||||
if json_available:
|
||||
from .helpers import json
|
||||
|
|
|
|||
|
|
@ -32,6 +32,7 @@ from .session import Session, _NullSession
|
|||
from .module import _ModuleSetupState
|
||||
from .templating import _DispatchingJinjaLoader, \
|
||||
_default_template_ctx_processor
|
||||
from .signals import request_started, request_finished, got_request_exception
|
||||
|
||||
# a lock used for logger initialization
|
||||
_logger_lock = Lock()
|
||||
|
|
@ -657,6 +658,7 @@ class Flask(_PackageBoundObject):
|
|||
|
||||
.. versionadded: 0.3
|
||||
"""
|
||||
got_request_exception.send(self, exception=e)
|
||||
handler = self.error_handlers.get(500)
|
||||
if self.debug:
|
||||
raise
|
||||
|
|
@ -791,6 +793,7 @@ class Flask(_PackageBoundObject):
|
|||
"""
|
||||
with self.request_context(environ):
|
||||
try:
|
||||
request_started.send(self)
|
||||
rv = self.preprocess_request()
|
||||
if rv is None:
|
||||
rv = self.dispatch_request()
|
||||
|
|
@ -801,6 +804,7 @@ class Flask(_PackageBoundObject):
|
|||
response = self.process_response(response)
|
||||
except Exception, e:
|
||||
response = self.make_response(self.handle_exception(e))
|
||||
request_finished.send(self, response=response)
|
||||
return response(environ, start_response)
|
||||
|
||||
def request_context(self, environ):
|
||||
|
|
|
|||
50
flask/signals.py
Normal file
50
flask/signals.py
Normal file
|
|
@ -0,0 +1,50 @@
|
|||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
flask.signals
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Implements signals based on blinker if available, otherwise
|
||||
falls silently back to a noop
|
||||
|
||||
:copyright: (c) 2010 by Armin Ronacher.
|
||||
:license: BSD, see LICENSE for more details.
|
||||
"""
|
||||
signals_available = False
|
||||
try:
|
||||
from blinker import Namespace
|
||||
signals_available = True
|
||||
_signals = Namespace()
|
||||
except ImportError:
|
||||
class Namespace(object):
|
||||
def signal(self, name, doc=None):
|
||||
return _FakeSignal(name, doc)
|
||||
class _FakeSignal(object):
|
||||
"""If blinker is unavailable, create a fake class with the same
|
||||
interface that allows sending of signals but will fail with an
|
||||
error on anything else. Instead of doing anything on send, it
|
||||
will just ignore the arguments and do nothing instead.
|
||||
"""
|
||||
|
||||
def __init__(self, name, doc=None):
|
||||
self.name = name
|
||||
self.__doc__ = doc
|
||||
def _fail(self, *args, **kwargs):
|
||||
raise RuntimeError('signalling support is unavailable '
|
||||
'because the blinker library is '
|
||||
'not installed.')
|
||||
send = lambda *a, **kw: None
|
||||
connect = disconnect = has_receivers_for = receivers_for = \
|
||||
temporarily_connected_to = _fail
|
||||
del _fail
|
||||
|
||||
# the namespace for code signals. If you are not flask code, do
|
||||
# not put signals in here. Create your own namespace instead.
|
||||
_signals = Namespace()
|
||||
|
||||
|
||||
# core signals. For usage examples grep the sourcecode or consult
|
||||
# the API documentation in docs/api.rst as well as docs/signals.rst
|
||||
template_rendered = _signals.signal('template-rendered')
|
||||
request_started = _signals.signal('request-started')
|
||||
request_finished = _signals.signal('request-finished')
|
||||
got_request_exception = _signals.signal('got-request-exception')
|
||||
|
|
@ -11,6 +11,7 @@
|
|||
from jinja2 import BaseLoader, FileSystemLoader, TemplateNotFound
|
||||
|
||||
from .globals import _request_ctx_stack
|
||||
from .signals import template_rendered
|
||||
|
||||
|
||||
def _default_template_ctx_processor():
|
||||
|
|
@ -59,6 +60,13 @@ class _DispatchingJinjaLoader(BaseLoader):
|
|||
return result
|
||||
|
||||
|
||||
def _render(template, context, app):
|
||||
"""Renders the template and fires the signal"""
|
||||
rv = template.render(context)
|
||||
template_rendered.send(app, template=template, context=context)
|
||||
return rv
|
||||
|
||||
|
||||
def render_template(template_name, **context):
|
||||
"""Renders a template from the template folder with the given
|
||||
context.
|
||||
|
|
@ -69,7 +77,8 @@ def render_template(template_name, **context):
|
|||
"""
|
||||
ctx = _request_ctx_stack.top
|
||||
ctx.app.update_template_context(context)
|
||||
return ctx.app.jinja_env.get_template(template_name).render(context)
|
||||
return _render(ctx.app.jinja_env.get_template(template_name),
|
||||
context, ctx.app)
|
||||
|
||||
|
||||
def render_template_string(source, **context):
|
||||
|
|
@ -83,4 +92,5 @@ def render_template_string(source, **context):
|
|||
"""
|
||||
ctx = _request_ctx_stack.top
|
||||
ctx.app.update_template_context(context)
|
||||
return ctx.app.jinja_env.from_string(source).render(context)
|
||||
return _render(ctx.app.jinja_env.from_string(source),
|
||||
context, ctx.app)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue