Spaces:
Sleeping
Sleeping
| import re | |
| from src.config.settings import PRICE_KEYWORDS, LEASE_KEYWORDS | |
| def classify_query(query: str, role: str = "customer") -> str: | |
| """ | |
| Returns one of: 'property_filter', 'lease', 'faq', 'general' | |
| """ | |
| q = query.lower() | |
| # Lease / rental queries — manager only | |
| if role == "manager" and any(k in q for k in LEASE_KEYWORDS): | |
| return "lease" | |
| # Structured property search signals | |
| has_price = any(k in q for k in PRICE_KEYWORDS) | |
| has_prop_attr = any(k in q for k in [ | |
| "1bhk", "2bhk", "3bhk", "4bhk", "bhk", "bedroom", | |
| "flat", "apartment", "villa", "studio", "penthouse", "row house", | |
| "andheri", "bandra", "malad", "powai", "goregaon", "thane", | |
| "borivali", "versova", "vikhroli", "navi mumbai", "lower parel", | |
| "chembur", "kandivali", "juhu", "mulund", "dahisar", | |
| "santacruz", "kurla", "kharghar", "mira road", | |
| "show me", "find", "properties", "property", "flat", | |
| "semi-furnished", "furnished", "unfurnished", "sqft", "sq ft", | |
| "under", "below", "above", "between", | |
| ]) | |
| if has_price or has_prop_attr: | |
| return "property_filter" | |
| # FAQ signals | |
| faq_signals = [ | |
| "loan", "emi", "stamp duty", "registration", "document", "warranty", | |
| "inspection", "site visit", "payment", "gst", "down payment", | |
| "rera", "noc", "encumbrance", "society", "maintenance", | |
| "brokerage", "commission", "legal", "interest", "bank", | |
| "working hours", "location", "contact", "security deposit", | |
| "rent agreement", "lease agreement", "whatsapp", "virtual tour", | |
| "tax", "80c", "possession", "grading", "condition", | |
| ] | |
| if any(k in q for k in faq_signals): | |
| return "faq" | |
| return "general" | |
| def extract_filters(query: str) -> dict: | |
| """Extract budget, BHK, property type, location from natural language.""" | |
| q = query.lower() | |
| filters = {} | |
| # --- Price extraction --- | |
| # Crore patterns: "1.5 crore", "2cr", "1.2 crore" | |
| crore_nums = re.findall(r"(\d+(?:\.\d+)?)\s*(?:crore|cr\b)", q) | |
| # Lakh patterns: "85 lakh", "50l", "50 lac" | |
| lakh_nums = re.findall(r"(\d+(?:\.\d+)?)\s*(?:lakh|lac|l\b)", q) | |
| numbers = [float(n) * 10000000 for n in crore_nums] + \ | |
| [float(n) * 100000 for n in lakh_nums] | |
| if "under" in q or "below" in q or "less than" in q or "upto" in q or "up to" in q: | |
| if numbers: | |
| filters["max_price"] = max(numbers) | |
| elif "above" in q or "more than" in q or "over" in q: | |
| if numbers: | |
| filters["min_price"] = min(numbers) | |
| elif "between" in q and len(numbers) >= 2: | |
| filters["min_price"] = min(numbers) | |
| filters["max_price"] = max(numbers) | |
| elif len(numbers) == 1: | |
| filters["max_price"] = numbers[0] | |
| elif len(numbers) == 2: | |
| filters["min_price"] = min(numbers) | |
| filters["max_price"] = max(numbers) | |
| # --- BHK --- | |
| bhk_match = re.search(r"(\d)\s*bhk", q) | |
| if bhk_match: | |
| filters["bhk"] = int(bhk_match.group(1)) | |
| # --- Property type --- | |
| type_map = { | |
| "villa": "Villa", | |
| "studio": "Studio", | |
| "penthouse": "Penthouse", | |
| "row house": "Row House", | |
| "apartment": "Apartment", | |
| "flat": "Apartment", | |
| } | |
| for k, v in type_map.items(): | |
| if k in q: | |
| filters["property_type"] = v | |
| break | |
| # --- Furnishing --- | |
| if "fully furnished" in q or "fully-furnished" in q: | |
| filters["furnishing"] = "Fully Furnished" | |
| elif "semi furnished" in q or "semi-furnished" in q: | |
| filters["furnishing"] = "Semi-Furnished" | |
| elif "unfurnished" in q: | |
| filters["furnishing"] = "Unfurnished" | |
| # --- Location --- | |
| locations = [ | |
| "andheri west", "andheri east", "andheri", | |
| "bandra west", "bandra east", "bandra", | |
| "malad west", "malad east", "malad", | |
| "powai", "goregaon east", "goregaon west", "goregaon", | |
| "thane west", "thane", "borivali east", "borivali west", "borivali", | |
| "versova", "vikhroli east", "vikhroli west", "vikhroli", | |
| "navi mumbai", "lower parel", "chembur", | |
| "kandivali west", "kandivali east", "kandivali", | |
| "juhu", "mulund west", "mulund east", "mulund", | |
| "dahisar east", "dahisar west", "dahisar", | |
| "santacruz west", "santacruz east", "santacruz", | |
| "kurla west", "kurla east", "kurla", | |
| "kharghar", "mira road", | |
| ] | |
| for loc in locations: | |
| if loc in q: | |
| filters["location"] = loc | |
| break | |
| # --- Min area --- | |
| area_match = re.search(r"(\d{3,4})\s*(?:sqft|sq ft|sq\.ft)", q) | |
| if area_match: | |
| filters["min_area"] = int(area_match.group(1)) | |
| # --- Parking --- | |
| if "parking" in q: | |
| filters["parking"] = True | |
| return filters | |