-
Notifications
You must be signed in to change notification settings - Fork 43
/
Copy pathitem_sorter.py
131 lines (103 loc) · 3.61 KB
/
item_sorter.py
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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
from typing import Union
from darwin.doc_enum import DocEnum
class SortDirection(DocEnum):
"""
The sorting direction of items.
"""
ASCENDING = "asc", "Ascending sort order."
DESCENDING = "desc", "Descending sort order."
@classmethod
def parse(cls, direction: str) -> "SortDirection":
"""
Parses the given direction and returns the corresponding sort Enum.
Parameters
----------
direction: str
The direction of the sorting order. Can be 'asc' or 'ascending', 'desc' or 'descending'.
Returns
-------
SortDirection
The Enum representing a sorting direction.
Raises
------
ValueError
If the ``direction`` given is invalid.
"""
normalized_direction = direction.lower()
if cls._is_ascending(normalized_direction):
return cls.ASCENDING
if cls._is_descending(normalized_direction):
return cls.DESCENDING
raise ValueError(
f"Invalid direction '{direction}', use 'asc' or 'ascending', 'desc' or 'descending'."
)
@staticmethod
def _is_ascending(direction: str) -> bool:
return direction == "asc" or direction == "ascending"
@staticmethod
def _is_descending(direction: str) -> bool:
return direction == "desc" or direction == "descending"
class ItemSorter:
"""
Represents sorting for list of items.
Parameters
----------
field : str
The name of the field to be sorted.
direction : SortDirection
The direction of the sort.
"""
def __init__(self, field: str, direction: SortDirection):
self.field = field
self.direction = direction
@classmethod
def parse(cls, sort: Union[str, "ItemSorter"]) -> "ItemSorter":
"""
Parses the sorting given into an ItemSorter, capable of being used by Darwin.
Parameters
----------
sort : Union[str, ItemSorter]
The sort order. If it is a ``str``, it will be parsed, otherwise it returns the
``ItemSorter``.
Returns
-------
ItemSorter
A parsed ``ItemSorter`` representing a sorting direction.
Raises
------
ValueError
If the given sort parameter is invalid.
"""
if isinstance(sort, ItemSorter):
return sort
if not cls._has_valid_format(sort):
raise ValueError(
f"Invalid sort parameter '{sort}'. Correct format is 'field:direction' where 'direction' is optional and defaults to 'asc', i.e. 'updated_at:asc' or just 'updated_at'."
)
if not cls._has_direction(sort):
field = sort
direction = "asc"
else:
field, direction = sort.split(":")
if not cls._has_valid_field(field):
raise ValueError(
f"Invalid sort parameter '{field}', available sort fields: 'inserted_at', 'updated_at', 'file_size', 'filename', 'priority'."
)
return cls(field=field, direction=SortDirection.parse(direction))
@staticmethod
def _has_direction(sort: str) -> bool:
return ":" in sort
@staticmethod
def _has_valid_format(sort_by: str) -> bool:
return len(sort_by.split(":")) in [1, 2]
@staticmethod
def _has_valid_field(sort: str) -> bool:
return sort in [
"inserted_at",
"updated_at",
"file_size",
"filename",
"priority",
]
def __str__(self):
return f"{self.field}:{self.direction.value}"