pattern_history.py 7.47 KB
# -*- coding: utf-8 -*-
from django.core.exceptions import ObjectDoesNotExist
from django.utils.translation import ugettext_lazy as _, string_concat

from common.util import GroupDict
from dictionary.models import Qualifier, Pattern, Ending, History
from patterns.models import BaseFormLabel, PatternType, Pattern

# FIXME dużo copypasty, można kiedyś zrefaktoryzować

attribute_translation_list = [
    # Wzór
    ('wzory', 'w_id', _(u'name')),
    ('wzory', 'typ', _(u'type')),
    ('wzory', 'przyklad', _(u'example')),
    ('wzory', 'zakp', _(u'basic form ending')),
    ('wzory', 'status', _(u'status')),
    ('wzory', 'komentarz', _(u'comment')),
    # Zakończenie
    ('zakonczenia', 'zind', _(u'index')),
    ('zakonczenia', 'efobaz', _(u'base form label')),
    ('zakonczenia', 'zak', _(u'ending')),
]

attribute_translation = dict(
    ((table, column), label)
    for table, column, label in attribute_translation_list)

pattern_attribute_order = [
    _(u'name'),
    _(u'type'),
    _(u'example'),
    _(u'basic form ending'),
    _(u'status'),
    _(u'comment'),
]

ending_attribute_order = [
    _(u'index'),
    _(u'base form label'),
    _(u'ending'),
    # _(u'kwalifikator'),
]


def get_pattern_attr(attr, pattern):
    if attr == 'w_id':
        return pattern.name
    elif attr == 'typ':
        return unicode(pattern.type)
    elif attr == 'przyklas':
        return pattern.example
    elif attr == 'zakp':
        return pattern.basic_form_ending
    elif attr == 'status':
        return pattern.status
    elif attr == 'komentarz':
        return pattern.comment


def get_ending_attr(attr, ending):
    if attr == 'zind':
        return ending.index
    elif attr == 'efobaz':
        return ending.base_form_label.symbol
    elif attr == 'zak':
        return ending.string


def prepare_value(column, value):
    try:
        if column == 'qualifier_id':
            prepared = Qualifier.all_objects.get(id=int(value)).label
        elif column == 'status':
            prepared = dict(Pattern.STATUS_CHOICES).get(value)
        elif column == 'typ':
            prepared = unicode(PatternType.objects.get(id=int(value)))
        elif column == 'efobaz':
            prepared = BaseFormLabel.objects.get(id=int(value)).symbol
        # elif value == 'true':
        #     prepared = 'tak'
        # elif value == 'false':
        #     prepared = 'nie'
        else:
            prepared = value
    except ObjectDoesNotExist:
        prepared = None
    except ValueError:
        prepared = None
    return prepared


def ending_header(base_form_label, index):
    return u'%s #%s' % (base_form_label.symbol, index)


def transaction_table(transaction_data):
    transaction_dict = {}
    endings = GroupDict()
    ending_qualifiers = {}
    deleted = False
    for item1 in transaction_data:
        table = item1.table_name
        column = item1.column_name
        if (table == 'leksemy' and column == 'deleted' and
                item1.new_value == 'true' and item1.old_value == 'false'):
            deleted = True
        attr = None
        if (table, column) in attribute_translation:
            attr = attribute_translation[(table, column)]
        before, after = tuple(
            prepare_value(column, v)
            for v in (item1.old_value, item1.new_value))
        before_after = (
            before if item1.operation != 'INSERT' else None,
            after if item1.operation != 'DELETE' else None)
        if attr:
            if table not in ('zakonczenia', 'kwalifikatory_zakonczen'):
                transaction_dict[attr] = before_after
            elif table == 'zakonczenia':
                if item1.row_id not in endings:
                    endings[item1.row_id] = {}
                endings[item1.row_id][attr] = before_after
        if table == 'kwalifikatory_zakonczen':
            if item1.row_id not in ending_qualifiers:
                ending_qualifiers[item1.row_id] = {}
            if column:
                ending_qualifiers[item1.row_id][column] = before_after
    if deleted:
        return deleted_pattern_table(transaction_data[0].pattern)
    rows = []
    for attr in pattern_attribute_order:
        if attr in transaction_dict:
            rows.append((attr, transaction_dict[attr]))
    ending_dict = GroupDict()
    for ending_id, ending_data in endings.iteritems():
        for attr in ending_attribute_order:
            if attr in ending_data:
                ending_dict.add(ending_id, (attr, ending_data[attr]))
    for q_data in ending_qualifiers.itervalues():
        if q_data:
            attr = _(u'qualifier')
            ending_data = q_data['ending_id']
            ending_id = int(ending_data[0] or ending_data[1])
            ending_dict.add(ending_id, (attr, q_data['qualifier_id']))
    ending_tables = []
    for ending_id, ending_data in ending_dict.iteritems():
        ending = Ending.all_objects.filter(pk=ending_id)
        if ending:
            ending = ending[0]
            header = ending_header(ending.base_form_label, ending.index)
        else:
            records = History.objects.filter(
                operation='DELETE', table_name='zakonczenia', row_id=ending_id)
            bfl_id = records.get(column_name='efobaz').old_value
            index = records.get(column_name='zind').old_value
            try:
                bfl = BaseFormLabel.objects.get(id=bfl_id)
                header = string_concat(
                    ending_header(bfl, index), u' ', _(u'(deleted)'))
            except BaseFormLabel.DoesNotExist:
                header = string_concat(
                    _(u'(deleted)'), u' %s ' % index, _(u'(deleted)'))
        ending_tables.append((header, ending_data))
    return rows, ending_tables


def deleted_pattern_table(pattern):
    rows = []
    for table, column, attr in attribute_translation_list:
        if table == 'wzory':
            rows.append((
                attr,
                (prepare_value(
                    column, get_pattern_attr(column, pattern)), None)
            ))
    ending_tables = []
    for ending in pattern.genders.all():
        ending_data = []
        for table, column, attr in attribute_translation_list:
            if table == 'zakonczenia':
                ending_data.append(
                    (attr, (get_ending_attr(column, ending), None)))
        for q in ending.qualifiers.all():
            attr = _(u'qualifier')
            ending_data.append((attr, (q.label, None)))
        header = ending_header(ending.base_form_label, ending.index)
        ending_tables.append((header, ending_data))
    return rows, ending_tables


def pattern_table(transaction_data, last_tb):
    rows, ending_tables = transaction_table(transaction_data)
    pattern = transaction_data[0].pattern
    return {
        'rows': rows,
        'ending_tables': ending_tables,
        'user': transaction_data[0].user,
        'date': last_tb,
        'pattern': pattern,
    }


def pattern_table_from_row(row):
    transaction_data = History.objects.filter(
        pattern_id=row['pattern'], user_id=row['user'],
        transaction_began=row['transaction_began'])
    return pattern_table(transaction_data, row['transaction_began'])


def pattern_tables(history_items):
    transaction_data = []
    last_tb = None
    for item in history_items:
        if last_tb and item.transaction_began != last_tb:
            yield pattern_table(transaction_data, last_tb)
            transaction_data = []
        last_tb = item.transaction_began
        transaction_data.append(item)
    if transaction_data:
        yield pattern_table(transaction_data, last_tb)