22from .option_normalization import normalize_boolean
33
44
5- def _build_year_range_values (start_value , end_value ):
5+ DEFAULT_YEAR_MIN = 1800
6+ DEFAULT_YEAR_MAX = 2100
7+
8+
9+ def _parse_number_bound (value ):
10+ try :
11+ return int (value ) if value not in (None , "" ) else None
12+ except (TypeError , ValueError ):
13+ return None
14+
15+
16+ def _parse_numeric_value (value , * , min_value = None , max_value = None ):
617 try :
7- start_year = int (start_value ) if start_value not in (None , "" ) else None
18+ numeric_value = int (value ) if value not in (None , "" ) else None
819 except (TypeError , ValueError ):
9- start_year = None
20+ return None
21+
22+ if numeric_value is None :
23+ return None
24+ if min_value is not None and numeric_value < min_value :
25+ return None
26+ if max_value is not None and numeric_value > max_value :
27+ return None
28+ return numeric_value
29+
30+
31+ def _build_numeric_range_value (start_value , end_value , * , min_value = None , max_value = None ):
32+ start_number = _parse_numeric_value (
33+ start_value ,
34+ min_value = min_value ,
35+ max_value = max_value ,
36+ )
37+ end_number = _parse_numeric_value (
38+ end_value ,
39+ min_value = min_value ,
40+ max_value = max_value ,
41+ )
42+
43+ if start_number is None and end_number is None :
44+ return {}
1045
46+ if start_number is not None and end_number is not None and start_number > end_number :
47+ start_number , end_number = end_number , start_number
48+
49+ range_value = {}
50+ if start_number is not None :
51+ range_value ["gte" ] = start_number
52+ if end_number is not None :
53+ range_value ["lte" ] = end_number
54+ return range_value
55+
56+
57+ def _parse_year_value (value , * , min_year = None , max_year = None ):
58+ try :
59+ year = int (value ) if value not in (None , "" ) else None
60+ except (TypeError , ValueError ):
61+ return None
62+
63+ if year is None :
64+ return None
65+ min_year = DEFAULT_YEAR_MIN if min_year is None else min_year
66+ max_year = DEFAULT_YEAR_MAX if max_year is None else max_year
67+ if len (str (abs (year ))) != 4 :
68+ return None
69+ if min_year is not None and year < min_year :
70+ return None
71+ if max_year is not None and year > max_year :
72+ return None
73+ return year
74+
75+
76+ def _parse_year_bound (value ):
1177 try :
12- end_year = int (end_value ) if end_value not in (None , "" ) else None
78+ return int (value ) if value not in (None , "" ) else None
1379 except (TypeError , ValueError ):
14- end_year = None
80+ return None
81+
82+
83+ def _build_year_range_values (start_value , end_value , * , min_year = None , max_year = None ):
84+ start_year = _parse_year_value (start_value , min_year = min_year , max_year = max_year )
85+ end_year = _parse_year_value (end_value , min_year = min_year , max_year = max_year )
1586
1687 if start_year is None and end_year is None :
1788 return []
@@ -49,7 +120,7 @@ def _map_transformed_filter(field_name, field_info, filters):
49120 return (real_field_name , normalized_value ), handled_fields
50121 return None , handled_fields
51122
52- if transform_type != "year_range" :
123+ if transform_type not in { "year_range" , "numeric_range" } :
53124 return None , set ()
54125
55126 source_names = list (transform .get ("sources" ) or [])
@@ -59,9 +130,28 @@ def _map_transformed_filter(field_name, field_info, filters):
59130 if len (source_names ) != 2 :
60131 return None , handled_fields
61132
133+ settings = field_info .get ("settings" ) or {}
134+ if transform_type == "numeric_range" :
135+ min_value = _parse_number_bound (settings .get ("min" ))
136+ max_value = _parse_number_bound (settings .get ("max" ))
137+ numeric_range = _build_numeric_range_value (
138+ filters .get (source_names [0 ]),
139+ filters .get (source_names [1 ]),
140+ min_value = min_value ,
141+ max_value = max_value ,
142+ )
143+ if numeric_range :
144+ return (real_field_name , numeric_range ), handled_fields
145+ return None , handled_fields
146+
147+ min_year = _parse_year_bound (settings .get ("min" ))
148+ max_year = _parse_year_bound (settings .get ("max" ))
149+
62150 year_values = _build_year_range_values (
63151 filters .get (source_names [0 ]),
64152 filters .get (source_names [1 ]),
153+ min_year = min_year ,
154+ max_year = max_year ,
65155 )
66156 if year_values :
67157 return (real_field_name , year_values ), handled_fields
0 commit comments