summaryrefslogtreecommitdiff
path: root/lib/python2.7/site-packages/django/contrib/messages/storage
diff options
context:
space:
mode:
Diffstat (limited to 'lib/python2.7/site-packages/django/contrib/messages/storage')
-rw-r--r--lib/python2.7/site-packages/django/contrib/messages/storage/__init__.py8
-rw-r--r--lib/python2.7/site-packages/django/contrib/messages/storage/base.py184
-rw-r--r--lib/python2.7/site-packages/django/contrib/messages/storage/cookie.py158
-rw-r--r--lib/python2.7/site-packages/django/contrib/messages/storage/fallback.py54
-rw-r--r--lib/python2.7/site-packages/django/contrib/messages/storage/session.py46
5 files changed, 0 insertions, 450 deletions
diff --git a/lib/python2.7/site-packages/django/contrib/messages/storage/__init__.py b/lib/python2.7/site-packages/django/contrib/messages/storage/__init__.py
deleted file mode 100644
index 9a09aff..0000000
--- a/lib/python2.7/site-packages/django/contrib/messages/storage/__init__.py
+++ /dev/null
@@ -1,8 +0,0 @@
-from django.conf import settings
-from django.utils.module_loading import import_by_path as get_storage
-
-
-# Callable with the same interface as the storage classes i.e. accepts a
-# 'request' object. It is wrapped in a lambda to stop 'settings' being used at
-# the module level
-default_storage = lambda request: get_storage(settings.MESSAGE_STORAGE)(request)
diff --git a/lib/python2.7/site-packages/django/contrib/messages/storage/base.py b/lib/python2.7/site-packages/django/contrib/messages/storage/base.py
deleted file mode 100644
index 7fe8a07..0000000
--- a/lib/python2.7/site-packages/django/contrib/messages/storage/base.py
+++ /dev/null
@@ -1,184 +0,0 @@
-from __future__ import unicode_literals
-
-from django.conf import settings
-from django.utils.encoding import force_text, python_2_unicode_compatible
-from django.contrib.messages import constants, utils
-
-
-LEVEL_TAGS = utils.get_level_tags()
-
-
-@python_2_unicode_compatible
-class Message(object):
- """
- Represents an actual message that can be stored in any of the supported
- storage classes (typically session- or cookie-based) and rendered in a view
- or template.
- """
-
- def __init__(self, level, message, extra_tags=None):
- self.level = int(level)
- self.message = message
- self.extra_tags = extra_tags
-
- def _prepare(self):
- """
- Prepares the message for serialization by forcing the ``message``
- and ``extra_tags`` to unicode in case they are lazy translations.
-
- Known "safe" types (None, int, etc.) are not converted (see Django's
- ``force_text`` implementation for details).
- """
- self.message = force_text(self.message, strings_only=True)
- self.extra_tags = force_text(self.extra_tags, strings_only=True)
-
- def __eq__(self, other):
- return isinstance(other, Message) and self.level == other.level and \
- self.message == other.message
-
- def __str__(self):
- return force_text(self.message)
-
- def _get_tags(self):
- label_tag = force_text(LEVEL_TAGS.get(self.level, ''),
- strings_only=True)
- extra_tags = force_text(self.extra_tags, strings_only=True)
- if extra_tags and label_tag:
- return ' '.join([extra_tags, label_tag])
- elif extra_tags:
- return extra_tags
- elif label_tag:
- return label_tag
- return ''
- tags = property(_get_tags)
-
-
-class BaseStorage(object):
- """
- This is the base backend for temporary message storage.
-
- This is not a complete class; to be a usable storage backend, it must be
- subclassed and the two methods ``_get`` and ``_store`` overridden.
- """
-
- def __init__(self, request, *args, **kwargs):
- self.request = request
- self._queued_messages = []
- self.used = False
- self.added_new = False
- super(BaseStorage, self).__init__(*args, **kwargs)
-
- def __len__(self):
- return len(self._loaded_messages) + len(self._queued_messages)
-
- def __iter__(self):
- self.used = True
- if self._queued_messages:
- self._loaded_messages.extend(self._queued_messages)
- self._queued_messages = []
- return iter(self._loaded_messages)
-
- def __contains__(self, item):
- return item in self._loaded_messages or item in self._queued_messages
-
- @property
- def _loaded_messages(self):
- """
- Returns a list of loaded messages, retrieving them first if they have
- not been loaded yet.
- """
- if not hasattr(self, '_loaded_data'):
- messages, all_retrieved = self._get()
- self._loaded_data = messages or []
- return self._loaded_data
-
- def _get(self, *args, **kwargs):
- """
- Retrieves a list of stored messages. Returns a tuple of the messages
- and a flag indicating whether or not all the messages originally
- intended to be stored in this storage were, in fact, stored and
- retrieved; e.g., ``(messages, all_retrieved)``.
-
- **This method must be implemented by a subclass.**
-
- If it is possible to tell if the backend was not used (as opposed to
- just containing no messages) then ``None`` should be returned in
- place of ``messages``.
- """
- raise NotImplementedError()
-
- def _store(self, messages, response, *args, **kwargs):
- """
- Stores a list of messages, returning a list of any messages which could
- not be stored.
-
- One type of object must be able to be stored, ``Message``.
-
- **This method must be implemented by a subclass.**
- """
- raise NotImplementedError()
-
- def _prepare_messages(self, messages):
- """
- Prepares a list of messages for storage.
- """
- for message in messages:
- message._prepare()
-
- def update(self, response):
- """
- Stores all unread messages.
-
- If the backend has yet to be iterated, previously stored messages will
- be stored again. Otherwise, only messages added after the last
- iteration will be stored.
- """
- self._prepare_messages(self._queued_messages)
- if self.used:
- return self._store(self._queued_messages, response)
- elif self.added_new:
- messages = self._loaded_messages + self._queued_messages
- return self._store(messages, response)
-
- def add(self, level, message, extra_tags=''):
- """
- Queues a message to be stored.
-
- The message is only queued if it contained something and its level is
- not less than the recording level (``self.level``).
- """
- if not message:
- return
- # Check that the message level is not less than the recording level.
- level = int(level)
- if level < self.level:
- return
- # Add the message.
- self.added_new = True
- message = Message(level, message, extra_tags=extra_tags)
- self._queued_messages.append(message)
-
- def _get_level(self):
- """
- Returns the minimum recorded level.
-
- The default level is the ``MESSAGE_LEVEL`` setting. If this is
- not found, the ``INFO`` level is used.
- """
- if not hasattr(self, '_level'):
- self._level = getattr(settings, 'MESSAGE_LEVEL', constants.INFO)
- return self._level
-
- def _set_level(self, value=None):
- """
- Sets a custom minimum recorded level.
-
- If set to ``None``, the default level will be used (see the
- ``_get_level`` method).
- """
- if value is None and hasattr(self, '_level'):
- del self._level
- else:
- self._level = int(value)
-
- level = property(_get_level, _set_level, _set_level)
diff --git a/lib/python2.7/site-packages/django/contrib/messages/storage/cookie.py b/lib/python2.7/site-packages/django/contrib/messages/storage/cookie.py
deleted file mode 100644
index 619c692..0000000
--- a/lib/python2.7/site-packages/django/contrib/messages/storage/cookie.py
+++ /dev/null
@@ -1,158 +0,0 @@
-import json
-
-from django.conf import settings
-from django.contrib.messages.storage.base import BaseStorage, Message
-from django.http import SimpleCookie
-from django.utils.crypto import salted_hmac, constant_time_compare
-from django.utils.safestring import SafeData, mark_safe
-from django.utils import six
-
-
-class MessageEncoder(json.JSONEncoder):
- """
- Compactly serializes instances of the ``Message`` class as JSON.
- """
- message_key = '__json_message'
-
- def default(self, obj):
- if isinstance(obj, Message):
- # Using 0/1 here instead of False/True to produce more compact json
- is_safedata = 1 if isinstance(obj.message, SafeData) else 0
- message = [self.message_key, is_safedata, obj.level, obj.message]
- if obj.extra_tags:
- message.append(obj.extra_tags)
- return message
- return super(MessageEncoder, self).default(obj)
-
-
-class MessageDecoder(json.JSONDecoder):
- """
- Decodes JSON that includes serialized ``Message`` instances.
- """
-
- def process_messages(self, obj):
- if isinstance(obj, list) and obj:
- if obj[0] == MessageEncoder.message_key:
- if obj[1]:
- obj[3] = mark_safe(obj[3])
- return Message(*obj[2:])
- return [self.process_messages(item) for item in obj]
- if isinstance(obj, dict):
- return dict([(key, self.process_messages(value))
- for key, value in six.iteritems(obj)])
- return obj
-
- def decode(self, s, **kwargs):
- decoded = super(MessageDecoder, self).decode(s, **kwargs)
- return self.process_messages(decoded)
-
-class CookieStorage(BaseStorage):
- """
- Stores messages in a cookie.
- """
- cookie_name = 'messages'
- # uwsgi's default configuration enforces a maximum size of 4kb for all the
- # HTTP headers. In order to leave some room for other cookies and headers,
- # restrict the session cookie to 1/2 of 4kb. See #18781.
- max_cookie_size = 2048
- not_finished = '__messagesnotfinished__'
-
- def _get(self, *args, **kwargs):
- """
- Retrieves a list of messages from the messages cookie. If the
- not_finished sentinel value is found at the end of the message list,
- remove it and return a result indicating that not all messages were
- retrieved by this storage.
- """
- data = self.request.COOKIES.get(self.cookie_name)
- messages = self._decode(data)
- all_retrieved = not (messages and messages[-1] == self.not_finished)
- if messages and not all_retrieved:
- # remove the sentinel value
- messages.pop()
- return messages, all_retrieved
-
- def _update_cookie(self, encoded_data, response):
- """
- Either sets the cookie with the encoded data if there is any data to
- store, or deletes the cookie.
- """
- if encoded_data:
- response.set_cookie(self.cookie_name, encoded_data,
- domain=settings.SESSION_COOKIE_DOMAIN)
- else:
- response.delete_cookie(self.cookie_name,
- domain=settings.SESSION_COOKIE_DOMAIN)
-
- def _store(self, messages, response, remove_oldest=True, *args, **kwargs):
- """
- Stores the messages to a cookie, returning a list of any messages which
- could not be stored.
-
- If the encoded data is larger than ``max_cookie_size``, removes
- messages until the data fits (these are the messages which are
- returned), and add the not_finished sentinel value to indicate as much.
- """
- unstored_messages = []
- encoded_data = self._encode(messages)
- if self.max_cookie_size:
- # data is going to be stored eventually by SimpleCookie, which
- # adds it's own overhead, which we must account for.
- cookie = SimpleCookie() # create outside the loop
- def stored_length(val):
- return len(cookie.value_encode(val)[1])
-
- while encoded_data and stored_length(encoded_data) > self.max_cookie_size:
- if remove_oldest:
- unstored_messages.append(messages.pop(0))
- else:
- unstored_messages.insert(0, messages.pop())
- encoded_data = self._encode(messages + [self.not_finished],
- encode_empty=unstored_messages)
- self._update_cookie(encoded_data, response)
- return unstored_messages
-
- def _hash(self, value):
- """
- Creates an HMAC/SHA1 hash based on the value and the project setting's
- SECRET_KEY, modified to make it unique for the present purpose.
- """
- key_salt = 'django.contrib.messages'
- return salted_hmac(key_salt, value).hexdigest()
-
- def _encode(self, messages, encode_empty=False):
- """
- Returns an encoded version of the messages list which can be stored as
- plain text.
-
- Since the data will be retrieved from the client-side, the encoded data
- also contains a hash to ensure that the data was not tampered with.
- """
- if messages or encode_empty:
- encoder = MessageEncoder(separators=(',', ':'))
- value = encoder.encode(messages)
- return '%s$%s' % (self._hash(value), value)
-
- def _decode(self, data):
- """
- Safely decodes a encoded text stream back into a list of messages.
-
- If the encoded text stream contained an invalid hash or was in an
- invalid format, ``None`` is returned.
- """
- if not data:
- return None
- bits = data.split('$', 1)
- if len(bits) == 2:
- hash, value = bits
- if constant_time_compare(hash, self._hash(value)):
- try:
- # If we get here (and the JSON decode works), everything is
- # good. In any other case, drop back and return None.
- return json.loads(value, cls=MessageDecoder)
- except ValueError:
- pass
- # Mark the data as used (so it gets removed) since something was wrong
- # with the data.
- self.used = True
- return None
diff --git a/lib/python2.7/site-packages/django/contrib/messages/storage/fallback.py b/lib/python2.7/site-packages/django/contrib/messages/storage/fallback.py
deleted file mode 100644
index 6c35343..0000000
--- a/lib/python2.7/site-packages/django/contrib/messages/storage/fallback.py
+++ /dev/null
@@ -1,54 +0,0 @@
-from django.contrib.messages.storage.base import BaseStorage
-from django.contrib.messages.storage.cookie import CookieStorage
-from django.contrib.messages.storage.session import SessionStorage
-
-class FallbackStorage(BaseStorage):
- """
- Tries to store all messages in the first backend, storing any unstored
- messages in each subsequent backend backend.
- """
- storage_classes = (CookieStorage, SessionStorage)
-
- def __init__(self, *args, **kwargs):
- super(FallbackStorage, self).__init__(*args, **kwargs)
- self.storages = [storage_class(*args, **kwargs)
- for storage_class in self.storage_classes]
- self._used_storages = set()
-
- def _get(self, *args, **kwargs):
- """
- Gets a single list of messages from all storage backends.
- """
- all_messages = []
- for storage in self.storages:
- messages, all_retrieved = storage._get()
- # If the backend hasn't been used, no more retrieval is necessary.
- if messages is None:
- break
- if messages:
- self._used_storages.add(storage)
- all_messages.extend(messages)
- # If this storage class contained all the messages, no further
- # retrieval is necessary
- if all_retrieved:
- break
- return all_messages, all_retrieved
-
- def _store(self, messages, response, *args, **kwargs):
- """
- Stores the messages, returning any unstored messages after trying all
- backends.
-
- For each storage backend, any messages not stored are passed on to the
- next backend.
- """
- for storage in self.storages:
- if messages:
- messages = storage._store(messages, response,
- remove_oldest=False)
- # Even if there are no more messages, continue iterating to ensure
- # storages which contained messages are flushed.
- elif storage in self._used_storages:
- storage._store([], response)
- self._used_storages.remove(storage)
- return messages
diff --git a/lib/python2.7/site-packages/django/contrib/messages/storage/session.py b/lib/python2.7/site-packages/django/contrib/messages/storage/session.py
deleted file mode 100644
index c3e293c..0000000
--- a/lib/python2.7/site-packages/django/contrib/messages/storage/session.py
+++ /dev/null
@@ -1,46 +0,0 @@
-import json
-
-from django.contrib.messages.storage.base import BaseStorage
-from django.contrib.messages.storage.cookie import MessageEncoder, MessageDecoder
-from django.utils import six
-
-
-class SessionStorage(BaseStorage):
- """
- Stores messages in the session (that is, django.contrib.sessions).
- """
- session_key = '_messages'
-
- def __init__(self, request, *args, **kwargs):
- assert hasattr(request, 'session'), "The session-based temporary "\
- "message storage requires session middleware to be installed, "\
- "and come before the message middleware in the "\
- "MIDDLEWARE_CLASSES list."
- super(SessionStorage, self).__init__(request, *args, **kwargs)
-
- def _get(self, *args, **kwargs):
- """
- Retrieves a list of messages from the request's session. This storage
- always stores everything it is given, so return True for the
- all_retrieved flag.
- """
- return self.deserialize_messages(self.request.session.get(self.session_key)), True
-
- def _store(self, messages, response, *args, **kwargs):
- """
- Stores a list of messages to the request's session.
- """
- if messages:
- self.request.session[self.session_key] = self.serialize_messages(messages)
- else:
- self.request.session.pop(self.session_key, None)
- return []
-
- def serialize_messages(self, messages):
- encoder = MessageEncoder(separators=(',', ':'))
- return encoder.encode(messages)
-
- def deserialize_messages(self, data):
- if data and isinstance(data, six.string_types):
- return json.loads(data, cls=MessageDecoder)
- return data