# -*- coding: utf-8 -*- from semantics.models import SemanticRole, SemanticFrame, Complement, \ LexicalUnit, FrameRankings, SemanticRolesDisplay, \ LexicalUnitExamples, SelectivePreferenceRelations, \ GeneralSelectivePreference, FrameOpinion from dictionary.models import Frame_Char_Model, Lemma, Lemma_Status, \ sort_arguments, sort_positions from dictionary.ajax_lemma_view import user_can_modify from django.core.exceptions import SuspiciousOperation from django.core.urlresolvers import reverse from django.db.models import Q from common.decorators import render, ajax from semantics.saving import modify_frames, update_meanings from semantics.validation import validate_schemas, validate_frames, validate_lexical_units ####################################### render ##################################### @render('semantics.html') @ajax(method='get', encode_result=False) def ajax_semantics(request, id): context = {} lemma = Lemma.objects.get(id=id) context['lemma'] = lemma context['can_modify'] = (user_can_modify(lemma, request.user) and lemma.status.stage_of_work.sym_name == 'semantics') context['js_vars'] = { 'ajax_frames': reverse('ajax_frames'), 'ajax_schemas': reverse('ajax_schemas'), 'ajax_units': reverse('ajax_units'), 'ajax_roles': reverse('ajax_roles'), 'ajax_opinions': reverse('ajax_opinions'), 'ajax_create_frame': reverse('ajax_create_frame'), 'ajax_create_complement': reverse('ajax_create_complement'), 'ajax_examples': reverse('ajax_examples'), 'ajax_update_meanings': reverse('ajax_update_meanings'), 'ajax_modify_frames': reverse('ajax_modify_frames'), 'ajax_synsets': reverse('ajax_synsets'), 'ajax_relations': reverse('ajax_relations'), 'ajax_predefined_preferences': reverse('ajax_predefined_preferences'), 'ajax_plWN_context_lookup': reverse('ajax_plWN_context_lookup'), } return context def reorder_history(frames_list): next_ids = set() for frame in frames_list: if frame.next is not None: next_ids.add(frame.next.id) first = set() for frame in frames_list: if frame.id not in next_ids: first.add(frame) result = [] for frame in first: current = frame while current is not None: result.append(current) current = current.next result.reverse() return result @render('frames.json') @ajax(method='get', encode_result=False) def ajax_frames(request, lemma_id): lemma = Lemma.objects.get(id=lemma_id, old=False) 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') alternations = {} frames_dict = {} frame_units = {} for lexical_unit in lexical_units: frames = lexical_unit.actual_frames() for frame in frames: alternations[frame.id] = {} frames_dict[frame.id] = frame if frame.id not in frame_units: frame_units[frame.id] = [] frame_units[frame.id].append(lexical_unit) type_frames = {} for frame_id in frame_units: t = tuple(frame_units[frame_id]) if t not in type_frames: type_frames[t] = [] type_frames[tuple(frame_units[frame_id])].append(frames_dict[frame_id]) # ala[ma]=kot frames_display = [] complement_arguments = {} arguments_frame_connected = {} for t in type_frames: type_frames[t] = reorder_history(type_frames[t]) for t in type_frames: frame_display = {"lexical_units": [], "frames": []} for lu in list(t): frame_display["lexical_units"].append({"id": str(lu.id), "base": lu.base, "sense": str(lu.sense)}) for frame in type_frames[t]: # frame_complements = Complement.objects.filter(frame=frame) frame_complements = frame.complements.all() # classes and first frame/position part of identifiers frame_ids = [u'frame_' + str(frame.id) + '_comp_' + str(complement.id) + '_' for complement in frame_complements] # names of roles frame_roles = [{'csv_id': i, 'csv_class': c, 'argument': a} for i, c, a in zip(frame_ids, frame_ids, [[role.id for role in complement.roles.all()] for complement in frame_complements])] # rowspan for 'Argumenty:' # frame_preferences_rowspan = max(max([len(preference) for preference in [complement.selective_preference.all() for complement in frame_complements]] + [0]), 1) frame_preferences_rowspan = max(max([len(complement.selective_preference.generals.all()) + len(complement.selective_preference.synsets.all()) + len(complement.selective_preference.relations.all()) for complement in frame_complements if complement.selective_preference is not None] +[0]), 1) frame_preferences = [] for i in range(frame_preferences_rowspan): row = [] idents = [] for frame_id, complement in zip(frame_ids, frame_complements): if complement.selective_preference is not None: generals = complement.selective_preference.generals.all() synsets = complement.selective_preference.synsets.all() relations = complement.selective_preference.relations.all() synset_relations = complement.selective_preference.synset_relations.all() generals_len = len(generals) synsets_len = len(synsets) relations_len = len(relations) synset_relations_len = len(synset_relations) if generals_len > i: general = generals[i] row.append(general.name) idents.append(frame_id + 'pref_g' + str(general.id) + '_') elif generals_len + synsets_len > i: synset = synsets[i - generals_len] # lexical_units_preference = LexicalUnit.objects.filter(synset=synset) row.append(unicode(synset)) idents.append(frame_id + 'pref_s' + str(synset.id) + '_') elif generals_len + synsets_len + relations_len > i: relation = relations[i - generals_len - synsets_len] row.append(relation.relation.name + '<br /> -> [' + ', '.join([r.role for r in relation.to.roles.all()]) + ']') idents.append(frame_id + 'pref_r' + str(relation.id) + '_') elif generals_len + synsets_len + relations_len + synset_relations_len > i: relation = relations[i - generals_len - synsets_len - relations_len] synset = relation.to row.append(relation.relation.name + '<br /> -> [' + unicode(synset) + ']') idents.append(frame_id + 'pref_R' + str(relation.id) + '_') else: row.append('') idents.append(frame_id + 'pref_-' + str(i + 1) + '_') else: row.append('') idents.append(frame_id + 'pref_-' + str(i + 1) + '_') frame_preferences.append([{'csv_id': i, 'csv_class': c, 'preference': p} for i, c, p in zip(idents, frame_ids, row)]) display = {"roles": frame_roles, "preferences": frame_preferences} if frame.opinion is None: status = u'brak' else: status = frame.opinion.value frame_display["frames"].append({"frame_id": str(frame.id), "colspan": str(max(len(frame_roles), 1)), "rowspan": str(frame_preferences_rowspan), "status": status, "display": display}) for complement, complement_class in zip(frame_complements, frame_ids): if complement_class not in complement_arguments: complement_arguments[complement_class] = [] for schema_position in complement.realizations.all(): schema = schema_position.frame position = schema_position.position argument = schema_position.argument alternation = schema_position.alternation realization_id = u'schema_' + str(schema.id) + u'_pos_' + str(position.id) + '_arg_' + str(argument.id) + '_' + 'alt_' + str(alternation) + '_' complement_arguments[complement_class].append(realization_id) if realization_id not in arguments_frame_connected: arguments_frame_connected[realization_id] = [] arguments_frame_connected[realization_id].append('frame_' + str(frame.id) + '_') if schema.id in alternations[frame.id]: alternations[frame.id][schema.id] = max(alternations[frame.id][schema.id], alternation) else: alternations[frame.id][schema.id] = alternation # alternations[frame.id] = {} frames_display.append(frame_display) # ala["ma"] = "kot" context = { 'frames_display': frames_display, 'connections': {'connected': complement_arguments, 'connected_reverse': arguments_frame_connected}, 'frames_count': lemma.entry_obj.actual_frames().count(), 'alternations': alternations } return context @render('units.json') @ajax(method='get', encode_result=False) def ajax_units(request, lemma_id): lemma = Lemma.objects.get(id=lemma_id, old=False) # 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 = 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 = { 'lexical_units': [{"id": lu.id, "luid": lu.luid, "base": lu.base, "sense": lu.sense, "pos": lu.pos, "glossa": lu.glossa, "definition": lu.definition} for lu in lexical_units], 'informations': {'base': lemma.entry, 'sense': max(['A'] + [chr(ord(lu.sense) + 1) for lu in lexical_units.filter(luid=-1)])}, # TODO: 2 different free senses for with/whthout 'się' } return context @ajax(method='get') def ajax_predefined_preferences(request): predefined = [] for preference in GeneralSelectivePreference.objects.order_by('name'): if preference.members: members = [member.name for member in preference.members.generals.order_by('name')] members.extend([unicode(synset) for synset in preference.members.synsets.all()]) content = u'%s: (%s)' % (preference.name, ', '.join(members)) else: content = u'%s' % (preference.name) predefined.append({"id": preference.id, "content": content}) context = { 'predefined': predefined, } return context @render('synsets.json') @ajax(method='get', encode_result=False) def ajax_synsets(request, base, pos): if pos == '_': lexical_units = LexicalUnit.objects.filter(base=base).order_by('pos', 'base', 'sense') else: lexical_units = LexicalUnit.objects.filter(base=base, pos=pos).order_by('pos', 'base', 'sense') synsets = [] for representative in lexical_units: synset = [{"id": lu.id, "luid": lu.luid, "base": lu.base, "sense": lu.sense, "pos": lu.pos, "glossa": lu.definition} for lu in LexicalUnit.objects.filter(synset=representative.synset)] synsets.append({"id": representative.synset.id, "content": synset}) context = { 'synsets': synsets, } return context @render('relations.json') @ajax(method='get', encode_result=False) def ajax_relations(request): relations = [{"id": relation.id, "content": relation.name} for relation in SelectivePreferenceRelations.objects.all()] context = { 'relations': relations, } return context @render('opinions.json') @ajax(method='get', encode_result=False) def ajax_opinions(request): opinions = [{"id": opinion.short, "name": opinion.value} for opinion in FrameOpinion.objects.all().order_by('priority')] context = { 'opinions': opinions, } return context @render('roles.json') @ajax(method='get', encode_result=False) def ajax_roles(request): roles_display = [] maxrow = SemanticRolesDisplay.objects.all().order_by('-row')[0].row for i in range(1, maxrow + 1): row = [] cells = SemanticRolesDisplay.objects.filter(row=i).order_by('column') for cell in cells: content = cell.roles.all().order_by('id') commas = [','] * max(len(content) - 1, 0) + [''] row.append((cell.caption, cell.rowspan, cell.colspan, zip(content, commas))) commas = [','] * max(len(row) - 1, 0) + [''] captions, rowspans, colspans, contents = zip(*row) roles_display.append(zip(list(captions), list(rowspans), list(colspans), list(contents), commas)) commas = [','] * max(len(roles_display) - 1, 0) + [''] context = { 'roles_display': zip(roles_display, commas), } return context @render('schemas.json') @ajax(method='get', encode_result=False) def ajax_schemas(request, lemma_id): lemma = Lemma.objects.get(id=lemma_id, old=False) schemas_all = lemma.frames.all() characteristics = {} characteristics_ids = [] schemas_by_characteristic = {} for schema in schemas_all: chars = schema.characteristics.all() char_types = [c.type for c in chars] l = [(Frame_Char_Model.objects.get(model_name=c.type).priority, c) for c in chars] l.sort() _, chars = zip(*l) chars = list(chars) characteristic_id = tuple([char.id for char in chars]) if characteristic_id not in characteristics: characteristics_ids.append(characteristic_id) values = [char.value.value for char in chars] if values[0]: characteristics[characteristic_id] = "%s (%s)" % (values[0], ','.join(values[1:])) else: characteristics[characteristic_id] = "(%s)" % (','.join(values[1:])) 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ę')) schemas_display = [] schema_unit_rank = {} for characteristic_id in characteristics_ids: schema_display = {"characteristic_id": '_'.join([str(i) for i in characteristic_id]), "characteristic_display": characteristics[characteristic_id], "schemas": []} schemas = schemas_by_characteristic[characteristic_id] for schema in schemas: # row by row display for schema tables ordered_positions = sort_positions(schema.positions.all()) # classes and first frame/position part of identifiers schema_ids = [u'schema_' + str(schema.id) + '_pos_' + str(position.id) + '_' for position in ordered_positions] # names of categories (along with class names schema_categories = zip(schema_ids, [','.join([category.category for category in position.ordered_categories()]) for position in ordered_positions]) # value of rowspan for 'Argumenty:' header schema_arguments_rowspan = max(max([position.arguments.count() for position in ordered_positions] + [0]), 1) display = {"categories": [{"csv_id": c, "csv_class": c, "argument": a} for c, a in schema_categories], "arguments": []} for i in range(schema_arguments_rowspan): row = [] idents = [] for schema_id, position in zip(schema_ids, ordered_positions): if position.arguments.count() > i: ordered_arguments = sort_arguments(position.arguments.all()) row.append(unicode(ordered_arguments[i])) idents.append(schema_id + 'arg_' + str(ordered_arguments[i].id) + '_') else: # this category has fewer posible argument realizations row.append('') idents.append(schema_id + 'arg_-' + str(i + 1) + '_') # identifier, class, argument display["arguments"].append([{"csv_id": i, "csv_class": c, "argument": a} for i, c, a in zip(idents, schema_ids, row)]) schema_display["schemas"].append({"schema_id": str(schema.id), "grade": lemma.get_schema_opinion(schema), "colspan": str(max(len(schema_categories), 1)), "rowspan": str(schema_arguments_rowspan), "display": display, "phraseologic": schema.phraseologic}) ranks = FrameRankings.objects.filter(frame=schema) for rank in ranks: if rank.lexical_unit.id not in schema_unit_rank: schema_unit_rank[rank.lexical_unit.id] = {} schema_unit_rank[rank.lexical_unit.id]["schema_" + str(schema.id) + "_"] = str(rank.rank) schemas_display.append(schema_display) context = { 'lemma': lemma, 'schemas_display': schemas_display, 'ranks': schema_unit_rank } return context @render('examples.json') @ajax(method='get', encode_result=False) def ajax_examples(request, lemma_id): lemma = Lemma.objects.get(id=lemma_id, old=False) nkjp_examples = lemma.nkjp_examples.all() lexical_units = LexicalUnit.objects.filter(Q(base = lemma.entry)|Q(base = lemma.entry + u' się')) lexical_units_ids = [lu.id for lu in lexical_units] examples_linked = [] for nkjp_example in nkjp_examples: linked = LexicalUnitExamples.objects.filter(example=nkjp_example) meanings = [] for link in linked: if link.lexical_unit.id in lexical_units_ids: meanings.append(link.lexical_unit.id) all_argselection = nkjp_example.arguments.all() arguments = [] for argselection in all_argselection: pos = argselection.position.id args = argselection.arguments.all() for arg in args: arguments.append({'id': 'schema_' + str(nkjp_example.frame.id) + '_pos_' + str(pos) + '_arg_' + str(arg.id) + '_'}) examples_linked.append({'schema': 'schema_' + str(nkjp_example.frame.id) + '_', 'arguments': arguments, 'id': nkjp_example.id, 'sentence': nkjp_example.sentence, 'source': nkjp_example.source.source, 'opinion': nkjp_example.opinion.opinion, 'meanings': meanings}) context = { 'examples': examples_linked } return context @ajax(method='get', encode_result=False) def ajax_create_frame(request, lexical_units): #lexical_unit_id_list = request.GET.get('lexical_units', '') lexical_unit_id_list = lexical_units lexical_units_ids = [int(id) for id in lexical_unit_id_list.split(',')] lexical_units = [] for lexical_unit_id in lexical_units_ids: lexical_units.append(LexicalUnit.objects.get(id=lexical_unit_id)) unit_bases = [lexical_unit.base for lexical_unit in lexical_units] base = unit_bases[0].split(' ')[0] for unit_base in unit_bases: if unit_base != base and unit_base != base + u' się': raise SuspiciousOperation frame = SemanticFrame() frame.save() for lexical_unit in lexical_units: frame.lexical_units.add(lexical_unit) lemma = Lemma.objects.get(entry=lexical_unit.base, old=False) return ajax_frames(request, lemma.id) @ajax(method='get', encode_result=False) def ajax_create_complement(request, lemma_id, frame, roles): #lemma_id = int(request.GET.get('lemma_id', '')) lemma = Lemma.objects.get(id=lemma_id, old=False) frame_id = frame #frame_id = int(request.GET.get('frame', '')) frame = SemanticFrame.objects.get(id=frame_id) #role_id_list = request.GET.get('roles', '') role_id_list = roles role_ids = [int(id) for id in role_id_list.split(',')] roles = [] for role_id in role_ids: roles.append(SemanticRole.objects.get(id=role_id)) complement = Complement(frame=frame) complement.save() for role in roles: complement.roles.add(role) return ajax_frames(request, lemma.id) @ajax(method='get', encode_result=False) def ajax_update_meanings(request, operations, lemma_id): update_meanings(operations) return ajax_units(request) @ajax(method='get', encode_result=False) def ajax_modify_frames(request, operations, lemma_id): if not request.user.is_authenticated(): return 'user logged out' modify_frames(lemma_id, operations, request.user) return ajax_frames(request) @ajax(method='get', encode_result=True) def ajax_plWN_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_bases(obj_results) return {'result': results} def get_ordered_lexical_units_bases(lexical_units_query): last_unit_base = '' lexical_unit_bases = [] ordered_lexical_units = lexical_units_query.order_by('base') for lexical_unit in ordered_lexical_units: if lexical_unit.base != last_unit_base: lexical_unit_bases.append(lexical_unit.base) last_unit_base = lexical_unit.base return lexical_unit_bases @ajax(method='get') def validate_semantics(request, lemma_id, new_status_id): error_msg = '' if Lemma.objects.get(id=lemma_id).old: error_msg = u'Odśwież hasło, widoczna wersja nie jest aktualna.' else: try: status = Lemma_Status.objects.get(id=new_status_id) except Lemma_Status.DoesNotExist: status = None if status and status.check_semantics: error_msg = validate_frames(lemma_id) if not error_msg: error_msg = validate_lexical_units(lemma_id) if not error_msg: error_msg = validate_schemas(lemma_id) return {'error_message': error_msg}