ajax_pattern_view.py 5.48 KB
#-*- coding:utf-8 -*-

from django.utils.simplejson import dumps as json_encode
from dictionary.models import Pattern, Ending, BaseFormLabel, PatternType, \
                              visible_vocabularies, Qualifier
from dictionary.forms import PatternEditForm, PatternTypeForm, QualifierForm
from dictionary.ajax_jqgrid import JqGridAjax
from accounts.models import filtering_mode
from common.decorators import render, ajax, AjaxError


class PatternGrid(JqGridAjax):
  model = Pattern
  search_field = 'name'

  @staticmethod
  def filter_special_case(filter, lookup, negated, queryset):
    field = filter['field']
    if field == 'part_of_speech':
      field = 'type__lexical_class__symbol'
    elif field == 'type':
      field = 'type__entry'
    return False, field, {}, queryset

  @staticmethod
  def apply_mask(patterns, mask, sort_rules):
    return patterns.filter(name__istartswith=mask)

  @staticmethod
  def response_row(pattern):
    return [
      pattern.name,
      pattern.type.entry,
      pattern.type.lexical_class.symbol,
    ]


# Zapytanie o indeks wiersza o pewnym id przy danym sortowaniu
@ajax(method='get')
def find_id(request, id, sort_rules, mask, filters=None):
  return PatternGrid.find_id(
    filtering_mode(request.user), id, filters, sort_rules, mask)


# Zapytanie o id oraz indeks wiersza przy danym sortowaniu
# pierwszego wiersza, którego hasło rozpoczyna się od mask.
# 'selected_id' < 0, jeśli takiego nie ma
@ajax(method='get')
def get_location(request, sort_rules, filters=None, mask=''):
  return PatternGrid.get_location(
    filtering_mode(request.user), sort_rules, filters, mask)


@ajax(method='get')
def get_patterns(request, page, rows, sort_rules, filters=None, mask='',
                 target_page=0, totalrows=0):
  request.session['pattern-sort_rules'] = json_encode(sort_rules)
  request.session['pattern-filters'] = json_encode(filters)
  page = target_page or page
  limit = totalrows or rows
  return PatternGrid.get_page(
    filtering_mode(request.user), page, limit, sort_rules, filters, mask)


@render()
@ajax(method='get', encode_result=False)
def pattern_edit_form(request, id):
  if not request.user.has_perm('dictionary.view_pattern'):
    raise AjaxError('access denied')
  to_return = {}
  p = Pattern.objects.get(pk=id)
  editable = request.user.has_perm('dictionary.change_pattern')
  to_return['form'] = PatternEditForm(instance=p, editable=editable)
  to_return['type_form'] = PatternTypeForm(instance=p.type, editable=editable)
  to_return['id'] = p.pk
  to_return['editable'] = editable
  bfls = p.type.base_form_labels()
  ending_groups = dict((bfl, []) for bfl in bfls)
  endings = p.endings.order_by('base_form_label', 'index')
  visible_vocabs = visible_vocabularies(request.user)
  vocabularies = visible_vocabs.filter(editors=request.user)
  for e in endings:
    q_form = QualifierForm(
      qualified=e, rw_vocabularies=vocabularies, editable=editable,
      prefix='end%s' % e.pk)
    ending_groups[e.base_form_label].append((e, q_form))
  to_return['ending_groups'] = ending_groups
  return to_return


# mogłoby iść przez js_vars...
@render('ending_row.html')
@ajax(method='get', encode_result=False)
def new_ending_row(request):
  ending = {'string': '', 'id': 'add-NUM'}
  visible_vocabs = visible_vocabularies(request.user)
  vocabularies = visible_vocabs.filter(editors=request.user)
  form = QualifierForm(rw_vocabularies=vocabularies, prefix='add-NUM')
  return {'ending': ending, 'editable': True, 'form': form}


@ajax(method='post')
def update_pattern(request, form_data):
  if not request.user.has_perm('dictionary.change_pattern'):
    raise AjaxError('access denied')
  form_dict = dict((x['name'], x['value']) for x in form_data)
  p = Pattern.objects.get(pk=form_dict['id'])
  form = PatternEditForm(data=form_dict, instance=p)
  type_form = PatternTypeForm(data=form_dict)
  if type_form.is_valid():
    type_qs = PatternType.objects.filter(
      entry=type_form.cleaned_data['entry'],
      lexical_class=type_form.cleaned_data['lexical_class'])
  else:
    raise AjaxError('invalid data')
  if form.is_valid() and len(type_qs) == 1:
    form.save()
    p.type = type_qs[0]
    p.save()
    for ending_pk in form_dict['deleted']:
      Ending.objects.get(pk=int(ending_pk)).delete()
    visible_vocabs = visible_vocabularies(request.user)
    vocabularies = visible_vocabs.filter(editors=request.user)
    qualifiers = Qualifier.objects.filter(vocabulary__in=vocabularies)
    for bfl_endings in form_dict['ending_list']:
      endings_data = bfl_endings['endings']
      bfl = BaseFormLabel.objects.get(entry=bfl_endings['base_form_label'])
      endings = []
      for index, ending_data in zip(range(1, len(endings_data) + 1), endings_data):
        quals = set(int(q) for q in ending_data['qualifiers'])
        if ending_data['id'] == 'add':
          ending = Ending.objects.create(
            pattern=p, base_form_label=bfl, string=ending_data['string'],
            index=index)
        else:
          ending = Ending.objects.get(pk=int(ending_data['id']))
          ending.index = index
          ending.string = ending_data['string']
          ending.save()
        for qualifier in qualifiers:
          qualifier.set_for(ending, qualifier.pk in quals)
        endings.append(ending)
  else:
    raise AjaxError('invalid data')
  return {}


@ajax(method='post')
def save_columns(request, col_model, col_names, remap):
  request.session['pattern-colModel'] = col_model
  request.session['pattern-colNames'] = col_names
  request.session['pattern-remap'] = remap
  return {}