# -*- coding: utf-8 -*- import operator from django.db.models import Q from django.db.models import Count, Max from accounts.models import RealizedLemma, RealizedPhraseology, RealizedSemantics from common.decorators import render, ajax, AjaxError from dictionary.common_func import frame_structure_exists from dictionary.models import Configuration, Frame, Lemma, Lemma_Status, StatusChange from semantics.change_log import backup_lemma_and_get_frames from semantics.models import SemanticFrame from semantics.utils import get_frames_differences @render('lemma_status.html') @ajax(method='get', encode_result=False) def get_lemma_status(request, id): selected_lemma = Lemma.objects.get(id=id) abort_status = None next_statuses = [] pos = selected_lemma.entry_obj.pos if ((selected_lemma.owner == request.user and selected_lemma.status.type.sym_name != 'checked') or request.user.has_perm('dictionary.confirm_lemma') or (selected_lemma.vocabulary.editors.filter(id=request.user.id).exists() and request.user.has_perm('dictionary.change_lemmas') and selected_lemma.status.type.sym_name == 'initial') or phraseologic_status_changes(request.user, selected_lemma) or semantic_status_changes(request.user, selected_lemma)): if request.user.groups.filter(group_settings__abort_statuses=selected_lemma.status.abort_status).exists(): abort_status = selected_lemma.status.abort_status next_statuses = selected_lemma.status.next_statuses if not lemma_can_be_temporary(selected_lemma): next_statuses = next_statuses.exclude(status=u'zalążkowe') next_statuses = next_statuses.filter(pk__in=request.user.groups.all()[0].group_settings.next_statuses.all()) next_statuses = next_statuses.all() return {'lemma': selected_lemma, 'abort_status': abort_status, 'next_statuses': next_statuses, 'pos': pos, 'status_changes': selected_lemma.status_history.order_by('-date')} def phraseologic_status_changes(user, selected_lemma): phraseologic_change = False if (user.has_perm('dictionary.add_phraseologic_frames') and selected_lemma.status.type.sym_name != 'checked_f' and selected_lemma.vocabulary.editors.filter(id=user.id).exists() and (selected_lemma.phraseologist == user or selected_lemma.status.type.sym_name == 'checked')): phraseologic_change = True return phraseologic_change def semantic_status_changes(user, selected_lemma): semantic_change = False if (user.has_perm('dictionary.add_semantic_frames') and selected_lemma.status.type.sym_name != 'checked_s' and selected_lemma.vocabulary.editors.filter(id=user.id).exists() and (selected_lemma.semanticist == user or selected_lemma.status.type.sym_name == 'checked_f')): semantic_change = True return semantic_change def lemma_can_be_temporary(lemma): can_be_temporary = False system_conf = Configuration.objects.get(selected_conf=True) if (lemma.frequency_1M < system_conf.min_1M_freq and lemma.frequency_300M < system_conf.min_300M_freq and lemma.skladnica_frames.exists()): can_be_temporary = True return can_be_temporary @ajax(method='post') def status_need_validation(request, status_id, lemma_id): next_status = False lemma_status = Lemma.objects.get(id=lemma_id).status new_status = Lemma_Status.objects.get(id=status_id) if(new_status.priority > lemma_status.priority): next_status = True need_validation = (new_status.validate or new_status.check_examples or new_status.check_semantics) and next_status return {'need_validation': need_validation} @ajax(method='post') def lemma_status_change(request, status_id, lemma_id): if not request.user.is_authenticated(): raise AjaxError('user logged out') try: lemma_obj = Lemma.objects.get(id=lemma_id, old=False) except Lemma.DoesNotExist: raise AjaxError('old version') entry_obj = lemma_obj.entry_obj # sprawdza czy uzytkownik moze modyfikowac hasla w danym slowniku try: lemma_obj.vocabulary.editors.get(username=request.user.username) edit_vocabulary = True except: edit_vocabulary = False changed = False message = '' new_status = None try: # jesli zarezerowano haslo przyciskiem new_status = Lemma_Status.objects.get(id=status_id) except: pass if new_status and new_status == lemma_obj.status: raise AjaxError('already changed') if(new_status and not new_status == lemma_obj.status.abort_status and not lemma_obj.status.next_statuses.filter(pk=new_status.pk).exists()): raise AjaxError('wrong change') actual_semantic_frames = SemanticFrame.objects.none() next_status = False if(new_status): actual_semantic_frames = backup_lemma_and_get_frames(lemma_obj) if(new_status and new_status.priority > lemma_obj.status.priority): next_status = True # reserve lemma if(lemma_obj.status.type.sym_name == 'initial' and edit_vocabulary and request.user.has_perm('dictionary.change_lemmas')): lemma_obj.owner = request.user changed = True if not new_status: new_status = lemma_obj.status.next_statuses.order_by('priority')[0] # resign from lemma elif(not next_status and new_status and new_status.type.sym_name == 'initial'): lemma_obj.owner = None changed = True # lemma type changed to ready or temporary elif(new_status and new_status.type.sym_name == 'ready' and next_status): if entry_obj.pos.tag == 'verb': flat_frames_value = 4.5 else: flat_frames_value = 3.5 update_lemma_stats_ready(lemma_obj, lemma_obj.owner, new_status, flat_frames_value) changed = True # lemma type changed to checked elif(new_status and new_status.type.sym_name == 'checked' and next_status): if lemma_obj.owner == request.user: if lemma_obj.status.abort_status != new_status: message = u'Nie można zatwierdzać hasła, którego jest się właścicielem.' else: if lemma_obj.status.abort_status != new_status: if entry_obj.pos.tag == 'verb': checked_frame_value = 1.0 corrected_frame_value = 7.0 bonus_factor = 1.2 else: checked_frame_value = 1.0 corrected_frame_value = 6.0 bonus_factor = 1.0 update_lemma_stats_conf(lemma_obj, lemma_obj.owner, request.user, new_status, checked_frame_value, corrected_frame_value, bonus_factor) changed = True # zmiana statusu na w obrobce elif(new_status and (lemma_obj.status.type.sym_name == 'ready' or lemma_obj.status.type.sym_name == 'checked') and lemma_obj.status.abort_status == new_status): remove_lexicography_payments(lemma_obj) changed = True # pobieranie hasla do obrobki frazeologicznej elif(new_status and lemma_obj.status.type.sym_name == 'checked' and edit_vocabulary and new_status.type.sym_name == 'edit_f' and next_status): lemma_obj.phraseologist = request.user add_new_frames_to_phraseologic_propositions(lemma_obj) changed = True # porzucanie obrobki frazeologicznej hasla elif(new_status and lemma_obj.status.type.sym_name == 'edit_f' and lemma_obj.status.abort_status == new_status): lemma_obj.phraseologist = None changed = True # zmiana statusu hasla na gotowe frazeologicznie elif(new_status and new_status.type.sym_name == 'ready_f' and next_status): new_phraseologic_frame_value = 7.0 proposed_phraseologic_frame_value = 2.0 update_lemma_stats_ready_f(lemma_obj, lemma_obj.phraseologist, new_status, new_phraseologic_frame_value, proposed_phraseologic_frame_value) add_new_frames_to_phraseologic_propositions(lemma_obj) changed = True # zmiana statusu hasla na sprawdzone frazeologicznie elif(new_status and new_status.type.sym_name == 'checked_f' and next_status): checked_frame_value = 4.0 corrected_frame_value = 7.0 bonus = 0.5 update_lemma_stats_conf_f(lemma_obj, lemma_obj.phraseologist, request.user, new_status, checked_frame_value, corrected_frame_value, bonus) add_new_frames_to_phraseologic_propositions(lemma_obj) changed = True # pobieranie hasla do obrobki semantycznej elif(new_status and lemma_obj.status.type.sym_name == 'checked_f' and edit_vocabulary and new_status.type.sym_name == 'edit_s' and next_status): lemma_obj.semanticist = request.user add_new_frames_to_phraseologic_propositions(lemma_obj) changed = True # porzucanie obrobki semantycznej hasla elif(new_status and lemma_obj.status.type.sym_name == 'edit_s' and lemma_obj.status.abort_status == new_status): lemma_obj.semanticist = None changed = True # zmiana statusu hasla na gotowe semantycznie elif(new_status and new_status.type.sym_name == 'ready_s' and next_status): ### naliczanie oplat za gotowosc semantyczna frame_value = 8.0 update_sem_stats_ready_s(lemma_obj.entry_obj, actual_semantic_frames, lemma_obj.semanticist, new_status, frame_value) add_new_frames_to_phraseologic_propositions(lemma_obj) changed = True # zmiana statusu hasla na sprawdzone semantycznie elif(new_status and new_status.type.sym_name == 'checked_s' and next_status): checked_frame_value = 0.0 corrected_frame_value = 0.0 bonus = 4.0 part_bonus = 2.0 connection_bonus = 0.1 ### naliczanie oplat za sprawdzenie i bonusow update_sem_stats_conf_s(entry=lemma_obj.entry_obj, semantic_frames=actual_semantic_frames, semanticist=lemma_obj.semanticist, supersemanticist=request.user, status=new_status, checked_frame_value=checked_frame_value, corrected_frame_value=corrected_frame_value, bonus_factor=bonus, part_bonus_factor=part_bonus, connection_bonus=connection_bonus) add_new_frames_to_phraseologic_propositions(lemma_obj) changed = True # zmiana statusu na w obrobce semantycznej elif(new_status and (lemma_obj.status.type.sym_name == 'ready_s' or lemma_obj.status.type.sym_name == 'checked_s') and lemma_obj.status.abort_status == new_status): remove_semantic_payments(lemma_obj.entry_obj) changed = True # jak oznaczamy status jako "do usuniecia", to czyscimy oplaty za haslo elif(new_status and new_status.type.sym_name == 'erase' and next_status): changed = True erase_payments(lemma_obj) elif(new_status): changed = True if changed and new_status != lemma_obj.status: lemma_obj.status = new_status lemma_obj.save() status_change = StatusChange(act_owner=lemma_obj.owner, changer=request.user, lemma=lemma_obj, status=new_status) status_change.save() status_change.semantic_frames.add(*actual_semantic_frames.all()) lemma_obj.status_history.add(status_change) if new_status: new_status_type = new_status.type.sym_name else: new_status_type = '' return {'entry' : lemma_obj.entry, 'lemma_id' : lemma_obj.id, 'changed' : changed, 'message' : message, 'new_status_type': new_status_type, 'next_status' : next_status} ############# marking as 'to erase' ################# def erase_payments(lemma): RealizedLemma.objects.filter(lemma__entry_obj=lemma.entry_obj).delete() RealizedPhraseology.objects.filter(lemma__entry_obj=lemma.entry_obj).delete() RealizedSemantics.objects.filter(entry=lemma.entry_obj).delete() ############## lexicography ####################### def update_lemma_stats_ready(lemma, lex, status, flat_frames_value): lex_dict = {'made_frames': 0, 'cash': 0.0} for frame in lemma.frames.all(): flat_frames = float(frame.positions.annotate(num_args=Count('arguments')).aggregate(Max('num_args'))['num_args__max']) lex_dict['made_frames'] += flat_frames lex_dict['cash'] += flat_frames_value*flat_frames lex_real_lemma = RealizedLemma(lemma=lemma, cash=lex_dict['cash'], made_frames=lex_dict['made_frames'], paid=False, status=status, bonus=False, counted=False) lex_real_lemma.save() lex.user_stats.lemma_real_history.add(lex_real_lemma) def update_lemma_stats_conf(lemma, lex, superlex, status, checked_frame_value, corrected_frame_value, bonus_factor): ready_statuses = Lemma_Status.objects.filter(type__sym_name='ready') q_ready_statuses = [Q(status=ready_status) for ready_status in ready_statuses.all()] all_realized_lemmas = RealizedLemma.objects.filter(reduce(operator.or_, q_ready_statuses)) ready_lemma = all_realized_lemmas.get(lemma__entry_obj=lemma.entry_obj).lemma lex_dict = {'same_frames': 0, 'wrong_frames': 0, 'cash': 0.0} superlex_dict = {'same_frames': [], 'redo_frames': [], 'cash': 0.0} q_same_frames = [] for frame in ready_lemma.frames.all(): flat_frames = float(frame.positions.annotate(num_args=Count('arguments')).aggregate(Max('num_args'))['num_args__max']) try: same_frame = lemma.frames.get(text_rep=frame.text_rep) superlex_dict['same_frames'].append(frame) superlex_dict['cash'] += checked_frame_value lex_dict['same_frames'] += flat_frames bonus = flat_frames * bonus_factor*flat_frames**(1.0/3.0) lex_dict['cash'] += bonus q_same_frames.append(Q(text_rep=same_frame.text_rep)) except Frame.DoesNotExist: lex_dict['wrong_frames'] += flat_frames continue new_frames = lemma.frames if len(q_same_frames) > 0: new_frames = new_frames.exclude(reduce(operator.or_, q_same_frames)) superlex_dict['redo_frames'] = new_frames.all() for frame in superlex_dict['redo_frames']: superlex_dict['cash'] += corrected_frame_value # superleksykograf nie zostal jeszcze oplacony za dane haslo, zmien wartosc superlex_real_lemma = RealizedLemma(lemma=lemma, cash=superlex_dict['cash'], corr_frames=len(superlex_dict['redo_frames']), ncorr_frames=len(superlex_dict['same_frames']), paid=False, status=status, bonus=False, counted=False) superlex_real_lemma.save() superlex.user_stats.lemma_real_history.add(superlex_real_lemma) # hasla pochodzace z cesara maja cash = 0.0 i nie nalezy ich bonusować try: RealizedLemma.objects.get(lemma__entry=lemma.entry, status__type__sym_name='ready', bonus=False, cash=0.0, paid=True, counted=True) except RealizedLemma.DoesNotExist: lex_real_lemma = RealizedLemma(lemma=lemma, cash=lex_dict['cash'], prop_frames=lex_dict['same_frames'], wrong_frames=lex_dict['wrong_frames'], paid=False, status=status, bonus=True, counted=False) lex_real_lemma.save() lex.user_stats.lemma_real_history.add(lex_real_lemma) def remove_lexicography_payments(lemma): RealizedLemma.objects.filter(lemma__entry_obj=lemma.entry_obj).delete() ######################## phraseology ############################# def add_new_frames_to_phraseologic_propositions(lemma): entry_obj = lemma.entry_obj phraseologic_frames = lemma.frames.filter(phraseologic=True).all() phraseologic_propositions = entry_obj.phraseologic_propositions.all() propositions_to_add = [] for frame in phraseologic_frames: if not frame_structure_exists(frames=phraseologic_propositions, searched_frame=frame): propositions_to_add.append(frame) entry_obj.phraseologic_propositions.add(*propositions_to_add) def update_lemma_stats_ready_f(lemma, phraseologist, status, new_phraseologic_frame_value, proposed_phraseologic_frame_value): phraseologist_dict = {'new_frames': 0, 'reused_frames': 0, 'cash': 0.0} for frame in lemma.frames.filter(phraseologic=True).all(): if frame_structure_exists(frames=lemma.entry_obj.phraseologic_propositions.all(), searched_frame=frame): phraseologist_dict['reused_frames'] += 1 phraseologist_dict['cash'] += proposed_phraseologic_frame_value else: phraseologist_dict['new_frames'] += 1 phraseologist_dict['cash'] += new_phraseologic_frame_value phrase_real_lemma = RealizedPhraseology(lemma=lemma, cash=phraseologist_dict['cash'], new_frames=phraseologist_dict['new_frames'], reused_frames=phraseologist_dict['reused_frames'], paid=False, status=status, bonus=False, counted=False) phrase_real_lemma.save() phraseologist.user_stats.phraseology_real_history.add(phrase_real_lemma) def update_lemma_stats_conf_f(lemma, phraseologist, superphraseologist, status, checked_frame_value, corrected_frame_value, bonus): ready_statuses = Lemma_Status.objects.filter(type__sym_name='ready_f') q_ready_statuses = [Q(status=ready_status) for ready_status in ready_statuses.all()] ready_lemmas = RealizedPhraseology.objects.filter(reduce(operator.or_, q_ready_statuses)) ready_lemma = ready_lemmas.get(lemma__entry_obj=lemma.entry_obj).lemma phraseologist_dict = {'same_frames': 0, 'wrong_frames': 0, 'cash': 0.0} superphraseologist_dict = {'same_frames': [], 'redo_frames': [], 'cash': 0.0} q_same_frames = [] for frame in ready_lemma.frames.filter(phraseologic=True).all(): try: same_frame = lemma.frames.filter(phraseologic=True).get(text_rep=frame.text_rep) superphraseologist_dict['same_frames'].append(frame) superphraseologist_dict['cash'] += checked_frame_value phraseologist_dict['same_frames'] += 1 phraseologist_dict['cash'] += bonus q_same_frames.append(Q(text_rep=same_frame.text_rep)) except Frame.DoesNotExist: phraseologist_dict['wrong_frames'] += 1 continue new_frames = lemma.frames.filter(phraseologic=True) if len(q_same_frames) > 0: new_frames = new_frames.exclude(reduce(operator.or_, q_same_frames)) superphraseologist_dict['redo_frames'] = new_frames.all() for frame in superphraseologist_dict['redo_frames']: superphraseologist_dict['cash'] += corrected_frame_value superphraseologist_real_lemma = RealizedPhraseology(lemma=lemma, cash=superphraseologist_dict['cash'], corr_frames=len(superphraseologist_dict['redo_frames']), ncorr_frames=len(superphraseologist_dict['same_frames']), paid=False, status=status, bonus=False, counted=False) superphraseologist_real_lemma.save() superphraseologist.user_stats.phraseology_real_history.add(superphraseologist_real_lemma) phraseologist_real_lemma = RealizedPhraseology(lemma=lemma, cash=phraseologist_dict['cash'], prop_frames=phraseologist_dict['same_frames'], wrong_frames=phraseologist_dict['wrong_frames'], paid=False, status=status, bonus=True, counted=False) phraseologist_real_lemma.save() phraseologist.user_stats.phraseology_real_history.add(phraseologist_real_lemma) ####################### semantics ############################# def update_sem_stats_ready_s(entry, semantic_frames, semanticist, status, frame_value): actual_frames_count = semantic_frames.count() sem_dict = {'made_frames': actual_frames_count, 'cash': frame_value*float(actual_frames_count)} realized_semantics = RealizedSemantics(entry=entry, cash=sem_dict['cash'], made_frames=sem_dict['made_frames'], status=status, bonus=False) realized_semantics.save() realized_semantics.frames.add(*semantic_frames.all()) semanticist.user_stats.semantics_real_history.add(realized_semantics) def update_sem_stats_conf_s(entry, semantic_frames, semanticist, supersemanticist, status, checked_frame_value, corrected_frame_value, bonus_factor, part_bonus_factor, connection_bonus): ready_statuses = Lemma_Status.objects.filter(type__sym_name='ready_s') q_ready_statuses = [Q(status=ready_status) for ready_status in ready_statuses.all()] ready_semantics = RealizedSemantics.objects.filter(reduce(operator.or_, q_ready_statuses)) ready_sem_frames= ready_semantics.get(entry=entry).frames checked_sem_frames = semantic_frames ready_to_checked_diffs = get_frames_differences(ready_sem_frames.all(), checked_sem_frames.all()) checked_to_ready_diffs = get_frames_differences(checked_sem_frames.all(), ready_sem_frames.all()) connections_amount = count_connections(ready_to_checked_diffs) sem_cash = (bonus_factor*float(len(ready_to_checked_diffs['matching_frames'])) + part_bonus_factor*float(len(ready_to_checked_diffs['part_matching_frames'])) + connection_bonus*float(connections_amount)) sem_dict = {'same_frames': len(ready_to_checked_diffs['matching_frames']), 'part_same_frames': len(ready_to_checked_diffs['part_matching_frames']), 'wrong_frames': len(ready_to_checked_diffs['missing_frames']), 'added_connections': connections_amount, 'cash': sem_cash} supersem_cash = (float(len(checked_to_ready_diffs['missing_frames'])+len(checked_to_ready_diffs['part_matching_frames']))*corrected_frame_value + float(len(ready_to_checked_diffs['matching_frames']))*checked_frame_value) supersem_dict = {'same_frames': len(checked_to_ready_diffs['matching_frames']), 'part_same_frames': len(checked_to_ready_diffs['part_matching_frames']), 'redo_frames': len(checked_to_ready_diffs['missing_frames']), 'cash': supersem_cash} supersem_real_semantics = RealizedSemantics(entry=entry, cash=supersem_dict['cash'], corr_frames=supersem_dict['redo_frames'], part_corr_frames=supersem_dict['part_same_frames'], ncorr_frames=supersem_dict['same_frames'], status=status, bonus=False) supersem_real_semantics.save() supersem_real_semantics.frames.add(*semantic_frames.all()) supersemanticist.user_stats.semantics_real_history.add(supersem_real_semantics) sem_real_semantics = RealizedSemantics(entry=entry, cash=sem_dict['cash'], prop_frames=sem_dict['same_frames'], part_prop_frames=sem_dict['part_same_frames'], wrong_frames=sem_dict['wrong_frames'], added_connections=sem_dict['added_connections'], status=status, bonus=True) sem_real_semantics.save() sem_real_semantics.frames.add(*semantic_frames.all()) semanticist.user_stats.semantics_real_history.add(sem_real_semantics) def count_connections(differences): amount = 0 for frame in differences['matching_frames']: amount += frame.connected_schemata().count() for frame in differences['part_matching_frames']: amount += frame.connected_schemata().count() return amount def remove_semantic_payments(entry): RealizedSemantics.objects.filter(entry=entry).delete()