import traceback
import os
import sys
import defines

def filter_traceback(tb, app_path=None, module_name=None):
    """
    Filter traceback to include only frames from the specified application path or module.
    
    Args:
        tb: Traceback object (e.g., from sys.exc_info()[2])
        app_path: Directory path of your application (e.g., '/path/to/your/app')
        module_name: Name of the module to include (e.g., 'myapp')
    
    Returns:
        Formatted traceback string with filtered frames.
    """
    # Extract stack frames
    stack = traceback.extract_tb(tb)
    
    # Filter frames based on app_path or module_name
    filtered_stack = []
    for frame in stack:
        # frame.filename is the full path to the file
        # frame.name is the function name, frame.lineno is the line number
        if app_path and os.path.realpath(frame.filename).startswith(os.path.realpath(app_path)):
            filtered_stack.append(frame)
        elif module_name and frame.filename.startswith(module_name):
            filtered_stack.append(frame)
    
    # Format the filtered stack trace
    formatted_stack = traceback.format_list(filtered_stack)
    
    # Get exception info to include the exception type and message
    exc_type, exc_value, _ = sys.exc_info()
    formatted_exc = traceback.format_exception_only(exc_type, exc_value)
    
    # Combine the filtered stack trace with the exception message
    return ''.join(formatted_stack + formatted_exc)

def format_exc(app_path=defines.app_path, module_name=None):
    """
    Custom version of traceback.format_exc() that filters stack frames.
    
    Args:
        app_path: Directory path of your application
        module_name: Name of the module to include
    
    Returns:
        Formatted traceback string with only relevant frames.
    """
    exc_type, exc_value, exc_tb = sys.exc_info()
    if exc_tb is None:
        return ""  # No traceback available
    return filter_traceback(exc_tb, app_path=app_path, module_name=module_name)
