Source code for djangofloor.wsgi.window_info

"""WindowInfo object and associated functions
==========================================

A :class:`WindowInfo` object carries important data the browser window that is connected to the websocket:

  * the window key that is unique to each open browser window,
  * user information about the connected user,
  * i18n information.

The :class:`WindowInfo` object is populated by middlewares, thath should be any subclass of
:class:`djangofloor.middleware.WindowInfoMiddleware`.
The list of used middlewares is defined by the `WINDOW_INFO_MIDDLEWARES` setting.

.. warning::
  Never modify a :class:`WindowInfo`: the same object can be reused for all websocket signals from a given connection.

Designed to be instanciated from a :class:`django.http.request.HttpRequest` and reused across signals
(when a signal calls another one). However, a blank :class:`WindowInfo` can also be directly instanciated.

"""
import logging

from django.conf import settings
from django.template.loader import render_to_string as raw_render_to_string
from django.utils.module_loading import import_string

__author__ = "Matthieu Gallet"
logger = logging.getLogger("djangofloor.signals")
middlewares = [import_string(x)() for x in settings.WINDOW_INFO_MIDDLEWARES]


[docs]class Session: def __init__(self, key=None): self.key = key
[docs]class WindowInfo: """ Built to store the username and the window key and must be supplied to any Python signal call. All attributes are set by "WindowInfoMiddleware"'s. Can be constructed from a standard :class:`django.http.HttpRequest` or from a dict. Like the request, you should check the installed middlewares to obtain the full list of attributes. The default ones are provided by :mod:`djangofloor.middleware`. """ def __init__(self, init=True): if init: for mdw in middlewares: mdw.new_window_info(self)
[docs] @classmethod def from_dict(cls, values): """Generate a new :class:`WindowInfo` from a dict.""" if values is None: return None window_info = cls(init=False) for mdw in middlewares: mdw.from_dict(window_info, values=values) return window_info
[docs] def to_dict(self): """Convert this :class:`djangofloor.wsgi.window_info.WindowInfo` to a :class:`dict` which can be provided to JSON. :return: a dict ready to be serialized in JSON :rtype: :class:`dict` """ result = {} for mdw in middlewares: extra_values = mdw.to_dict(self) if extra_values: result.update(extra_values) return result
[docs] @classmethod def from_request(cls, request): """ return a :class:`djangofloor.wsgi.window_info.WindowInfo` from a :class:`django.http.HttpRequest`. If the request already is a :class:`djangofloor.wsgi.window_info.WindowInfo`, then it is returned as-is (not copied!). :param request: standard Django request :type request: :class:`django.http.HttpRequest` or :class:`djangofloor.wsgi.window_info.WindowInfo` :return: a valid request :rtype: :class:`djangofloor.wsgi.window_info.WindowInfo` """ if isinstance(request, WindowInfo): return request elif request is None: return WindowInfo() window_info = cls(init=False) for mdw in middlewares: mdw.from_request(request, window_info) return window_info
for mdw_ in middlewares: mdw_.install_methods(WindowInfo)
[docs]def get_window_context(window_info): """Generate a template context from the `window_info`, equivalent of a template context from a :class:`django.http.request.HttpRequest`.""" context = {} if window_info: for mdw in middlewares: context.update(mdw.get_context(window_info)) return context
[docs]def render_to_string(template_name, context=None, window_info=None, using=None): """Render a template to a string using a context from the `window_info`, equivalent of the :meth:`django.template.loader.render_to_string`.""" if window_info is not None and context: window_context = get_window_context(window_info) window_context.update(context) elif window_info is not None: window_context = get_window_context(window_info) else: window_context = context return raw_render_to_string(template_name, context=window_context, using=using)