<commit_before># -*- coding: utf-8 -*-


# OpenFisca -- A versatile microsimulation software
# By: OpenFisca Team <<EMAIL>>
#
# Copyright (C) 2011, 2012, 2013, 2014 OpenFisca Team
# https://github.com/openfisca
#
# This file is part of OpenFisca.
#
# OpenFisca is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# OpenFisca is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


"""Korma questions and factories"""


import logging

from biryani1.baseconv import check, guess_bool, pipe
from korma.base import Button
from korma.checkbox import Checkbox
from korma.choice import Radio, Select
from korma.date import Date
from korma.group import Group
from korma.text import Hidden, Number, Text

from ..conv import base


email_log = logging.getLogger('email')


bootstrap_form_group = u'<div class="form-group">{self.inner_html}</div>'


bootstrapize = lambda question_class, *args, **kwargs: \
    question_class(
        control_attributes = {'class': u'form-control'},
        *args, **kwargs)


def BootstrapButton(control_attributes = None, other_classes = None, *args, **kwargs):
    if control_attributes is None:
        control_attributes = {'class': 'btn', 'type': 'submit'}
    if other_classes is not None and control_attributes.get('class'):
        control_attributes['class'] += ' ' + other_classes
    return Button(control_attributes = control_attributes, *args, **kwargs)


BootstrapCheckbox = lambda *args, **kwargs: \
    Checkbox(
        inner_html_template = u'''
<div class="col-sm-offset-4 col-sm-8">
  <div class="checkbox">
    <label>{self.control_html} {self.label}</label>
  </div>
</div>''',
        *args, **kwargs)


BootstrapNumber = lambda *args, **kwargs: bootstrapize(Number, *args, **kwargs)


class BootstrapRadio(Radio):
    _inner_html_template = u'''
<label for="{self.full_name}">{self.label}</label>
<div>{self.control_html}</div>
'''

    def item_html(self, label, value):
        input_ = u'<input{attributes}>'.format(attributes=self.format_attributes(self.item_attributes(value)))
        return u'<label class="radio-inline">{input} {label}</label>'.format(input=input_, label=label)


BootstrapSelect = lambda *args, **kwargs: bootstrapize(Select, *args, **kwargs)


BootstrapText = lambda *args, **kwargs: bootstrapize(Text, *args, **kwargs)


custom_column_default_values = {
    # TODO remove birth as it is no more needed by API.
    u'birth': 1984,
    }


class MongoDate(Date):
    @property
    def data_to_str(self):
        return pipe(base.datetime_to_date, super(MongoDate, self).data_to_str)

    @property
    def default_input_to_data(self):
        return pipe(super(MongoDate, self).default_input_to_data, base.date_to_datetime)


FrenchDate = lambda placeholder = u'jj/mm/aaaa', *args, **kwargs: \
    MongoDate(format=u'%d/%m/%Y', placeholder=placeholder, *args, **kwargs)


BootstrapFrenchDate = lambda *args, **kwargs: bootstrapize(FrenchDate, *args, **kwargs)


def make_categories_groups(entity):
    from .. import contexts, model

    ctx = contexts.Ctx()
    fields_api_data = model.fields_api_data()

    class ModalGroup(Group):
        _outer_html_template = u'''
<a href="#" class="list-group-item" data-toggle="modal" data-target="#modal-{self.full_name_as_selector}">
  {self.label}
</a>
<div class="modal fade" id="modal-{self.full_name}" tabindex="-1" role="dialog" \
aria-labelledby="modal-label-{self.full_name}" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="modal-label-{self.full_name}">{self.label}</h4>
      </div>
      <div class="modal-body">
        {self.questions_html}
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">{self.messages[close]}</button>
        <button type="submit" class="btn btn-primary" data-dismiss="modal">{self.messages[validate]}</button>
      </div>
    </div>
  </div>
</div>'''
        messages = {
            u'close': ctx._(u'Close'),
            u'validate': ctx._(u'Validate'),
            }

    def build_category_questions(entity_category):
        category_questions = []
        for column_name in entity_category['children']:
            column = fields_api_data['columns'].get(column_name)
            if column is not None:
                # Transform prenom question into hidden for use with x-editable field.
                question = Hidden(name = column['name']) \
                    if entity == 'individus' and entity_category['label'] == u'Principal' \
                    and column['name'] == 'prenom' else make_question(column)
                if question is None:
                    email_log.error(u'Unable to make question from column: {!r}'.format(column))
                else:
                    category_questions.append(question)
        return category_questions

    entity_categories = fields_api_data['columns_tree'][entity]['children']
    categories_groups = []
    for entity_category in entity_categories:
        group_questions = build_category_questions(entity_category)
        if entity_category['label'] == u'Principal':
            category_group = Group(
                children_attributes = {'_outer_html_template': bootstrap_form_group},
                name = 'principal',
                outer_html_template = u'<div class="main-category">{self.inner_html}</div>',
                questions = group_questions,
                )
        else:
            category_group = ModalGroup(
                children_attributes = {'_outer_html_template': bootstrap_form_group},
                label = entity_category['label'],
                questions = group_questions,
                )
        categories_groups.append(category_group)
    return categories_groups


