# -*- coding: utf-8 -*- import operator from django.contrib.auth.models import User from django.db.models import Q from accounts.models import get_anon_profile from dictionary.common_func import escape_regex from dictionary.forms import FilterForm from dictionary.models import Argument, Frame, Frame_Char_Model, Frame_Opinion_Value, \ Lemma, Lemma_Status, NKJP_Example, NKJP_Source, POS, \ Position, Vocabulary, \ get_frame_char_and_its_value, get_schemata_by_type from semantics.forms import GeneralSelPrefForm, RelationalSelPrefForm, RoleForm, \ SynsetSelPrefForm from semantics.models import Complement, FrameOpinion, RelationalSelectivePreference, \ SemanticFrame from wordnet.models import LexicalUnit def schemata_filter_options(): # pobieranie wartosci aspektu aspect_model = Frame_Char_Model.objects.get(model_name=u'ASPEKT') aspect_vals_objs = aspect_model.frame_char_values.order_by('-priority') aspect_options = [{'name': '*', 'value': '*'}] aspect_options.extend([{'name': val.value, 'value': val.value} for val in aspect_vals_objs]) # pobieranie wartosci zwrotnosci reflex_model = Frame_Char_Model.objects.get(model_name=u'ZWROTNOŚĆ') reflex_vals_objs = reflex_model.frame_char_values.order_by('-priority') reflex_options = [{'name': '*', 'value': '*'}] reflex_options.extend([{'name': val.value, 'value': val.value} for val in reflex_vals_objs]) # pobieranie wartosci negatywnosci neg_model = Frame_Char_Model.objects.get(model_name=u'NEGATYWNOŚĆ') neg_vals_objs = neg_model.frame_char_values.order_by('-priority') neg_options = [{'name': '*', 'value': '*'}] neg_options.extend([{'name': val.value, 'value': val.value} for val in neg_vals_objs]) # pobieranie wartosci predykatywnosci pred_model = Frame_Char_Model.objects.get(model_name=u'PREDYKATYWNOŚĆ') pred_vals_objs = pred_model.frame_char_values.order_by('-priority') pred_options = [{'name': '*', 'value': '*'}] pred_options.extend([{'name': val.value, 'value': val.value} for val in pred_vals_objs]) # pobieranie opinii o schemacie opinion_options = [{'name': '*', 'value': '*'}] opinion_options.extend([{'name': val.value, 'value': val.value} for val in Frame_Opinion_Value.objects.order_by('priority')]) schema_type_options = [{'name': '*', 'value': '*'}, {'name': 'normalny', 'value': 'normal'}, {'name': 'frazeologiczny', 'value': 'phraseologic'}] return {'schema_type_options': schema_type_options, 'reflex_options': reflex_options, 'aspect_options': aspect_options, 'neg_options': neg_options, 'pred_options': pred_options, 'opinion_options': opinion_options} def all_filter_rules_loaded(rules): if set(default_filter_rules().keys()) != set(rules): return False return True def default_filter_rules(): return {'lemma': '.*', 'pos': None, 'contains_phraseology': None, 'owner': None, 'phraseologist': None, 'semanticist': None, 'vocabulary': None, 'status': None, 'example_source': None, 'approver': None, 'reflex': None, 'negativity': None, 'predicativity': None, 'aspect': None, 'argument': '.*', 'position': '.*', 'schema_opinion' : None, 'sender': None, 'schema_type': None, 'frame_opinion': None, 'sem_arguments': []} def prepare_filter_form(request): if request.session.has_key('lemma_preview') and request.session['lemma_preview']: if not request.session.has_key('filter_rules_lemma_preview'): request.session['filter_rules_lemma_preview'] = default_filter_rules() filter_rules = request.session['filter_rules_lemma_preview'] else: if not request.session.has_key('filter_rules'): request.session['filter_rules'] = default_filter_rules() filter_rules = request.session['filter_rules'] users = User.objects.none() phraseologists = User.objects.none() semanticists = User.objects.none() vocabularies = Vocabulary.objects.none() senders = User.objects.none() statuses = get_anon_profile().visible_statuses.all() can_confirm_example = False if request.user.is_authenticated(): users = User.objects.filter(lemmas__old=False).distinct().order_by('username') phraseologists = User.objects.filter(phraseologist_lemmas__old=False).distinct().order_by('username') semanticists = User.objects.filter(semanticist_lemmas__old=False).distinct().order_by('username') vocabularies = request.user.visible_vocabularies.all() senders = User.objects.order_by('groups__group_settings__priority') statuses = Lemma_Status.objects.all() if request.user.has_perm('dictionary.confirm_example') or request.user.is_superuser: can_confirm_example = True form = FilterForm(users=users, phraseologists=phraseologists, semanticists=semanticists, vocabularies=vocabularies, senders=senders, statuses=statuses, lemma=filter_rules['lemma'], sel_pos=filter_rules['pos'], contains_phraseology=filter_rules['contains_phraseology'], sel_user=filter_rules['owner'], sel_phraseologist=filter_rules['phraseologist'], sel_semanticist=filter_rules['semanticist'], sel_vocabulary=filter_rules['vocabulary'], sel_status=filter_rules['status'], sel_reflex=filter_rules['reflex'], sel_negativity=filter_rules['negativity'], sel_predicativity=filter_rules['predicativity'], sel_aspect=filter_rules['aspect'], sel_has_argument=filter_rules['argument'], sel_has_position=filter_rules['position'], sel_schema_opinion=filter_rules['schema_opinion'], can_confirm_example = can_confirm_example, sel_example_source=filter_rules['example_source'], sel_approver=filter_rules['approver'], sel_sender=filter_rules['sender'], sel_schema_type=filter_rules['schema_type'], sel_frame_opinion=filter_rules['frame_opinion']) return {'form': form, 'sem_args_forms': sem_args_to_forms(filter_rules['sem_arguments'])} def sem_args_to_forms(sem_arguments): args_forms = [] first_alternative = True for alternative in sem_arguments: if first_alternative: first_alternative = False else: args_forms.append('or') for arg in alternative: args_forms.append(RoleForm(negation=arg['negation'], sel_role=arg['role'], sel_attribute=arg['attribute'], sel_preferences=get_sel_prefs_as_forms(arg))) return args_forms def get_sel_prefs_as_forms(arg): forms = [] if arg['general_prefs']: forms.extend(general_prefs_to_forms(arg['general_prefs'])) if arg['synset_prefs']: forms.extend(synset_prefs_to_forms(arg['synset_prefs'])) if arg['relational_prefs']: forms.extend(relational_prefs_to_forms(arg['relational_prefs'])) return forms def general_prefs_to_forms(prefs): forms = [] for pref in prefs: forms.append(GeneralSelPrefForm(sel_preference=pref)) return forms def synset_prefs_to_forms(prefs): forms = [] for pref in prefs: forms.append(SynsetSelPrefForm(sel_preference=pref)) return forms def relational_prefs_to_forms(prefs): forms = [] for pref in prefs: forms.append(RelationalSelPrefForm(sel_relation=pref['relation'], sel_role=pref['role'], sel_attribute=pref['attribute'])) return forms def save_lemma_filters_and_get_schemata_filter_setup(request, filter_dict): if filter_dict['pos']: pos_obj = POS.objects.get(id=filter_dict['pos']) else: pos_obj = None if filter_dict['owner']: owner_obj = User.objects.get(id=filter_dict['owner']) else: owner_obj = None if filter_dict['phraseologist']: phraseologist_obj = User.objects.get(id=filter_dict['phraseologist']) else: phraseologist_obj = None if filter_dict['semanticist']: semanticist_obj = User.objects.get(id=filter_dict['semanticist']) else: semanticist_obj = None if filter_dict['vocabulary']: vocabulary_obj = Vocabulary.objects.get(name=filter_dict['vocabulary']) else: vocabulary_obj = None if filter_dict['status']: status_obj = Lemma_Status.objects.get(id=filter_dict['status']) else: status_obj = None if filter_dict['example_source']: nkjp_source_obj = NKJP_Source.objects.get(id=filter_dict['example_source']) else: nkjp_source_obj = None if filter_dict['approver']: approver_obj = User.objects.get(id=filter_dict['approver']) else: approver_obj = None if filter_dict['has_message_from']: try: sender_obj = User.objects.get(pk=filter_dict['has_message_from']) except User.DoesNotExist: sender_obj = None else: sender_obj = None reflex_obj, reflex_val = get_frame_char_and_its_value(filter_dict['reflex'], '*') negativity_obj, negativity_val = get_frame_char_and_its_value(filter_dict['negativity'], '*') aspect_obj, aspect_val = get_frame_char_and_its_value(filter_dict['aspect'], '*') pred_obj, pred_val = get_frame_char_and_its_value(filter_dict['predicativity'], '*') if filter_dict['schema_opinion']: schema_opinion_obj = Frame_Opinion_Value.objects.get(id=filter_dict['schema_opinion']) opinion_val = schema_opinion_obj.value else: schema_opinion_obj = None opinion_val = '*' if 'schema_type' in filter_dict: schema_type = filter_dict['schema_type'] else: schema_type = None if 'frame_opinion' in filter_dict and filter_dict['frame_opinion']: frame_opinion = FrameOpinion.objects.get(id=filter_dict['frame_opinion']) else: frame_opinion = None sem_arguments = [constraints for constraints in filter_dict['sem_arguments'] if constraints != []] if request.session.has_key('lemma_preview') and request.session['lemma_preview']: request.session['filter_rules_lemma_preview'] = {'pos' : pos_obj, 'contains_phraseology': filter_dict['contains_phraseology'], 'owner' : owner_obj, 'phraseologist' : phraseologist_obj, 'semanticist' : semanticist_obj, 'vocabulary' : vocabulary_obj, 'status' : status_obj, 'example_source' : nkjp_source_obj, 'approver' : approver_obj, 'reflex' : reflex_obj, 'negativity' : negativity_obj, 'predicativity' : pred_obj, 'aspect' : aspect_obj, 'argument' : filter_dict['has_argument'], 'position' : filter_dict['has_position'], 'lemma' : filter_dict['lemma'], 'schema_opinion' : schema_opinion_obj, 'sender' : sender_obj, 'schema_type' : schema_type, 'frame_opinion' : frame_opinion, 'sem_arguments' : sem_arguments} else: request.session['filter_rules'] = {'pos' : pos_obj, 'contains_phraseology': filter_dict['contains_phraseology'], 'owner' : owner_obj, 'phraseologist' : phraseologist_obj, 'semanticist' : semanticist_obj, 'vocabulary' : vocabulary_obj, 'status' : status_obj, 'example_source' : nkjp_source_obj, 'approver' : approver_obj, 'reflex' : reflex_obj, 'negativity' : negativity_obj, 'predicativity' : pred_obj, 'aspect' : aspect_obj, 'argument' : filter_dict['has_argument'], 'position' : filter_dict['has_position'], 'lemma' : filter_dict['lemma'], 'schema_opinion' : schema_opinion_obj, 'sender' : sender_obj, 'schema_type' : schema_type, 'frame_opinion' : frame_opinion, 'sem_arguments' : sem_arguments} return {'filter_frames': filter_dict['filter_frames'], 'schema_type' : schema_type, 'reflex' : reflex_val, 'negativity' : negativity_val, 'predicativity': pred_val, 'opinion' : opinion_val, 'aspect' : aspect_val, 'position' : filter_dict['has_position'], 'argument' : filter_dict['has_argument']} def filter_lemmas(lemmas, filter_rules, user): lemmas = filter_by_lemma_properties(lemmas, filter_rules, user) lemmas = filter_by_schemata(lemmas, filter_rules) lemmas = filter_by_frames(lemmas, filter_rules) return lemmas def filter_by_lemma_properties(lemmas, filter_rules, user): if filter_rules['owner']: lemmas = lemmas.filter(owner=filter_rules['owner']) if filter_rules['phraseologist']: lemmas = lemmas.filter(phraseologist=filter_rules['phraseologist']) if filter_rules['semanticist']: lemmas = lemmas.filter(semanticist=filter_rules['semanticist']) if filter_rules['vocabulary']: lemmas = lemmas.filter(vocabulary=filter_rules['vocabulary']) if filter_rules['status']: lemmas = lemmas.filter(status=filter_rules['status']) if filter_rules['schema_opinion']: lemmas = lemmas.filter(frame_opinions__value=filter_rules['schema_opinion']) if filter_rules['lemma'] and filter_rules['lemma'] != '.*': lemmas = lemma_regex_filter(lemmas, filter_rules['lemma']) if filter_rules['sender']: lemmas = lemmas.filter(messages__sender=filter_rules['sender']) if filter_rules['pos']: lemmas = lemmas.filter(entry_obj__pos=filter_rules['pos']) if filter_rules['contains_phraseology']: phraseologic_lemmas = lemmas.filter(frames__phraseologic=True) if filter_rules['contains_phraseology'] == 'yes': lemmas = phraseologic_lemmas else: lemmas = lemmas.exclude(pk__in=phraseologic_lemmas) if filter_rules['example_source']: lemmas = lemmas.filter(Q(nkjp_examples__source=filter_rules['example_source']) & Q(nkjp_examples__approved=False)).distinct() napproved_examples = NKJP_Example.objects.filter(Q(source=filter_rules['example_source']) & Q(approved=False) & Q(lemmas__old=False) & ~Q(approvers=user)).distinct() if filter_rules['approver']: napproved_examples = napproved_examples.filter(approvers=filter_rules['approver']) lemmas = lemmas.filter(nkjp_examples__in=napproved_examples) lemmas = lemmas.distinct() return lemmas def lemma_regex_filter(lemmas, string): try: alternative_queries = [] for alternative in string.split('|'): possible_lemmas = lemmas for conj in alternative.split('&'): model_results = [] negation = False conj = conj.strip() if conj.startswith('!'): conj = conj.lstrip('!') negation = True regex = ur'^%s$' % escape_regex(conj) model_results = Lemma.objects.filter(old=False, entry_obj__name__regex=regex).distinct() if model_results.exists(): if negation: possible_lemmas = possible_lemmas.exclude(pk__in=model_results) else: possible_lemmas = possible_lemmas.filter(pk__in=model_results) elif not model_results.exists() and not negation: possible_lemmas = Lemma.objects.none() alternative_queries.append(Q(id__in=possible_lemmas)) lemmas = lemmas.filter(reduce(operator.or_, alternative_queries)).distinct() except: lemmas = Lemma.objects.none() return lemmas def filter_by_schemata(lemmas, filter_rules): schemata = Frame.objects if filter_rules['reflex']: schemata = schemata.filter(characteristics=filter_rules['reflex']) if filter_rules['negativity']: schemata = schemata.filter(characteristics=filter_rules['negativity']) if filter_rules['predicativity']: schemata = schemata.filter(characteristics=filter_rules['predicativity']) if filter_rules['aspect']: schemata = schemata.filter(characteristics=filter_rules['aspect']) if filter_rules['position'] and filter_rules['position'] != '.*': schemata = pos_regex_frames(schemata, filter_rules['position']) if filter_rules['argument'] and filter_rules['argument'] != '.*': schemata = arg_regex_frames(schemata, filter_rules['argument']) if filter_rules['schema_type']: schemata = get_schemata_by_type(filter_rules['schema_type'], schemata) if (filter_rules['reflex'] or filter_rules['negativity'] or filter_rules['aspect'] or filter_rules['predicativity'] or filter_rules['schema_type'] or filter_rules['schema_opinion'] or (filter_rules['argument'] and filter_rules['argument'] != '.*') or (filter_rules['position'] and filter_rules['position'] != '.*')): if filter_rules['schema_opinion']: lemmas = lemmas.filter(frame_opinions__frame__in=schemata.all(), frame_opinions__value=filter_rules['schema_opinion']) else: lemmas = lemmas.filter(frames__in=schemata.all()) lemmas = lemmas.distinct() return lemmas def pos_regex_frames(frames, string): try: alternative_queries = [] for alternative in string.split('|'): possible_frames = frames for conj in alternative.split('&'): model_results = [] negation = False conj = conj.strip() if conj.startswith('!'): conj = conj.lstrip('!') negation = True regex = ur'^%s$' % escape_regex(conj) model_results = Position.objects.filter(frames__lemmas__old=False, text_rep__regex=regex).distinct() if model_results.exists(): if negation: possible_frames = possible_frames.exclude(positions__in=model_results) else: possible_frames = possible_frames.filter(positions__in=model_results) elif not model_results.exists() and not negation: possible_frames = Frame.objects.none() alternative_queries.append(Q(id__in=possible_frames)) frames = frames.filter(reduce(operator.or_, alternative_queries)).distinct() except: frames = Frame.objects.none() return frames def arg_regex_frames(frames, string): try: alternative_queries = [] for alternative in string.split('|'): possible_frames = frames for conj in alternative.split('&'): model_results = [] negation = False conj = conj.strip() if conj.startswith('!'): conj = conj.lstrip('!') negation = True regex = ur'^%s$' % escape_regex(conj) model_results = Argument.objects.filter(positions__frames__lemmas__old=False, text_rep__regex=regex).distinct() if model_results.exists(): if negation: possible_frames = possible_frames.exclude(positions__arguments__in=model_results) else: possible_frames = possible_frames.filter(positions__arguments__in=model_results) elif not model_results.exists() and not negation: possible_frames = Frame.objects.none() alternative_queries.append(Q(id__in=possible_frames)) frames = frames.filter(reduce(operator.or_, alternative_queries)).distinct() except: frames = Frame.objects.none() return frames def filter_by_frames(lemmas, filter_rules): frames = SemanticFrame.objects.filter(next__isnull=True, removed=False) if filter_rules['frame_opinion']: frames = frames.filter(opinion=filter_rules['frame_opinion']) if filter_rules['sem_arguments']: frames = get_frames_by_args_rule(frames, filter_rules['sem_arguments']) if filter_rules['frame_opinion'] or filter_rules['sem_arguments']: lemmas = lemmas.filter(entry_obj__meanings__frames__in=frames).distinct() return lemmas def get_frames_by_args_rule(frames, args_filter_rule): matching_frames = [] for alternative in args_filter_rule: alt_matching_frames = get_matching_frames(frames, alternative) matching_frames.extend(alt_matching_frames.values_list('id', flat=True)) return frames.filter(id__in=list(set(matching_frames))) def get_matching_frames(frames, arguments_rules): for rules in arguments_rules: if not rules['negation']: frames = frames.filter(complements__in=matching_complements(rules)) else: frames = frames.exclude(complements__in=matching_complements(rules)) return frames def matching_complements(filter_rules): complements = Complement.objects if filter_rules['role']: complements = complements.filter(roles=filter_rules['role']) if filter_rules['attribute']: complements = complements.filter(roles=filter_rules['attribute']) if filter_rules['general_prefs'] or filter_rules['synset_prefs'] or filter_rules['relational_prefs']: complements = complements.filter(selective_preference__isnull=False) if filter_rules['general_prefs']: complements = filter_by_general_prefs(complements, filter_rules['general_prefs']) if filter_rules['synset_prefs']: complements = filter_by_synset_prefs(complements, filter_rules['synset_prefs']) if filter_rules['relational_prefs']: complements = filter_by_relational_prefs(complements, filter_rules['relational_prefs']) return complements.all() def filter_by_general_prefs(complements, prefs): complements = complements.exclude(selective_preference__generals=None) for pref in list(set(prefs)): if pref: complements = complements.filter(selective_preference__generals=pref) return complements def filter_by_synset_prefs(complements, prefs): complements = complements.exclude(selective_preference__synsets=None) for pref in list(set(prefs)): if pref: try: pref_parts = pref.split('-') base = pref_parts[0] sense = pref_parts[1] synset = LexicalUnit.objects.get(base=base, sense=sense).synset complements = complements.filter(selective_preference__synsets=synset) except: complements = Complement.objects.none() return complements def filter_by_relational_prefs(complements, prefs): complements = complements.exclude(selective_preference__relations=None) for pref in prefs: if pref['relation'] or pref['role'] or pref['attribute']: relational_prefs = RelationalSelectivePreference.objects if pref['relation']: relational_prefs = relational_prefs.filter(relation=pref['relation']) if pref['role'] or pref['attribute']: to_complements = Complement.objects if pref['role']: to_complements = to_complements.filter(roles=pref['role']) if pref['attribute']: to_complements = to_complements.filter(roles=pref['attribute']) relational_prefs = relational_prefs.filter(to__in=to_complements.all()).distinct() complements = complements.filter(selective_preference__relations__in=relational_prefs).distinct() return complements