]>
Commit | Line | Data |
---|---|---|
39ae355f TL |
1 | from typing import Any, Dict, List |
2 | ||
3 | from ..exceptions import DashboardException | |
4 | ||
5 | ||
6 | class ListPaginator: | |
7 | # pylint: disable=W0102 | |
8 | def __init__(self, offset: int, limit: int, sort: str, search: str, | |
9 | input_list: List[Any], default_sort: str, | |
10 | searchable_params: List[str] = [], sortable_params: List[str] = []): | |
11 | self.offset = offset | |
12 | if limit < -1: | |
13 | raise DashboardException(msg=f'Wrong limit value {limit}', code=400) | |
14 | self.limit = limit | |
15 | self.sort = sort | |
16 | self.search = search | |
17 | self.input_list = input_list | |
18 | self.default_sort = default_sort | |
19 | self.searchable_params = searchable_params | |
20 | self.sortable_params = sortable_params | |
21 | self.count = len(self.input_list) | |
22 | ||
23 | def get_count(self): | |
24 | return self.count | |
25 | ||
26 | def find_value(self, item: Dict[str, Any], key: str): | |
27 | # dot separated keys to lookup nested values | |
28 | keys = key.split('.') | |
29 | value = item | |
30 | for nested_key in keys: | |
31 | if nested_key in value: | |
32 | value = value[nested_key] | |
33 | else: | |
34 | return '' | |
35 | return value | |
36 | ||
37 | def list(self): | |
38 | end = self.offset + self.limit | |
39 | # '-1' is a special number to refer to all items in list | |
40 | if self.limit == -1: | |
41 | end = len(self.input_list) | |
42 | ||
43 | if not self.sort: | |
44 | self.sort = self.default_sort | |
45 | ||
46 | desc = self.sort[0] == '-' | |
47 | sort_by = self.sort[1:] | |
48 | ||
49 | if sort_by not in self.sortable_params: | |
50 | sort_by = self.default_sort[1:] | |
51 | ||
52 | # trim down by search | |
53 | trimmed_list = [] | |
54 | if self.search: | |
55 | for item in self.input_list: | |
56 | for searchable_param in self.searchable_params: | |
57 | value = self.find_value(item, searchable_param) | |
58 | if isinstance(value, str): | |
59 | if self.search in str(value): | |
60 | trimmed_list.append(item) | |
61 | ||
62 | else: | |
63 | trimmed_list = self.input_list | |
64 | ||
65 | def sort(item): | |
66 | return self.find_value(item, sort_by) | |
67 | ||
68 | sorted_list = sorted(trimmed_list, key=sort, reverse=desc) | |
69 | self.count = len(sorted_list) | |
70 | for item in sorted_list[self.offset:end]: | |
71 | yield item |