ajax_table_view.py 7.62 KB
# -*- coding: utf-8 -*-
from common.decorators import render_ajax, ajax, AjaxError
from common.util import FakeQueryset
from dictionary.forms import LexemeClosedAttributeForm
from management.forms import CellRestrictionsForm, GenderForm, \
    AttributeValuesForm, BaseFormLabelForm, CSSClassForm, TemplatePreviewForm, \
    TemplatePreviewGenderForm
from dictionary.models import Gender, LexemeAttributeValue
from tables.models import Variant, TableTemplate, TableCell, ExportCell, \
    TableHeader
from patterns.models import BaseFormLabel, PatternType


def tt_params(tt):
    pt_queryset = tt.pattern_types.all()
    p_types = FakeQueryset(pt_queryset)
    parts_of_speech = list(tt.parts_of_speech.all())
    color_scheme = parts_of_speech[0].color_scheme
    bfls = BaseFormLabel.objects.filter(patterntype__in=p_types).distinct()
    return bfls, color_scheme, p_types


@render_ajax(template='table_edit_form.html', method='get',
             permission_required='dictionary.manage_vocabulary')
def table_edit_form(request, template_id):
    tt = TableTemplate.objects.get(id=template_id)
    tt_attrs = tt.cell_attributes.prefetch_related('values')

    def cr_form(x):
        return CellRestrictionsForm(
            x.pattern_types.all(), p_types, prefix=prefix)

    def gender_form(x):
        return GenderForm(x.genders.all(), prefix=prefix)

    def attr_forms(x):
        vals = x.attribute_values.all()
        return [
            AttributeValuesForm(
                attr, [v for v in vals if v.attribute == attr],
                prefix='%s_%s' % (prefix, attr.id))
            for attr in tt_attrs]

    form_rows = []
    bfls, color_scheme, p_types = tt_params(tt)
    table_cells = tt.table_cells.prefetch_related(
        'pattern_types', 'attribute_values', 'genders')
    export_cells = tt.export_cells.prefetch_related(
        'pattern_types', 'attribute_values', 'genders').select_related(
        'base_form_label')
    headers = tt.headers.prefetch_related(
        'pattern_types', 'attribute_values', 'genders')
    for tc in table_cells:
        prefix = u'tc%s' % tc.id
        bfl_form = BaseFormLabelForm(
            bfls, tc.base_form_label_id, prefix=prefix)
        g_form = gender_form(tc) if tt.takes_gender else None
        form_rows.append((
            (tc.row, tc.col, tc.rowspan, tc.colspan, tc.index),
            ('table', bfl_form, tc.prefix, tc.suffix, tc.qualifier),
            cr_form(tc),
            g_form,
            attr_forms(tc),
        ))
    for ec in export_cells:
        prefix = u'ec%s' % ec.id
        bfl_form = BaseFormLabelForm(
            bfls, ec.base_form_label_id, prefix=prefix)
        g_form = gender_form(ec) if tt.takes_gender else None
        form_rows.append((
            ec.tag_template,
            ('export', bfl_form, ec.prefix, ec.suffix),
            cr_form(ec),
            g_form,
            attr_forms(ec),
            ec.base_form_label.index,
        ))
    for header in headers:
        prefix = u'th%s' % header.id
        class_form = CSSClassForm(
            header.css_class, prefix=prefix)
        g_form = gender_form(header) if tt.takes_gender else None
        form_rows.append((
            (header.row, header.col, header.rowspan, header.colspan),
            ('header', header.label, class_form),
            cr_form(header),
            g_form,
            attr_forms(header),
        ))
    if export_cells:
        form_rows.sort(key=lambda row: (row[-1], row[0], row[1][2:]))
        export = True
    else:
        form_rows.sort()
        export = False
    return {
        'form_rows': form_rows,
        'color_scheme': color_scheme,
        'export': export,
        'template_attrs': tt_attrs,
        'takes_gender': tt.takes_gender,
        'template_type': tt.variant.type,
    }


