-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathutils.py
More file actions
153 lines (121 loc) · 4.83 KB
/
Copy pathutils.py
File metadata and controls
153 lines (121 loc) · 4.83 KB
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
#!/usr/bin/env python3
"""
Utility functions for dejavu2-cli.
This module contains helper functions for:
- Logging setup
- String processing
- Date/time utilities
"""
import logging
import warnings
from datetime import datetime
import tzlocal
# Setup logging
def setup_logging(verbose=False, log_file=None, quiet=True):
"""
Configure logging for the application with proper formatting and filters.
Args:
verbose: Whether to use DEBUG level logging (default: False)
log_file: Path to a log file to write logs to (default: None)
quiet: Whether to suppress console output (default: True)
Returns:
The configured root logger instance
"""
# Configure root logger
root_logger = logging.getLogger()
# Clear any existing handlers to avoid duplicate logs
for handler in root_logger.handlers[:]:
root_logger.removeHandler(handler)
# Set log level based on verbosity
root_level = logging.DEBUG if verbose else logging.INFO
root_logger.setLevel(root_level)
# Create formatters
detailed_formatter = logging.Formatter("%(asctime)s - %(levelname)s - %(name)s - %(message)s", datefmt="%Y-%m-%d %H:%M:%S")
console_formatter = logging.Formatter("%(levelname)s - %(name)s: %(message)s")
# Set up console handler unless quiet mode is enabled
if not quiet:
console_handler = logging.StreamHandler()
console_handler.setFormatter(console_formatter)
console_handler.setLevel(root_level)
root_logger.addHandler(console_handler)
# Set up file handler if a log file is specified
if log_file:
try:
file_handler = logging.FileHandler(log_file)
file_handler.setFormatter(detailed_formatter)
file_handler.setLevel(logging.DEBUG) # Always log everything to file
root_logger.addHandler(file_handler)
except Exception as e:
logging.error(f"Failed to set up log file: {str(e)}")
# Get the utils logger (this module)
logger = logging.getLogger(__name__)
# Configure third-party library loggers
# Suppress warnings from specific modules
warnings.filterwarnings("ignore", category=UserWarning, module=r"^anthropic\..*")
warnings.filterwarnings("ignore", category=UserWarning, module=r"^openai\..*")
# Set conservative logging levels for noisy libraries
logging.getLogger("anthropic").setLevel(logging.WARNING)
logging.getLogger("openai").setLevel(logging.WARNING)
logging.getLogger("httpx").setLevel(logging.WARNING)
logging.getLogger("urllib3").setLevel(logging.WARNING)
# Log the logging configuration
logger.debug(f"Logging initialized (verbose={verbose}, log_file={log_file}, quiet={quiet})")
return root_logger
def spacetime_placeholders(text: str) -> str:
"""
Replace date/time placeholders in a text string with current values.
Supported placeholders:
- {date}: Current date in YYYY-MM-DD format
- {time}: Current time in HH:MM:SS format
- {datetime}: Combined date and time (YYYY-MM-DD HH:MM:SS)
- {year}: Current year (YYYY)
- {month}: Current month (MM)
- {day}: Current day (DD)
- {hour}: Current hour (HH)
- {minute}: Current minute (MM)
- {second}: Current second (SS)
- {dow}: Current day of week name (e.g., "Monday")
- {tz}: Current timezone name
- {spacetime}: Complete string with day, date, time, and timezone
Args:
text: The string containing placeholders to replace
Returns:
String with placeholders replaced by current values
Example:
>>> spacetime_placeholders("Today is {date} at {time}")
'Today is 2025-01-03 at 12:30:45'
"""
if not text or not isinstance(text, str):
return text
if "{" not in text:
return text
try:
now = datetime.now()
# Create map of placeholders to their values
replacements = {
"{date}": now.strftime("%Y-%m-%d"),
"{time}": now.strftime("%H:%M:%S"),
"{datetime}": now.strftime("%Y-%m-%d %H:%M:%S"),
"{year}": now.strftime("%Y"),
"{month}": now.strftime("%m"),
"{day}": now.strftime("%d"),
"{hour}": now.strftime("%H"),
"{minute}": now.strftime("%M"),
"{second}": now.strftime("%S"),
"{dow}": now.strftime("%A"), # Full day name
"{tz}": str(tzlocal.get_localzone().key),
}
# Add spacetime after we have all the other values
replacements["{spacetime}"] = f"{replacements['{dow}']} {replacements['{date}']} {replacements['{time}']} {replacements['{tz}']}"
# Replace each placeholder in the text
result = text
for placeholder, value in replacements.items():
result = result.replace(placeholder, value)
# Also handle double-brace format for backward compatibility
double_brace = placeholder.replace("{", "{{").replace("}", "}}")
result = result.replace(double_brace, value)
return result
except Exception as e:
# Log but don't crash on date/time errors
logging.warning(f"Error processing date/time placeholders: {str(e)}")
return text