]> git.phdru.name Git - m_librarian.git/blob - m_librarian/search.py
Feat(config): getlist
[m_librarian.git] / m_librarian / search.py
1 from sqlobject.sqlbuilder import AND, OR, func
2 from .config import get_config
3 from .db import Author, Book, Extension, Genre, Language
4
5 __all__ = [
6     'mk_search_conditions',
7     'search_authors', 'search_books', 'search_extensions',
8     'search_genres', 'search_languages',
9 ]
10
11
12 def _mk_search_conditions_with_operator(table, case_sensitive, comparison_op,
13                                         values, expressions):
14     if expressions is None:
15         expressions = []
16     _expressions = []
17     for column, value in values.items():
18         if column == 'id':
19             _expressions.append(table.q.id == value)
20             break
21     if case_sensitive:
22         for column, value in values.items():
23             if column == 'id':
24                 continue
25             _expressions.append(
26                 getattr(getattr(table.q, column), comparison_op)(value))
27         for expr, value in expressions:
28             _expressions.append(
29                 getattr(expr, comparison_op)(value))
30     else:
31         for column, value in values.items():
32             if column == 'id':
33                 continue
34             _expressions.append(
35                 getattr(func.lower(
36                     getattr(table.q, column)),
37                     comparison_op)(value.lower()))
38         for expr, value in expressions:
39             _expressions.append(
40                 getattr(func.lower(expr), comparison_op)(value.lower()))
41     return _expressions
42
43
44 _comparison_operators = {
45     'start': 'startswith',
46     'substring': 'contains',
47     'full': '__eq__',
48 }
49
50
51 def mk_search_conditions(table, search_type, case_sensitive, values,
52                          expressions=None, join_expressions=None):
53     if join_expressions is None:
54         join_expressions = []
55     return _mk_search_conditions_with_operator(
56         table, case_sensitive, _comparison_operators[search_type],
57         values, expressions) + join_expressions
58
59
60 def _search(table, search_type, case_sensitive, values,
61             expressions=None, join_expressions=None, orderBy=None):
62     conditions = mk_search_conditions(
63         table, search_type, case_sensitive, values, expressions=expressions,
64         join_expressions=join_expressions)
65     return table.select(AND(*conditions), orderBy=orderBy)
66
67
68 def search_authors(search_type, case_sensitive, values,
69                    expressions=None, orderBy=None):
70     return _search(Author, search_type, case_sensitive, values,
71                    expressions=expressions, orderBy=orderBy)
72
73
74 def search_books(search_type, case_sensitive, values, join_expressions=None,
75                  orderBy=None, use_filters=False):
76     if use_filters:
77         config = get_config()
78         lang_filter = config.getlist('filters', 'lang')
79         deleted_filter = config.getint('filters', 'deleted')
80         if lang_filter:
81             if join_expressions is None:
82                 join_expressions = []
83             lang_conditions = []
84             for lang in lang_filter:
85                 lvalues = {'name': lang}
86                 conditions = mk_search_conditions(
87                     Language, search_type, case_sensitive, lvalues)
88                 lang_conditions.append(conditions)
89             join_expressions.append(Book.j.language)
90             join_expressions.append(OR(*lang_conditions))
91     conditions = mk_search_conditions(
92         Book, search_type, case_sensitive, values,
93         join_expressions=join_expressions)
94     if use_filters and not deleted_filter:
95         conditions.append(Book.q.deleted == False)  # noqa: E712
96     return Book.select(AND(*conditions), orderBy=orderBy)
97
98
99 def search_extensions(search_type, case_sensitive, values, orderBy=None):
100     return _search(Extension, search_type, case_sensitive, values,
101                    orderBy=orderBy)
102
103
104 def search_genres(search_type, case_sensitive, values, orderBy=None):
105     return _search(Genre, search_type, case_sensitive, values,
106                    orderBy=orderBy)
107
108
109 def search_languages(search_type, case_sensitive, values, orderBy=None):
110     return _search(Language, search_type, case_sensitive, values,
111                    orderBy=orderBy)