# -*- 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 dictionary.ajax_argument_form import get_or_create_text_attr_value, \ is_empty_lemma, correct_empty_lemma_value, \ prepare_text_attr_value, get_or_create_argument, \ get_or_create_argument_attr_value, get_or_create_position_attr_value from dictionary.models import Argument_Model, AttrValueSelectionMode, PositionCategory, \ get_or_create_position, get_or_create_attr_parameter, \ get_attr_models_to_exclude, get_or_create_attribute, \ get_or_create_parameter_attr_value def parse_argument_text_rep(text_rep): arg_type, attributes_ls = get_arg_parts(text_rep) arg_model_obj = Argument_Model.objects.get(arg_model_name=arg_type) atribute_objs = parse_attributes(arg_model_obj, attributes_ls) arg_obj = get_or_create_argument(arg_model_obj, atribute_objs) return arg_obj def parse_argument_parts(arg_type, attributes_ls): arg_model_obj = Argument_Model.objects.get(arg_model_name=arg_type) atribute_objs = parse_attributes(arg_model_obj, attributes_ls) arg_obj = get_or_create_argument(arg_model_obj, atribute_objs) return arg_obj def get_arg_parts(text_rep): attributes_ls = [] arg_parts = text_rep.split('(', 1) arg_type = arg_parts[0] if len(arg_parts) == 2: attributes_str = arg_parts[1][:-1] attributes_ls = get_attributes(attributes_str) return arg_type, attributes_ls def get_attributes(attributes_str): attribute = '' attributes_ls = [] opened_brackets = 0 for char in attributes_str: attribute += char if char == '(' or char == '[': opened_brackets += 1 elif char == ')' or char == ']': opened_brackets -= 1 if char == ',' and opened_brackets == 0: attribute = attribute.strip(',') attributes_ls.append(attribute.strip()) attribute = '' attributes_ls.append(attribute.strip()) return attributes_ls def parse_attributes(arg_model_obj, attributes_ls): attribute_objs = [] attribute_models = get_attribute_models(arg_model_obj, attributes_ls) for i in range(len(attribute_models)): attribute_type = attribute_models[i].type.sym_name selection_modes = attribute_models[i].values_selection_modes attribute_str = attributes_ls[i].strip() if attribute_type == 'text' and not selection_modes.exists(): attribute_objs.append(get_or_create_simple_text_attr(attribute_models[i], attribute_str)) elif attribute_type == 'text' and selection_modes.exists(): attribute_objs.append(get_or_create_complex_text_attr(attribute_models[i], attribute_str)) elif attribute_type == 'parameter' and not selection_modes.exists(): attribute_objs.append(get_or_create_simple_parameter_attr(attribute_models[i], attribute_str)) elif attribute_type == 'parameter' and selection_modes.exists(): attribute_objs.append(get_or_create_complex_parameter_attr(attribute_models[i], attribute_str)) elif attribute_type == 'argument' and not selection_modes.exists(): argument_attr = get_or_create_simple_argument_attr(attribute_models[i], attribute_str) attribute_objs.append(argument_attr) elif attribute_type == 'argument' and selection_modes.exists(): argument_attr = get_or_create_complex_argument_attr(attribute_models[i], attribute_str) attribute_objs.append(argument_attr) elif attribute_type == 'position': attribute_objs.append(get_or_create_positions_attr(attribute_models[i], attribute_str)) return attribute_objs def get_attribute_models(arg_model, attributes_ls): 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(attributes_ls) > i: try: #argument_attr_type, xx = get_arg_parts(attributes_ls[i]) arg_attr = parse_argument_text_rep(attributes_ls[i]) attr_models_to_exclude = get_attr_models_to_exclude(arg_attr) # argument_attr_model = Argument_Model.objects.get(arg_model_name=argument_attr_type) # attr_models_to_exclude = argument_attr_model.sec_attr_limitations.all() attribute_models = attribute_models.exclude(pk__in=attr_models_to_exclude) attribute_models = attribute_models.order_by('priority') except ValueError: pass break return attribute_models def get_or_create_simple_text_attr(attribute_model, attr_str): attr_str = prepare_text_attr_value(attr_str) attr_val_obj = get_or_create_text_attr_value(attr_str) attr_obj = get_or_create_attribute(attribute_model=attribute_model, values=[attr_val_obj], selection_mode=None, separator=None) return attr_obj def get_or_create_complex_text_attr(attribute_model, attr_str): values = [] separator = get_attr_separator(attribute_model, attr_str) selection_mode = get_attr_selection_mode(attribute_model, attr_str) lemmas_str = get_attr_values_str(attribute_model, attr_str, selection_mode) if is_empty_lemma(lemmas_str): empty_lemma_value = correct_empty_lemma_value(lemmas_str) empty_lemma_value = prepare_text_attr_value(empty_lemma_value) values.append(get_or_create_text_attr_value(empty_lemma_value)) else: if separator: text_values = lemmas_str.split(separator.symbol) else: text_values = [attr_str] 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 get_attr_separator(attribute_model, attr_str): separator = None possible_separators = attribute_model.value_separators.all() for poss_separator in possible_separators: if poss_separator.symbol in attr_str: separator = poss_separator break if not separator and possible_separators.count() == 1: separator = possible_separators.all()[0] return separator def get_attr_selection_mode(attribute_model, attr_str): selection_mode = None possible_selection_modes = attribute_model.values_selection_modes if possible_selection_modes.count() == 1: selection_mode = possible_selection_modes.all()[0] else: selection_mode_str = attr_str.split(attribute_model.val_list_start)[0] try: selection_mode = possible_selection_modes.get(name=selection_mode_str) except AttrValueSelectionMode.DoesNotExist: selection_mode = None return selection_mode def get_attr_values_str(attribute_model, attr_str, selection_mode): attr_values_str = attr_str if selection_mode: if attribute_model.val_list_start != '': attr_parts = attr_values_str.split(attribute_model.val_list_start, 1) else: attr_parts = [attr_values_str] if len(attr_parts) == 1: if selection_mode.name: attr_values_str = '' else: attr_values_str = attr_parts[1][:-1] return attr_values_str def get_or_create_simple_parameter_attr(attribute_model, attr_str): attr_val_obj = parse_parameter_attr_value(attribute_model, attr_str) attr_obj = get_or_create_attribute(attribute_model=attribute_model, values=[attr_val_obj], selection_mode=None, separator=None) return attr_obj def parse_parameter_attr_value(attribute_model, attr_val_str): param_model_name, subparameters_str_ls = get_param_parts(attr_val_str) param_model = attribute_model.possible_parameters.get(name=param_model_name) subparam_objs = [param_model.possible_subparams.get(name=subparam_name) for subparam_name in subparameters_str_ls] 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_param_parts(param_str): subparameters_str_ls = [] param_parts = param_str.split('[', 1) param_model_name = param_parts[0] if len(param_parts) == 2: subparameters_str = param_parts[1][:-1] subparameters_str_ls = subparameters_str.split(';') return param_model_name, subparameters_str_ls def get_or_create_complex_parameter_attr(attribute_model, attr_str): selection_mode = get_attr_selection_mode(attribute_model, attr_str) separator = get_attr_separator(attribute_model, attr_str) values_str = get_attr_values_str(attribute_model, attr_str, selection_mode) values_text_reps = values_str.split(separator.symbol) values = [parse_parameter_attr_value(attribute_model, value_text_rep) for value_text_rep in values_text_reps] 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_str): argument = parse_argument_text_rep(attr_str) 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_str): values = [] selection_mode = get_attr_selection_mode(attribute_model, attr_str) separator = get_attr_separator(attribute_model, attr_str) args_str = attr_str[len(selection_mode.name):] args_str = args_str.lstrip(attribute_model.val_list_start) args_str = args_str.rstrip(attribute_model.val_list_end) arguments_text_reps = get_arguments(args_str, separator.symbol) for arg_text_rep in arguments_text_reps: argument = parse_argument_text_rep(arg_text_rep) 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_positions_attr(attribute_model, attr_str): values = [] selection_mode = get_attr_selection_mode(attribute_model, attr_str) separator = get_attr_separator(attribute_model, attr_str) positions_str = get_attr_values_str(attribute_model, attr_str, selection_mode) positions = parse_positions_str(positions_str) for position in positions: 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 parse_positions_str(positions_str): positions_str_ls = get_positions(positions_str) positions_objs = [parse_position_text_rep(position_str) for position_str in positions_str_ls if position_str] return positions_objs def get_positions(positions_str): position = '' positions_ls = [] opened_brackets = 0 for char in positions_str: position += char if char == '{': opened_brackets += 1 elif char == '}': opened_brackets -= 1 if char == '+' and opened_brackets == 0: position = position.strip('+') positions_ls.append(position.strip()) position = '' positions_ls.append(position.strip()) return positions_ls def parse_position_text_rep(text_rep): categories_objs = [] categories_str_ls, arguments_str_ls = get_position_parts(text_rep) if categories_str_ls: categories_objs = [PositionCategory.objects.get(category=cat_str) for cat_str in categories_str_ls] argument_objs = [parse_argument_text_rep(arg_str) for arg_str in arguments_str_ls if arg_str] position_obj = get_or_create_position(categories_objs, argument_objs) return position_obj def get_position_parts(text_rep): position_parts = text_rep.split('{', 1) categories = position_parts[0].strip().split(',') categories = [cat for cat in categories if cat] if len(position_parts) == 1: arguments_str = '' else: arguments_str = position_parts[1][:-1] arguments = get_arguments(arguments_str) return categories, arguments def get_arguments(arguments_str, separator=';'): argument = '' arguments_ls = [] opened_brackets = 0 for char in arguments_str: argument += char if char == '(' or char == '[': opened_brackets += 1 elif char == ')' or char == ']': opened_brackets -= 1 if char == separator and opened_brackets == 0: argument = argument.strip(separator) arguments_ls.append(argument.strip()) argument = '' if argument: arguments_ls.append(argument.strip()) return arguments_ls