ajax_user_stats.py 14.3 KB
# -*- 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.

"""Module covering functions used in user statistics views"""

from django.contrib.auth.models import User
from django.db.models import Count, Sum

from common.decorators import render, ajax
from dictionary.models import Lemma, Lemma_Status
from accounts.models import RealizedLemma, RealizedPhraseology, \
                            RealizedPhraseologyBinding, RealizedSemantics

@render('sel_user_stats.html')
@ajax(method='get', encode_result=False)
def get_user_stats(request, user_name):
  """Function rendering sel_user_stats.html page."""
  if user_name:
    user = User.objects.get(username=user_name)
  else:
    user = request.user
  
  all_owned_lemmas = user.lemmas.filter(old=False)
  all_phraseologic_owned_lemmas = user.phraseologist_lemmas.filter(old=False)
  all_semantic_owned_lemmas = user.semanticist_lemmas.filter(old=False)
  ord_statuses = Lemma_Status.objects.order_by('priority')[1:]
  status_table_dict = []
  all_owned_frames_count = 0
  all_phraseologic_owned_frames_count = 0
  all_semantic_owned_frames_count = 0

  for status in ord_statuses:
    owned_lemmas = all_owned_lemmas.filter(status=status)
    phraseologic_owned_lemmas = all_phraseologic_owned_lemmas.filter(status=status)
    semantic_owned_lemmas = all_semantic_owned_lemmas.filter(status=status)
    owned_frames_count = owned_lemmas.annotate(num_frames=Count('frames')).aggregate(Sum('num_frames'))['num_frames__sum']
    phraseologic_owned_frames_count = phraseologic_owned_lemmas.annotate(num_frames=Count('frames')).aggregate(Sum('num_frames'))['num_frames__sum']
    semantic_owned_frames_count = semantic_owned_lemmas.annotate(num_frames=Count('frames')).aggregate(Sum('num_frames'))['num_frames__sum']
    
    if not owned_frames_count:
        owned_frames_count = 0
    if not phraseologic_owned_frames_count:
        phraseologic_owned_frames_count = 0
    if not semantic_owned_frames_count:
        semantic_owned_frames_count = 0
    status_dict = {'status': status.status,
                   'owned_lemmas_count': owned_lemmas.count(),
                   'owned_frames_count': owned_frames_count,
                   'phraseologic_owned_lemmas_count': phraseologic_owned_lemmas.count(),
                   'phraseologic_owned_frames_count': phraseologic_owned_frames_count,
                   'semantic_owned_lemmas_count': semantic_owned_lemmas.count(),
                   'semantic_owned_frames_count': semantic_owned_frames_count}
    status_table_dict.append(status_dict)
    all_owned_frames_count += owned_frames_count
    all_phraseologic_owned_frames_count += phraseologic_owned_frames_count
    all_semantic_owned_frames_count += semantic_owned_frames_count
    
  lex_work_stats = get_lexical_stats(user)
  phraseology_work_stats = get_phraseology_stats(user)
  semantics_work_stats = get_semantics_stats(user)
  total_earned_cash = lex_work_stats['earned_cash']+phraseology_work_stats['earned_cash']+semantics_work_stats['earned_cash']
  return {'lemma_status_tab': status_table_dict,
          'all_owned_lemmas_count': all_owned_lemmas.count(),
          'all_owned_frames_count': all_owned_frames_count,
          'all_phraseologic_owned_lemmas_count': all_phraseologic_owned_lemmas.count(),
          'all_phraseologic_owned_frames_count': all_phraseologic_owned_frames_count,
          'all_semantic_owned_lemmas_count': all_semantic_owned_lemmas.count(),
          'all_semantic_owned_frames_count': all_semantic_owned_frames_count,
          'earned_cash': total_earned_cash,
          'paid_cash'     : round(user.user_stats.paid_cash, 2),
          'surcharge'     : round(user.user_stats.paid_cash-total_earned_cash, 2),
          'lex_work_stats': lex_work_stats,
          'phraseology_work_stats': phraseology_work_stats,
          'semantics_work_stats': semantics_work_stats}
  
