b2cbe8d94b7cd90d9b1d80cb2abbaa15f2023f8d
[wolnelektury.git] / src / search / utils.py
1 from django.db.models import Func
2 from django.contrib.postgres.search import SearchVector, SearchQuery, SearchQueryField, SearchHeadline as SH
3
4
5
6 class UnaccentTSVector(Func):
7     function = 'UNACCENT'
8     template = '%(function)s(%(expressions)s::text)::tsvector'
9
10
11 class Unaccent(Func):
12     function = 'UNACCENT'
13
14     
15 class ConcatTSVector(Func):
16     function = 'CONCAT'
17     template = '%(function)s(%(expressions)s)::tsvector'    
18
19
20 class UnaccentTSQuery(Func):
21     function = 'UNACCENT'
22     template = '%(function)s(%(expressions)s::text)::tsquery'
23     output_field = SearchQueryField()
24
25
26 class TSV(Func):
27     function='to_tsvector'
28     template = '''unaccent(
29       %(function)s('polish', %(expressions)s)::text)::tsvector ||
30      to_tsvector(
31        'polish_simple', 
32        unaccent(%(expressions)s)
33      )'''
34
35
36 def build_search_vector(*fields):
37     return TSV(*fields)
38
39
40 def build_search_query(*fields, **kwargs):
41     return UnaccentTSQuery(SearchQuery(*fields, **kwargs))
42
43
44
45 class SearchHeadline(SH):
46
47     def __init__(
48         self,
49         expression,
50         query,
51         *,
52         config=None,
53         start_sel=None,
54         stop_sel=None,
55         max_words=None,
56         min_words=None,
57         short_word=None,
58         highlight_all=None,
59         max_fragments=None,
60         fragment_delimiter=None,
61     ):
62         options = {
63             "StartSel": start_sel,
64             "StopSel": stop_sel,
65             "MaxWords": max_words,
66             "MinWords": min_words,
67             "ShortWord": short_word,
68             "HighlightAll": highlight_all,
69             "MaxFragments": max_fragments,
70             "FragmentDelimiter": fragment_delimiter,
71         }
72         self.options = {
73             option: value for option, value in options.items() if value is not None
74         }
75         expressions = (expression, query)
76         if config is not None:
77             config = SearchConfig.from_parameter(config)
78             expressions = (config,) + expressions
79         Func.__init__(self, *expressions)