<commit_before># -*- coding: utf-8 -*-
#
# dcolumn/dcolumns/views.py
#

import logging

from django.shortcuts import render
from django.views.generic import TemplateView
from django.core.urlresolvers import reverse
from django.utils.decorators import method_decorator

from dcolumn.common.view_mixins import JSONResponseMixin
from dcolumn.common.decorators import dcolumn_login_required
from .models import DynamicColumn, ColumnCollection
from .manager import dcolumn_manager

log = logging.getLogger('dcolumns.dcolumns.views')


class ContextDataMixin(object):
    """
    Mixin for context data.
    """

    def get_dynamic_column_context_data(self, class_name=''):
        """
        Generates the data needed for HTML select option tags. This data is
        in a dict keyed by ``dynamicColumns`` giving it a namespace in the
        context. The slug for each ``CHOICE`` object is the key to the list
        used for the option tags.

        Example of Output::

          {'dynamicColumns': {
           u'author': [(0, 'Choose a value'),
                       (17, u'<NAME>'),
                       (5, u'<NAME>'),
                       (23, u'<NAME> & <NAME>'),
                       (25, u'<NAME>'),
                       (6, u'<NAME>'),
                       (7, u'<NAME>'),
                       (15, u'<NAME> & <NAME>'),
                       (8, u'<NAME>')],
           u'language': [(0, 'Choose a value'),
                         (1, 'Chinese'),
                         (2, 'English'),
                         (3, 'Portuguese'),
                         (4, 'Russian'),
                         (5, 'Japanese')],
           ...}
          }

        :param class_name: This is a mandatory keyword that defines the
                           ``ColumnCollection`` name.
        :type class_name: str
        :rtype: dict
        """
        context = {}
        fk_slugs = DynamicColumn.objects.get_fk_slugs()
        name = dcolumn_manager.get_collection_name(class_name)

        for model_name in ColumnCollection.objects.get_active_relation_items(
            name):
            model, field = dcolumn_manager.choice_map.get(model_name)
            objects = context.setdefault('dynamicColumns', {})
            values = [(r.pk, getattr(r, field))
                      for r in model.objects.model_objects()]
            values.insert(0, (0, "Choose a value"))
            objects[fk_slugs.get(model_name)] = values
            log.debug("model_name: %s, model: %s, field: %s, fk_slugs: %s, "
                      "values: %s", model_name, model, field, fk_slugs, values)

        log.debug("context: %s", context)
        return context

    def get_relation_context_data(self, class_name='', obj=None, form=None):
        """
        Generates an OrderedDict of meta data needed to determine how the
        values of a ``KeyValue`` is to interpreted. If ``obj`` is supplied
        and ``form`` is not supplied values from the ``KeyWord`` objects will
        be included in the list of meta data. If ``form`` is supplied the
        meta data will be taken from the Django form exclusively.

        Example of Output::

          OrderedDict([
            (19,
              {'location': 'book-bottom',
               'name': u'Promotion',
               'order': 1,
               'pk': 19,
               'relation': 2,
               'required': False,
               'slug': u'promotion',
               'store_relation': True,
               'value_type': 2}),
            (20,
              {'location': 'book-center',
               'name': u'Language',
               'order': 6,
               'pk': 20,
               'relation': 1,
               'required': False,
               'slug': u'language',
               'store_relation': False,
               'value_type': 2}),
            ...])

        :param class_name: This is a mandatory keyword that defines the
                           ``ColumnCollection`` name.
        :type class_name: str
        :param obj: Optional model object that inherits from ``CollectionBase``.
        :type obj: object
        :param form: Optional form object.
        :type: Django Form object.
        :rtype: OrderedDict
        """
        if form:
            relations = form.get_display_data()
        else:
            name = dcolumn_manager.get_collection_name(class_name)
            relations = ColumnCollection.objects.serialize_columns(
                name, obj=obj)

        log.debug("relations: %s", relations)
        return {'relations': relations}


#
# CollectionAJAXView
#
class CollectionAJAXView(JSONResponseMixin, TemplateView, ContextDataMixin):
    """
    Web service endpoint used in the Django admin to format ``KeyValue`` values
    as per the ``DynamicColumn`` meta data.
    """
    http_method_names = ('get',)

    @method_decorator(dcolumn_login_required)
    def dispatch(self, *args, **kwargs):
        """
        Django view dispatch decorated for login requierments.
        """
        return super(CollectionAJAXView, self).dispatch(*args, **kwargs)

    def get_context_data(self, **kwargs):
        """
        Get context data for the ``KeyValue`` objects.

        Do not call super on get_context_data, it puts self into the context
        which is not valid JSON.
        """
        log.debug("kwargs: %s", kwargs)
        context = {'valid': True}

        try:
            context.update(self.get_dynamic_column_context_data(**kwargs))
            context.update(self.get_relation_context_data(**kwargs))
        except Exception, e:
            context['valid'] = False
            context['message'] = "Error occurred: {}".format(e)
            log.error(context['message'], exc_info=True)

        return context

