File size: 4,737 Bytes
c08424b
9297d6e
 
 
c08424b
2bfc495
c08424b
9297d6e
74f2401
6be6030
9297d6e
b488f18
c08424b
9297d6e
 
c08424b
74f2401
c08424b
74f2401
 
c08424b
74f2401
 
 
 
c08424b
74f2401
c08424b
9297d6e
 
acba2e1
74f2401
 
 
 
 
2bfc495
74f2401
c08424b
 
74f2401
c08424b
9297d6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b488f18
9297d6e
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
b488f18
9297d6e
 
 
 
 
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
132
"""
Flare – Parameter Validation (locale-aware)
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Locale-based validation with multi-language support
"""

import re
from typing import Any, Optional, List
from datetime import datetime
from config_models import ParameterConfig
from locale_manager import LocaleManager
from logger import log_info, log_error, log_warning, log_debug

def validate(value: str, param: ParameterConfig, locale: Optional[str] = None) -> bool:
    """Validate parameter value based on type and locale"""
    t = param.canonical_type()
    
    if t == "int":
        if not value.isdigit(): 
            return False
    elif t == "float":
        try: 
            float(value)
        except ValueError: 
            return False
    elif t in ("str", "string"):
        pass  # All strings are valid
    elif t == "bool":
        # Locale-aware boolean validation
        return validate_boolean(value, locale)
    elif t == "date":
        try:
            # Check if it's a valid ISO date format (YYYY-MM-DD)
            datetime.strptime(value, "%Y-%m-%d")
        except ValueError:
            return False

    # Regex validation if provided
    if param.validation_regex and not re.fullmatch(param.validation_regex, value, re.I):
        return False
        
    return True

def validate_boolean(value: str, locale: Optional[str] = None) -> bool:
    """Validate boolean value based on locale"""
    # Default values (always accepted)
    default_true = ["1", "true"]
    default_false = ["0", "false"]
    
    value_lower = value.lower().strip()
    
    # Check default values first
    if value_lower in default_true or value_lower in default_false:
        return True
    
    # If no locale specified, use minimal validation
    if not locale:
        return value_lower in ["yes", "no", "evet", "hayır"]
    
    try:
        # Get locale data
        locale_data = LocaleManager.get_locale(locale)
        
        # Get boolean values from locale
        boolean_values = locale_data.get("boolean_values", {})
        true_values = boolean_values.get("true_values", [])
        false_values = boolean_values.get("false_values", [])
        
        # Include synonyms if available
        yes_synonyms = boolean_values.get("yes_synonyms", [])
        no_synonyms = boolean_values.get("no_synonyms", [])
        
        # Combine all accepted values
        all_true_values = set(true_values + yes_synonyms + default_true)
        all_false_values = set(false_values + no_synonyms + default_false)
        
        # Convert to lowercase for comparison
        all_true_values = {v.lower() for v in all_true_values}
        all_false_values = {v.lower() for v in all_false_values}
        
        return value_lower in all_true_values or value_lower in all_false_values
        
    except Exception as e:
        log_error("⚠️ Error in locale-based boolean validation", e)
        # Fallback to basic validation
        return value_lower in ["yes", "no", "evet", "hayır", "1", "0", "true", "false"]

def get_boolean_value(value: str, locale: Optional[str] = None) -> Optional[bool]:
    """Convert locale-specific boolean string to Python bool"""
    value_lower = value.lower().strip()
    
    # Default true values
    if value_lower in ["1", "true"]:
        return True
    if value_lower in ["0", "false"]:
        return False
    
    if not locale:
        # Basic conversion without locale
        if value_lower in ["yes", "evet"]:
            return True
        elif value_lower in ["no", "hayır"]:
            return False
        return None
    
    try:
        # Get locale data
        locale_data = LocaleManager.get_locale(locale)
        boolean_values = locale_data.get("boolean_values", {})
        
        true_values = set(v.lower() for v in boolean_values.get("true_values", []))
        false_values = set(v.lower() for v in boolean_values.get("false_values", []))
        yes_synonyms = set(v.lower() for v in boolean_values.get("yes_synonyms", []))
        no_synonyms = set(v.lower() for v in boolean_values.get("no_synonyms", []))
        
        # Check if it's a true value
        if value_lower in true_values or value_lower in yes_synonyms or value_lower == "1":
            return True
        
        # Check if it's a false value
        if value_lower in false_values or value_lower in no_synonyms or value_lower == "0":
            return False
        
        return None
        
    except Exception as e:
        log_error("⚠️ Error converting boolean value", e)
        return None

def get_supported_locales() -> List[str]:
    """Get list of supported locales for validation"""
    return LocaleManager.list_available_locales()