From bd965883a57e6010da8e21bea4442412869c73eb Mon Sep 17 00:00:00 2001 From: janek@kublik <janek@kublik> Date: Sun, 13 Dec 2015 13:00:44 +0100 Subject: [PATCH] osobna aplikacja do tabelek --- dictionary/ajax_lexeme_view.py | 57 +++++++++------------------------------------------------ dictionary/management/commands/export_template.py | 68 -------------------------------------------------------------------- dictionary/management/commands/export_templates.py | 31 ------------------------------- dictionary/management/commands/import_template.py | 74 -------------------------------------------------------------------------- dictionary/management/commands/import_templates.py | 41 ----------------------------------------- dictionary/models.py | 2 +- dictionary/templates/inflection_table.html | 60 ------------------------------------------------------------ dictionary/urls.py | 1 - dictionary/util.py | 33 --------------------------------- management/templates/table_preview.html | 3 --- settings.py | 1 + tables/__init__.py | 0 tables/management/__init__.py | 0 tables/management/commands/__init__.py | 0 tables/management/commands/export_template.py | 68 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tables/management/commands/export_templates.py | 32 ++++++++++++++++++++++++++++++++ tables/management/commands/import_template.py | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tables/management/commands/import_templates.py | 43 +++++++++++++++++++++++++++++++++++++++++++ tables/migrations/__init__.py | 0 tables/models.py | 3 +++ tables/templates/inflection_table.html | 60 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ tables/templates/table_preview.html | 3 +++ tables/tests.py | 3 +++ tables/urls.py | 10 ++++++++++ tables/util.py | 34 ++++++++++++++++++++++++++++++++++ tables/views.py | 45 +++++++++++++++++++++++++++++++++++++++++++++ urls.py | 1 + 27 files changed, 387 insertions(+), 360 deletions(-) delete mode 100644 dictionary/management/commands/export_template.py delete mode 100644 dictionary/management/commands/export_templates.py delete mode 100644 dictionary/management/commands/import_template.py delete mode 100644 dictionary/management/commands/import_templates.py delete mode 100644 dictionary/templates/inflection_table.html delete mode 100644 management/templates/table_preview.html create mode 100644 tables/__init__.py create mode 100644 tables/management/__init__.py create mode 100644 tables/management/commands/__init__.py create mode 100644 tables/management/commands/export_template.py create mode 100644 tables/management/commands/export_templates.py create mode 100644 tables/management/commands/import_template.py create mode 100644 tables/management/commands/import_templates.py create mode 100644 tables/migrations/__init__.py create mode 100644 tables/models.py create mode 100644 tables/templates/inflection_table.html create mode 100644 tables/templates/table_preview.html create mode 100644 tables/tests.py create mode 100644 tables/urls.py create mode 100644 tables/util.py create mode 100644 tables/views.py diff --git a/dictionary/ajax_lexeme_view.py b/dictionary/ajax_lexeme_view.py index d75bb4c..e72d91d 100644 --- a/dictionary/ajax_lexeme_view.py +++ b/dictionary/ajax_lexeme_view.py @@ -1,26 +1,24 @@ # -*- coding: utf-8 -*- -from django.utils import timezone - from django.core.cache import cache +from django.db.models import Max from django.shortcuts import get_object_or_404 +from django.utils import timezone from django.utils.encoding import force_unicode from django.utils.translation import ugettext as _ -from django.db.models import Max +from common.decorators import ajax, AjaxError, render_ajax +from common.util import error_messages, bisect_left, format_date from dictionary.ajax_lexeme_slickgrid import LexemeQuery from dictionary.auto_derivatives import lexeme_derivatives, create_derivative -from dictionary.models import Lexeme, LexemeInflectionPattern, PartOfSpeech, \ - Vocabulary, Qualifier, ClassificationValue, CrossReference, InputLexeme, \ - CrossReferenceType, LexemeAttributeValue, Gender, LexemeAttribute, \ - LexemeAV, LexemeCV, LexemeList -from dictionary.util import prepare_table -from patterns.models import Pattern, Ending from dictionary.forms import LexemeEditForm, LIPEditForm, ClassificationForm, \ CrossReferenceForm, ActionFieldForm, ACTION_FIELDS,\ LexemeOpenAttributeForm, LexemeClosedAttributeForm, \ LexemeMultipleAttributeForm -from common.decorators import ajax, AjaxError, render_ajax -from common.util import error_messages, bisect_left, format_date +from dictionary.models import Lexeme, LexemeInflectionPattern, PartOfSpeech, \ + Vocabulary, Qualifier, ClassificationValue, CrossReference, InputLexeme, \ + CrossReferenceType, LexemeAttributeValue, Gender, LexemeAttribute, \ + LexemeAV, LexemeCV, LexemeList +from patterns.models import Ending @render_ajax( @@ -56,43 +54,6 @@ def inflection_tables(request, variant, lexeme_id): } -@render_ajax(template='table_preview.html', method='get') -def table_preview(request, lexeme_id, lip_id, pattern, attr_data=None, - gender=None, entry=None, pos=None): - lexeme = Lexeme.all_objects.get(pk=lexeme_id) - if not lexeme.perm(request.user, 'view'): - raise AjaxError('access denied') - if pos is not None: - part_of_speech = PartOfSpeech.objects.get(symbol=pos) - else: - part_of_speech = lexeme.part_of_speech - try: - if entry is not None: - lexeme.entry = entry - pattern = Pattern.objects.get(name=pattern) - gender = Gender.objects.get(id=gender) if gender else None - if attr_data: - attr_vals = LexemeAttributeValue.objects.filter( - id__in=attr_data) - else: - attr_vals = None - if lip_id.startswith('lip_add'): - lip = LexemeInflectionPattern(lexeme=lexeme, index=0) - else: - lip = LexemeInflectionPattern.objects.get(pk=int(lip_id[3:])) - lip.pattern = pattern - lip.gender = gender - lip.root = lip.get_root() - qualifiers = Qualifier.visible_qualifiers(request.user) - table = lip.inflection_table( - '0', separated=True, qualifiers=qualifiers, edit_view=True, - attr_vals=attr_vals, pos=part_of_speech) - prepare_table(table) - except Pattern.DoesNotExist: - table = None - return {'table': table, 'color_scheme': part_of_speech.color_scheme} - - @ajax(template='odm_forms.html', method='get') def odm_forms(request, lexeme_id): to_return = {} diff --git a/dictionary/management/commands/export_template.py b/dictionary/management/commands/export_template.py deleted file mode 100644 index b7de638..0000000 --- a/dictionary/management/commands/export_template.py +++ /dev/null @@ -1,68 +0,0 @@ -# -*- coding: utf-8 -*- -from django.core.management.base import BaseCommand -from common.util import json_encode, uniprint -from dictionary.models import TableTemplate, Variant - - -class Command(BaseCommand): - help = "Exports a table template to JSON." - - def handle(self, name, variant, *args, **options): - tt = TableTemplate.objects.get( - name=name.decode('utf-8'), variant__id=variant) - uniprint(json_encode(export_template(tt))) - - -def export_template(tt): - data = {'name': tt.name, 'variant': tt.variant.id} - if tt.variant.type == Variant.TYPE_TABLE: - data['table_cells'] = [] - data['headers'] = [] - else: - data['export_cells'] = [] - table_cells = tt.table_cells.select_related( - 'base_form_label__lexical_class').prefetch_related( - 'pattern_types', 'attribute_values') - export_cells = tt.export_cells.select_related( - 'base_form_label__lexical_class').prefetch_related( - 'pattern_types', 'attribute_values') - headers = tt.headers.prefetch_related( - 'pattern_types', 'attribute_values') - table_elements = [('table_cells', tc) for tc in table_cells] - table_elements += [('export_cells', ec) for ec in export_cells] - table_elements += [('headers', h) for h in headers] - for elem_type, elem in table_elements: - data_row = { - 'pattern_types': list( - elem.pattern_types.values_list('symbol', 'lexical_class_id')), - 'attr_vals': list(elem.attribute_values.values_list( - 'value', 'attribute__name')), - } - if tt.takes_gender: - data_row['genders'] = list( - elem.genders.values_list('symbol', flat=True)) - if elem_type in ('table_cells', 'headers'): - data_row.update({ - 'row': elem.row, - 'col': elem.col, - 'rowspan': elem.rowspan, - 'colspan': elem.colspan, - }) - if elem_type in ('table_cells', 'export_cells'): - data_row.update({ - 'bfl': (elem.base_form_label.symbol, - elem.base_form_label.lexical_class.symbol), - 'prefix': elem.prefix, - 'suffix': elem.suffix, - }) - if elem_type == 'table_cells': - data_row['index'] = elem.index - if elem_type == 'export_cells': - data_row['tag'] = elem.tag_template - if elem_type == 'headers': - data_row.update({ - 'label': elem.label, - 'css_class': elem.css_class, - }) - data[elem_type].append(data_row) - return data diff --git a/dictionary/management/commands/export_templates.py b/dictionary/management/commands/export_templates.py deleted file mode 100644 index e8a2304..0000000 --- a/dictionary/management/commands/export_templates.py +++ /dev/null @@ -1,31 +0,0 @@ -# -*- coding: utf-8 -*- -from django.core.management.base import BaseCommand -from common.util import uniprint, json_encode -from dictionary.management.commands.export_template import export_template -from dictionary.models import TableTemplate - - -class Command(BaseCommand): - help = "Exports all templates to JSON." - - def handle(self, *args, **options): - uniprint(json_encode(export_templates())) - - -def export_templates(): - data = [] - for tt in TableTemplate.objects.all(): - data_row = export_template(tt) - data_row['parts_of_speech'] = list( - tt.parts_of_speech.values_list('symbol', flat=True)) - data_row['pattern_types'] = list( - tt.pattern_types.values_list('symbol', 'lexical_class_id')) - data_row['attributes'] = list( - tt.attributes.values_list('name', flat=True)) - data_row['attribute_values'] = list( - tt.attribute_values.values_list('value', 'attribute__name')) - data_row['cell_attributes'] = list( - tt.cell_attributes.values_list('name', flat=True)) - data_row['takes_gender'] = tt.takes_gender - data.append(data_row) - return data \ No newline at end of file diff --git a/dictionary/management/commands/import_template.py b/dictionary/management/commands/import_template.py deleted file mode 100644 index 4d1cd84..0000000 --- a/dictionary/management/commands/import_template.py +++ /dev/null @@ -1,74 +0,0 @@ -# -*- coding: utf-8 -*- -import json -from django.core.management.base import BaseCommand -from dictionary.models import Variant, TableTemplate, TableCell, \ - PatternType, LexemeAttributeValue, TableHeader, ExportCell, Gender -from patterns.models import BaseFormLabel, PatternType - - -class Command(BaseCommand): - help = "Imports a table template from JSON." - - def handle(self, filename, *args, **options): - import_template(json.load(open(filename))) - -PATTERN_TYPES = dict( - ((pt.symbol, pt.lexical_class.symbol), pt) - for pt in PatternType.objects.all()) - -GENDERS = dict((g.symbol, g) for g in Gender.objects.all()) - -ATTR_VALS = dict( - ((av.value, av.attribute.name), av) - for av in LexemeAttributeValue.objects.all()) - -BFLS = dict( - ((bfl.symbol, bfl.lexical_class.symbol), bfl) - for bfl in BaseFormLabel.objects.all()) - - -def get_bfl(data): - return BFLS[tuple(data['bfl'])] - - -def import_template(data): - def add_restrictions(x, x_data): - x.pattern_types = (PATTERN_TYPES[tuple(pt_data)] - for pt_data in x_data['pattern_types']) - if 'genders' in x_data: - x.genders = (GENDERS[gender] for gender in x_data['genders']) - x.attribute_values = ( - ATTR_VALS[tuple(av_data)] for av_data in x_data['attr_vals']) - - variant = Variant.objects.get(id=data['variant']) - tt, created = TableTemplate.objects.get_or_create( - variant=variant, name=data['name']) - if not created: - tt.table_cells.all().delete() - tt.headers.all().delete() - tt.export_cells.all().delete() - for tc_data in data.get('table_cells', []): - tc = TableCell( - table_template=tt, - row=tc_data['row'], col=tc_data['col'], rowspan=tc_data['rowspan'], - colspan=tc_data['colspan'], index=tc_data['index'], - base_form_label=get_bfl(tc_data), prefix=tc_data['prefix'], - suffix=tc_data['suffix']) - tc.save() - add_restrictions(tc, tc_data) - for h_data in data.get('headers', []): - th = TableHeader( - table_template=tt, - row=h_data['row'], col=h_data['col'], rowspan=h_data['rowspan'], - colspan=h_data['colspan'], label=h_data['label'], - css_class=h_data['css_class']) - th.save() - add_restrictions(th, h_data) - for ec_data in data.get('export_cells', []): - ec = ExportCell( - table_template=tt, - base_form_label=get_bfl(ec_data), prefix=ec_data['prefix'], - suffix=ec_data['suffix'], tag_template=ec_data['tag']) - ec.save() - add_restrictions(ec, ec_data) - return tt \ No newline at end of file diff --git a/dictionary/management/commands/import_templates.py b/dictionary/management/commands/import_templates.py deleted file mode 100644 index 7b19235..0000000 --- a/dictionary/management/commands/import_templates.py +++ /dev/null @@ -1,41 +0,0 @@ -# -*- coding: utf-8 -*- -import json -from django.core.management.base import BaseCommand -from dictionary.management.commands.import_template import import_template -from dictionary.models import TableTemplate, LexemeAttribute, \ - LexemeAttributeValue -from patterns.models import PatternType - - -class Command(BaseCommand): - help = "Imports templated from JSON." - - def handle(self, filename, *args, **options): - import_templates(json.load(open(filename))) - -PATTERN_TYPES = dict( - ((pt.symbol, pt.lexical_class.symbol), pt) - for pt in PatternType.objects.all()) - -ATTRS = dict((attr.name, attr) for attr in LexemeAttribute.objects.all()) - -ATTR_VALS = dict( - ((av.value, av.attribute.name), av) - for av in LexemeAttributeValue.objects.all()) - - -def import_templates(data): - TableTemplate.objects.all().delete() - for tt_data in data: - tt = import_template(tt_data) - tt.parts_of_speech = tt_data['parts_of_speech'] - tt.pattern_types = (PATTERN_TYPES[tuple(pt_data)] - for pt_data in tt_data['pattern_types']) - tt.attributes = (ATTRS[attr_name] - for attr_name in tt_data['attributes']) - for av_data in tt_data['attribute_values']: - tt.attribute_values.add(ATTR_VALS[tuple(av_data)]) - for attr_name in tt_data['cell_attributes']: - tt.cell_attributes.add(ATTRS[attr_name]) - tt.takes_gender = tt_data['takes_gender'] - tt.save() \ No newline at end of file diff --git a/dictionary/models.py b/dictionary/models.py index 219ebfe..cdb31f4 100644 --- a/dictionary/models.py +++ b/dictionary/models.py @@ -12,7 +12,7 @@ from django.utils.translation import ugettext_lazy as _, get_language from accounts.util import users_with_perm from common.models import NotDeletedManager from common.util import no_history -from dictionary.util import prepare_table +from tables.util import prepare_table from patterns.models import InflectionType, BaseFormLabel, PatternType, Pattern diff --git a/dictionary/templates/inflection_table.html b/dictionary/templates/inflection_table.html deleted file mode 100644 index d906672..0000000 --- a/dictionary/templates/inflection_table.html +++ /dev/null @@ -1,60 +0,0 @@ -<div class="scheme{{ color_scheme }}"> - <table class="inflection-table"> - {% if tables and tables|length > 1 %} - <caption> - {{ gender.symbol }}: - {% if pronunciations %} - <span class="lip-pronunciation">[{{ pronunciations|join:"/"|safe }}]{% if gender_qualifiers %};{% endif %}</span> - {% endif %} - <span class="qualifiers">{{ gender_qualifiers|join:" " }}</span> - {% include "pattern_list.html" %} - </caption> - {% endif %} - {% for row in table %} - <tr> - {% for cell in row %} - {% if cell.type != "span" %} - {% if cell.type == "empty" %} - <td class="empty"></td> - {% else %} - {% if cell.type == "forms" %} - <td rowspan="{{ cell.rowspan }}" - colspan="{{ cell.colspan }}" - {% if cell.colspan > 1 %}class="data-c"{% endif %}> - <ul class="form-list"> - {% for entry in cell.forms %} - <li> - <span class="form {% for p in entry.patterns %}p{{ p.id }} {% endfor %}"> - {{ entry.form|safe }} - </span> - <span class="qualifiers"> - {% for q in entry.qualifiers %} - {{ q.label }} - {% endfor %} - </span> - </li> - {% endfor %} - </ul> - </td> - {% else %} - <td rowspan="{{ cell.rowspan }}" - colspan="{{ cell.colspan }}" - {% if cell.colspan > 1 and cell.css_class == 'data' %} - class="data-c" - {% else %}class="{{ cell.css_class }}"{% endif %}> - <ul class="form-list"> - {% for label in cell.label %} - <li> - <span class="header-label">{{ label|safe }}</span> - </li> - {% endfor %} - </ul> - </td> - {% endif %} - {% endif %} - {% endif %} - {% endfor %} - </tr> - {% endfor %} - </table> -</div> \ No newline at end of file diff --git a/dictionary/urls.py b/dictionary/urls.py index 9327284..a34d046 100644 --- a/dictionary/urls.py +++ b/dictionary/urls.py @@ -25,7 +25,6 @@ urlpatterns += patterns( url(r'^ajax/odm-forms/$', 'odm_forms'), url(r'^ajax/lexeme-edit-form/$', 'lexeme_edit_form'), url(r'^ajax/update-lexeme/$', 'update_lexeme'), - url(r'^ajax/table-preview/$', 'table_preview'), url(r'^ajax/new-lip-row/$', 'new_lip_edit_row'), url(r'^ajax/new-cr-row/$', 'new_cross_reference_row'), url(r'^ajax/delete-lexeme/$', 'delete_lexeme'), diff --git a/dictionary/util.py b/dictionary/util.py index 4fb560e..8042d73 100644 --- a/dictionary/util.py +++ b/dictionary/util.py @@ -58,36 +58,3 @@ def check_query_params(request, query_params): reader = query_params.get('reader', True) if not request.user.is_authenticated() and not reader: raise AjaxError('access denied') - - -def prepare_table(table): - for row in table: - for cell in row: - if type(cell) == dict and 'forms' in cell: - cell['forms'].sort() - seen_forms = [] - unique_forms = [] - form_patterns = {} - for form in cell['forms']: - if form[1] not in seen_forms: - seen_forms.append(form[1]) - unique_forms.append(form) - form_patterns[form[1]] = set() - form_patterns[form[1]].add(form[3]) - cell['forms'] = [ - { - 'form': form, - 'qualifiers': qualifiers, - 'patterns': form_patterns[form], - } - for (key, form, qualifiers, pattern) in unique_forms] - elif type(cell) == dict and 'label' in cell: - seen_labels = [] - - def is_new(label): - new = label not in seen_labels - seen_labels.append(label) - return new - - cell['label'] = filter(is_new, cell['label']) - return table \ No newline at end of file diff --git a/management/templates/table_preview.html b/management/templates/table_preview.html deleted file mode 100644 index 25288eb..0000000 --- a/management/templates/table_preview.html +++ /dev/null @@ -1,3 +0,0 @@ -<div class="scheme{{ color_scheme }}"> - {% include 'inflection_table.html' %} -</div> \ No newline at end of file diff --git a/settings.py b/settings.py index a70e470..047bfc1 100644 --- a/settings.py +++ b/settings.py @@ -123,6 +123,7 @@ INSTALLED_APPS = ( # aplikacje projektu 'dictionary', 'patterns', + 'tables', 'management', 'export', 'accounts', diff --git a/tables/__init__.py b/tables/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tables/__init__.py diff --git a/tables/management/__init__.py b/tables/management/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tables/management/__init__.py diff --git a/tables/management/commands/__init__.py b/tables/management/commands/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tables/management/commands/__init__.py diff --git a/tables/management/commands/export_template.py b/tables/management/commands/export_template.py new file mode 100644 index 0000000..b7de638 --- /dev/null +++ b/tables/management/commands/export_template.py @@ -0,0 +1,68 @@ +# -*- coding: utf-8 -*- +from django.core.management.base import BaseCommand +from common.util import json_encode, uniprint +from dictionary.models import TableTemplate, Variant + + +class Command(BaseCommand): + help = "Exports a table template to JSON." + + def handle(self, name, variant, *args, **options): + tt = TableTemplate.objects.get( + name=name.decode('utf-8'), variant__id=variant) + uniprint(json_encode(export_template(tt))) + + +def export_template(tt): + data = {'name': tt.name, 'variant': tt.variant.id} + if tt.variant.type == Variant.TYPE_TABLE: + data['table_cells'] = [] + data['headers'] = [] + else: + data['export_cells'] = [] + table_cells = tt.table_cells.select_related( + 'base_form_label__lexical_class').prefetch_related( + 'pattern_types', 'attribute_values') + export_cells = tt.export_cells.select_related( + 'base_form_label__lexical_class').prefetch_related( + 'pattern_types', 'attribute_values') + headers = tt.headers.prefetch_related( + 'pattern_types', 'attribute_values') + table_elements = [('table_cells', tc) for tc in table_cells] + table_elements += [('export_cells', ec) for ec in export_cells] + table_elements += [('headers', h) for h in headers] + for elem_type, elem in table_elements: + data_row = { + 'pattern_types': list( + elem.pattern_types.values_list('symbol', 'lexical_class_id')), + 'attr_vals': list(elem.attribute_values.values_list( + 'value', 'attribute__name')), + } + if tt.takes_gender: + data_row['genders'] = list( + elem.genders.values_list('symbol', flat=True)) + if elem_type in ('table_cells', 'headers'): + data_row.update({ + 'row': elem.row, + 'col': elem.col, + 'rowspan': elem.rowspan, + 'colspan': elem.colspan, + }) + if elem_type in ('table_cells', 'export_cells'): + data_row.update({ + 'bfl': (elem.base_form_label.symbol, + elem.base_form_label.lexical_class.symbol), + 'prefix': elem.prefix, + 'suffix': elem.suffix, + }) + if elem_type == 'table_cells': + data_row['index'] = elem.index + if elem_type == 'export_cells': + data_row['tag'] = elem.tag_template + if elem_type == 'headers': + data_row.update({ + 'label': elem.label, + 'css_class': elem.css_class, + }) + data[elem_type].append(data_row) + return data diff --git a/tables/management/commands/export_templates.py b/tables/management/commands/export_templates.py new file mode 100644 index 0000000..cf82ac4 --- /dev/null +++ b/tables/management/commands/export_templates.py @@ -0,0 +1,32 @@ +# -*- coding: utf-8 -*- +from django.core.management.base import BaseCommand + +from common.util import uniprint, json_encode +from dictionary.models import TableTemplate +from tables.management.commands.export_template import export_template + + +class Command(BaseCommand): + help = "Exports all templates to JSON." + + def handle(self, *args, **options): + uniprint(json_encode(export_templates())) + + +def export_templates(): + data = [] + for tt in TableTemplate.objects.all(): + data_row = export_template(tt) + data_row['parts_of_speech'] = list( + tt.parts_of_speech.values_list('symbol', flat=True)) + data_row['pattern_types'] = list( + tt.pattern_types.values_list('symbol', 'lexical_class_id')) + data_row['attributes'] = list( + tt.attributes.values_list('name', flat=True)) + data_row['attribute_values'] = list( + tt.attribute_values.values_list('value', 'attribute__name')) + data_row['cell_attributes'] = list( + tt.cell_attributes.values_list('name', flat=True)) + data_row['takes_gender'] = tt.takes_gender + data.append(data_row) + return data \ No newline at end of file diff --git a/tables/management/commands/import_template.py b/tables/management/commands/import_template.py new file mode 100644 index 0000000..4d1cd84 --- /dev/null +++ b/tables/management/commands/import_template.py @@ -0,0 +1,74 @@ +# -*- coding: utf-8 -*- +import json +from django.core.management.base import BaseCommand +from dictionary.models import Variant, TableTemplate, TableCell, \ + PatternType, LexemeAttributeValue, TableHeader, ExportCell, Gender +from patterns.models import BaseFormLabel, PatternType + + +class Command(BaseCommand): + help = "Imports a table template from JSON." + + def handle(self, filename, *args, **options): + import_template(json.load(open(filename))) + +PATTERN_TYPES = dict( + ((pt.symbol, pt.lexical_class.symbol), pt) + for pt in PatternType.objects.all()) + +GENDERS = dict((g.symbol, g) for g in Gender.objects.all()) + +ATTR_VALS = dict( + ((av.value, av.attribute.name), av) + for av in LexemeAttributeValue.objects.all()) + +BFLS = dict( + ((bfl.symbol, bfl.lexical_class.symbol), bfl) + for bfl in BaseFormLabel.objects.all()) + + +def get_bfl(data): + return BFLS[tuple(data['bfl'])] + + +def import_template(data): + def add_restrictions(x, x_data): + x.pattern_types = (PATTERN_TYPES[tuple(pt_data)] + for pt_data in x_data['pattern_types']) + if 'genders' in x_data: + x.genders = (GENDERS[gender] for gender in x_data['genders']) + x.attribute_values = ( + ATTR_VALS[tuple(av_data)] for av_data in x_data['attr_vals']) + + variant = Variant.objects.get(id=data['variant']) + tt, created = TableTemplate.objects.get_or_create( + variant=variant, name=data['name']) + if not created: + tt.table_cells.all().delete() + tt.headers.all().delete() + tt.export_cells.all().delete() + for tc_data in data.get('table_cells', []): + tc = TableCell( + table_template=tt, + row=tc_data['row'], col=tc_data['col'], rowspan=tc_data['rowspan'], + colspan=tc_data['colspan'], index=tc_data['index'], + base_form_label=get_bfl(tc_data), prefix=tc_data['prefix'], + suffix=tc_data['suffix']) + tc.save() + add_restrictions(tc, tc_data) + for h_data in data.get('headers', []): + th = TableHeader( + table_template=tt, + row=h_data['row'], col=h_data['col'], rowspan=h_data['rowspan'], + colspan=h_data['colspan'], label=h_data['label'], + css_class=h_data['css_class']) + th.save() + add_restrictions(th, h_data) + for ec_data in data.get('export_cells', []): + ec = ExportCell( + table_template=tt, + base_form_label=get_bfl(ec_data), prefix=ec_data['prefix'], + suffix=ec_data['suffix'], tag_template=ec_data['tag']) + ec.save() + add_restrictions(ec, ec_data) + return tt \ No newline at end of file diff --git a/tables/management/commands/import_templates.py b/tables/management/commands/import_templates.py new file mode 100644 index 0000000..6be9c5c --- /dev/null +++ b/tables/management/commands/import_templates.py @@ -0,0 +1,43 @@ +# -*- coding: utf-8 -*- +import json + +from django.core.management.base import BaseCommand + +from dictionary.models import TableTemplate, LexemeAttribute, \ + LexemeAttributeValue +from patterns.models import PatternType +from tables.management.commands.import_template import import_template + + +class Command(BaseCommand): + help = "Imports templated from JSON." + + def handle(self, filename, *args, **options): + import_templates(json.load(open(filename))) + +PATTERN_TYPES = dict( + ((pt.symbol, pt.lexical_class.symbol), pt) + for pt in PatternType.objects.all()) + +ATTRS = dict((attr.name, attr) for attr in LexemeAttribute.objects.all()) + +ATTR_VALS = dict( + ((av.value, av.attribute.name), av) + for av in LexemeAttributeValue.objects.all()) + + +def import_templates(data): + TableTemplate.objects.all().delete() + for tt_data in data: + tt = import_template(tt_data) + tt.parts_of_speech = tt_data['parts_of_speech'] + tt.pattern_types = (PATTERN_TYPES[tuple(pt_data)] + for pt_data in tt_data['pattern_types']) + tt.attributes = (ATTRS[attr_name] + for attr_name in tt_data['attributes']) + for av_data in tt_data['attribute_values']: + tt.attribute_values.add(ATTR_VALS[tuple(av_data)]) + for attr_name in tt_data['cell_attributes']: + tt.cell_attributes.add(ATTRS[attr_name]) + tt.takes_gender = tt_data['takes_gender'] + tt.save() \ No newline at end of file diff --git a/tables/migrations/__init__.py b/tables/migrations/__init__.py new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/tables/migrations/__init__.py diff --git a/tables/models.py b/tables/models.py new file mode 100644 index 0000000..71a8362 --- /dev/null +++ b/tables/models.py @@ -0,0 +1,3 @@ +from django.db import models + +# Create your models here. diff --git a/tables/templates/inflection_table.html b/tables/templates/inflection_table.html new file mode 100644 index 0000000..d906672 --- /dev/null +++ b/tables/templates/inflection_table.html @@ -0,0 +1,60 @@ +<div class="scheme{{ color_scheme }}"> + <table class="inflection-table"> + {% if tables and tables|length > 1 %} + <caption> + {{ gender.symbol }}: + {% if pronunciations %} + <span class="lip-pronunciation">[{{ pronunciations|join:"/"|safe }}]{% if gender_qualifiers %};{% endif %}</span> + {% endif %} + <span class="qualifiers">{{ gender_qualifiers|join:" " }}</span> + {% include "pattern_list.html" %} + </caption> + {% endif %} + {% for row in table %} + <tr> + {% for cell in row %} + {% if cell.type != "span" %} + {% if cell.type == "empty" %} + <td class="empty"></td> + {% else %} + {% if cell.type == "forms" %} + <td rowspan="{{ cell.rowspan }}" + colspan="{{ cell.colspan }}" + {% if cell.colspan > 1 %}class="data-c"{% endif %}> + <ul class="form-list"> + {% for entry in cell.forms %} + <li> + <span class="form {% for p in entry.patterns %}p{{ p.id }} {% endfor %}"> + {{ entry.form|safe }} + </span> + <span class="qualifiers"> + {% for q in entry.qualifiers %} + {{ q.label }} + {% endfor %} + </span> + </li> + {% endfor %} + </ul> + </td> + {% else %} + <td rowspan="{{ cell.rowspan }}" + colspan="{{ cell.colspan }}" + {% if cell.colspan > 1 and cell.css_class == 'data' %} + class="data-c" + {% else %}class="{{ cell.css_class }}"{% endif %}> + <ul class="form-list"> + {% for label in cell.label %} + <li> + <span class="header-label">{{ label|safe }}</span> + </li> + {% endfor %} + </ul> + </td> + {% endif %} + {% endif %} + {% endif %} + {% endfor %} + </tr> + {% endfor %} + </table> +</div> \ No newline at end of file diff --git a/tables/templates/table_preview.html b/tables/templates/table_preview.html new file mode 100644 index 0000000..25288eb --- /dev/null +++ b/tables/templates/table_preview.html @@ -0,0 +1,3 @@ +<div class="scheme{{ color_scheme }}"> + {% include 'inflection_table.html' %} +</div> \ No newline at end of file diff --git a/tables/tests.py b/tables/tests.py new file mode 100644 index 0000000..7ce503c --- /dev/null +++ b/tables/tests.py @@ -0,0 +1,3 @@ +from django.test import TestCase + +# Create your tests here. diff --git a/tables/urls.py b/tables/urls.py new file mode 100644 index 0000000..d506bdf --- /dev/null +++ b/tables/urls.py @@ -0,0 +1,10 @@ +# -*- coding: utf-8 -*- + +from django.conf.urls import patterns +from common.util import url + + +urlpatterns = patterns( + 'tables.views', + url(r'^ajax/table-preview/$', 'table_preview'), +) \ No newline at end of file diff --git a/tables/util.py b/tables/util.py new file mode 100644 index 0000000..9804dca --- /dev/null +++ b/tables/util.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + + +def prepare_table(table): + for row in table: + for cell in row: + if type(cell) == dict and 'forms' in cell: + cell['forms'].sort() + seen_forms = [] + unique_forms = [] + form_patterns = {} + for form in cell['forms']: + if form[1] not in seen_forms: + seen_forms.append(form[1]) + unique_forms.append(form) + form_patterns[form[1]] = set() + form_patterns[form[1]].add(form[3]) + cell['forms'] = [ + { + 'form': form, + 'qualifiers': qualifiers, + 'patterns': form_patterns[form], + } + for (key, form, qualifiers, pattern) in unique_forms] + elif type(cell) == dict and 'label' in cell: + seen_labels = [] + + def is_new(label): + new = label not in seen_labels + seen_labels.append(label) + return new + + cell['label'] = filter(is_new, cell['label']) + return table diff --git a/tables/views.py b/tables/views.py new file mode 100644 index 0000000..81671bf --- /dev/null +++ b/tables/views.py @@ -0,0 +1,45 @@ +# -*- coding: utf-8 -*- +from django.shortcuts import render + +from common.decorators import render_ajax, AjaxError +from dictionary.models import Lexeme, PartOfSpeech, Gender, \ + LexemeAttributeValue, LexemeInflectionPattern, Qualifier +from tables.util import prepare_table +from patterns.models import Pattern + + +@render_ajax(template='table_preview.html', method='get') +def table_preview(request, lexeme_id, lip_id, pattern, attr_data=None, + gender=None, entry=None, pos=None): + lexeme = Lexeme.all_objects.get(pk=lexeme_id) + if not lexeme.perm(request.user, 'view'): + raise AjaxError('access denied') + if pos is not None: + part_of_speech = PartOfSpeech.objects.get(symbol=pos) + else: + part_of_speech = lexeme.part_of_speech + try: + if entry is not None: + lexeme.entry = entry + pattern = Pattern.objects.get(name=pattern) + gender = Gender.objects.get(id=gender) if gender else None + if attr_data: + attr_vals = LexemeAttributeValue.objects.filter( + id__in=attr_data) + else: + attr_vals = None + if lip_id.startswith('lip_add'): + lip = LexemeInflectionPattern(lexeme=lexeme, index=0) + else: + lip = LexemeInflectionPattern.objects.get(pk=int(lip_id[3:])) + lip.pattern = pattern + lip.gender = gender + lip.root = lip.get_root() + qualifiers = Qualifier.visible_qualifiers(request.user) + table = lip.inflection_table( + '0', separated=True, qualifiers=qualifiers, edit_view=True, + attr_vals=attr_vals, pos=part_of_speech) + prepare_table(table) + except Pattern.DoesNotExist: + table = None + return {'table': table, 'color_scheme': part_of_speech.color_scheme} \ No newline at end of file diff --git a/urls.py b/urls.py index 8e4ac83..8e07901 100644 --- a/urls.py +++ b/urls.py @@ -36,4 +36,5 @@ urlpatterns = patterns( (r'^paginer/', include('paginer.urls')), (r'^historia/', include('history.urls')), (r'^eksport/', include('export.urls')), + (r'^tables/', include('tables.urls')), ) -- libgit2 0.22.2