|
1 |
| -from typing import List, Optional, Sequence, Tuple, Union |
| 1 | +from typing import Optional |
2 | 2 |
|
3 | 3 | from flask import request
|
4 | 4 |
|
5 | 5 | from ._exceptions import UnAuthenticatedException, ValidationFailedException
|
6 |
| -from .utils import TimeValues |
7 | 6 |
|
8 | 7 |
|
9 | 8 | def resolve_auth_token() -> Optional[str]:
|
@@ -55,135 +54,3 @@ def require_any(*values: str, empty=False) -> bool:
|
55 | 54 | if request.values.get(value) or (empty and value in request.values):
|
56 | 55 | return True
|
57 | 56 | raise ValidationFailedException(f"missing parameter: need one of [{', '.join(values)}]")
|
58 |
| - |
59 |
| - |
60 |
| -def _extract_value(key: Union[str, Sequence[str]]) -> Optional[str]: |
61 |
| - if isinstance(key, str): |
62 |
| - return request.values.get(key) |
63 |
| - for k in key: |
64 |
| - if k in request.values: |
65 |
| - return request.values[k] |
66 |
| - return None |
67 |
| - |
68 |
| - |
69 |
| -def _extract_list_value(key: Union[str, Sequence[str]]) -> List[str]: |
70 |
| - if isinstance(key, str): |
71 |
| - return request.values.getlist(key) |
72 |
| - for k in key: |
73 |
| - if k in request.values: |
74 |
| - return request.values.getlist(k) |
75 |
| - return [] |
76 |
| - |
77 |
| - |
78 |
| -def extract_strings(key: Union[str, Sequence[str]]) -> Optional[List[str]]: |
79 |
| - s = _extract_list_value(key) |
80 |
| - if not s: |
81 |
| - # nothing to do |
82 |
| - return None |
83 |
| - # we can have multiple values |
84 |
| - return [v for vs in s for v in vs.split(",")] |
85 |
| - |
86 |
| - |
87 |
| -IntRange = Union[Tuple[int, int], int] |
88 |
| - |
89 |
| - |
90 |
| -def extract_integer(key: Union[str, Sequence[str]]) -> Optional[int]: |
91 |
| - s = _extract_value(key) |
92 |
| - if not s: |
93 |
| - # nothing to do |
94 |
| - return None |
95 |
| - try: |
96 |
| - return int(s) |
97 |
| - except ValueError: |
98 |
| - raise ValidationFailedException(f"{key}: not a number: {s}") |
99 |
| - |
100 |
| - |
101 |
| -def extract_integers(key: Union[str, Sequence[str]]) -> Optional[List[IntRange]]: |
102 |
| - parts = extract_strings(key) |
103 |
| - if not parts: |
104 |
| - # nothing to do |
105 |
| - return None |
106 |
| - |
107 |
| - def _parse_range(part: str): |
108 |
| - if "-" not in part: |
109 |
| - return int(part) |
110 |
| - r = part.split("-", 2) |
111 |
| - first = int(r[0]) |
112 |
| - last = int(r[1]) |
113 |
| - if first == last: |
114 |
| - # the first and last numbers are the same, just treat it as a singe value |
115 |
| - return first |
116 |
| - elif last > first: |
117 |
| - # add the range as an array |
118 |
| - return (first, last) |
119 |
| - # the range is inverted, this is an error |
120 |
| - raise ValidationFailedException(f"{key}: the given range is inverted") |
121 |
| - |
122 |
| - try: |
123 |
| - values = [_parse_range(part) for part in parts] |
124 |
| - # check for invalid values |
125 |
| - return None if any(v is None for v in values) else values |
126 |
| - except ValueError as e: |
127 |
| - raise ValidationFailedException(f"{key}: not a number: {str(e)}") |
128 |
| - |
129 |
| - |
130 |
| -def parse_date(s: str) -> int: |
131 |
| - # parses a given string in format YYYYMMDD or YYYY-MM-DD to a number in the form YYYYMMDD |
132 |
| - try: |
133 |
| - return int(s.replace("-", "")) |
134 |
| - except ValueError: |
135 |
| - raise ValidationFailedException(f"not a valid date: {s}") |
136 |
| - |
137 |
| - |
138 |
| -def extract_date(key: Union[str, Sequence[str]]) -> Optional[int]: |
139 |
| - s = _extract_value(key) |
140 |
| - if not s: |
141 |
| - return None |
142 |
| - return parse_date(s) |
143 |
| - |
144 |
| - |
145 |
| -def extract_dates(key: Union[str, Sequence[str]]) -> Optional[TimeValues]: |
146 |
| - parts = extract_strings(key) |
147 |
| - if not parts: |
148 |
| - return None |
149 |
| - values: TimeValues = [] |
150 |
| - |
151 |
| - def push_range(first: str, last: str): |
152 |
| - first_d = parse_date(first) |
153 |
| - last_d = parse_date(last) |
154 |
| - if first_d == last_d: |
155 |
| - # the first and last numbers are the same, just treat it as a singe value |
156 |
| - return first_d |
157 |
| - if last_d > first_d: |
158 |
| - # add the range as an array |
159 |
| - return (first_d, last_d) |
160 |
| - # the range is inverted, this is an error |
161 |
| - raise ValidationFailedException(f"{key}: the given range is inverted") |
162 |
| - |
163 |
| - for part in parts: |
164 |
| - if "-" not in part and ":" not in part: |
165 |
| - # YYYYMMDD |
166 |
| - values.append(parse_date(part)) |
167 |
| - continue |
168 |
| - if ":" in part: |
169 |
| - # YYYY-MM-DD:YYYY-MM-DD |
170 |
| - range_part = part.split(":", 2) |
171 |
| - r = push_range(range_part[0], range_part[1]) |
172 |
| - if r is None: |
173 |
| - return None |
174 |
| - values.append(r) |
175 |
| - continue |
176 |
| - # YYYY-MM-DD or YYYYMMDD-YYYYMMDD |
177 |
| - # split on the dash |
178 |
| - range_part = part.split("-") |
179 |
| - if len(range_part) == 2: |
180 |
| - # YYYYMMDD-YYYYMMDD |
181 |
| - r = push_range(range_part[0], range_part[1]) |
182 |
| - if r is None: |
183 |
| - return None |
184 |
| - values.append(r) |
185 |
| - continue |
186 |
| - # YYYY-MM-DD |
187 |
| - values.append(parse_date(part)) |
188 |
| - # success, return the list |
189 |
| - return values |
0 commit comments