File size: 15,993 Bytes
877e000
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6e3dbdb
877e000
 
 
 
6e3dbdb
 
877e000
6e3dbdb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
877e000
 
 
6e3dbdb
877e000
6e3dbdb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
877e000
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
6e3dbdb
 
877e000
6e3dbdb
 
 
 
 
877e000
6e3dbdb
877e000
 
6e3dbdb
877e000
6e3dbdb
 
877e000
6e3dbdb
877e000
 
6e3dbdb
 
877e000
 
6e3dbdb
877e000
1049797
 
 
 
6e3dbdb
1049797
 
 
 
 
 
6e3dbdb
1049797
 
6e3dbdb
1049797
 
 
6e3dbdb
1049797
 
 
 
6e3dbdb
1049797
 
 
 
 
 
 
 
6e3dbdb
1049797
 
877e000
 
6e3dbdb
1049797
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
# models/property_summary.py

from .model_loader import load_model
from .logging_config import logger
import json
import re

def validate_and_format_data(data):
    """Validate and format property data"""
    if not isinstance(data, dict):
        logger.warning(f"Input to validate_and_format_data is not a dict: {type(data)}")
        data = {}
    
    # Format square feet
    try:
        sq_ft = float(data.get('sq_ft', 0) or 0)
        if sq_ft < 100:  # If square feet seems too small, it might be in wrong unit
            sq_ft *= 100  # Convert to square feet if it was in square meters
        data['sq_ft'] = int(sq_ft)
    except Exception as e:
        logger.warning(f"Invalid sq_ft value: {data.get('sq_ft')}, error: {e}")
        data['sq_ft'] = 0

    # Format market value
    try:
        market_value = float(data.get('market_value', 0) or 0)
        if market_value > 1000000000:  # If value seems too high
            market_value = market_value / 100  # Adjust if there's a decimal point issue
        data['market_value'] = int(market_value)
    except Exception as e:
        logger.warning(f"Invalid market_value: {data.get('market_value')}, error: {e}")
        data['market_value'] = 0

    # Format amenities
    if data.get('amenities'):
        if isinstance(data['amenities'], str):
            amenities = [a.strip() for a in data['amenities'].split(',') if a.strip()]
            data['amenities'] = amenities
        elif isinstance(data['amenities'], list):
            data['amenities'] = [a.strip() for a in data['amenities'] if isinstance(a, str) and a.strip()]
        else:
            data['amenities'] = []
    else:
        data['amenities'] = []

    # Ensure all expected keys exist
    for key in ['bedrooms', 'bathrooms', 'year_built', 'parking_spaces', 'property_type', 'status', 'city', 'state', 'property_description', 'possession_date', 'nearby_landmarks']:
        if key not in data:
            data[key] = ''
    
    return data

def format_price(price):
    """Format price in Indian currency format"""
    try:
        price = float(price)
        if price >= 10000000:  # 1 Crore
            return f"₹{price/10000000:.2f} Cr"
        elif price >= 100000:  # 1 Lakh
            return f"₹{price/100000:.2f} L"
        else:
            return f"₹{price:,.2f}"
    except Exception as e:
        logger.warning(f"Invalid price for formatting: {price}, error: {e}")
        return f"₹0"

def create_property_prompt(data):
    """Create a comprehensive prompt for the SLM to generate property summary"""
    
    # Build location string
    location_parts = []
    if data.get('address'):
        location_parts.append(data['address'])
    if data.get('city'):
        location_parts.append(data['city'])
    if data.get('state'):
        location_parts.append(data['state'])
    location = ', '.join(location_parts) if location_parts else 'Prime location'
    
    # Build amenities string
    amenities = data.get('amenities', [])
    amenities_str = ', '.join(amenities[:5]) if amenities else 'Modern amenities'
    
    # Build landmarks string
    landmarks = data.get('nearby_landmarks', '')
    if isinstance(landmarks, str) and landmarks:
        landmarks_list = [l.strip() for l in landmarks.split(',') if l.strip()]
        landmarks_str = ', '.join(landmarks_list[:3])
    else:
        landmarks_str = 'Convenient location'
    
    # Create the prompt
    prompt = f"""Generate a compelling 512-word property summary for an Indian real estate listing. Write in a warm, professional tone that appeals to potential buyers.

Property Information:
- Type: {data.get('property_type', 'Property')}
- Status: {data.get('status', 'Available')}
- Location: {location}
- Size: {data.get('sq_ft', '0')} sq. ft.
- Price: {format_price(data.get('market_value', '0'))}
- Bedrooms: {data.get('bedrooms', '0')}
- Bathrooms: {data.get('bathrooms', '0')}
- Year Built: {data.get('year_built', 'N/A')}
- Parking: {data.get('parking_spaces', '0')} spaces
- Possession: {data.get('possession_date', 'Immediate')}
- Amenities: {amenities_str}
- Nearby: {landmarks_str}

Description: {data.get('property_description', 'Beautiful property with modern features')}

Instructions:
1. Start with an engaging introduction about the property
2. Highlight key features and benefits
3. Emphasize location advantages
4. Mention pricing and value proposition
5. Include amenities and nearby facilities
6. End with a compelling call-to-action
7. Keep the tone warm, professional, and trustworthy
8. Use Indian real estate terminology appropriately
9. Make it exactly 512 words

Property Summary:"""

    return prompt

