""" Configuration module for Multi-User Slack Presence Tracker with readable names """ import os from pathlib import Path from dotenv import load_dotenv import logging from datetime import datetime import pytz # Load environment variables load_dotenv() # Base paths BASE_DIR = Path(__file__).parent DATA_DIR = BASE_DIR / "data" RAW_DATA_DIR = DATA_DIR / "raw" SUMMARIES_DIR = DATA_DIR / "summaries" LOGS_DIR = BASE_DIR / "logs" # Create directories if they don't exist for dir_path in [DATA_DIR, RAW_DATA_DIR, SUMMARIES_DIR, LOGS_DIR]: dir_path.mkdir(parents=True, exist_ok=True) # Slack Configuration SLACK_BOT_TOKEN = os.getenv('SLACK_BOT_TOKEN') # Multi-user configuration SLACK_USER_IDS = os.getenv('SLACK_USER_IDS', '').split(',') SLACK_USER_IDS = [uid.strip() for uid in SLACK_USER_IDS if uid.strip()] # Tracking options TRACK_ALL_USERS = os.getenv('TRACK_ALL_USERS', 'False').lower() == 'true' TRACK_DOMAINS = os.getenv('TRACK_DOMAINS', '').split(',') TRACK_DOMAINS = [domain.strip() for domain in TRACK_DOMAINS if domain.strip()] # Exclusions EXCLUDED_USER_IDS = os.getenv('EXCLUDED_USER_IDS', '').split(',') EXCLUDED_USER_IDS = [uid.strip() for uid in EXCLUDED_USER_IDS if uid.strip()] # Application Configuration TIMEZONE = pytz.timezone(os.getenv('TIMEZONE', 'UTC')) DEBUG_MODE = os.getenv('DEBUG_MODE', 'False').lower() == 'true' # Performance settings USE_BATCH_API = False # Deprecated, always use individual calls now MAX_USERS_PER_BATCH = int(os.getenv('MAX_USERS_PER_BATCH', '100')) # File naming preference USE_READABLE_NAMES = os.getenv('USE_READABLE_NAMES', 'True').lower() == 'true' # File paths for multi-user with readable names def get_raw_data_file(date=None, user_id=None, user_name=None): """Get the path for raw data file with readable names""" if date is None: date = datetime.now(TIMEZONE).date() if user_id: if USE_READABLE_NAMES and user_name: # Use sanitized real name for filename import re sanitized_name = re.sub(r'[^\w\s-]', '', user_name) sanitized_name = re.sub(r'[-\s]+', '_', sanitized_name).lower() filename = f"{sanitized_name}_{date.strftime('%Y-%m-%d')}.csv" else: # Fallback to user ID filename = f"presence_{user_id}_{date.strftime('%Y-%m-%d')}.csv" else: # Combined file for all users filename = f"all_users_{date.strftime('%Y-%m-%d')}.csv" return RAW_DATA_DIR / filename def get_summary_file(user_id=None, user_name=None): """Get summary file path with readable names""" if user_id: if USE_READABLE_NAMES and user_name: import re sanitized_name = re.sub(r'[^\w\s-]', '', user_name) sanitized_name = re.sub(r'[-\s]+', '_', sanitized_name).lower() return SUMMARIES_DIR / f"summary_{sanitized_name}.csv" else: return SUMMARIES_DIR / f"summary_{user_id}.csv" else: return SUMMARIES_DIR / "team_summary.csv" def setup_logging(name, log_file=None): """Setup logging configuration""" if log_file is None: log_file = LOGS_DIR / f"{name}_{datetime.now().strftime('%Y-%m-%d')}.log" # Create logger logger = logging.getLogger(name) logger.setLevel(logging.DEBUG if DEBUG_MODE else logging.INFO) # Don't add handlers if they already exist if logger.handlers: return logger # File handler file_handler = logging.FileHandler(log_file) file_handler.setLevel(logging.DEBUG if DEBUG_MODE else logging.INFO) # Console handler (for cron job output) console_handler = logging.StreamHandler() console_handler.setLevel(logging.ERROR) # Formatter formatter = logging.Formatter( '%(asctime)s - %(name)s - %(levelname)s - %(message)s', datefmt='%Y-%m-%d %H:%M:%S' ) file_handler.setFormatter(formatter) console_handler.setFormatter(formatter) # Add handlers logger.addHandler(file_handler) logger.addHandler(console_handler) return logger def validate_config(): """Validate that all required configuration is present""" errors = [] if not SLACK_BOT_TOKEN: errors.append("SLACK_BOT_TOKEN is not set in .env file") if not TRACK_ALL_USERS and not SLACK_USER_IDS and not TRACK_DOMAINS: errors.append("No users to track! Set SLACK_USER_IDS, TRACK_ALL_USERS=True, or TRACK_DOMAINS") if errors: raise ValueError("Configuration errors:\n" + "\n".join(errors)) return True def get_users_to_track(): """Get the list of user IDs to track based on configuration""" if TRACK_ALL_USERS: return None elif SLACK_USER_IDS: return SLACK_USER_IDS else: return None