search fix
[wolnelektury.git] / apps / search / views.py
1 # -*- coding: utf-8 -*-
2
3 from django.shortcuts import render_to_response, get_object_or_404
4 from django.template import RequestContext
5 from django.contrib.auth.decorators import login_required
6 from django.views.decorators import cache
7 from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponsePermanentRedirect
8 from django.utils.translation import ugettext as _
9
10 from catalogue.utils import get_random_hash
11 from catalogue.models import Book, Tag, Fragment, TAG_CATEGORIES
12 from catalogue.fields import dumps
13 from catalogue.views import JSONResponse
14 from catalogue import forms
15 from search import MultiSearch, JVM, SearchResult
16 from lucene import StringReader
17 from suggest.forms import PublishingSuggestForm
18
19 import enchant
20
21 dictionary = enchant.Dict('pl_PL')
22
23
24 def did_you_mean(query, tokens):
25     change = {}
26     # sprawdzić, czy słowo nie jest aby autorem - proste szukanie termu w author!
27     for t in tokens:
28         print("%s ok? %s, sug: %s" %(t, dictionary.check(t), dictionary.suggest(t)))
29         if not dictionary.check(t):
30             try:
31                 change[t] = dictionary.suggest(t)[0]
32             except IndexError:
33                 pass
34
35     if change == {}:
36         return None
37
38     for frm, to in change.items():
39         query = query.replace(frm, to)
40
41     return query
42
43
44 def hint(request):
45     prefix = request.GET.get('term', '')
46     if len(prefix) < 2:
47         return JSONResponse([])
48     JVM.attachCurrentThread()
49     s = MultiSearch()
50
51     hint = s.hint()
52     try:
53         tags = request.GET.get('tags', '')
54         hint.tags(Tag.get_tag_list(tags))
55     except:
56         pass
57
58     # tagi beda ograniczac tutaj
59     # ale tagi moga byc na ksiazce i na fragmentach
60     # jezeli tagi dot tylko ksiazki, to wazne zeby te nowe byly w tej samej ksiazce
61     # jesli zas dotycza themes, to wazne, zeby byly w tym samym fragmencie.
62
63     
64     tags = s.hint_tags(prefix)
65     books = s.hint_books(prefix)
66
67     # TODO DODAC TU HINTY
68
69     return JSONResponse(
70         [{'label': t.name,
71           'category': _(t.category),
72           'id': t.id,
73           'url': t.get_absolute_url()}
74           for t in tags] + \
75           [{'label': b.title,
76             'category': _('book'),
77             'id': b.id,
78             'url': b.get_absolute_url()}
79             for b in books])
80
81
82 def foo(s, q, tag_list=None):
83     hint = s.hint()
84     try:
85         tag_list = Tag.get_tag_list(tag_list)
86         hint.tags(tag_list)
87     except:
88         tag_list = None
89
90     q = StringReader(q)
91     return (q, hint)
92
93
94 def main(request):
95     results = {}
96     JVM.attachCurrentThread()  # where to put this?
97     srch = MultiSearch()
98
99     results = None
100     query = None
101     fuzzy = False
102
103     if 'q' in request.GET:
104         tags = request.GET.get('tags', '')
105         query = request.GET['q']
106         book_id = request.GET.get('book', None)
107         book = None
108         if book_id is not None:
109             book = get_object_or_404(Book, id=book_id)
110
111         hint = srch.hint()
112         try:
113             tag_list = Tag.get_tag_list(tags)
114         except:
115             tag_list = []
116
117         if len(query) < 2:
118             return render_to_response('catalogue/search_too_short.html', {'tags': tag_list, 'prefix': query},
119                                       context_instance=RequestContext(request))
120
121         hint.tags(tag_list)
122         if book:
123             hint.books(book)
124
125         toks = StringReader(query)
126         fuzzy = 'fuzzy' in request.GET
127         if fuzzy:
128             fuzzy = 0.7
129
130         results = SearchResult.aggregate(srch.search_perfect_book(toks, fuzzy=fuzzy, hint=hint),
131                                          srch.search_perfect_parts(toks, fuzzy=fuzzy, hint=hint),
132                                          srch.search_everywhere(toks, fuzzy=fuzzy, hint=hint))
133         results.sort(reverse=True)
134
135         for r in results:
136             print r.hits
137
138         if len(results) == 1:
139             if len(results[0].hits) == 0:
140                 return HttpResponseRedirect(results[0].book.get_absolute_url())
141             elif len(results[0].hits) == 1 and results[0].hits[0] is not None:
142                 frag = Fragment.objects.get(anchor=results[0].hits[0])
143                 return HttpResponseRedirect(frag.get_absolute_url())
144         elif len(results) == 0:
145             form = PublishingSuggestForm(initial={"books": query + ", "})
146             return render_to_response('catalogue/search_no_hits.html',
147                                       {'tags': tag_list, 'prefix': query, "pubsuggest_form": form,
148                                        'form': forms.SearchForm()},
149                 context_instance=RequestContext(request))
150
151         return render_to_response('catalogue/search_multiple_hits.html',
152                                   {'tags': tag_list, 'prefix': query,
153                                    'results': results, 'from': forms.SearchForm()},
154             context_instance=RequestContext(request))
155
156     # return render_to_response('newsearch/search.html', {'results': results,
157     #                                                     'did_you_mean': (query is not None) and
158     #                                                     did_you_mean(query, srch.get_tokens(query, field='SIMPLE')),
159     #                                                     'fuzzy': fuzzy},
160     #                           context_instance=RequestContext(request))