def make_question(column):
    default = column.get('default')
    if default is None:
        default = custom_column_default_values.get(column['name'])
    default_str = lambda question: check(question.data_to_str(default))
    question_label = column.get('label')
    cerfa_field = column.get('cerfa_field')
    if cerfa_field is not None and isinstance(cerfa_field, basestring):
        question_label += u' (CERFA {})'.format(cerfa_field)
    if column['@type'] == 'Boolean':
        question = BootstrapRadio(
            choices = ((False, u'Non'), (True, u'Oui')),
            input_to_data = guess_bool,
            label = question_label,
            name = column['name'],<commit_msg>Drop None values for categories.<commit_after># -*- coding: utf-8 -*-


# OpenFisca -- A versatile microsimulation software
# By: OpenFisca Team <<EMAIL>>
#
# Copyright (C) 2011, 2012, 2013, 2014 OpenFisca Team
# https://github.com/openfisca
#
# This file is part of OpenFisca.
#
# OpenFisca is free software; you can redistribute it and/or modify
# it under the terms of the GNU Affero General Public License as
# published by the Free Software Foundation, either version 3 of the
# License, or (at your option) any later version.
#
# OpenFisca is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program.  If not, see <http://www.gnu.org/licenses/>.


"""Korma questions and factories"""


import logging

from biryani1.baseconv import check, guess_bool, pipe, struct
from korma.base import Button
from korma.checkbox import Checkbox
from korma.choice import Radio, Select
from korma.date import Date
from korma.group import Group
from korma.text import Hidden, Number, Text

from ..conv import base


email_log = logging.getLogger('email')


bootstrap_form_group = u'<div class="form-group">{self.inner_html}</div>'


bootstrapize = lambda question_class, *args, **kwargs: \
    question_class(
        control_attributes = {'class': u'form-control'},
        *args, **kwargs)


def BootstrapButton(control_attributes = None, other_classes = None, *args, **kwargs):
    if control_attributes is None:
        control_attributes = {'class': 'btn', 'type': 'submit'}
    if other_classes is not None and control_attributes.get('class'):
        control_attributes['class'] += ' ' + other_classes
    return Button(control_attributes = control_attributes, *args, **kwargs)


BootstrapCheckbox = lambda *args, **kwargs: \
    Checkbox(
        inner_html_template = u'''
<div class="col-sm-offset-4 col-sm-8">
  <div class="checkbox">
    <label>{self.control_html} {self.label}</label>
  </div>
</div>''',
        *args, **kwargs)


BootstrapNumber = lambda *args, **kwargs: bootstrapize(Number, *args, **kwargs)


class BootstrapRadio(Radio):
    _inner_html_template = u'''
<label for="{self.full_name}">{self.label}</label>
<div>{self.control_html}</div>
'''

    def item_html(self, label, value):
        input_ = u'<input{attributes}>'.format(attributes=self.format_attributes(self.item_attributes(value)))
        return u'<label class="radio-inline">{input} {label}</label>'.format(input=input_, label=label)


BootstrapSelect = lambda *args, **kwargs: bootstrapize(Select, *args, **kwargs)


BootstrapText = lambda *args, **kwargs: bootstrapize(Text, *args, **kwargs)


custom_column_default_values = {
    # TODO remove birth as it is no more needed by API.
    u'birth': 1984,
    }


class MongoDate(Date):
    @property
    def data_to_str(self):
        return pipe(base.datetime_to_date, super(MongoDate, self).data_to_str)

    @property
    def default_input_to_data(self):
        return pipe(super(MongoDate, self).default_input_to_data, base.date_to_datetime)


FrenchDate = lambda placeholder = u'jj/mm/aaaa', *args, **kwargs: \
    MongoDate(format=u'%d/%m/%Y', placeholder=placeholder, *args, **kwargs)


BootstrapFrenchDate = lambda *args, **kwargs: bootstrapize(FrenchDate, *args, **kwargs)


def make_categories_groups(entity):
    from .. import contexts, model

    ctx = contexts.Ctx()
    fields_api_data = model.fields_api_data()

    class CleanGroup(Group):
        @property
        def default_input_to_data(self):
            return struct(
                dict((question.name(), question.input_to_data) for question in self.iter_children()),
                default='drop',
                drop_none_values=True,
            )

    class ModalGroup(CleanGroup):
        _outer_html_template = u'''
<a href="#" class="list-group-item" data-toggle="modal" data-target="#modal-{self.full_name_as_selector}">
  {self.label}
</a>
<div class="modal fade" id="modal-{self.full_name}" tabindex="-1" role="dialog" \
aria-labelledby="modal-label-{self.full_name}" aria-hidden="true">
  <div class="modal-dialog">
    <div class="modal-content">
      <div class="modal-header">
        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
        <h4 class="modal-title" id="modal-label-{self.full_name}">{self.label}</h4>
      </div>
      <div class="modal-body">
        {self.questions_html}
      </div>
      <div class="modal-footer">
        <button type="button" class="btn btn-default" data-dismiss="modal">{self.messages[close]}</button>
        <button type="submit" class="btn btn-primary" data-dismiss="modal">{self.messages[validate]}</button>
      </div>
    </div>
  </div>
</div>'''
        messages = {
            u'close': ctx._(u'Close'),
            u'validate': ctx._(u'Validate'),
            }

    def build_category_questions(entity_category):
        category_questions = []
        for column_name in entity_category['children']:
            column = fields_api_data['columns'].get(column_name)
            if column is not None:
                # Transform prenom question into hidden for use with x-editable field.
                question = Hidden(name = column['name']) \
                    if entity == 'individus' and entity_category['label'] == u'Principal' \
                    and column['name'] == 'prenom' else make_question(column)
                if question is None:
                    email_log.error(u'Unable to make question from column: {!r}'.format(column))
                else:
                    category_questions.append(question)
        return category_questions

    entity_categories = fields_api_data['columns_tree'][entity]['children']
    categories_groups = []
    for entity_category in entity_categories:
        group_questions = build_category_questions(entity_category)
        if entity_category['label'] == u'Principal':
            category_group = CleanGroup(
                children_attributes = {'_outer_html_template': bootstrap_form_group},
                name = 'principal',
                outer_html_template = u'<div class="main-category">{self.inner_html}</div>',
                questions = group_questions,
                )
        else:
            category_group = ModalGroup(
                children_attributes = {'_outer_html_template': bootstrap_form_group},
                label = entity_category['label'],
                questions = group_questions,
                )
        categories_groups.append(category_group)
    return categories_groups


def make_question(column):
    default = column.get('default')
    if default is None:
        default = custom_column_default_values.get(column['name'])
    default_str = lambda question: check(question.data_to_str(default))
    question_label = column.get('label')
    cerfa_field = column.get('cerfa_field')
    if cerfa_field is not None and isinstance(cerfa_field, basestring):
        question_label += u' (CERFA {})'.format(cerfa_field)
    if column['@type'] == 'Boolean':
        question = BootstrapRadio(
            choices = ((False, u'Non'), (True, u'Oui')),
            input_to_data = guess_bool,
            label = question_label,
            name = column['name'],
{'fraction_non_alphanumeric': 0.1275838466803559, 'fraction_numerical': 0.0038329911019849418, 'mean_word_length': 3.324060372891388, 'pattern_counts': {'":': 0, '<': 87, '<?xml version=': 0, '>': 87, 'https://': 2, 'lorem ipsum': 0, 'www.': 2, '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': '2995770', 'n_tokens_mistral': 4407, 'n_tokens_neox': 4202, 'n_words': 1069}