File size: 4,122 Bytes
0a6cbcb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
"""
Utils package - Consolidated utility functions
Provides logging setup and other utility functions for the application
"""

# Import logger functions first (most critical)
try:
    from .logger import setup_logger
except ImportError as e:
    print(f"ERROR: Failed to import setup_logger from .logger: {e}")
    import logging
    def setup_logger(name: str, level: str = "INFO") -> logging.Logger:
        """Fallback setup_logger if import fails"""
        logger = logging.getLogger(name)
        if not logger.handlers:
            handler = logging.StreamHandler()
            handler.setFormatter(logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s'))
            logger.addHandler(handler)
            logger.setLevel(getattr(logging, level.upper()))
        return logger

# Create setup_logging as an alias for setup_logger for backward compatibility
# This MUST be defined before any other imports that might use it
def setup_logging():
    """
    Setup logging for the application
    This is a compatibility wrapper around setup_logger
    
    Returns:
        logging.Logger: Configured logger instance
    """
    return setup_logger("crypto_aggregator", level="INFO")


# Import utility functions from the standalone utils.py module
# We need to access it via a different path since we're inside the utils package
import sys
import os

# Add parent directory to path to import standalone utils module
parent_dir = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
if parent_dir not in sys.path:
    sys.path.insert(0, parent_dir)

# Import from standalone utils.py with a different name to avoid circular imports
try:
    # Try importing specific functions from the standalone utils file
    import importlib.util
    utils_path = os.path.join(parent_dir, 'utils.py')
    spec = importlib.util.spec_from_file_location("utils_standalone", utils_path)
    if spec and spec.loader:
        utils_standalone = importlib.util.module_from_spec(spec)
        spec.loader.exec_module(utils_standalone)
        
        # Expose the functions
        format_number = utils_standalone.format_number
        calculate_moving_average = utils_standalone.calculate_moving_average
        calculate_rsi = utils_standalone.calculate_rsi
        extract_coins_from_text = utils_standalone.extract_coins_from_text
        export_to_csv = utils_standalone.export_to_csv
        validate_price_data = utils_standalone.validate_price_data
        is_data_stale = utils_standalone.is_data_stale
        cache_with_ttl = utils_standalone.cache_with_ttl
        safe_float = utils_standalone.safe_float
        safe_int = utils_standalone.safe_int
        truncate_string = utils_standalone.truncate_string
        percentage_change = utils_standalone.percentage_change
except Exception as e:
    print(f"Warning: Could not import from standalone utils.py: {e}")
    # Provide dummy implementations to prevent errors
    def format_number(num, decimals=2):
        return str(num)
    def calculate_moving_average(prices, period):
        return None
    def calculate_rsi(prices, period=14):
        return None
    def extract_coins_from_text(text):
        return []
    def export_to_csv(data, filename):
        return False
    def validate_price_data(price_data):
        return True
    def is_data_stale(timestamp_str, max_age_minutes=30):
        return False
    def cache_with_ttl(ttl_seconds=300):
        def decorator(func):
            return func
        return decorator
    def safe_float(value, default=0.0):
        return default
    def safe_int(value, default=0):
        return default
    def truncate_string(text, max_length=100, suffix="..."):
        return text
    def percentage_change(old_value, new_value):
        return None


__all__ = [
    'setup_logging',
    'setup_logger',
    'format_number',
    'calculate_moving_average',
    'calculate_rsi',
    'extract_coins_from_text',
    'export_to_csv',
    'validate_price_data',
    'is_data_stale',
    'cache_with_ttl',
    'safe_float',
    'safe_int',
    'truncate_string',
    'percentage_change',
]