def generate_dynamic_summary_with_slm(data):
    """Generate property summary using AI summarization model"""
    try:
        # Validate and format data
        data = validate_and_format_data(data)
        
        # Create the property description text
        property_text = create_property_description_text(data)
        
        # Try to use summarization model
        try:
            summarizer = load_model("summarization")
            
            # Check if we have a proper summarization model
            if hasattr(summarizer, 'fallback_used') and not summarizer.fallback_used:
                # Use the actual AI model for summarization
                result = summarizer(property_text, max_length=150, min_length=50, do_sample=False)
                if isinstance(result, list) and len(result) > 0:
                    summary = result[0].get('summary_text', '')
                    if summary and len(summary.strip()) > 20:
                        return summary.strip()
            
            # If AI model fails or returns poor results, use enhanced fallback
            return generate_enhanced_fallback_summary(data)
            
        except Exception as model_error:
            logger.warning(f"Summarization model failed: {str(model_error)}")
            return generate_enhanced_fallback_summary(data)
            
    except Exception as e:
        logger.error(f"Error in dynamic summary generation: {str(e)}")
        return generate_enhanced_fallback_summary(data)

def create_property_description_text(data):
    """Create a comprehensive property description text for summarization"""
    try:
        # Build location string
        location_parts = []
        if data.get('address'):
            location_parts.append(data['address'])
        if data.get('city'):
            location_parts.append(data['city'])
        if data.get('state'):
            location_parts.append(data['state'])
        location = ', '.join(location_parts) if location_parts else 'Prime location'
        
        # Build amenities string
        amenities = data.get('amenities', [])
        amenities_str = ', '.join(amenities[:5]) if amenities else 'Modern amenities'
        
        # Build landmarks string
        landmarks = data.get('nearby_landmarks', '')
        if isinstance(landmarks, str) and landmarks:
            landmarks_list = [l.strip() for l in landmarks.split(',') if l.strip()]
            landmarks_str = ', '.join(landmarks_list[:3])
        else:
            landmarks_str = 'Convenient location'
        
        # Create comprehensive property description
        description_parts = [
            f"This is a {data.get('property_type', 'property')} located in {location}.",
            f"The property is currently {data.get('status', 'available')} for sale.",
            f"It features {data.get('bedrooms', '0')} bedrooms and {data.get('bathrooms', '0')} bathrooms.",
            f"The total area is {data.get('sq_ft', '0')} square feet.",
            f"The property is priced at {format_price(data.get('market_value', '0'))}.",
            f"It includes amenities such as {amenities_str}.",
            f"The property is near {landmarks_str}.",
            f"It was built in {data.get('year_built', 'recent years')}.",
            f"The property offers {data.get('parking_spaces', '0')} parking spaces.",
            f"This is an excellent investment opportunity in a prime location with modern facilities and strategic connectivity."
        ]
        
        return " ".join(description_parts)
        
    except Exception as e:
        logger.error(f"Error creating property description text: {str(e)}")
        return f"This is a {data.get('property_type', 'property')} located in {data.get('city', 'prime location')} with excellent features and amenities."

