Source code for boardinghouse.signals
"""
Signals that are fired as part of the django-boardinghouse project.
.. data:: schema_created
Sent when a new schema object has been created in the database. Accepts a
single argument, the (internal) name of the schema.
.. data:: schema_pre_activate
Sent just before a schema will be activated. May be used to abort this by
throwing an exception.
.. data:: schema_post_activate
Sent immediately after a schema has been activated.
.. data:: session_requesting_schema_change
Sent when a user-session has requested (and is, according to default rules,
allowed to change to this schema). May be used to prevent the change, by
throwing an exception.
.. data:: session_schema_changed
Sent when a user-session has changed it's schema.
"""
import logging
from django.dispatch import Signal
from django.db import connection
from django.core.cache import cache
from .schema import (
_schema_exists, is_shared_model, get_schema_model,
get_active_schema_name
)
LOGGER = logging.getLogger(__name__)
LOGGER.addHandler(logging.NullHandler())
# Provided signals.
schema_created = Signal(providing_args=["schema"])
schema_pre_activate = Signal(providing_args=["schema"])
schema_post_activate = Signal(providing_args=["schema"])
session_requesting_schema_change = Signal(providing_args=["user", "schema", "session"])
session_schema_changed = Signal(providing_args=["user", "schema", "session"])
# Signal handlers.
[docs]def create_schema(sender, instance, created, **kwargs):
"""
Actually create the schema in the database.
We do this in a signal handler instead of .save() so we can catch
those created using raw methods.
"""
if created:
schema_name = instance.schema
cursor = connection.cursor()
if _schema_exists(schema_name):
LOGGER.warn('Attempt to create an existing schema: %s' % schema_name)
return
cursor.execute("SELECT clone_schema('__template__', %s)", [schema_name])
cursor.close()
if schema_name != '__template__':
schema_created.send(sender=get_schema_model(), schema=schema_name)
LOGGER.info('New schema created: %s' % schema_name)
[docs]def inject_schema_attribute(sender, instance, **kwargs):
"""
A signal listener that injects the current schema on the object
just after it is instantiated.
You may use this in conjunction with :class:`MultiSchemaMixin`, it will
respect any value that has already been set on the instance.
"""
if is_shared_model(sender):
return
if not getattr(instance, '_schema', None):
instance._schema = get_active_schema_name()
[docs]def invalidate_cache(sender, **kwargs):
"""
A signal listener designed to invalidate the cache of a single
user's visible schemata items.
"""
if kwargs['reverse']:
cache.delete('visible-schemata-%s' % kwargs['instance'].pk)
else:
if kwargs['pk_set']:
for pk in kwargs['pk_set']:
cache.delete('visible-schemata-%s' % pk)
[docs]def invalidate_all_user_caches(sender, **kwargs):
"""
A signal listener that invalidates all schemata caches for all users
who have access to the sender instance (schema).
"""
cache.delete('active-schemata')
cache.delete('all-schemata')
for user in kwargs['instance'].users.values('pk'):
cache.delete('visible-schemata-%s' % user['pk'])
[docs]def invalidate_all_caches(sender, **kwargs):
"""
Invalidate all schemata caches. Not entirely sure this one works.
"""
if sender.name == 'boardinghouse':
cache.delete('active-schemata')
cache.delete('all-schemata')