Spaces:
Sleeping
Sleeping
| from typing import Dict, Any | |
| import ast | |
| from typing import Any, Dict | |
| def clean_modified_dict(modified_dict: Dict[str, Any]) -> Dict[str, Any]: | |
| """ | |
| Cleans the modified dictionary by removing only values that are: | |
| - None | |
| - empty list [] | |
| - empty dict {} | |
| - empty string '' | |
| But keeps values like 0, False, etc. | |
| """ | |
| def is_meaningfully_empty(value): | |
| return value in (None, '', []) or (isinstance(value, dict) and not value) | |
| return {k: v for k, v in modified_dict.items() if not is_meaningfully_empty(v)} | |
| def convert_to_lines(query_dict): | |
| lines = [] | |
| for field, condition in query_dict.items(): | |
| if isinstance(condition, dict): | |
| for operator, value in condition.items(): | |
| # Special handling for $ne with '' or [] | |
| if operator in ['$ne', 'ne']: | |
| if value == '': | |
| value_str = "''" | |
| elif value == []: | |
| value_str = '[]' | |
| elif isinstance(value, list): | |
| value_str = ','.join(map(str, value)) | |
| elif isinstance(value, str): | |
| value_str = f"'{value}'" | |
| else: | |
| value_str = str(int(value) if isinstance(value, float) and value.is_integer() else value) | |
| elif isinstance(value, list): | |
| # Output lists as valid Python lists for complex cases | |
| value_str = repr(value) | |
| elif isinstance(value, str): | |
| value_str = f"'{value}'" | |
| else: | |
| value_str = str(int(value) if isinstance(value, float) and value.is_integer() else value) | |
| lines.append(f"{field} {operator} {value_str}") | |
| else: | |
| if isinstance(condition, str): | |
| condition_str = f"'{condition}'" | |
| else: | |
| condition_str = str(condition) | |
| lines.append(f"{field} = {condition_str}") | |
| return '\n'.join(lines) | |
| def parse_line_based_query(lines): | |
| query = {} | |
| for line in lines.strip().split('\n'): | |
| if not line.strip(): | |
| continue | |
| parts = line.split(maxsplit=2) | |
| if len(parts) < 3: | |
| # If operator is present but value is empty, set value to empty string | |
| if len(parts) == 2: | |
| field, operator = parts | |
| value = '' | |
| else: | |
| continue # Skip invalid lines | |
| else: | |
| field, operator, value = parts | |
| # Special handling for sort, limit, skip, etc. | |
| if field in {"sort", "order_by"}: | |
| # Handle both 'sort field value' and 'sort = {field: value}' | |
| if operator == "=": | |
| query[field] = _convert_value(value) | |
| else: | |
| if field not in query: | |
| query[field] = {} | |
| query[field][operator] = _convert_value(value) | |
| continue | |
| if field in {"limit", "skip", "offset"}: | |
| query[field] = _convert_value(value) | |
| continue | |
| # Special handling for _original_numbers (parse value as string if quoted, else as number) | |
| if field == "_original_numbers": | |
| if field not in query: | |
| query[field] = {} | |
| v = value.strip() | |
| if (v.startswith("'") and v.endswith("'")) or (v.startswith('"') and v.endswith('"')): | |
| query[field][operator] = v[1:-1] | |
| else: | |
| try: | |
| # Try to parse as int or float | |
| query[field][operator] = int(v) | |
| except ValueError: | |
| try: | |
| query[field][operator] = float(v) | |
| except ValueError: | |
| query[field][operator] = v | |
| continue | |
| # Handle equality operator | |
| if operator == "=": | |
| query[field] = _convert_value(value) | |
| continue | |
| # Handle other operators | |
| # If operator is $in, $nin, $all and value is empty, use [] | |
| empty_list_ops = {'in', '$in', 'nin', '$nin', 'all', '$all'} | |
| op_key = operator if operator.startswith('$') else f'${operator}' | |
| if operator in empty_list_ops and value == '': | |
| value_obj = [] | |
| elif operator in {'ne', '$ne'}: | |
| if value.strip() == '[]': | |
| value_obj = [] | |
| elif value.strip() == "''" or value.strip() == '""': | |
| value_obj = '' | |
| elif value == '': | |
| value_obj = [] | |
| else: | |
| value_obj = _convert_value(value, operator) | |
| else: | |
| value_obj = _convert_value(value, operator) | |
| if field in query: | |
| if isinstance(query[field], dict): | |
| query[field][op_key] = value_obj | |
| else: | |
| raise ValueError(f"Conflict in {field}: direct value and operator") | |
| else: | |
| query[field] = {op_key: value_obj} | |
| return query | |
| def _convert_value(value_str, operator=None): | |
| """Convert string values to appropriate types""" | |
| # Handle lists for $in and $all operators | |
| if operator in ('in', '$in', 'all', '$all'): | |
| s = value_str.strip() | |
| if s.startswith('[') and s.endswith(']'): | |
| try: | |
| return ast.literal_eval(s) | |
| except Exception: | |
| pass | |
| if ',' in value_str: | |
| return [_parse_single_value(v) for v in value_str.split(',')] | |
| # Handle regex flags (e.g., "pattern i" → "pattern" with $options: 'i') | |
| if operator == 'regex' and ' ' in value_str: | |
| pattern, *flags = value_str.split() | |
| return {'$regex': pattern, '$options': ''.join(flags)} | |
| return _parse_single_value(value_str) | |
| def _parse_single_value(s): | |
| """Convert individual values to int/float/string/dict/bool""" | |
| s = s.strip() | |
| # Remove surrounding quotes if present | |
| if (s.startswith("'") and s.endswith("'")) or (s.startswith('"') and s.endswith('"')): | |
| return s[1:-1].strip() # Always return as string if quoted | |
| # Handle None | |
| if s == 'None': | |
| return None | |
| # Try to parse as dict if it looks like one | |
| if (s.startswith('{') and s.endswith('}')) or (s.startswith('[') and s.endswith(']')): | |
| try: | |
| return ast.literal_eval(s) | |
| except Exception: | |
| pass | |
| # Handle booleans | |
| if s.lower() == 'true': | |
| return True | |
| if s.lower() == 'false': | |
| return False | |
| try: | |
| return int(s) | |
| except ValueError: | |
| try: | |
| return float(s) | |
| except ValueError: | |
| return s | |