autocompletes.py 2.93 KB
from django.http import JsonResponse

from django.utils.translation import gettext as _

from syntax.models_phrase import PhraseType, FixedAttributes, Lemma
from connections.models import Entry
from meanings.models import LexicalUnit

from entries.form_fields.query_managers import RegexQueryManager

object_getters = {
    # only take lus that are used as sel. prefs
    'lu' : lambda: LexicalUnit.objects.filter(synset__argument__isnull=False)
}

lookups = {
    'phrasetype' : (PhraseType, 'text_rep'),
    'lemma'      : (Entry, 'name'),
    'lex_lemma'  : (Lemma, 'name'),
    'fixed'      : (FixedAttributes, 'text'),
    'lu'         : (LexicalUnit,  'text_rep')
}

def get_lu_tooltip(lu):
    ret = []
    if lu.definition:
        ret.append(_('definicja:') + '<ul><li>{}</li></ul>'.format(lu.definition))
    if lu.gloss:
        ret.append(_('glosa:') + '<ul><li>{}</li></ul>'.format(lu.gloss))
    if lu.synset.definition:
        ret.append(_('definicja synsetu:') + '<ul><li>{}</li></ul>'.format(lu.synset.definition))
    other_lus = list(lu.synset.lexical_units.exclude(id=lu.id))
    if other_lus:
        ret.append(_('inne jednostki w synsecie:') + '<ul>{}</ul>'.format(''.join(map('<li>{}</li>'.format, sorted(map(str, other_lus))))))
    hypernyms = list(lu.synset.hypernyms.all())
    if hypernyms:
        ret.append(_('hiperonimy synsetu:') + '<ul>{}</ul>'.format(''.join(map('<li>{}</li>'.format, sorted(map(str, hypernyms))))))
    return ' '.join(ret)

tooltip_getters = {
    'lu' : get_lu_tooltip,
}

def autocomplete(request):
    if request.method == 'GET':
        what, text = request.GET['what'], request.GET['text']
        text = '{}.*'.format(text.strip())
        suggestions = []
        tooltips = dict()
        if what in lookups:
            model, field = lookups[what]
            tooltip_getter = tooltip_getters.get(what, None)
            qm = RegexQueryManager(lookup=field)
            try:
                queries = qm.make_queries(text, None)
                objects = object_getters.get(what, model.objects.all)()
                for query in queries:
                    objects = objects.filter(query).distinct()
                for o in objects:
                    suggestion = getattr(o, field)
                    suggestions.append(suggestion)
                    if tooltip_getter:
                        tooltip = tooltip_getter(o)
                        if tooltip:
                            tooltips[suggestion] = tooltip
                suggestions = sorted(suggestions)
            except Exception as e:
                suggestions = ['brak sugestii (błąd) ' + str(e)]
        else:
            suggestions = ['brak sugestii (nie zdefiniowano)']
        if not suggestions:
            suggestions = ['brak sugestii']
        if len(suggestions) > 10:
            suggestions = suggestions[:10] + ['+ {} sugestii'.format(len(suggestions) - 10)]
        return JsonResponse({'suggestions' : suggestions, 'tooltips' : tooltips})