Skip to main content
Glama
unified_search.py5.46 kB
""" Unified search functionality for email operations. This module provides the main unified search function that coordinates between server-side search implementations. """ # Type imports from typing import Any, Dict, List, Optional, Tuple # Local application imports from ..logging_config import get_logger from ..outlook_session.session_manager import OutlookSessionManager from ..shared import add_email_to_cache, clear_email_cache, email_cache from ..validation import BatchProcessing from ..validators import EmailSearchParams from .search_common import ( extract_email_info, get_folder_path_safe, is_server_search_supported, unified_cache_load_workflow ) from .server_search import server_side_search logger = get_logger(__name__) def unified_search( search_term: str, days: int = 7, folder_name: Optional[str] = None, match_all: bool = True, search_type: str = "subject" ) -> Tuple[List[Dict[str, Any]], str]: """ Unified search function that prioritizes fast server-side search. Args: search_term: The term to search for days: Number of days to look back folder_name: Folder to search in (defaults to Inbox) match_all: Whether to match all terms (AND logic) or any term (OR logic) search_type: Type of search (subject, sender, recipient, body) Returns: Tuple of (list of email dictionaries, status message) """ if not search_term or not isinstance(search_term, str): return [], "Search term must be a non-empty string" if days < 1 or days > 30: return [], "Days must be between 1 and 30" try: folder_path = get_folder_path_safe(folder_name) with OutlookSessionManager() as session: folder = session.get_folder(folder_path) if not folder: return [], f"Folder '{folder_path}' not found" # Use server-side search only - completely disable client-side search for performance results = [] if is_server_search_supported(search_type): try: results = server_side_search(folder, search_term, days, search_type, match_all, session.outlook_namespace) if results: logger.info(f"Server-side search successful: found {len(results)} results") else: logger.info(f"Server-side search completed but no results found") except Exception as e: logger.error(f"Server-side search failed: {e}") # Return empty results instead of falling back to slow client-side search return [], f"Search failed for '{search_term}' in '{folder_path}'" else: # For unsupported search types, return empty rather than using slow client-side logger.warning(f"Search type '{search_type}' not supported by server-side search") return [], f"Search type '{search_type}' is not supported for performance reasons" if not results: return [], f"No emails found in '{folder_path}' matching '{search_term}'" # Convert results to email data format - OPTIMIZED email_list = [] # Clear COM cache before processing to prevent memory growth from .search_common import clear_com_attribute_cache clear_com_attribute_cache() # Process in batches for better performance batch_size = BatchProcessing.DEFAULT_BATCH_SIZE total_results = len(results) for batch_start in range(0, total_results, batch_size): batch_end = min(batch_start + batch_size, total_results) batch_items = results[batch_start:batch_end] # Process batch for item in batch_items: try: email_data = extract_email_info(item) if email_data: email_list.append(email_data) except Exception as e: logger.warning(f"Failed to extract email info: {e}") continue # Clear COM cache periodically to prevent memory growth if batch_start % 200 == 0: clear_com_attribute_cache() if not email_list: return [], "No valid emails found" # Sort by received time (newest first) email_list.sort(key=lambda x: x.get("received_time", ""), reverse=True) # Use unified cache loading workflow for consistent cache management success = unified_cache_load_workflow(email_list, f"unified_search({search_term})") if success: logger.info(f"Unified cache workflow completed successfully for {len(email_list)} search results") else: logger.warning("Unified cache workflow failed for search results") message = f"Found {len(email_list)} emails in '{folder_path}'" return email_list, message except Exception as e: error_msg = f"Error searching emails: {e}" logger.error(error_msg) return [], error_msg

Latest Blog Posts

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/marlonluo2018/outlook-mcp-server'

If you have feedback or need assistance with the MCP directory API, please join our Discord server