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