# -*- coding: utf-8 -*- #Copyright (c) 2014, Bartłomiej Nitoń #All rights reserved. #Redistribution and use in source and binary forms, with or without modification, are permitted provided #that the following conditions are met: # Redistributions of source code must retain the above copyright notice, this list of conditions and # the following disclaimer. # Redistributions in binary form must reproduce the above copyright notice, this list of conditions # and the following disclaimer in the documentation and/or other materials provided with the distribution. # THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED # WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A # PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR # ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED # TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) # HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING # NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE # POSSIBILITY OF SUCH DAMAGE. from operator import itemgetter, or_ from django.db.models import Count, Q, Sum from accounts.models import can_modify_phraseology_only from common.decorators import render, ajax, AjaxError from common.js_to_obj import jsArgToObj from dictionary.forms import AddArgumentForm, ArgPropositionsForm, Atribute_Model, \ AtributeChoiceForm, AtributeTextForm, ValueAttrMultiValueForm, \ TextAttrMultiValueForm, PositionsForm, SelectArgumentForm, \ ArgumentsForm from dictionary.models import Argument, Argument_Model, Atribute, Atribute_Value, AttributeSubparameter, \ AttributeParameterModel, Entry, Lemma, Position, AttributeType, \ AttrValueSelectionMode, \ sortatributes, sortPositions, sortArguments, get_or_create_attr_parameter, \ get_attr_models_to_exclude, is_morfeusz_exception, get_or_create_attribute, \ get_or_create_parameter_attr_value from settings import MORFEUSZ2 @render('argument_form.html') @ajax(method='post', encode_result=False) def argument_form(request, form_data, lemma_id, position_arguments, selected_arg='', phraseologic=False, lex_arg_choosing=False, # flagi okreslajace w jakim polu wybierany jest argument position_or_arguments_arg_choosing=False, creating_editing_new_realization=False): form_dict = {} has_realizations = False form_type = 'standard' if position_or_arguments_arg_choosing: form_type = 'position_or_arguments_arg_choosing' elif lex_arg_choosing: form_type = 'lex_arg_choosing' if creating_editing_new_realization: form_type = 'realization_arg' phraseologic_modify_only = can_modify_phraseology_only(request.user, phraseologic) lemma_pos = None if lemma_id: lemma_obj = Lemma.objects.get(pk=lemma_id) lemma_pos = lemma_obj.entry_obj.pos # jesli wybieramy argument do pozycji w modyfikacji lub jeden # z argumentow do zleksykalizowanego compara to dostepne sa modele argumentow # dla wszystkich czesci mowy if position_or_arguments_arg_choosing or lex_arg_choosing: lemma_pos = None propositions_form = None attr_subforms_values = [] if form_data: form_dict = dict((x['name'], x['value']) for x in form_data) # TODO tutaj dodano wykluczenie funkcjonalnosci "czesto koordynujace sie argumenty", poprawic na madrzejsze if position_arguments and lemma_obj.entry_obj.pos.tag == 'verb' and not phraseologic_modify_only: propositions_form = create_propositions_form(form_dict, position_arguments) arg_model = get_argument_model(form_dict, phraseologic_modify_only) if form_dict: # zaznaczono wartosci # prezentowanie formularza na podstawie reprezentacji teksowej argumentu if form_dict['arg_id']: argument = Argument.objects.get(id=form_dict['arg_id']) attr_subforms_values = argument_to_form_values(argument) elif form_dict['arg_type']: attr_subforms_values = form_dict['subform_values'] selected_arg_model = None if selected_arg: selected_arg_obj = Argument.objects.get(id=selected_arg) selected_arg_model = Argument_Model.objects.get(arg_model_name=selected_arg_obj.type) if selected_arg_model and phraseologic_modify_only and not selected_arg_model.phraseologic: attr_subforms_values = fill_argument_attr_field(attr_subforms_values, selected_arg) type_form, attr_sheets = create_argument_form(arg_model=arg_model, subforms_values=attr_subforms_values, pos=lemma_pos, phraseologic=phraseologic_modify_only, form_type=form_type) if arg_model: has_realizations = arg_model.has_realizations return {'propositions_form': propositions_form, 'type_form': type_form, 'attr_sheets': attr_sheets, 'has_realizations': has_realizations} def fill_argument_attr_field(subforms_values, selected_argument_id): subforms_values[0] = [selected_argument_id] return subforms_values def argument_to_form_values(argument): form_values = [] sorted_attributes = sortatributes(argument) for attribute in sorted_attributes: form_values.append(attribute_to_form_values(attribute)) return form_values def attribute_to_form_values(attribute): attribute_form_values = [] attribute_model = Atribute_Model.objects.get(atr_model_name=attribute.type) attribute_value_type = attribute_model.type.sym_name selection_modes = attribute_model.values_selection_modes if attribute_value_type == 'text' and not selection_modes.exists(): attribute_form_values = get_simple_text_attr_form_values(attribute) elif attribute_value_type == 'text' and selection_modes.exists(): attribute_form_values = get_complex_text_attr_form_values(attribute) elif attribute_value_type == 'parameter' and not selection_modes.exists(): attribute_form_values = get_simple_parameter_attr_form_values(attribute) elif attribute_value_type == 'parameter' and selection_modes.exists(): attribute_form_values = get_complex_parameter_attr_form_values(attribute) elif attribute_value_type == 'argument' and not selection_modes.exists(): attribute_form_values = get_simple_argument_attr_form_values(attribute) elif attribute_value_type == 'argument' and selection_modes.exists(): attribute_form_values = get_complex_argument_attr_form_values(attribute) elif attribute_value_type == 'position': attribute_form_values = get_positions_attr_form_values(attribute) return attribute_form_values def get_simple_text_attr_form_values(attribute): subform_values = [] subform_values.append(attribute.values.all()[0].text) return subform_values def get_complex_text_attr_form_values(attribute): subform_values = [] selection_mode = None separator = None text_field_value = prepare_lemmas_text(attribute) if attribute.selection_mode: selection_mode = attribute.selection_mode.pk subform_values.append(selection_mode) if attribute.separator: separator = attribute.separator.pk subform_values.append(separator) subform_values.append(text_field_value) return subform_values def prepare_lemmas_text(attribute): separator_symbol = '' if attribute.separator: separator_symbol = attribute.separator.symbol values = attribute.values.order_by('text') values_text_reps = [value.text.strip("'") for value in values] return u'%s' % (separator_symbol.join(values_text_reps)) def get_simple_parameter_attr_form_values(attribute): subform_values = [] parameter = attribute.values.all()[0].parameter param_model = parameter.type subparameters = parameter.subparameters.order_by('name') subform_values.append(param_model.pk) for subparam in subparameters.all(): subform_values.append(subparam.pk) return subform_values def get_complex_parameter_attr_form_values(attribute): subform_values = [] subform_values.append(attribute.selection_mode.pk) subform_values.append(attribute.separator.pk) ordered_values = attribute.values.order_by('parameter__type__priority') subform_values.extend([value.parameter.type.pk for value in ordered_values]) return subform_values def get_simple_argument_attr_form_values(attribute): subform_values = [] subform_values.append(attribute.values.all()[0].argument.id) return subform_values def get_complex_argument_attr_form_values(attribute): subform_values = [] subform_values.append(attribute.selection_mode.pk) subform_values.append(attribute.separator.pk) arguments = [value.argument for value in attribute.values.all()] sorted_arguments = sortArguments(arguments) arguments_ids = [arg.id for arg in sorted_arguments] subform_values.extend(arguments_ids) return subform_values def get_positions_attr_form_values(attribute): subform_values = [] subform_values.append(attribute.selection_mode.pk) subform_values.append(attribute.separator.pk) positions = [value.position for value in attribute.values.all()] sorted_positions = sortPositions(positions) positions_ids = [pos['position'].id for pos in sorted_positions] subform_values.extend(positions_ids) return subform_values def create_argument_form(arg_model, subforms_values=[], pos=None, phraseologic=False, form_type='standard'):#, #lex_arg_choosing=False): attr_sheets = [] type_form = create_type_form(pos, arg_model, phraseologic, form_type)#, lex_arg_choosing) if arg_model: attr_sheets = create_attributes_forms(pos, arg_model, subforms_values, form_type) return type_form, attr_sheets def get_argument_model(arg_form_dict, phraseologic_modification=False): arg_model = None if arg_form_dict and arg_form_dict['arg_id']: arg_obj = Argument.objects.get(id=arg_form_dict['arg_id']) arg_model = Argument_Model.objects.get(arg_model_name=arg_obj.type) elif arg_form_dict and arg_form_dict['arg_type']: arg_model = Argument_Model.objects.get(arg_model_name=arg_form_dict['arg_type']) if phraseologic_modification: arg_model = change_to_phraseologic_model(arg_model) if arg_model and not arg_model.active: arg_model = None return arg_model def change_to_phraseologic_model(arg_model): if arg_model and not arg_model.phraseologic: phraseologic_arg_models = Argument_Model.objects.filter(phraseologic=True, active=True).order_by('priority') arg_model = phraseologic_arg_models.all()[0] return arg_model def create_propositions_form(arg_form_dict, position_arguments): selected_argument = None if 'freq_coordinated' in arg_form_dict.keys(): selected_argument = arg_form_dict['freq_coordinated'] freq_coor_choices = coor_arguments_query(position_arguments) return ArgPropositionsForm(freq_coor_choices=freq_coor_choices, sel_argument=selected_argument) def coor_arguments_query(args): coordinated_arguments = Argument.objects.none() positions = Position.objects.annotate(arg_count=Count('arguments')) q_args = [] sorted_args = [] for arg in args: arg_obj = jsArgToObj(arg) q_args.append(Q(pk=arg_obj.pk)) positions = positions.filter(arguments=arg_obj) positions = positions.filter(arg_count__gt=len(args)) for position in positions: coordinated_arguments = coordinated_arguments | position.arguments.all() coordinated_arguments = coordinated_arguments.exclude(reduce(or_, q_args)).distinct() # exclude arguments with inactive type (lexnp, preplexnp) coordinated_arguments = exclude_inactive_arguments(coordinated_arguments) for arg in coordinated_arguments: occurr = arg.positions.filter(id__in=positions.values_list('id')).aggregate(Sum('occurrences'))['occurrences__sum'] if occurr != 0: sorted_args.append({'arg': arg, 'occurrences': occurr}) sorted_args = sorted(sorted_args, key=itemgetter('occurrences'), reverse=True) args_tup_ls = list((arg['arg'].pk, '%s: %d' % (arg['arg'].text_rep, arg['occurrences'])) for arg in sorted_args) return args_tup_ls def exclude_inactive_arguments(arguments_query): inactive_models = Argument_Model.objects.filter(active=False).all() inactive_models_names = [arg_model.arg_model_name for arg_model in inactive_models] arguments_query = arguments_query.exclude(type__in=inactive_models_names) return arguments_query def create_type_form(pos, arg_model, phraseologic_modification=False, form_type='standard'):#, lex_arg_choosing=False): type_form = None label = 'Typ' label = create_label(label) model_queryset = Argument_Model.objects.filter(active=True) if form_type == 'realization_main_arg': model_queryset = model_queryset.filter(has_realizations=True) elif form_type == 'standard': model_queryset = model_queryset.exclude(realization_only=True) model_queryset = model_queryset.order_by('priority') if form_type == 'lex_arg_choosing': #lex_arg_choosing: model_queryset = model_queryset.filter(used_in_lex=True) elif form_type == 'realization_arg': pass else: model_queryset = model_queryset.exclude(lex_only=True) if arg_model and phraseologic_modification: model_queryset = model_queryset.filter(phraseologic=True).order_by('priority') #phraseologic_equivalents = arg_model.phraseologic_equivalents.order_by('priority') if not arg_model.phraseologic: arg_model = model_queryset.all()[0] type_form = AddArgumentForm(value=arg_model, model_queryset=model_queryset, empty_label=True, lemma_pos=pos, label=label) elif arg_model and not phraseologic_modification: type_form = AddArgumentForm(value=arg_model, model_queryset=model_queryset, lemma_pos=pos, label=label) elif not arg_model and phraseologic_modification: model_queryset = model_queryset.filter(phraseologic=True).order_by('priority') type_form = AddArgumentForm(lemma_pos=pos, model_queryset=model_queryset, label=label) else: type_form = AddArgumentForm(lemma_pos=pos, model_queryset=model_queryset, label=label) return type_form def create_attributes_forms(pos, arg_model, subforms_values, form_type='standard'): sheets = [] attribute_models = get_attribute_models(arg_model, subforms_values) param_models_to_exclude = get_parameter_types_to_exclude(arg_model) for i in range(len(attribute_models)): attr_form_values = [] attribute_model = attribute_models[i] if i < len(subforms_values): attr_form_values = subforms_values[i] #if attribute_model not in attr_models_to_exclude: sheet = create_attribute_form(pos=pos, selected_values=attr_form_values, attribute_model=attribute_model, param_models_to_exclude=param_models_to_exclude, form_type=form_type, arg_model=arg_model) sheets.append(sheet) return sheets def create_attribute_form(pos, attribute_model, param_models_to_exclude, selected_values, form_type, arg_model): arguments = [] form = None positions = [] label = create_label(attribute_model.atr_model_name) order = attribute_model.entry_edit_values_order #possible_attribute_values = attribute_model.atribute_values.exclude(id__in=attr_values_to_exclude) possible_parameter_models = attribute_model.possible_parameters.filter(active=True).exclude(id__in=param_models_to_exclude) hide_add_arg_button = False add_realization_button = False if arg_model.has_realizations: hide_add_arg_button = True if form_type == 'realization_arg': order = attribute_model.realizations_values_order elif form_type == 'standard': order = attribute_model.entry_edit_values_order possible_parameter_models = possible_parameter_models.exclude(realization_only=True) elif (form_type == 'position_or_arguments_arg_choosing' or form_type == 'lex_arg_choosing'): hide_add_arg_button = False; if arg_model.all_attr_params_used_in_lex: order = attribute_model.entry_edit_values_order else: possible_parameter_models = possible_parameter_models.exclude(realization_only=True) attribute_type = attribute_model.type.sym_name selection_modes = attribute_model.values_selection_modes.order_by('priority') value_separators = attribute_model.value_separators.order_by('priority') is_selection_mode_always_empty = False if attribute_type == 'text' and not selection_modes.exists(): if not selected_values or len(selected_values) < 1: selected_values = [''] selected_attribute_value = selected_values[0].replace("\'", '') form = AtributeTextForm(label=label, value=selected_attribute_value) elif attribute_type == 'text' and selection_modes.exists(): if not selected_values or len(selected_values) < 3: selected_values = [selection_modes.all()[0].pk, None, ''] if selected_values[0]: selection_mode = AttrValueSelectionMode.objects.get(pk=selected_values[0]) is_selection_mode_always_empty = selection_mode.always_empty form = TextAttrMultiValueForm(label=label, selection_mode_queryset=selection_modes, value_separator_queryset=value_separators, selection_mode=selected_values[0], value_separator=selected_values[1], lemmas_text=selected_values[2]) elif attribute_type == 'parameter' and not selection_modes.exists(): sel_subparameters = [] subparameters = AttributeSubparameter.objects.none() if not selected_values or len(selected_values) < 1: selected_values = [None] if selected_values[0]: param_model = AttributeParameterModel.objects.get(id=selected_values[0]) subparameters = param_model.possible_subparams.order_by('name') if len(selected_values) > 1: sel_subparameters = selected_values[1:] form = AtributeChoiceForm(values=possible_parameter_models.order_by(order), label=label, lemma_pos=pos, value=selected_values[0], subparameters=subparameters, sel_subparameters=sel_subparameters) elif attribute_type == 'parameter' and selection_modes.exists(): if not selected_values or len(selected_values) < 3: selected_values = [selection_modes.all()[0].pk, None, None] if selected_values[0]: selection_mode = selection_modes.get(pk=selected_values[0]) is_selection_mode_always_empty = selection_mode.always_empty form = ValueAttrMultiValueForm(label=label, selection_mode_queryset=selection_modes, value_separator_queryset=value_separators, values_queryset=possible_parameter_models.order_by(order), selection_mode=selected_values[0], value_separator=selected_values[1], values=selected_values[2:]) elif attribute_type == 'argument' and not selection_modes.exists(): form = SelectArgumentForm(label=label) if selected_values and selected_values[0]: try: arguments.append(Argument.objects.get(id=selected_values[0])) except ValueError: pass elif attribute_type == 'argument' and selection_modes.exists(): base_arg = None selection_mode = None if not selected_values or len(selected_values) < 2: selected_values = [selection_modes.all()[0].pk, None] if selected_values[0]: selection_mode = AttrValueSelectionMode.objects.get(pk=selected_values[0]) is_selection_mode_always_empty = selection_mode.always_empty if arg_model.has_realizations and selection_mode: # TODO troche nagiete to szukanie base arg, malo generyczne i jakis arg moze jeszcze nie istniec na bazie try: base_arg_text_rep = u'%s(%s)' % (arg_model.arg_model_name, selection_mode.name) base_arg = Argument.objects.get(text_rep=base_arg_text_rep) add_realization_button = True except Argument.DoesNotExist: pass sel_realizations = [] for argument_id in selected_values[2:]: try: argument = Argument.objects.get(id=argument_id) if base_arg and base_arg.realizations.filter(argument=argument).exists(): sel_realizations.append(argument) else: arguments.append({'id': argument.id, 'text_rep': argument.text_rep}) except ValueError: pass form = ArgumentsForm(label=label, selection_mode_queryset=selection_modes, value_separator_queryset=value_separators, selection_mode=selected_values[0], value_separator=selected_values[1], base_arg=base_arg, form_type=form_type, sel_realizations=sel_realizations) elif attribute_type == 'position' and selection_modes.exists(): if not selected_values or len(selected_values) < 2: selected_values = [selection_modes.all()[0].pk, None] if selected_values[0]: selection_mode = AttrValueSelectionMode.objects.get(pk=selected_values[0]) is_selection_mode_always_empty = selection_mode.always_empty form = PositionsForm(label=label, value_separator_queryset=value_separators, selection_mode_queryset=selection_modes, selection_mode=selected_values[0], value_separator=selected_values[1]) for position_id in selected_values[2:]: try: position = Position.objects.get(id=position_id) positions.append({'id': position.id, 'text_rep': position.text_rep}) except ValueError: pass sheet = {'form': form, 'arguments': arguments, 'positions': positions, 'is_empty_selection_mode': is_selection_mode_always_empty, 'hide_add_arg_button': hide_add_arg_button, 'add_realization_button': add_realization_button} return sheet def create_label(label): label = '%s' % label return label def get_parameter_types_to_exclude(arg_model): return [param_model.id for param_model in arg_model.exclude_param_models.all()] ############################## validation ################################## def is_correct_lemma(argument_model, attribute_model, lemma): correct_form = False possible_pos_tags = argument_model.get_possible_lemma_tags(attribute_model) for interp in MORFEUSZ2.analyse(lemma.encode('utf8')): if (base_form_correct(interp, lemma) and pos_tag_correct(interp, possible_pos_tags)): correct_form = True break elif is_morfeusz_exception(lemma, possible_pos_tags): correct_form = True break elif attribute_model.value_can_be_number and lemma.isdigit(): correct_form = True break return correct_form def base_form_correct(interp, lemma): if interp.lemma.split(':')[0] == lemma: return True return False def pos_tag_correct(interp, possible_pos_tags): tagstr = interp.getTag(MORFEUSZ2) pos_tag = tagstr.split(':')[0] if possible_pos_tags.filter(name=pos_tag).exists(): return True return False def contains_separator(lemma): contains_separator = False results_iter = MORFEUSZ2.analyse_iter(lemma.encode('utf8')) if len(lemma.split()) > 1: contains_separator = True else: while results_iter.hasNext(): tagstr = results_iter.peek().getTag(MORFEUSZ2) pos_tag = tagstr.split(':')[0] if pos_tag == 'interp': contains_separator = True break results_iter.next() return contains_separator def is_preposition_case_pair_valid(preposition_obj, case_obj): # postp is used by prepadjp case_str = unicode(case_obj) prep_str = unicode(preposition_obj).split()[-1] if case_str != 'postp': # str is used by prepadjp if case_str == 'str': pcase = ['nom', 'acc'] else: pcase = [case_str] for case in pcase: for interp in MORFEUSZ2.analyse(prep_str.encode('utf8')): tagstr = interp.getTag(MORFEUSZ2) tag_parts = tagstr.split(':') if len(tag_parts) > 1: interp_pos = tag_parts[0] interp_cases = tag_parts[1].split('.') if interp_pos == 'prep' and case in interp_cases: return True return False return True ############################################################################ ############################## Submit form ################################## ############################################################################ @ajax(method='post') def argument_form_submit(request, form_data): form_dict = dict((x['name'], x['value']) for x in form_data) error = validate_argument_form(form_dict) if error: raise AjaxError(error) if not form_dict['freq_coordinated']: arg_obj = get_argument_from_form(form_dict['arg_type'], form_dict['subform_values']) else: arg_obj = Argument.objects.get(id=form_dict['freq_coordinated']) return {'id': arg_obj.id, 'text_rep': arg_obj.text_rep, 'type': arg_obj.type} def validate_argument_form(form_dict): error = '' if not all_fields_filled(form_dict): error = u'Wypełnij wszystkie niezbędne pola formularza.' if not error and not form_dict['freq_coordinated']: error = validate_argument_form_fields(form_dict) return error def all_fields_filled(form_dict): if not form_dict['freq_coordinated'] and not form_dict['arg_type']: return False for attr_subform in form_dict['subform_values']: for attr_value in attr_subform: if not attr_value: return False return True def validate_argument_form_fields(form_dict): error = '' arg_model_obj = Argument_Model.objects.get(arg_model_name=form_dict['arg_type']) attribute_models = get_attribute_models(arg_model_obj, form_dict['subform_values']) lexicalized_arg_model = get_lexicalized_arg_model(arg_model_obj, form_dict['subform_values']) for i in range(len(attribute_models)): error = validate_attribute_subform(lexicalized_arg_model, attribute_models[i], form_dict['subform_values'][i], form_dict['lex_arg_choosing']) if error: break if not error: error = preposition_validation(attribute_models, form_dict['subform_values']) return error def get_lexicalized_arg_model(main_arg_model, attrs_subforms): lexicalized_arg_model = None attribute_models = main_arg_model.atribute_models.order_by('priority') if attribute_models.filter(atr_model_name=u'TYP FRAZY').exists(): for i in range(len(attribute_models)): if attribute_models[i].atr_model_name == u'TYP FRAZY' and len(attrs_subforms) > i: try: argument = Argument.objects.get(id=attrs_subforms[i][0]) lexicalized_arg_model = argument.model_used_for_limitations() except ValueError: pass except IndexError: # index error, zeby dalo sie edytowac stare fixy pass break return lexicalized_arg_model def preposition_validation(attribute_models, attr_subform_values): error = '' prep, case = find_preposition_case_pair(attribute_models, attr_subform_values) if prep and case and not is_preposition_case_pair_valid(prep, case): error = preposition_case_pair_error() return error def find_preposition_case_pair(attribute_models, attr_subform_values): case = None prep = None for i in range(len(attribute_models)): if attribute_models[i].sym_name == 'case': case = attribute_models[i].possible_parameters.get(pk=attr_subform_values[i][0]) elif attribute_models[i].sym_name == 'preposition': prep = attribute_models[i].possible_parameters.get(pk=attr_subform_values[i][0]) if case and prep: break return prep, case def preposition_case_pair_error(): return u'Przypadek nie jest zgodny z przyimkiem.' def validate_attribute_subform(argument_model, attribute_model, attr_subform_values, lex_arg_choosing): error = '' attribute_type = attribute_model.type.sym_name selection_modes = attribute_model.values_selection_modes if attribute_type == 'text' and selection_modes.exists(): error = validate_complex_text_attr(argument_model, attribute_model, attr_subform_values) elif attribute_type == 'parameter' and selection_modes.exists(): error = validate_complex_parameter_attr(attribute_model, attr_subform_values) elif attribute_type == 'argument' and not selection_modes.exists(): error = validate_simple_argument_attr(attribute_model, attr_subform_values) elif attribute_type == 'argument' and selection_modes.exists(): error = validate_complex_argument_attr(attribute_model, attr_subform_values, lex_arg_choosing) return error def strip_quotation_marks(value): value = value.strip() value = value.strip('\"\'') value = value.strip() return value def wrong_base_form_error(value): return u'Lemat %s jest nieprawidłowy.' % value def validate_complex_text_attr(argument_model, attribute_model, attr_subform_values): error = '' separator = attribute_model.value_separators.get(pk=attr_subform_values[1]) text_field_content = attr_subform_values[2] if not is_empty_lemma(text_field_content): text_values = text_field_content.split(separator.symbol) for text_value in text_values: text_value = strip_quotation_marks(text_value) if contains_separator(text_value): error = separator_error(attribute_model) break if not is_correct_lemma(argument_model, attribute_model, text_value): error = wrong_base_form_error(text_value) break return error def is_empty_lemma(text_field_value): is_empty_lemma = False text_field_value = strip_quotation_marks(text_field_value) empty_lemma_parts = text_field_value.split('(') if len(empty_lemma_parts) == 2: type = empty_lemma_parts[0] gender_str = empty_lemma_parts[1].rstrip(')') genders = gender_str.split('.') if type == 'E' and are_gender_values(genders): is_empty_lemma = True return is_empty_lemma def are_gender_values(genders): are_gender_values = True gender_model = Atribute_Model.objects.get(sym_name='gender') for gender in genders: if not gender_model.possible_parameters.filter(name=gender).exists(): are_gender_values = False break return are_gender_values def separator_error(attribute_model): attribute_model_name = attribute_model.atr_model_name return u'W polu tekstowym %s wykorzystano zły separator wartości.' % attribute_model_name def validate_complex_parameter_attr(attribute_model, attr_subform_values): error = '' if len(attr_subform_values) < 3: error = no_parameter_selection_error(attribute_model) return error def no_parameter_selection_error(attribute_model): attribute_model_name = attribute_model.atr_model_name return u'Zaznacz co najmniej jeden parametr określający %s.' % attribute_model_name def validate_simple_argument_attr(attribute_model, attr_subform_values): error = '' if len(attr_subform_values) >= 1: selected_arg = Argument.objects.get(id=attr_subform_values[0]) selected_arg_model = Argument_Model.objects.get(arg_model_name=selected_arg.type) if selected_arg_model.use_subarg_for_limitations: if not selected_arg.atributes.count() == 1: error = lex_nesting_error(selected_arg) elif not selected_arg.atributes.all()[0].values.count() == 1: error = lex_nesting_error(selected_arg) else: lexicalized_subarg = selected_arg.atributes.all()[0].values.all()[0].argument lexicalized_subarg_model = Argument_Model.objects.get(arg_model_name=lexicalized_subarg.type) if not lexicalized_subarg_model.used_in_lex or not lexicalized_subarg_model.active: error = lex_nesting_error(selected_arg) return error def validate_complex_argument_attr(attribute_model, attr_subform_values, lex_arg_choosing): error = '' attr_selection_mode = attribute_model.values_selection_modes.get(pk=attr_subform_values[0]) if lex_arg_choosing and len(attr_subform_values) != 3: error = lex_arg_error() elif lex_arg_choosing and len(attr_subform_values) == 3: selected_arg = Argument.objects.get(id=attr_subform_values[2]) selected_arg_model = Argument_Model.objects.get(arg_model_name=selected_arg.type) if not selected_arg_model.used_in_lex or not selected_arg_model.active: error = not_lexicalizable_arg(selected_arg_model) elif selected_arg_model.use_subarg_for_limitations: error = lex_nesting_error(selected_arg) elif (not lex_arg_choosing and len(attr_subform_values) > 2 and attribute_model.need_lexicalized_values and not is_phraseologic_arg_defined(attr_subform_values[2:])): error = no_lex_arg_error(attribute_model) if not error: if (len(attr_subform_values) < 3 and not (attr_selection_mode.always_empty or attr_selection_mode.can_be_empty)): error = no_arguments_error(attribute_model) return error def lex_arg_error(): return u'Wybierz jedno rozwinięcie typu frazy.' def lex_nesting_error(argument): return u'Nie można zleksykalizować typu frazy %s.' % argument.text_rep def not_lexicalizable_arg(argument_model): arg_model_name = argument_model.arg_model_name return u'Typy fraz %s nie podlegają leksykalizacji.' % arg_model_name def is_phraseologic_arg_defined(arguments_ids): for arg_id in arguments_ids: selected_arg = Argument.objects.get(id=arg_id) if selected_arg.is_phraseologic(): return True return False def no_lex_arg_error(attribute_model): attribute_model_name = attribute_model.atr_model_name return u'Do pola %s musi zostać dodany co najmniej jeden zleksykalizowany typ frazy.' % attribute_model_name def no_arguments_error(attribute_model): attribute_model_name = attribute_model.atr_model_name return u'Do pola %s musi zostać dodany co najmniej jeden typ frazy.' % attribute_model_name def get_argument_from_form(arg_type, attrs_subforms): arg_model_obj = Argument_Model.objects.get(arg_model_name=arg_type) atribute_objs = get_or_create_attributes(arg_model_obj, attrs_subforms) arg_obj = get_or_create_argument(arg_model_obj, atribute_objs) return arg_obj def get_or_create_argument(argument_model, sorted_attributes): arg_type = argument_model.arg_model_name atr_str_tab = [unicode(attr) for attr in sorted_attributes] arg_text_rep = '' if len(atr_str_tab) == 0: arg_text_rep = '%s' % (arg_type) elif argument_model.hide_type: arg_text_rep = '%s' % (','.join(atr_str_tab)) else: arg_text_rep = '%s(%s)' % (arg_type, ','.join(atr_str_tab)) try: arg_obj = Argument.objects.get(text_rep=arg_text_rep) except Argument.DoesNotExist: arg_obj = Argument(type=arg_type, text_rep=arg_text_rep) arg_obj.save() arg_obj.atributes.add(*sorted_attributes) return arg_obj def get_or_create_attributes(arg_model_obj, attrs_subforms): attribute_objs = [] #attribute_models = arg_model_obj.atribute_models.order_by('priority') attribute_models = get_attribute_models(arg_model_obj, attrs_subforms) for i in range(len(attribute_models)): #if not attribute_models[i] in attr_models_to_exclude: attribute_type = attribute_models[i].type.sym_name selection_modes = attribute_models[i].values_selection_modes attr_subform_values = attrs_subforms[i] if attribute_type == 'text' and not selection_modes.exists(): attribute_objs.append(get_or_create_simple_text_attr(attribute_models[i], attr_subform_values)) elif attribute_type == 'text' and selection_modes.exists(): attribute_objs.append(get_or_create_complex_text_attr(attribute_models[i], attr_subform_values)) elif attribute_type == 'parameter' and not selection_modes.exists(): attribute_objs.append(get_or_create_simple_parameter_attr(attribute_models[i], attr_subform_values)) elif attribute_type == 'parameter' and selection_modes.exists(): attribute_objs.append(get_or_create_complex_parameter_attr(attribute_models[i], attr_subform_values)) elif attribute_type == 'argument' and not selection_modes.exists(): attribute_objs.append(get_or_create_simple_argument_attr(attribute_models[i], attr_subform_values)) elif attribute_type == 'argument' and selection_modes.exists(): attribute_objs.append(get_or_create_complex_argument_attr(attribute_models[i], attr_subform_values)) elif attribute_type == 'position': attribute_objs.append(get_or_create_positions_attr(attribute_models[i], attr_subform_values)) return attribute_objs def get_attribute_models(arg_model, attrs_subforms): attribute_models = arg_model.atribute_models.order_by('priority') if attribute_models.filter(atr_model_name=u'TYP FRAZY').exists(): for i in range(len(attribute_models)): if attribute_models[i].atr_model_name == u'TYP FRAZY' and len(attrs_subforms) > i: try: argument = Argument.objects.get(id=attrs_subforms[i][0]) attr_models_to_exclude = get_attr_models_to_exclude(argument) attribute_models = attribute_models.exclude(pk__in=attr_models_to_exclude) attribute_models = attribute_models.order_by('priority') except ValueError: pass except IndexError: # index error, zeby dalo sie edytowac stare fixy pass break return attribute_models def get_or_create_simple_text_attr(attribute_model, attr_subform_values): attr_value = prepare_text_attr_value(attr_subform_values[0]) attr_val_obj = get_or_create_text_attr_value(attr_value) attr_obj = get_or_create_attribute(attribute_model=attribute_model, values=[attr_val_obj], selection_mode=None, separator=None) return attr_obj def prepare_text_attr_value(value): value = strip_quotation_marks(value) value = "\'%s\'" % value return value def get_or_create_complex_text_attr(attribute_model, attr_subform_values): values = [] selection_mode = attribute_model.values_selection_modes.get(pk=attr_subform_values[0]) separator = attribute_model.value_separators.get(pk=attr_subform_values[1]) text_field_value = attr_subform_values[2] if is_empty_lemma(text_field_value): empty_lemma_value = correct_empty_lemma_value(text_field_value) empty_lemma_value = prepare_text_attr_value(empty_lemma_value) values.append(get_or_create_text_attr_value(empty_lemma_value)) else: text_values = attr_subform_values[2].split(separator.symbol) for text_value in text_values: text_value = prepare_text_attr_value(text_value) values.append(get_or_create_text_attr_value(text_value)) # nie ma wyboru listowego kiedy mamy tylko jeden lemat if len(values) < 2: selection_mode = None separator = None attr_obj = get_or_create_attribute(attribute_model=attribute_model, values=values, selection_mode=selection_mode, separator=separator) return attr_obj def correct_empty_lemma_value(empty_lemma_value): empty_lemma_value = strip_quotation_marks(empty_lemma_value) empty_lemma_parts = empty_lemma_value.split('(') type = empty_lemma_parts[0] gender_str = empty_lemma_parts[1].rstrip(')') genders = gender_str.split('.') sorted_genders = sort_genders(genders) empty_lemma_value = u'E(%s)' % '.'.join(sorted_genders) return empty_lemma_value def sort_genders(genders): gender_model = Atribute_Model.objects.get(sym_name='gender') genders = [param_model.name for param_model in gender_model.possible_parameters.order_by('priority') if param_model.name in genders] return genders def get_or_create_simple_parameter_attr(attribute_model, attr_subform_values): attr_val_obj = get_parameter_attr_value_from_subform(attr_subform_values) attr_obj = get_or_create_attribute(attribute_model=attribute_model, values=[attr_val_obj], selection_mode=None, separator=None) return attr_obj def get_parameter_attr_value_from_subform(attr_subform_values): param_model = AttributeParameterModel.objects.get(pk=attr_subform_values[0]) subparam_objs = [AttributeSubparameter.objects.get(pk=subparam_pk) for subparam_pk in attr_subform_values[1:]] param_obj, xx = get_or_create_attr_parameter(param_model, subparam_objs) attr_val_obj, xx = get_or_create_parameter_attr_value(param_obj) return attr_val_obj def get_or_create_complex_parameter_attr(attribute_model, attr_subform_values): selection_mode = attribute_model.values_selection_modes.get(pk=attr_subform_values[0]) separator = attribute_model.value_separators.get(pk=attr_subform_values[1]) param_models_pks = attr_subform_values[2:] values = [get_parameter_attr_value_from_subform([pk]) for pk in param_models_pks] attr_obj = get_or_create_attribute(attribute_model=attribute_model, values=values, selection_mode=selection_mode, separator=separator) return attr_obj def get_or_create_positions_attr(attribute_model, attr_subform_values): values = [] selection_mode = attribute_model.values_selection_modes.get(pk=attr_subform_values[0]) separator = attribute_model.value_separators.get(pk=attr_subform_values[1]) positions_ids = attr_subform_values[2:] for pos_id in positions_ids: position = Position.objects.get(id=pos_id) values.append(get_or_create_position_attr_value(position)) attr_obj = get_or_create_attribute(attribute_model=attribute_model, values=values, selection_mode=selection_mode, separator=separator) return attr_obj def get_or_create_simple_argument_attr(attribute_model, attr_subform_values): argument = Argument.objects.get(id=attr_subform_values[0]) value = get_or_create_argument_attr_value(argument) attr_obj = get_or_create_attribute(attribute_model=attribute_model, values=[value], selection_mode=None, separator=None) return attr_obj def get_or_create_complex_argument_attr(attribute_model, attr_subform_values): values = [] selection_mode = attribute_model.values_selection_modes.get(pk=attr_subform_values[0]) separator = attribute_model.value_separators.get(pk=attr_subform_values[1]) arguments_ids = attr_subform_values[2:] for arg_id in arguments_ids: argument = Argument.objects.get(id=arg_id) values.append(get_or_create_argument_attr_value(argument)) attr_obj = get_or_create_attribute(attribute_model=attribute_model, values=values, selection_mode=selection_mode, separator=separator) return attr_obj def get_or_create_text_attr_value(value): text_type = AttributeType.objects.get(sym_name='text') try: attr_val_obj = Atribute_Value.objects.get(text=value, type=text_type) except: attr_val_obj = Atribute_Value(text=value, priority=1000, type=text_type) attr_val_obj.save() return attr_val_obj def get_or_create_argument_attr_value(argument): argument_type = AttributeType.objects.get(sym_name='argument') try: attr_val_obj = Atribute_Value.objects.get(argument=argument, type=argument_type) except: attr_val_obj = Atribute_Value(argument=argument, priority=2000, type=argument_type) attr_val_obj.save() return attr_val_obj def get_or_create_position_attr_value(position): position_type = AttributeType.objects.get(sym_name='position') try: attr_val_obj = Atribute_Value.objects.get(position=position, type=position_type) except: attr_val_obj = Atribute_Value(position=position, priority=3000, type=position_type) attr_val_obj.save() return attr_val_obj