@render_ajax(template='table_edit_row.html', method='get',
             permission_required='dictionary.manage_vocabulary')
def new_template_row(request, template_id, row_type, num):
    tt = TableTemplate.objects.get(id=template_id)
    bfls, color_scheme, p_types = tt_params(tt)
    prefix = 'new%s' % num
    if row_type == 'export':
        coord = ''
    elif row_type == 'table':
        coord = ('', '', '1', '1', '1')
    else:
        coord = ('', '', '1', '1')
    params = [row_type]
    if row_type != 'header':
        bfl_form = BaseFormLabelForm(bfls, prefix=prefix)
        params.extend([bfl_form, '', ''])
    else:
        class_form = CSSClassForm(prefix=prefix)
        params.extend(['', class_form])
    if row_type == 'table':
        params.extend([''])
    form = CellRestrictionsForm(p_types, p_types, prefix=prefix)
    return {
        'coord': coord,
        'params': params,
        'cr_form': form,
        'gender_form': GenderForm(),
        'attr_forms': [
            AttributeValuesForm(attr) for attr in tt.cell_attributes.all()],
        'takes_gender': tt.takes_gender,
    }


@render_ajax(template='template_preview_form.html', method='get')
def template_preview_form(request, template_id):
    tt = TableTemplate.objects.get(id=template_id)
    p_types = tt.pattern_types.all()
    form = TemplatePreviewForm(p_types)
    if tt.takes_gender:
        gender_form = TemplatePreviewGenderForm()
    else:
        gender_form = None
    attr_forms = [
        LexemeClosedAttributeForm(attr) for attr in tt.cell_attributes.all()]
    return {'form': form, 'gender_form': gender_form, 'attr_forms': attr_forms}


@render_ajax(template='table_preview.html', method='get')
def template_preview(request, template_id, pattern_type_id, gender_id,
                     attr_data):
    tt = TableTemplate.objects.get(id=template_id)
    if tt.variant.type != Variant.TYPE_TABLE:
        return {}
    pt = PatternType.objects.get(id=pattern_type_id)
    if gender_id:
        gender = Gender.objects.get(id=gender_id)
    else:
        gender = None
    attr_vals = LexemeAttributeValue.objects.filter(id__in=attr_data)
    table = tt.render_with_pattern_type(pt, gender, attr_vals, span=True)
    part_of_speech = tt.parts_of_speech.all()[0]
    return {'table': table, 'color_scheme': part_of_speech.color_scheme}


@ajax(method='post', permission_required='dictionary.manage_vocabulary')
def save_template(request, template_id, table_cells, headers, export_cells):
    def add_restrictions(x):
        x.pattern_types = pts
        if genders:
            x.genders = genders
        x.attribute_values = attr_vals

    tt = TableTemplate.objects.get(id=template_id)
    tt.table_cells.all().delete()
    tt.headers.all().delete()
    tt.export_cells.all().delete()
    for tc_data in table_cells:
        row, col, rspan, cspan, index, bfl, prefix, suffix, qualifier, pts, \
            genders, attr_vals = tc_data
        tc = TableCell(
            table_template=tt,
            row=row, col=col, rowspan=rspan, colspan=cspan, index=index,
            base_form_label_id=bfl, prefix=prefix, suffix=suffix,
            qualifier=qualifier)
        tc.save()
        add_restrictions(tc)
    for h_data in headers:
        row, col, rspan, cspan, label, css_class, pts, genders, \
            attr_vals = h_data
        th = TableHeader(
            table_template=tt,
            row=row, col=col, rowspan=rspan, colspan=cspan, label=label,
            css_class=css_class)
        th.save()
        add_restrictions(th)
    for ec_data in export_cells:
        bfl, prefix, suffix, tag_template, pts, genders, \
            attr_vals = ec_data
        if not bfl:
            raise AjaxError("A base form label can't be empty")
        ec = ExportCell(
            table_template=tt,
            base_form_label_id=bfl, prefix=prefix, suffix=suffix,
            tag_template=tag_template)
        ec.save()
        add_restrictions(ec)
    return {}