def get_lexical_stats(user):
    earned_cash = RealizedLemma.objects.filter(user_stats__user=user).aggregate(Sum('cash'))['cash__sum']
    if earned_cash == None:
        earned_cash = 0.0
    lemmas_marked_to_erase = Lemma.objects.filter(owner=user, 
                                                  old=False, 
                                                  status__type__sym_name='erase')
    lemmas_to_erase_cash = 1.0*float(lemmas_marked_to_erase.count())
    earned_cash += lemmas_to_erase_cash
    
    bonus_cash = RealizedLemma.objects.filter(user_stats__user=user, 
                                              bonus=True).aggregate(Sum('cash'))['cash__sum']
    if bonus_cash == None:
        bonus_cash = 0.0        
    prop_frames = RealizedLemma.objects.filter(user_stats__user=user, 
                                               paid=False).aggregate(Sum('prop_frames'))['prop_frames__sum']
    if prop_frames == None:
        prop_frames = 0
    wrong_frames = RealizedLemma.objects.filter(user_stats__user=user, 
                                                paid=False).aggregate(Sum('wrong_frames'))['wrong_frames__sum']
    if wrong_frames == None:
        wrong_frames = 0
    corr_frames = RealizedLemma.objects.filter(user_stats__user=user, 
                                               paid=False).aggregate(Sum('corr_frames'))['corr_frames__sum']
    if corr_frames == None:
        corr_frames = 0
    ncorr_frames = RealizedLemma.objects.filter(user_stats__user=user, 
                                               paid=False).aggregate(Sum('ncorr_frames'))['ncorr_frames__sum']
    if ncorr_frames == None:
        ncorr_frames = 0
    made_frames = RealizedLemma.objects.filter(user_stats__user=user, 
                                               paid=False).aggregate(Sum('made_frames'))['made_frames__sum']
    if made_frames == None:
        made_frames = 0
      
    efficacy = 0.0
    if prop_frames+wrong_frames > 0:
        efficacy = float(prop_frames)/float(prop_frames+wrong_frames)*100.0
        
    
    lex_work_stats = {'earned_cash': round(earned_cash, 2),
                      'bonus_cash' : round(bonus_cash, 2),
                      'lemmas_to_erase_cash': round(lemmas_to_erase_cash, 2),
                      'prop_frames': prop_frames,
                      'wrong_frames': wrong_frames,
                      'corr_frames': corr_frames,
                      'checked_frames': ncorr_frames+corr_frames,
                      'made_frames'   : made_frames,
                      'efficacy'      : round(efficacy, 2)}
    return lex_work_stats    
    
    
def get_phraseology_stats(user):
    added_bindings = RealizedPhraseologyBinding.objects.filter(user_stats__user=user)
    used_bindings = get_used_bindings(added_bindings)
    
    earned_cash_frames = RealizedPhraseology.objects.filter(user_stats__user=user).aggregate(Sum('cash'))['cash__sum']
    if earned_cash_frames == None:
        earned_cash_frames = 0.0
    earned_cash_bindings = used_bindings.aggregate(Sum('cash'))['cash__sum']
    if earned_cash_bindings == None:
        earned_cash_bindings = 0.0
    earned_cash = earned_cash_frames+earned_cash_bindings
    bonus_cash = RealizedPhraseology.objects.filter(user_stats__user=user, 
                                                    bonus=True).aggregate(Sum('cash'))['cash__sum']
    if bonus_cash == None:
        bonus_cash = 0.0
    
    prop_frames = RealizedPhraseology.objects.filter(user_stats__user=user, 
                                               paid=False).aggregate(Sum('prop_frames'))['prop_frames__sum']
    if prop_frames == None:
        prop_frames = 0
    wrong_frames = RealizedPhraseology.objects.filter(user_stats__user=user, 
                                                paid=False).aggregate(Sum('wrong_frames'))['wrong_frames__sum']
    if wrong_frames == None:
        wrong_frames = 0
    corr_frames = RealizedPhraseology.objects.filter(user_stats__user=user, 
                                               paid=False).aggregate(Sum('corr_frames'))['corr_frames__sum']
    if corr_frames == None:
        corr_frames = 0
    ncorr_frames = RealizedPhraseology.objects.filter(user_stats__user=user, 
                                               paid=False).aggregate(Sum('ncorr_frames'))['ncorr_frames__sum']
    if ncorr_frames == None:
        ncorr_frames = 0
        
    new_frames = RealizedPhraseology.objects.filter(user_stats__user=user, 
                                               paid=False).aggregate(Sum('new_frames'))['new_frames__sum']
    if new_frames == None:
        new_frames = 0
        
    reused_frames = RealizedPhraseology.objects.filter(user_stats__user=user, 
                                               paid=False).aggregate(Sum('reused_frames'))['reused_frames__sum']
    if reused_frames == None:
        reused_frames = 0
                                               
    efficacy = 0.0
    if prop_frames+wrong_frames > 0:
        efficacy = float(prop_frames)/float(prop_frames+wrong_frames)*100.0
    
    phraseologic_empty_frame_value = 1.0
    made_phraseologic_empty_entries = user.user_stats.made_phraseologic_empty_entries_count()
    checked_phraseologic_empty_entries = user.user_stats.checked_phraseologic_empty_entries_count()
    earned_cash += phraseologic_empty_frame_value*float(made_phraseologic_empty_entries+checked_phraseologic_empty_entries)
      
    phraseology_work_stats = {'earned_cash': round(earned_cash, 2),
                              'bonus_cash' : round(bonus_cash, 2),
                              'prop_frames': prop_frames,
                              'wrong_frames': wrong_frames,
                              'corr_frames': corr_frames,
                              'checked_frames': ncorr_frames+corr_frames,
                              'new_frames'   : new_frames,
                              'reused_frames': reused_frames,
                              'added_bindings': added_bindings.count(),
                              'used_bindings':  used_bindings.count(),
                              'made_phraseologic_empty_entries': made_phraseologic_empty_entries,
                              'checked_phraseologic_empty_entries': checked_phraseologic_empty_entries,
                              'efficacy'      : round(efficacy, 2)}
    return phraseology_work_stats 

