diff --git a/dictionary/ajax_lemma_view.py b/dictionary/ajax_lemma_view.py index 4a42a1b..b2c5067 100644 --- a/dictionary/ajax_lemma_view.py +++ b/dictionary/ajax_lemma_view.py @@ -12,6 +12,7 @@ from django.contrib.auth.models import User, Group from django.core import serializers from common.js_to_obj import frameObjToSerializableDict, jsArgToObj, jsFrameToObj, jsPosToObj +from dictionary.common_func import escape_regex from dictionary.convert_frames import frame_conversion from dictionary.filtering import default_filter_rules, prepare_filter_form, \ save_lemma_filters_and_get_schemata_filter_setup, \ @@ -29,7 +30,7 @@ from dictionary.models import Vocabulary, Lemma, Lemma_Status, Frame_Opinion, \ sortFrameChars, sortArguments, sortPositions, \ get_or_create_position, get_schemata_by_type, pos_compatible from dictionary.forms import AddPositionForm, FrameForm, Pos_Cat_Form, \ - AddNkjpExampleForm, MessageForm, SortForm, FilterForm, \ + AddNkjpExampleForm, MessageForm, SortForm, \ SimilarLemmasNewForm, ChangeUserFunctionForm, \ ExampleOpinionForm, \ FrameConversionForm, CreatePositionForm, AssignPhraseologicFrameForm @@ -39,6 +40,7 @@ from dictionary.saving import connect_example_operation, disconnect_all_examples from common.decorators import render, ajax, AjaxError from common.util import triple_arg_poss +from dictionary.filtering import filter_lemmas from dictionary.validation import find_similar_frames, get_all_test_missing_frames, get_aspect_rel_lemmas, \ get_wrong_aspect_frames, validate_B_frames, get_deriv_miss_frames_message, \ validate_phraseology_binded_frames, validate_rule_5, \ @@ -46,7 +48,7 @@ from dictionary.validation import find_similar_frames, get_all_test_missing_fram validate_schemata_for_semantics_and_mark_errors, \ get_missing_aspects_msg, validate_same_positions_schemata -from semantics.models import LexicalUnitExamples +from semantics.models import LexicalUnitExamples, SemanticFrame from wordnet.models import LexicalUnit @@ -147,7 +149,7 @@ def prepareFrameTable(frame): def nkjpExamplesObjToJs(nkjp_examples, user, lemma): example_dict_list = [] - lexical_units = lemma.entry_obj.lexical_units() + lexical_units = lemma.entry_obj.meanings.all() for example in nkjp_examples: frame = example.frame; frame_table_id = 'frame_'+str(frame.id)+'_' @@ -168,11 +170,6 @@ def nkjpExamplesObjToJs(nkjp_examples, user, lemma): sentence = example.sentence comment = example.comment -# sentence = example.sentence.replace('\\', '\\\\').replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\"", "\\\"") -# comment = example.comment.replace('\\', '\\\\').replace("\n", "\\n").replace("\r", "\\r").replace("\t", "\\t").replace("\"", "\\\"") -# h = HTMLParser.HTMLParser() -# sentence = h.unescape(sentence) -# comment = h.unescape(comment) example_dict = { 'example_id' : example.id, 'frame_id' : frame_table_id, @@ -423,11 +420,7 @@ def examples_pinned(frame, schema_examples): @ajax(method='get') def example_got_assigned_semantics(request, lemma_id, example_id): lemma = Lemma.objects.get(id=lemma_id) -# sprawdz czy najnowsza wersja -# if lemma.old: -# raise AjaxError('old lemma') - # TODO niech lexical units beda wybierane z uzyciem Entry jak juz Tomasz to zrobi - lexical_units = LexicalUnit.objects.filter(Q(base = lemma.entry)|Q(base = lemma.entry + u' się')) + lexical_units = lemma.entry_obj.meanings.all() for lu in lexical_units: if LexicalUnitExamples.objects.filter(example__id=example_id, lexical_unit=lu).exists(): @@ -789,8 +782,7 @@ def get_sort_order(request): @render('filter_form.html') @ajax(method='get', encode_result=False) def filter_form(request): - form = prepare_filter_form(request) - return {'form': form} + return prepare_filter_form(request) @ajax(method='post') def filter_form_submit(request, form_data): @@ -1355,10 +1347,7 @@ def get_default_char_value(possibilities): value = possibilities.get(default=True) except Frame_Char_Value.DoesNotExist: value = possibilities.all()[0] - return value - -def escape_regex(string): - return string.replace('(', '\(').replace(')', '\)').replace('{', '\{').replace('}', '\}').replace('[', '\[').replace(']', '\]') + return value def regex_query(string): q_query = [] @@ -2336,7 +2325,7 @@ def save_new_frames(request, data, id, examples, lemma_examples): reconnect_examples_operations.remove(disconnect_example_operation(example, nkjp_example_obj)) except ValueError: reconnect_examples_operations.append(connect_example_operation(example, nkjp_example_obj)) - reconnect_examples(reconnect_examples_operations) + reconnect_examples(new_lemma_ver, reconnect_examples_operations) # dodawanie przykladow nkjp do czasownika for example in decoded_lemma_examples: @@ -2607,90 +2596,6 @@ def prepare_sort_rules(sort_rules): prepared_sort_rules.append(rule['name']) return prepared_sort_rules -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 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 get_lemma_query(prepared_sort_rules, filter_rules, lemma_query, user): lemmas = Lemma.objects.none() if user.is_authenticated(): @@ -2711,72 +2616,8 @@ def get_lemma_query(prepared_sort_rules, filter_rules, lemma_query, user): lemmas = lemmas.filter(reduce(operator.or_, q_vocab_list)) lemmas = lemmas.filter(reduce(operator.or_, q_status_list)) - ## filtrowanie - 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['frame_opinion']: - lemmas = lemmas.filter(frame_opinions__value=filter_rules['frame_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() - - frames = Frame.objects - if filter_rules['reflex']: - frames = frames.filter(characteristics=filter_rules['reflex']) - if filter_rules['negativity']: - frames = frames.filter(characteristics=filter_rules['negativity']) - if filter_rules['predicativity']: - frames = frames.filter(characteristics=filter_rules['predicativity']) - if filter_rules['aspect']: - frames = frames.filter(characteristics=filter_rules['aspect']) - if filter_rules['position'] and filter_rules['position'] != '.*': - frames = pos_regex_frames(frames, filter_rules['position']) - if filter_rules['argument'] and filter_rules['argument'] != '.*': - frames = arg_regex_frames(frames, filter_rules['argument']) - if filter_rules['schema_type']: - frames = get_schemata_by_type(filter_rules['schema_type'], frames) - - if (filter_rules['reflex'] or filter_rules['negativity'] or - filter_rules['aspect'] or filter_rules['predicativity'] or - filter_rules['schema_type'] or filter_rules['frame_opinion'] or - (filter_rules['argument'] and filter_rules['argument'] != '.*') or - (filter_rules['position'] and filter_rules['position'] != '.*')): - if filter_rules['frame_opinion']: - lemmas = lemmas.filter(frame_opinions__frame__in=frames.all(), - frame_opinions__value=filter_rules['frame_opinion']).distinct() - else: - lemmas = lemmas.filter(frames__in=frames.all()).distinct() - - lemmas = lemmas.distinct() + ## filtrowanie + lemmas = filter_lemmas(lemmas, filter_rules, user) ## sortowanie entrySortDefined = False diff --git a/dictionary/common_func.py b/dictionary/common_func.py index ad4931d..612a426 100644 --- a/dictionary/common_func.py +++ b/dictionary/common_func.py @@ -1,25 +1,5 @@ #-*- coding:utf-8 -*- -#Copyright (c) 2012, 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. - ''' Common functions used in Slowal application. ''' @@ -131,4 +111,6 @@ def have_same_positions_structure(pos1, pos2): if(pos1_args == pos2_args and pos1_cats==pos2_cats): same_structure = True return same_structure - + +def escape_regex(string): + return string.replace('(', '\(').replace(')', '\)').replace('{', '\{').replace('}', '\}').replace('[', '\[').replace(']', '\]') diff --git a/dictionary/filtering.py b/dictionary/filtering.py index d308bd8..c5939be 100644 --- a/dictionary/filtering.py +++ b/dictionary/filtering.py @@ -1,12 +1,22 @@ # -*- 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 Frame_Char_Model, Frame_Opinion_Value, Lemma_Status, \ - NKJP_Source, POS, Vocabulary, \ - get_frame_char_and_its_value +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 @@ -70,9 +80,11 @@ def default_filter_rules(): 'aspect': None, 'argument': '.*', 'position': '.*', - 'frame_opinion' : None, + 'schema_opinion' : None, 'sender': None, - 'schema_type': 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']: @@ -121,13 +133,60 @@ def prepare_filter_form(request): sel_aspect=filter_rules['aspect'], sel_has_argument=filter_rules['argument'], sel_has_position=filter_rules['position'], - sel_frame_opinion=filter_rules['frame_opinion'], + 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']) - return form + 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']: @@ -183,17 +242,28 @@ def save_lemma_filters_and_get_schemata_filter_setup(request, filter_dict): 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['frame_opinion']: - frame_opinion_obj = Frame_Opinion_Value.objects.get(id=filter_dict['frame_opinion']) - opinion_val = frame_opinion_obj.value + 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: - frame_opinion_obj = None + schema_opinion_obj = None opinion_val = '*' if 'schema_type' in filter_dict: schema_type = filter_dict['schema_type'] else: schema_type = None + + if filter_dict['frame_opinion']: + frame_opinion = FrameOpinion.objects.get(id=filter_dict['frame_opinion']) + else: + frame_opinion = None + + if filter_dict['sem_arguments']: + sem_arguments = filter_dict['sem_arguments'] + else: + sem_arguments = [] + 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'], @@ -211,9 +281,11 @@ def save_lemma_filters_and_get_schemata_filter_setup(request, filter_dict): 'argument' : filter_dict['has_argument'], 'position' : filter_dict['has_position'], 'lemma' : filter_dict['lemma'], - 'frame_opinion' : frame_opinion_obj, + 'schema_opinion' : schema_opinion_obj, 'sender' : sender_obj, - 'schema_type' : schema_type} + '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'], @@ -231,9 +303,11 @@ def save_lemma_filters_and_get_schemata_filter_setup(request, filter_dict): 'argument' : filter_dict['has_argument'], 'position' : filter_dict['has_position'], 'lemma' : filter_dict['lemma'], - 'frame_opinion' : frame_opinion_obj, + 'schema_opinion' : schema_opinion_obj, 'sender' : sender_obj, - 'schema_type' : schema_type} + 'schema_type' : schema_type, + 'frame_opinion' : frame_opinion, + 'sem_arguments' : sem_arguments} return {'filter_frames': filter_dict['filter_frames'], 'schema_type' : schema_type, @@ -244,3 +318,242 @@ def save_lemma_filters_and_get_schemata_filter_setup(request, filter_dict): '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 + \ No newline at end of file diff --git a/dictionary/forms.py b/dictionary/forms.py index 9680663..e108e82 100644 --- a/dictionary/forms.py +++ b/dictionary/forms.py @@ -1,25 +1,5 @@ #-*- coding:utf-8 -*- -#Copyright (c) 2012, 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. - import datetime from django.contrib.auth.forms import UserCreationForm @@ -28,6 +8,7 @@ from django.db.models import Q from django.forms import * from dictionary.models import * +from semantics.models import FrameOpinion #Frame, Argument_Model, AttrValueSelectionMode, \ # AttrValuesSeparator, Atribute_Value, PositionCategory, \ # Argument, Atribute_Model, ArgRealOpinion, Frame_Characteristic, \ @@ -530,11 +511,6 @@ class MessageForm(ModelForm): ############################ sorting, filtering - -#trzeba dodac jeszcze opcje, ze zawiera tylko normalne hasla -#no i filtrowanie po lematach z wykorzystaniem wyrazen regularnych -# rozbić to wszystko na 3 zakładki Hasło, Schematy, Ramy -# no i oczywiście dodać te pola do filtrowania schematów class FilterForm(Form): # Lemma filters @@ -571,14 +547,13 @@ class FilterForm(Form): required=False) has_argument = forms.CharField(label=u'Zawiera typ frazy', required=False) has_position = forms.CharField(label=u'Zawiera pozycję', required=False) - frame_opinion = ModelChoiceField(label=u'Opinia o schemacie', queryset=Frame_Opinion_Value.objects.all(), - required=False) + schema_opinion = ModelChoiceField(label=u'Opinia o schemacie', queryset=Frame_Opinion_Value.objects.all(), + required=False) filter_frames = forms.BooleanField(label=u'Odfiltruj niepasujące schematy', initial=False, required=False) # Frame filters -# role = -# selective_preferences = -# opinion = + frame_opinion = ModelChoiceField(label=u'Opinia o ramie', queryset=FrameOpinion.objects.order_by('priority'), + required=False) def __init__(self, users, phraseologists, semanticists, vocabularies, statuses, senders, lemma='.*', sel_pos=None, contains_phraseology=None, @@ -586,8 +561,9 @@ class FilterForm(Form): sel_vocabulary=None, sel_status=None, sel_schema_type=None, sel_reflex=None, sel_negativity=None, sel_predicativity=None, sel_aspect=None, sel_has_argument='.*', sel_has_position='.*', - sel_frame_opinion=None, can_confirm_example=False, sel_example_source=None, - sel_approver=None, sel_sender=None, *args, **kwargs): + sel_schema_opinion=None, can_confirm_example=False, sel_example_source=None, + sel_approver=None, sel_sender=None, + sel_frame_opinion=None, *args, **kwargs): super(FilterForm, self).__init__(*args, **kwargs) self.fields['pos'].queryset = POS.objects.exclude(tag='unk') @@ -612,23 +588,20 @@ class FilterForm(Form): self.fields['example_source'].initial = None self.fields['approver'].widget = self.fields['approver'].hidden_widget() self.fields['approver'].initial = None -# self.fields['has_old_frames_property'].initial = sel_old_property self.fields['reflex'].initial = sel_reflex self.fields['negativity'].initial = sel_negativity self.fields['predicativity'].initial = sel_predicativity self.fields['aspect'].initial = sel_aspect self.fields['has_argument'].initial = sel_has_argument self.fields['has_position'].initial = sel_has_position - #self.fields['has_frame'].initial = sel_has_frame - self.fields['frame_opinion'].initial = sel_frame_opinion + self.fields['schema_opinion'].initial = sel_schema_opinion self.fields['has_message_from'].initial = sel_sender self.fields['has_message_from'].queryset = senders self.fields['schema_type'].initial = sel_schema_type + self.fields['frame_opinion'].initial = sel_frame_opinion self.hide_unused_fields() - - #self.fields['has_frame'].widget = self.fields['has_frame'].hidden_widget() def hide_unused_fields(self): for field_name in self.fields: diff --git a/dictionary/models.py b/dictionary/models.py index 941cfd6..ce91815 100644 --- a/dictionary/models.py +++ b/dictionary/models.py @@ -1,30 +1,8 @@ #-*- coding:utf-8 -*- -#Copyright (c) 2012, 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 django.contrib.auth.models import User from django.db.models import * -from wordnet.models import LexicalUnit - class Configuration(Model): name = CharField(max_length=16, primary_key=True, unique=True, db_column='nazwa_konfiguracji') selected_conf = BooleanField(db_column='wybrana_konfiguracja', default=False) @@ -766,13 +744,6 @@ class Argument(Model): break return is_fully_lexicalized - class Meta: - permissions = ( - ('view_realization', u'Może oglądać realizacje argumentów.'), - ('create_realization', u'Może kreować realizacje argumentów.'), - ('view_arg_stats', u'Może oglądać statystyki argumentów.'), - ) - def __unicode__(self): return '%s' % (self.text_rep) @@ -785,7 +756,21 @@ class Argument(Model): for value in attr.values.filter(type__sym_name=u'parameter'): if value.parameter.type.realization_only: return True - return False + return False + + def main_phrase_type(self): + category_attrs = self.atributes.filter(type=u'KATEGORIA') + if not category_attrs.exists() or category_attrs.all()[0].values.count() == 0: # xp bez podtypow + return self + else: + return Argument.objects.get(text_rep=u'%s(%s)' % (self.type, category_attrs.all()[0].selection_mode.name)) + + class Meta: + permissions = ( + ('view_realization', u'Może oglądać realizacje argumentów.'), + ('create_realization', u'Może kreować realizacje argumentów.'), + ('view_arg_stats', u'Może oglądać statystyki argumentów.'), + ) def sort_arguments(arguments): return sortArguments(arguments) @@ -1403,12 +1388,9 @@ class Entry(Model): ('view_semantics', u'Może oglądać semantykę.'), ) - def lexical_units(self): - return LexicalUnit.objects.filter(Q(base = self.name)|Q(base = self.name + u' się')) - def actual_frames(self): frame_ids = [] - lexical_units = self.lexical_units().order_by('sense') + lexical_units = self.meanings.order_by('sense') for lexical_unit in lexical_units: frame_ids.extend([f.id for f in lexical_unit.actual_frames()]) return get_model('semantics', 'SemanticFrame').objects.filter(id__in=list(set(frame_ids))) diff --git a/dictionary/saving.py b/dictionary/saving.py index f0bf09c..495f479 100644 --- a/dictionary/saving.py +++ b/dictionary/saving.py @@ -94,7 +94,7 @@ def update_connections(lemma_id, reconnect_operations, user): def disconnect_all_examples_operations(lemma): operations = [] - lex_units = lemma.entry_obj.lexical_units().all() + lex_units = lemma.entry_obj.meanings.all() for lu in lex_units: lu_examples = LexicalUnitExamples.objects.filter(lexical_unit=lu) for lu_ex in lu_examples: @@ -112,6 +112,6 @@ def disconnect_example_operation(example_dict, example_obj): lu = LexicalUnit.objects.get(id=example_dict['lexical_unit']) return {'operation': 'remove_example', 'unit': lu.id, 'example': example_obj.id} -def reconnect_examples(operations): - update_meanings(operations) +def reconnect_examples(lemma, operations): + update_meanings(lemma.id, operations) \ No newline at end of file diff --git a/dictionary/static/css/lemmas_filtering.css b/dictionary/static/css/lemmas_filtering.css new file mode 100644 index 0000000..268017c --- /dev/null +++ b/dictionary/static/css/lemmas_filtering.css @@ -0,0 +1,11 @@ +hr.filtersSeparator { + border-top: medium double #333; +} + +hr.argSeparator { + border-top: 1px dashed #8c8b8b; +} + +hr.alterSeparator { + border-top: 1px solid #8c8b8b; +} diff --git a/dictionary/static/js/lemmas_filtering.js b/dictionary/static/js/lemmas_filtering.js index ab1cf89..2e1ef19 100644 --- a/dictionary/static/js/lemmas_filtering.js +++ b/dictionary/static/js/lemmas_filtering.js @@ -3,15 +3,74 @@ function filter_form_submit() { form_data = this_form.serializeArray(); var filter_frames = false; + var actSemArgument = {}; + var relationalSemPref = {'relation': '', + 'role': '', + 'attribute': ''}; + var semArgumentsAlternatives = []; + var semArguments = []; form_data = $.map(form_data, function(elem) { - if (elem.name != 'filter_frames') return elem; + if (elem.name != 'filter_frames' && !isPartOfSemArgFilter(elem)) { + return elem; + } else { - if (elem.name == 'filter_frames') filter_frames = elem.value; + if(elem.name == 'filter_frames') { + filter_frames = elem.value; + } + else if(elem.name == 'negation') { + if(!jQuery.isEmptyObject(actSemArgument)) { + semArguments.push(actSemArgument); + } + actSemArgument = {'negation': elem.value, + 'role': '', + 'attribute': '', + 'general_prefs': [], + 'synset_prefs': [], + 'relational_prefs': []} + } + else if(elem.name == 'or') { + if(!jQuery.isEmptyObject(actSemArgument)) { + semArguments.push(actSemArgument); + actSemArgument = {}; + } + semArgumentsAlternatives.push(semArguments); + semArguments = []; + } + else if(elem.name == 'role' || elem.name == 'attribute') { + actSemArgument[elem.name] = elem.value; + } + else if(elem.name == 'general_pref' || elem.name == 'synset_pref') { + actSemArgument[elem.name+'s'].push(elem.value); + } + else if(elem.name.startsWith('relational_pref')) { + if(elem.name.endsWith('relation')) { + relationalSemPref = {'relation': elem.value, + 'role': '', + 'attribute': ''}; + } + else if(elem.name.endsWith('role')) { + relationalSemPref['role'] = elem.value; + } + else if(elem.name.endsWith('attribute')) { + relationalSemPref['attribute'] = elem.value; + actSemArgument['relational_prefs'].push(relationalSemPref); + relationalSemPref = {}; + } + } } }); + if(!jQuery.isEmptyObject(actSemArgument)) { + semArguments.push(actSemArgument); + } + if(semArguments.length > 0) { + semArgumentsAlternatives.push(semArguments); + } + + form_data.push({name: 'filter_frames', value: filter_frames}); + form_data.push({name: 'sem_arguments', value: semArgumentsAlternatives}); act_lemma_id = window.prev_lemma_id; if(window.activeLemmaPanel != 'preview_lemma') @@ -82,3 +141,51 @@ function filter_form_submit() { }); return false; } + +function isPartOfSemArgFilter(field) { + if(field.name == 'or' || field.name == 'negation' || + field.name == 'role' || field.name == 'attribute' || + field.name == 'general_pref' || field.name == 'synset_pref' || + field.name.startsWith('relational_pref')) { + return true; + } + return false; +} + +function addSemArgFilter(buttonElem) { + var semArgsElem = $(buttonElem).parent().parent(); + semArgsElem.append('<p id="sem-argument"></p>'); + semArgsElem.children().last().load(ajax_sem_arg_form); +} + +function addArgAlternative(buttonElem) { + var semArgsElem = $(buttonElem).parent().parent(); + semArgsElem.append('<div><hr class="alterSeparator"><input type="hidden" name="or" value="or"><strong>lub</strong> <button type="button" onclick="removeAlternative(this)">Usuń</button></div>'); +} + +function removeAlternative(buttonElem) { + $(buttonElem).parent().remove(); +} + +function removeSemArgFilter(buttonElem) { + $(buttonElem).parent().parent().remove(); +} + +function addSelectivePreferenceFilter(buttonElem) { + var selPrefsElem = $(buttonElem).parent().parent(); + var selPrefType = selPrefsElem.find('#id_preference_type').first().val(); + selPrefsElem.append('<p id="sel-preference"></p>'); + if(selPrefType === 'general') { + selPrefsElem.children().last().load(ajax_general_preference_form); + } + else if(selPrefType === 'synset') { + selPrefsElem.children().last().load(ajax_synset_preference_form); + } + else if(selPrefType === 'relation') { + selPrefsElem.children().last().load(ajax_relational_preference_form); + } +} + +function removeSelPreferenceFilter(buttonElem) { + $(buttonElem).parent().remove(); +} diff --git a/dictionary/teixml.py b/dictionary/teixml.py index 46cdf50..d14590b 100644 --- a/dictionary/teixml.py +++ b/dictionary/teixml.py @@ -437,7 +437,7 @@ def write_example(parent_elem, lemma, example): def get_and_write_meaning_link(parent_elem, entry, example): try: - entry_lex_units = entry.lexical_units() + entry_lex_units = entry.meanings.all() lex_unit_example = LexicalUnitExamples.objects.get(example=example, lexical_unit__in=entry_lex_units) meaning = lex_unit_example.lexical_unit @@ -674,8 +674,7 @@ def write_meanings_layer(parent_elem, lemma): def write_meanings(parent_elem, lemma): entry = lemma.entry_obj - lex_units = entry.lexical_units() - for lex_unit in lex_units.all(): + for lex_unit in entry.meanings.all(): write_meaning(parent_elem, entry, lex_unit) def write_meaning(parent_elem, entry, lex_unit): diff --git a/dictionary/templates/filter_form.html b/dictionary/templates/filter_form.html index 93c9795..8fbe57f 100644 --- a/dictionary/templates/filter_form.html +++ b/dictionary/templates/filter_form.html @@ -47,6 +47,7 @@ $(function(){ <ul> <li><a href="#lemma-filters">Hasło</a></li> <li><a href="#schema-filters">Schematy</a></li> + <li><a href="#frame-filters">Ramy</a></li> </ul> <div id="lemma-filters"> {% if not form.lemma.is_hidden %} @@ -68,7 +69,7 @@ $(function(){ </p> {% endif %} {% if not form.owner.is_hidden or not form.phraseologist.is_hidden or not form.semanticist.is_hidden %} - <hr> + <hr class="filtersSeparator"> {% endif %} {% if not form.owner.is_hidden %} <p class="fieldWrapper"> @@ -89,7 +90,7 @@ $(function(){ </p> {% endif %} {% if not form.vocabulary.is_hidden or not form.status.is_hidden or not form.has_message_from.is_hidden %} - <hr> + <hr class="filtersSeparator"> {% endif %} {% if not form.vocabulary.is_hidden %} <p class="fieldWrapper"> @@ -110,7 +111,7 @@ $(function(){ </p> {% endif %} {% if not form.example_source.is_hidden or not form.approver.is_hidden %} - <hr> + <hr class="filtersSeparator"> {% endif %} {% if not form.example_source.is_hidden %} <p class="fieldWrapper"> @@ -126,10 +127,10 @@ $(function(){ {% endif %} </div> <div id="schema-filters"> - {% if not form.frame_opinion.is_hidden %} + {% if not form.schema_opinion.is_hidden %} <p class="fieldWrapper"> - {{ form.frame_opinion.errors }} - {{ form.frame_opinion.label_tag }}: {{ form.frame_opinion }} + {{ form.schema_opinion.errors }} + {{ form.schema_opinion.label_tag }}: {{ form.schema_opinion }} </p> {% endif %} {% if not form.schema_type.is_hidden %} @@ -181,6 +182,26 @@ $(function(){ </p> {% endif %} </div> + <div id="frame-filters"> + {% if not form.frame_opinion.is_hidden %} + <p class="fieldWrapper"> + {{ form.frame_opinion.errors }} + {{ form.frame_opinion.label_tag }}: {{ form.frame_opinion }} + </p> + {% endif %} + <hr class="filtersSeparator"> + <div id="sem-arguments"> + <p>Argumenty semantyczne: + <button type="button" onclick="addSemArgFilter(this)">Dodaj</button> + <button type="button" onclick="addArgAlternative(this)">Lub</button> + </p> + {% for arg_form in sem_args_forms %} + <div id="sem-argument"> + {% include 'sem_arg_form.html' with form=arg_form only %} + </div> + {% endfor %} + </div> + </div> </div> {% for hidden in form.hidden_fields %} {{ hidden }} diff --git a/dictionary/templates/lemma_view.html b/dictionary/templates/lemma_view.html index 0f2fb4d..ed50f1e 100644 --- a/dictionary/templates/lemma_view.html +++ b/dictionary/templates/lemma_view.html @@ -9,6 +9,7 @@ <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/examples_table.css"/> <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/aspect_relations_table.css"/> <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/filter_frames_menu.css"/> + <link rel="stylesheet" type="text/css" href="{{ STATIC_URL }}css/lemmas_filtering.css"/> <script type="text/javascript" src="{{ STATIC_URL }}js/lib/grid.locale-pl.js"></script> <script type="text/javascript"> jQuery.jgrid.no_legacy_api = true; @@ -62,9 +63,7 @@ <ul> <li id="refresh_frames"><a href="#new_frames">{% trans "Schematy" %} [<span id="new-frames-count"></span>]</a></li> - {% if perms.dictionary.view_semantics %} - <li><a href="#semantics">{% trans "Semantyka" %} [<span id="semantic-frames-count"></span>]</a></li> - {% endif %} + <li><a href="#semantics">{% trans "Semantyka" %} [<span id="semantic-frames-count"></span>]</a></li> <!-- li><a href="#old_frames">{% trans "Stare schematy" %}</a></li --> {% if perms.dictionary.add_notes %} <li><a href="#notes">{% trans "Notatki" %} [<span id="lemma-notes-count"></span>]</a></li> @@ -81,10 +80,8 @@ </ul> <div id="new_frames"> </div> - {% if perms.dictionary.view_semantics %} - <div id="semantics"> - </div> - {% endif %} + <div id="semantics"> + </div> {% if perms.dictionary.add_notes %} <div id="notes"> </div> diff --git a/dictionary/views.py b/dictionary/views.py index 7c6e9a0..a269ee8 100644 --- a/dictionary/views.py +++ b/dictionary/views.py @@ -1,25 +1,5 @@ #-*- coding:utf-8 -*- -#Copyright (c) 2012, 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. - import datetime import os @@ -212,6 +192,11 @@ def lemma_view(request): 'ajax_save_columns': reverse('save_columns'), 'ajax_save_columns': reverse('save_columns'), 'ajax_get_sort_order': reverse('get_sort_order'), + 'ajax_sem_arg_form': reverse('sem_arg_form'), + 'ajax_general_preference_form': reverse('general_preference_form'), + 'ajax_synset_preference_form': reverse('synset_preference_form'), + 'ajax_relational_preference_form': reverse('relational_preference_form'), + 'ajax_synset_context_lookup': reverse('synset_context_lookup'), # czasowniki podobne 'ajax_similar_lemmas_old_form_submit': reverse('similar_lemmas_old_form_submit'), diff --git a/semantics/change_log.py b/semantics/change_log.py index b9c0e1b..87f12c8 100644 --- a/semantics/change_log.py +++ b/semantics/change_log.py @@ -179,7 +179,7 @@ def backup_lemma_and_get_frames(lemma): def backup_lemma(lemma_id): lemma = Lemma.objects.get(id=lemma_id, old=False) - lexical_units = LexicalUnit.objects.filter(Q(base = lemma.entry)|Q(base = lemma.entry + u' się')).order_by('sense') + lexical_units = lemma.entry_obj.meanings.order_by('sense') frame_ids = [] for lexical_unit in lexical_units: diff --git a/semantics/forms.py b/semantics/forms.py new file mode 100644 index 0000000..a1d3ddd --- /dev/null +++ b/semantics/forms.py @@ -0,0 +1,64 @@ +#-*- coding:utf-8 -*- + +from django.forms import CharField, ChoiceField, Form, ModelChoiceField + +from semantics.models import GeneralSelectivePreference, SelectivePreferenceRelations, SemanticRole + +class RoleForm(Form): + negation = ChoiceField(choices=[('', u'---'), ('!', u'!')], required=False, + label=u'') + role = ModelChoiceField(label=u'Rola', required=False, + queryset=SemanticRole.objects.filter(gradient__isnull=True)) + attribute = ModelChoiceField(label=u'Atrybut', required=False, + queryset=SemanticRole.objects.filter(gradient__isnull=False)) + preference_type = ChoiceField(choices=[('general', u'Predefiniowana'), ('synset', u'Słowosieć'), ('relation', u'Relacja')], + label=u'Preferencje selekcyjne', required=False) + preferences = [] + + def __init__(self, negation=None, sel_role=None, sel_attribute=None, + sel_preferences=[], + *args, **kwargs): + super(RoleForm, self).__init__(*args, **kwargs) + self.fields['negation'].initial = negation + self.fields['role'].initial = sel_role + self.fields['attribute'].initial = sel_attribute + self.preferences = sel_preferences + +class GeneralSelPrefForm(Form): + general_pref = ModelChoiceField(label=u'Predefiniowana', + queryset=GeneralSelectivePreference.objects.order_by('name'), required=False) + + def pref_type(self): + return 'general' + + def __init__(self, sel_preference=None, *args, **kwargs): + super(GeneralSelPrefForm, self).__init__(*args, **kwargs) + self.fields['general_pref'].initial = sel_preference + +class SynsetSelPrefForm(Form): + synset_pref = CharField(label=u'Słowosieć', required=False) + + def pref_type(self): + return 'synset' + + def __init__(self, sel_preference=None, *args, **kwargs): + super(SynsetSelPrefForm, self).__init__(*args, **kwargs) + self.fields['synset_pref'].initial = sel_preference + +class RelationalSelPrefForm(Form): + relational_pref_relation = ModelChoiceField(label=u'Relacja', + queryset=SelectivePreferenceRelations.objects.all(), required=False) + relational_pref_role = ModelChoiceField(label=u'Rola', required=False, + queryset=SemanticRole.objects.filter(gradient__isnull=True)) + relational_pref_attribute = ModelChoiceField(label=u'Atrybut', required=False, + queryset=SemanticRole.objects.filter(gradient__isnull=False)) + + def pref_type(self): + return 'relational' + + def __init__(self, sel_relation=None, sel_role=None, sel_attribute=None, *args, **kwargs): + super(RelationalSelPrefForm, self).__init__(*args, **kwargs) + self.fields['relational_pref_relation'].initial = sel_relation + self.fields['relational_pref_role'].initial = sel_role + self.fields['relational_pref_attribute'].initial = sel_attribute + \ No newline at end of file diff --git a/semantics/saving.py b/semantics/saving.py index 9afb9d7..8cec66d 100644 --- a/semantics/saving.py +++ b/semantics/saving.py @@ -2,7 +2,7 @@ from django.db.models import Min -from dictionary.models import Argument, Frame, NKJP_Example, Position +from dictionary.models import Argument, Frame, Lemma, NKJP_Example, Position from semantics.change_log import store_old_versions from semantics.models import Complement, GeneralSelectivePreference, FramePosition,\ LexicalUnitExamples, RelationalSelectivePreference, \ @@ -278,8 +278,9 @@ def remove_preference(frame_id, complement_id, preference): complement.selective_preference.relations.remove(r) -def update_meanings(operations): +def update_meanings(lemma_id, operations): translation = {} + entry = Lemma.objects.get(id=lemma_id).entry_obj for operation in operations: if operation['operation'] == "set_glossa": if int(operation['unit']) in translation: @@ -300,7 +301,7 @@ def update_meanings(operations): unit = int(operation['unit']) remove_example(unit, operation['example']) elif operation['operation'] == "add_unit": - translation[operation['unit']['id']] = add_unit(operation['unit']) + translation[operation['unit']['id']] = add_unit(entry, operation['unit']) elif operation['operation'] == "remove_unit": luid = int(operation['luid']) if luid in translation: @@ -327,11 +328,11 @@ def remove_example(unit_id, example_id): lue = LexicalUnitExamples.objects.get(example=nkjp_example, lexical_unit=unit) lue.delete() -def add_unit(unit): # returns new id +def add_unit(entry, unit): # returns new id s1 = Synset(id=(min(Synset.objects.all().aggregate(Min('id'))['id__min'], 0) - 1)) s1.save() - lu = LexicalUnit(base=unit['base'], sense=unit['sense'], pos=unit['pos'], glossa=unit['glossa'], luid=-1, synset=s1) + lu = LexicalUnit(entry=entry, base=unit['base'], sense=unit['sense'], pos=unit['pos'], glossa=unit['glossa'], luid=-1, synset=s1) lu.save() diff --git a/semantics/sem_urls.py b/semantics/sem_urls.py index 2ee28d9..8917c2b 100644 --- a/semantics/sem_urls.py +++ b/semantics/sem_urls.py @@ -19,5 +19,10 @@ SEMANTIC_PATTERNS = patterns('semantics.views', url(r'^ajax/update_meanings/$', 'ajax_update_meanings'), url(r'^ajax/modify_frames/$', 'ajax_modify_frames'), url(r'^ajax/plWN_context_lookup/$', 'ajax_plWN_context_lookup'), + url(r'^ajax/synset_context_lookup/$', 'synset_context_lookup'), url(r'^ajax/validate_semantics/$', 'validate_semantics'), + url(r'^ajax/sem_arg_form/$', 'sem_arg_form'), + url(r'^ajax/general_preference_form/$', 'general_preference_form'), + url(r'^ajax/synset_preference_form/$', 'synset_preference_form'), + url(r'^ajax/relational_preference_form/$', 'relational_preference_form'), ) diff --git a/semantics/templates/general_preference_form.html b/semantics/templates/general_preference_form.html new file mode 100644 index 0000000..869dd65 --- /dev/null +++ b/semantics/templates/general_preference_form.html @@ -0,0 +1,4 @@ +<p class="fieldWrapper"> + {{ form.general_pref.errors }} + {{ form.general_pref.label_tag }}: {{ form.general_pref }} + <button type="button" onclick="removeSelPreferenceFilter(this)">Usuń</button> +</p> \ No newline at end of file diff --git a/semantics/templates/relational_preference_form.html b/semantics/templates/relational_preference_form.html new file mode 100644 index 0000000..2bc360f --- /dev/null +++ b/semantics/templates/relational_preference_form.html @@ -0,0 +1,6 @@ +<p class="fieldWrapper"> + {{ form.relational_pref_relation.errors }} + {{ form.relational_pref_relation.label_tag }}: {{ form.relational_pref_relation }} + {{ form.relational_pref_role.errors }} Do: {{ form.relational_pref_role }} + {{ form.relational_pref_attribute.errors }} {{ form.relational_pref_attribute }} + <button type="button" onclick="removeSelPreferenceFilter(this)">Usuń</button> +</p> \ No newline at end of file diff --git a/semantics/templates/sem_arg_form.html b/semantics/templates/sem_arg_form.html new file mode 100644 index 0000000..4e2707a --- /dev/null +++ b/semantics/templates/sem_arg_form.html @@ -0,0 +1,29 @@ +{% if form == 'or' %} + <div> + <hr class="alterSeparator"> + <input type="hidden" name="or" value="or"><strong>lub</strong> + <button type="button" onclick="removeAlternative(this)">Usuń</button> + </div> +{% else %} + <hr class="argSeparator"> + <p class="fieldWrapper"> + {{ form.negation.errors }} {{ form.negation }} + {{ form.role.errors }} {{ form.role.label_tag }}: {{ form.role }} + {{ form.attribute.errors }} {{ form.attribute.label_tag }}: {{ form.attribute }} + <button type="button" onclick="removeSemArgFilter(this)">Usuń</button> + </p> + <div id="selectional-preferences"> + <p>{{ form.preference_type.errors }} {{ form.preference_type.label_tag }}: {{ form.preference_type }} <button type="button" onclick="addSelectivePreferenceFilter(this)">Dodaj</button></p> + {% for pref_form in form.preferences %} + <p id="sel-preference"> + {% if pref_form.pref_type == 'general' %} + {% include 'general_preference_form.html' with form=pref_form only %} + {% elif pref_form.pref_type == 'relational' %} + {% include 'relational_preference_form.html' with form=pref_form only %} + {% elif pref_form.pref_type == 'synset' %} + {% include 'synset_preference_form.html' with form=pref_form only %} + {% endif %} + </p> + {% endfor %} + </div> +{% endif %} \ No newline at end of file diff --git a/semantics/templates/synset_preference_form.html b/semantics/templates/synset_preference_form.html new file mode 100644 index 0000000..ce23e2a --- /dev/null +++ b/semantics/templates/synset_preference_form.html @@ -0,0 +1,21 @@ +<p class="fieldWrapper"> + {{ form.synset_pref.errors }} + {{ form.synset_pref.label_tag }}: {{ form.synset_pref }} + <button type="button" onclick="removeSelPreferenceFilter(this)">Usuń</button> + <script type="text/javascript"> + $(function(){ + $('input#id_synset_pref').autocomplete({ + select: function(event, ui){ + }, + source: function(req, add){ + $.getJSON(ajax_synset_context_lookup, req, function(data) { + var suggestions = []; + $.each(data['result'], function(i, val){ + suggestions.push(val); + }); + add(suggestions); + }); + }, + }); + }); + </script> +</p> \ No newline at end of file diff --git a/semantics/validation.py b/semantics/validation.py index 900734d..0058d67 100644 --- a/semantics/validation.py +++ b/semantics/validation.py @@ -2,7 +2,7 @@ from django.db.models import Max -from dictionary.models import Lemma, reflex_phrase_types, Argument_Model +from dictionary.models import Lemma, reflex_phrase_types from semantics.models import LexicalUnitExamples from semantics.utils import get_structural_matching_frame @@ -182,7 +182,7 @@ def schema_used(schema, frames): def validate_lexical_units(lemma_id): error_msg = '' lemma = Lemma.objects.get(id=lemma_id, old=False) - lexical_units = lemma.entry_obj.lexical_units() + lexical_units = lemma.entry_obj.meanings for lex_unit in lexical_units.all(): if not examples_reflex_agreed(lex_unit): error_msg = u'Semantyka: Znaczenie %s ma podpięte przykłady o niezgodnej zwrotności.' % unicode(lex_unit) diff --git a/semantics/views.py b/semantics/views.py index 8a82520..182244e 100644 --- a/semantics/views.py +++ b/semantics/views.py @@ -15,6 +15,7 @@ from django.core.urlresolvers import reverse from django.db.models import Q from common.decorators import render, ajax +from semantics.forms import GeneralSelPrefForm, RelationalSelPrefForm, RoleForm, SynsetSelPrefForm from semantics.saving import modify_frames, update_meanings from semantics.validation import validate_schemas, validate_frames, validate_lexical_units @@ -79,7 +80,7 @@ def create_frames_context(lemma_id): lemma = Lemma.objects.get(id=lemma_id) #lexical_units = LexicalUnit.objects.filter(Q(base__startswith=lemma.entry + u' ')|Q(base__contains=u' '+lemma.entry+u' ')|Q(base__endswith=u' '+lemma.entry)|Q(base=lemma.entry)).order_by('sense') - lexical_units = LexicalUnit.objects.filter(Q(base = lemma.entry)|Q(base = lemma.entry + u' się')).order_by('sense') + lexical_units = lemma.entry_obj.meanings.order_by('sense') alternations = {} frames_dict = {} @@ -216,7 +217,7 @@ def ajax_units(request, lemma_id): def create_units_context(lemma_id): lemma = Lemma.objects.get(id=lemma_id) - lexical_units = LexicalUnit.objects.filter(Q(base = lemma.entry, pos="czasownik")|Q(base = lemma.entry + u' się', pos="czasownik")).order_by('base', 'sense') + lexical_units = lemma.entry_obj.meanings.order_by('base', 'sense') # lexical_units = LexicalUnit.objects.filter(Q(base__startswith=lemma.entry + u' ', pos="czasownik")|Q(base__contains=u' '+lemma.entry+u' ', pos="czasownik")|Q(base__endswith=u' '+lemma.entry, pos="czasownik")|Q(base=lemma.entry, pos="czasownik")).order_by('base', 'sense') context = { @@ -354,7 +355,7 @@ def ajax_schemas(request, lemma_id): schemas_by_characteristic[characteristic_id] = [] schemas_by_characteristic[characteristic_id].append(schema) - lexical_units = LexicalUnit.objects.filter(Q(base=lemma.entry) | Q(base=lemma.entry+u' się')) + lexical_units = lemma.entry_obj.meanings.all() schemas_display = [] schema_unit_rank = {} @@ -414,7 +415,7 @@ def ajax_examples(request, lemma_id): lemma = Lemma.objects.get(id=lemma_id).entry_obj.actual_lemma() nkjp_examples = lemma.nkjp_examples.all() - lexical_units = LexicalUnit.objects.filter(Q(base = lemma.entry)|Q(base = lemma.entry + u' się')) + lexical_units = lemma.entry_obj.meanings.all() lexical_units_ids = [lu.id for lu in lexical_units] @@ -488,7 +489,7 @@ def ajax_create_complement(request, lemma_id, frame, roles): @ajax(method='post', encode_result=True) def ajax_update_meanings(request, operations, lemma_id): - update_meanings(operations) + update_meanings(lemma_id, operations) units_context = create_units_context(lemma_id) return units_context @@ -519,6 +520,19 @@ def get_ordered_lexical_units_bases(lexical_units_query): last_unit_base = lexical_unit.base return lexical_unit_bases +@ajax(method='get', encode_result=True) +def synset_context_lookup(request, term): + results = [] + term = unicode(term) + if len(term) > 0: + obj_results = LexicalUnit.objects.filter(base__startswith=term) + results = get_ordered_lexical_units(obj_results) + return {'result': results} + +def get_ordered_lexical_units(lexical_units_query): + ordered_lexical_units = lexical_units_query.order_by('base', 'sense') + return [unicode(lu) for lu in ordered_lexical_units] + @ajax(method='get') def validate_semantics(request, lemma_id, new_status_id): error_msg = '' @@ -536,3 +550,27 @@ def validate_semantics(request, lemma_id, new_status_id): if not error_msg: error_msg = validate_schemas(lemma_id) return {'error_message': error_msg} + +@render('sem_arg_form.html') +@ajax(method='get', encode_result=False) +def sem_arg_form(request): + form = RoleForm() + return {'form': form} + +@render('general_preference_form.html') +@ajax(method='get', encode_result=False) +def general_preference_form(request): + form = GeneralSelPrefForm() + return {'form': form} + +@render('synset_preference_form.html') +@ajax(method='get', encode_result=False) +def synset_preference_form(request): + form = SynsetSelPrefForm() + return {'form': form} + +@render('relational_preference_form.html') +@ajax(method='get', encode_result=False) +def relational_preference_form(request): + form = RelationalSelPrefForm() + return {'form': form} diff --git a/static/js/script.js b/static/js/script.js index 8ad2ccd..f990811 100644 --- a/static/js/script.js +++ b/static/js/script.js @@ -202,6 +202,7 @@ function resetForm($form) { $form.find('input:text, input:password, input:file, select, textarea').val(''); $form.find('input:radio, input:checkbox') .removeAttr('checked').removeAttr('selected'); + $form.find('#sem-arguments').remove(); } // funkcja konwertujaca kody html znakow do znakow diff --git a/wordnet/models.py b/wordnet/models.py index 7cae7a9..3f5747e 100644 --- a/wordnet/models.py +++ b/wordnet/models.py @@ -33,6 +33,8 @@ class LexicalUnit(models.Model): definition = models.TextField(default="") # glossa glossa = models.TextField(default="") + # haslo w Walentym + entry = models.ForeignKey('dictionary.Entry', null=True, related_name='meanings') def __unicode__(self): return u'%s-%s' % (self.base, self.sense)