PYTHONPython

config

real world projects / file sync / sync

PYTHON
config.py🐍
"""
Configuration management for the sync tool.
"""

import os
from dataclasses import dataclass, field
from typing import List
from pathlib import Path
from dotenv import load_dotenv

# Load environment variables
load_dotenv()


@dataclass
class SyncSettings:
    """Sync tool configuration."""
    
    # Directories
    WATCH_DIR: str = field(default_factory=lambda: os.getenv("WATCH_DIR", str(Path.home() / "sync")))
    BACKUP_DIR: str = field(default_factory=lambda: os.getenv("BACKUP_DIR", str(Path.home() / "backup")))
    
    # Backend
    BACKEND_TYPE: str = field(default_factory=lambda: os.getenv("BACKEND_TYPE", "local"))
    
    # AWS S3
    AWS_ACCESS_KEY_ID: str = field(default_factory=lambda: os.getenv("AWS_ACCESS_KEY_ID", ""))
    AWS_SECRET_ACCESS_KEY: str = field(default_factory=lambda: os.getenv("AWS_SECRET_ACCESS_KEY", ""))
    AWS_REGION: str = field(default_factory=lambda: os.getenv("AWS_REGION", "us-east-1"))
    S3_BUCKET: str = field(default_factory=lambda: os.getenv("S3_BUCKET", ""))
    S3_PREFIX: str = field(default_factory=lambda: os.getenv("S3_PREFIX", "sync/"))
    
    # Sync settings
    SYNC_INTERVAL: int = field(default_factory=lambda: int(os.getenv("SYNC_INTERVAL", "60")))
    DEBOUNCE_SECONDS: int = field(default_factory=lambda: int(os.getenv("DEBOUNCE_SECONDS", "2")))
    
    # Compression and encryption
    COMPRESSION_ENABLED: bool = field(
        default_factory=lambda: os.getenv("COMPRESSION_ENABLED", "true").lower() == "true"
    )
    ENCRYPTION_ENABLED: bool = field(
        default_factory=lambda: os.getenv("ENCRYPTION_ENABLED", "false").lower() == "true"
    )
    ENCRYPTION_KEY: str = field(default_factory=lambda: os.getenv("ENCRYPTION_KEY", ""))
    
    # Ignore patterns
    IGNORE_PATTERNS: List[str] = field(default_factory=lambda: [
        p.strip() for p in os.getenv(
            "IGNORE_PATTERNS",
            ".git,*.pyc,__pycache__,*.tmp,.DS_Store,*.swp"
        ).split(",")
    ])
    
    # Conflict resolution
    CONFLICT_RESOLUTION: str = field(
        default_factory=lambda: os.getenv("CONFLICT_RESOLUTION", "keep_both")
    )
    
    # Logging
    LOG_LEVEL: str = field(default_factory=lambda: os.getenv("LOG_LEVEL", "INFO"))
    LOG_FILE: str = field(default_factory=lambda: os.getenv("LOG_FILE", "sync.log"))
    
    def validate(self) -> bool:
        """Validate configuration."""
        errors = []
        
        if not os.path.isdir(self.WATCH_DIR):
            errors.append(f"Watch directory does not exist: {self.WATCH_DIR}")
        
        if self.BACKEND_TYPE == "local" and not self.BACKUP_DIR:
            errors.append("BACKUP_DIR required for local backend")
        
        if self.BACKEND_TYPE == "s3":
            if not self.S3_BUCKET:
                errors.append("S3_BUCKET required for S3 backend")
            if not self.AWS_ACCESS_KEY_ID or not self.AWS_SECRET_ACCESS_KEY:
                errors.append("AWS credentials required for S3 backend")
        
        if self.ENCRYPTION_ENABLED and not self.ENCRYPTION_KEY:
            errors.append("ENCRYPTION_KEY required when encryption is enabled")
        
        if errors:
            for error in errors:
                print(f"Config Error: {error}")
            return False
        
        return True


# Global settings instance
settings = SyncSettings()
PreviousNext