def generate_enhanced_fallback_summary(data):
    """Enhanced fallback summary generation with better AI-like text"""
    try:
        data = validate_and_format_data(data)
        
        # Create a comprehensive and dynamic summary
        summary_parts = []
        
        # Introduction with property type and status
        property_type = data.get('property_type', 'Property')
        status = data.get('status', 'Available')
        summary_parts.append(f"Discover this exceptional {property_type.lower()} that's currently {status.lower()} for sale.")
        
        # Location information
        location_parts = []
        if data.get('city'):
            location_parts.append(data['city'])
        if data.get('state'):
            location_parts.append(data['state'])
        if location_parts:
            summary_parts.append(f"This prime property is strategically located in {', '.join(location_parts)}, offering excellent connectivity and accessibility.")
        
        # Key features section
        features = []
        if data.get('sq_ft'):
            features.append(f"{data['sq_ft']} sq. ft. of thoughtfully designed space")
        if data.get('bedrooms'):
            features.append(f"{data['bedrooms']} spacious bedroom{'s' if str(data['bedrooms']) != '1' else ''}")
        if data.get('bathrooms'):
            features.append(f"{data['bathrooms']} modern bathroom{'s' if str(data['bathrooms']) != '1' else ''}")
        if data.get('parking_spaces'):
            features.append(f"{data['parking_spaces']} covered parking space{'s' if str(data['parking_spaces']) != '1' else ''}")
        
        if features:
            summary_parts.append(f"The property features {', '.join(features)}.")
        
        # Pricing information
        if data.get('market_value'):
            price_str = format_price(data['market_value'])
            summary_parts.append(f"Priced at {price_str}, this property offers excellent value for money and represents a sound investment opportunity.")
        
        # Amenities and facilities
        amenities = data.get('amenities', [])
        if amenities:
            amenities_str = ', '.join(amenities[:3])
            summary_parts.append(f"The property includes modern amenities such as {amenities_str}.")
        
        # Location benefits
        landmarks = data.get('nearby_landmarks', '')
        if landmarks:
            summary_parts.append(f"Conveniently located near {landmarks}, this property offers easy access to essential facilities and transportation.")
        
        # Closing statement
        summary_parts.append("Perfect for families and investors alike, this property combines modern amenities with strategic location. Don't miss this opportunity to own a piece of prime real estate. Contact us today for a detailed viewing and exclusive offers.")
        
        return " ".join(summary_parts)
        
    except Exception as e:
        logger.error(f"Error in enhanced fallback summary: {str(e)}")
        return create_basic_summary(data)

def generate_property_summary(data):
    """Main function to generate property summary using AI model"""
    try:
        # Validate input data
        if not data or not isinstance(data, dict):
            return "A beautiful property with excellent features and prime location. Contact us for detailed information and exclusive offers."
        
        # Try to use AI model for summary generation
        try:
            # Use the new dynamic SLM-based approach
            summary = generate_dynamic_summary_with_slm(data)
            
            # Ensure summary is a proper string
            if not summary or not isinstance(summary, str):
                summary = generate_enhanced_fallback_summary(data)
            
            if not summary or not summary.strip():
                summary = generate_enhanced_fallback_summary(data)
            
            # Final fallback - always return something meaningful
            if not summary or not summary.strip():
                summary = create_basic_summary(data)
            
            # Ensure it's a string and clean it up
            summary = str(summary).strip()
            if summary == '[object Object]' or summary == 'null' or summary == 'undefined':
                summary = generate_enhanced_fallback_summary(data)
            
            # If still no valid summary, create a basic one
            if not summary or len(summary) < 50:
                summary = create_basic_summary(data)
            
            return summary
            
        except Exception as e:
            logger.error(f"Error in AI summary generation: {str(e)}")
            return create_basic_summary(data)
        
    except Exception as e:
        logger.error(f"Error generating property summary: {str(e)}")
        return create_basic_summary(data)

def create_basic_summary(data):
    """Create a basic summary even for invalid data"""
    try:
        # Extract basic information
        property_type = data.get('property_type', 'Property')
        city = data.get('city', 'Prime Location')
        state = data.get('state', '')
        bedrooms = data.get('bedrooms', '')
        bathrooms = data.get('bathrooms', '')
        sq_ft = data.get('sq_ft', '')
        market_value = data.get('market_value', '')
        
        # Create location string
        location_parts = []
        if city:
            location_parts.append(city)
        if state:
            location_parts.append(state)
        location = ', '.join(location_parts) if location_parts else 'Prime Location'
        
        # Create features string
        features = []
        if bedrooms:
            features.append(f"{bedrooms} bedroom{'s' if str(bedrooms) != '1' else ''}")
        if bathrooms:
            features.append(f"{bathrooms} bathroom{'s' if str(bathrooms) != '1' else ''}")
        if sq_ft:
            features.append(f"{sq_ft} sq. ft.")
        
        features_str = ', '.join(features) if features else 'excellent features'
        
        # Create price string
        price_str = ""
        if market_value:
            try:
                price_val = float(str(market_value).replace(',', '').replace('₹', ''))
                if price_val > 0:
                    price_str = f" at ₹{price_val:,.0f}"
            except:
                pass
        
        # Create property name - use a generic name if the original is invalid
        property_name = data.get('property_name', '')
        if property_name in ['2', '0', '1', 'test', 'sample', 'dummy'] or len(str(property_name)) < 3:
            property_name = f"Beautiful {property_type}"
        
        # Build the summary
        summary_parts = [
            f"Discover this exceptional {property_type.lower()} located in {location}.",
            f"This property features {features_str} and offers excellent value for money.",
            f"Perfect for families and investors alike, this property combines modern amenities with strategic location.",
            f"Don't miss this opportunity to own a piece of prime real estate{price_str}.",
            "Contact us today for a detailed viewing and exclusive offers."
        ]
        
        return " ".join(summary_parts)
        
    except Exception as e:
        logger.error(f"Error creating basic summary: {str(e)}")
        return "A beautiful property with excellent features and prime location. Contact us for detailed information and exclusive offers."