# image_searcher.py import requests import random from typing import List, Dict, Optional class ImageSearcher: def __init__(self, pexels_api_key: str): self.pexels_api_key = pexels_api_key self.headers = { 'Authorization': self.pexels_api_key, 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36' } def search_pexels(self, query: str, num_images: int = 10) -> List[Dict]: try: url = "https://api.pexels.com/v1/search" params = { 'query': query, 'per_page': min(num_images, 80), 'page': 1 } response = requests.get(url, params=params, headers=self.headers, timeout=10) response.raise_for_status() data = response.json() images = [] for item in data.get('photos', []): images.append({ 'url': item['src']['medium'], 'thumbnail': item['src']['small'], 'title': item.get('alt', query), 'author': item['photographer'], 'source': 'pexels' }) print(f"Found {len(images)} images from Pexels for query: {query}") return images except Exception as e: print(f"Pexels search failed for query {query}: {e}") return [] def search_lorem_picsum(self, query: str, width: int = 400, height: int = 300, num_images: int = 10) -> List[Dict]: images = [] title_base = f"Pakistan {query}" if query else "Pakistan Travel" for i in range(num_images): seed = random.randint(1, 1000) images.append({ 'url': f"https://picsum.photos/{width}/{height}?random={seed}", 'thumbnail': f"https://picsum.photos/200/150?random={seed}", 'title': f"{title_base} View {i+1}", 'author': 'Lorem Picsum', 'source': 'lorem_picsum' }) print(f"Generated {len(images)} placeholder images for query: {query}") return images def search_all_sources(self, queries: List[str], num_images: int = 6) -> List[Dict]: all_images = [] for query in queries: if query: full_query = f"{query} Pakistan" pexels_images = self.search_pexels(full_query, num_images) all_images.extend(pexels_images) if len(all_images) >= num_images: break if len(all_images) < num_images: for query in queries: if query and not any(f"{query} Pakistan" in q for q in [img['title'] for img in all_images]): pexels_images = self.search_pexels(query, num_images - len(all_images)) all_images.extend(pexels_images) if len(all_images) >= num_images: break if len(all_images) < num_images: print(f"Insufficient results, generating placeholders.") placeholder_images = self.search_lorem_picsum(queries[0] if queries else '', num_images=num_images - len(all_images)) all_images.extend(placeholder_images) return all_images[:num_images] def create_image_queries(travel_data: Dict, destination: Optional[str]) -> List[str]: queries = [] location_type = travel_data.get("location_type", "").lower() if travel_data.get("location_type") != "Other" else "" province = travel_data.get("province", "").lower().replace("-", " ") if travel_data.get("province") else "" preferences = travel_data.get("preferences", []) preference_map = { "Cultural Experience": "culture", "Food and Dining": "food", "Shopping": "market", "Nature": "nature", "History": "historical" } pref_terms = [preference_map.get(pref, pref.lower()) for pref in preferences if pref in preference_map] if destination and destination != "Suggested Destination": queries.append(destination) if destination and destination != "Suggested Destination" and location_type: queries.append(f"{destination} {location_type}") if destination and destination != "Suggested Destination" and pref_terms: queries.append(f"{destination} {' '.join(pref_terms)}") if destination and destination != "Suggested Destination" and location_type and pref_terms: queries.append(f"{destination} {location_type} {' '.join(pref_terms)}") if province and location_type: queries.append(f"{province} {location_type}") if province and pref_terms: queries.append(f"{province} {' '.join(pref_terms)}") if province: queries.append(province) if location_type and pref_terms: queries.append(f"{location_type} {' '.join(pref_terms)}") if location_type: queries.append(location_type) queries = list(dict.fromkeys([q for q in queries if q])) if not queries: queries.append("Pakistan travel") print(f"Created image search queries: {queries}") return queries def extract_destination(plan_text: str, travel_data: Dict) -> Optional[str]: lines = plan_text.split('\n') for line in lines: if line.strip().startswith('- Destination:'): parts = line.split(':', 1) if len(parts) > 1: destination = parts[1].strip() print(f"Extracted destination from plan: {destination}") return destination if travel_data.get("destination"): return travel_data["destination"] if travel_data.get("additional_preferences"): return " ".join(travel_data["additional_preferences"].split()[:3]) if travel_data.get("province"): return travel_data["province"] return None