def get_used_bindings(added_bindings):
    used_bindings = added_bindings
    for added_binding in added_bindings.all():
        binded_entry = added_binding.binded_entry
        act_binded_lemma = binded_entry.lemmas.get(old=False)
        if act_binded_lemma.status.type.sym_name == 'erase':
            used_bindings = used_bindings.exclude(pk=added_binding.pk)
        else:
            added_frame = added_binding.phraseologic_frame
            act_lemma_phras_frames = act_binded_lemma.frames.annotate(positions_count=Count('positions'))\
                                                            .filter(phraseologic=True, 
                                                                    positions_count=added_frame.positions.count())
            for pos in added_frame.positions.all():
                act_lemma_phras_frames = act_lemma_phras_frames.filter(positions__text_rep=pos.text_rep)
            if not act_lemma_phras_frames.exists():
                used_bindings = used_bindings.exclude(pk=added_binding.pk)
    return used_bindings

def get_semantics_stats(user):
    earned_cash = RealizedSemantics.objects.filter(user_stats__user=user).aggregate(Sum('cash'))['cash__sum']
    if earned_cash == None:
        earned_cash = 0.0
    
    bonus_cash = RealizedSemantics.objects.filter(user_stats__user=user, 
                                                  bonus=True).aggregate(Sum('cash'))['cash__sum']
    if bonus_cash == None:
        bonus_cash = 0.0        
    prop_frames = RealizedSemantics.objects.filter(user_stats__user=user).aggregate(Sum('prop_frames'))['prop_frames__sum']
    if prop_frames == None:
        prop_frames = 0
    wrong_frames = RealizedSemantics.objects.filter(user_stats__user=user).aggregate(Sum('wrong_frames'))['wrong_frames__sum']
    if wrong_frames == None:
        wrong_frames = 0
    corr_frames = RealizedSemantics.objects.filter(user_stats__user=user).aggregate(Sum('corr_frames'))['corr_frames__sum']
    if corr_frames == None:
        corr_frames = 0
    ncorr_frames = RealizedSemantics.objects.filter(user_stats__user=user).aggregate(Sum('ncorr_frames'))['ncorr_frames__sum']
    if ncorr_frames == None:
        ncorr_frames = 0
    made_frames = RealizedSemantics.objects.filter(user_stats__user=user).aggregate(Sum('made_frames'))['made_frames__sum']
    if made_frames == None:
        made_frames = 0
    efficacy = 0.0
    if prop_frames+wrong_frames > 0:
        efficacy = float(prop_frames)/float(prop_frames+wrong_frames)*100.0
    
    sem_work_stats = {'earned_cash'   : round(earned_cash, 2),
                      'bonus_cash'    : round(bonus_cash, 2),
                      'prop_frames'   : prop_frames,
                      'wrong_frames'  : wrong_frames,
                      'corr_frames'   : corr_frames,
                      'checked_frames': ncorr_frames+corr_frames,
                      'made_frames'   : made_frames,
                      'efficacy'      : round(efficacy, 2)}
    return sem_work_stats