collection_ajax_view = CollectionAJAXView.as_view()


#
# CollectionCreateUpdateViewMixin
#
class CollectionCreateUpdateViewMixin(ContextDataMixin):
    """
    This mixin is needed by any create or update view where the view is
    associated with a model that inherits ``CollectionBase``.
    """

    def get_initial(self):
        """
        Provides initial data to forms.
        """
        return {'request': self.request}

    def get_context_data(self, **kwargs):
        """
        Get context data for the ``KeyValue`` objects.
        """
        kwargs['class_name'] = self.model.__name__
        context = super(CollectionCreateUpdateViewMixin,
                        self).get_context_data(**kwargs)
        context.update(self.get_dynamic_column_context_data(**kwargs))
        context.update(self.get_relation_context_data(
            obj=self.object, **kwargs))
        context.update({'css': dcolumn_manager.css_container_map})
        return context


#
# CollectionDetailViewMixin
#
class CollectionDetailViewMixin(ContextDataMixin):
    """
    This mixin is needed by any detail view where the view is associated with
    a model that inherits ``CollectionBase``.
    """

    def get_context_data(self, **kwargs):
        """
        Get context data for the ``KeyValue`` objects.
        """
        kwargs['class_name'] = self.model.__name__
        context = super(CollectionDetailViewMixin,
                        self).get_context_data(**kwargs)
        context.update(self.get_dynamic_column_context_data(**kwargs))
        context.update(self.get_relation_context_data(
            obj=self.object, **kwargs))
        context.update({'css': dcolumn_manager.css_container_map})
        return context
<commit_msg>Added module level docs.<commit_after># -*- coding: utf-8 -*-
#
# dcolumn/dcolumns/views.py
#
"""
Dynamic Column dependent views.
"""
__docformat__ = "restructuredtext en"

import logging

from django.shortcuts import render
from django.views.generic import TemplateView
from django.core.urlresolvers import reverse
from django.utils.decorators import method_decorator

from dcolumn.common.view_mixins import JSONResponseMixin
from dcolumn.common.decorators import dcolumn_login_required
from .models import DynamicColumn, ColumnCollection
from .manager import dcolumn_manager

log = logging.getLogger('dcolumns.dcolumns.views')


class ContextDataMixin(object):
    """
    Mixin for context data.
    """

    def get_dynamic_column_context_data(self, class_name=''):
        """
        Generates the data needed for HTML select option tags. This data is
        in a dict keyed by ``dynamicColumns`` giving it a namespace in the
        context. The slug for each ``CHOICE`` object is the key to the list
        used for the option tags.

        Example of Output::

          {'dynamicColumns': {
           u'author': [(0, 'Choose a value'),
                       (17, u'<NAME>'),
                       (5, u'<NAME>'),
                       (23, u'<NAME> & <NAME>'),
                       (25, u'<NAME>'),
                       (6, u'<NAME>'),
                       (7, u'<NAME>'),
                       (15, u'<NAME> & <NAME>'),
                       (8, u'<NAME>')],
           u'language': [(0, 'Choose a value'),
                         (1, 'Chinese'),
                         (2, 'English'),
                         (3, 'Portuguese'),
                         (4, 'Russian'),
                         (5, 'Japanese')],
           ...}
          }

        :param class_name: This is a mandatory keyword that defines the
                           ``ColumnCollection`` name.
        :type class_name: str
        :rtype: dict
        """
        context = {}
        fk_slugs = DynamicColumn.objects.get_fk_slugs()
        name = dcolumn_manager.get_collection_name(class_name)

        for model_name in ColumnCollection.objects.get_active_relation_items(
            name):
            model, field = dcolumn_manager.choice_map.get(model_name)
            objects = context.setdefault('dynamicColumns', {})
            values = [(r.pk, getattr(r, field))
                      for r in model.objects.model_objects()]
            values.insert(0, (0, "Choose a value"))
            objects[fk_slugs.get(model_name)] = values
            log.debug("model_name: %s, model: %s, field: %s, fk_slugs: %s, "
                      "values: %s", model_name, model, field, fk_slugs, values)

        log.debug("context: %s", context)
        return context

    def get_relation_context_data(self, class_name='', obj=None, form=None):
        """
        Generates an OrderedDict of meta data needed to determine how the
        values of a ``KeyValue`` is to interpreted. If ``obj`` is supplied
        and ``form`` is not supplied values from the ``KeyWord`` objects will
        be included in the list of meta data. If ``form`` is supplied the
        meta data will be taken from the Django form exclusively.

        Example of Output::

          OrderedDict([
            (19,
              {'location': 'book-bottom',
               'name': u'Promotion',
               'order': 1,
               'pk': 19,
               'relation': 2,
               'required': False,
               'slug': u'promotion',
               'store_relation': True,
               'value_type': 2}),
            (20,
              {'location': 'book-center',
               'name': u'Language',
               'order': 6,
               'pk': 20,
               'relation': 1,
               'required': False,
               'slug': u'language',
               'store_relation': False,
               'value_type': 2}),
            ...])

        :param class_name: This is a mandatory keyword that defines the
                           ``ColumnCollection`` name.
        :type class_name: str
        :param obj: Optional model object that inherits from ``CollectionBase``.
        :type obj: object
        :param form: Optional form object.
        :type: Django Form object.
        :rtype: OrderedDict
        """
        if form:
            relations = form.get_display_data()
        else:
            name = dcolumn_manager.get_collection_name(class_name)
            relations = ColumnCollection.objects.serialize_columns(
                name, obj=obj)

        log.debug("relations: %s", relations)
        return {'relations': relations}


#
# CollectionAJAXView
#
class CollectionAJAXView(JSONResponseMixin, TemplateView, ContextDataMixin):
    """
    Web service endpoint used in the Django admin to format ``KeyValue`` values
    as per the ``DynamicColumn`` meta data.
    """
    http_method_names = ('get',)

    @method_decorator(dcolumn_login_required)
    def dispatch(self, *args, **kwargs):
        """
        Django view dispatch decorated for login requierments.
        """
        return super(CollectionAJAXView, self).dispatch(*args, **kwargs)

    def get_context_data(self, **kwargs):
        """
        Get context data for the ``KeyValue`` objects.

        Do not call super on get_context_data, it puts self into the context
        which is not valid JSON.
        """
        log.debug("kwargs: %s", kwargs)
        context = {'valid': True}

        try:
            context.update(self.get_dynamic_column_context_data(**kwargs))
            context.update(self.get_relation_context_data(**kwargs))
        except Exception, e:
            context['valid'] = False
            context['message'] = "Error occurred: {}".format(e)
            log.error(context['message'], exc_info=True)

        return context

collection_ajax_view = CollectionAJAXView.as_view()


#
# CollectionCreateUpdateViewMixin
#
class CollectionCreateUpdateViewMixin(ContextDataMixin):
    """
    This mixin is needed by any create or update view where the view is
    associated with a model that inherits ``CollectionBase``.
    """

    def get_initial(self):
        """
        Provides initial data to forms.
        """
        return {'request': self.request}

    def get_context_data(self, **kwargs):
        """
        Get context data for the ``KeyValue`` objects.
        """
        kwargs['class_name'] = self.model.__name__
        context = super(CollectionCreateUpdateViewMixin,
                        self).get_context_data(**kwargs)
        context.update(self.get_dynamic_column_context_data(**kwargs))
        context.update(self.get_relation_context_data(
            obj=self.object, **kwargs))
        context.update({'css': dcolumn_manager.css_container_map})
        return context


#
# CollectionDetailViewMixin
#
class CollectionDetailViewMixin(ContextDataMixin):
    """
    This mixin is needed by any detail view where the view is associated with
    a model that inherits ``CollectionBase``.
    """

    def get_context_data(self, **kwargs):
        """
        Get context data for the ``KeyValue`` objects.
        """
        kwargs['class_name'] = self.model.__name__
        context = super(CollectionDetailViewMixin,
                        self).get_context_data(**kwargs)
        context.update(self.get_dynamic_column_context_data(**kwargs))
        context.update(self.get_relation_context_data(
            obj=self.object, **kwargs))
        context.update({'css': dcolumn_manager.css_container_map})
        return context

{'fraction_non_alphanumeric': 0.11022840119165839, 'fraction_numerical': 0.004766633565044687, 'mean_word_length': 2.061613295500608, 'pattern_counts': {'":': 0, '<': 23, '<?xml version=': 0, '>': 23, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5597620', 'n_tokens_mistral': 4146, 'n_tokens_neox': 3980, 'n_words': 1116}