import os from pathlib import Path from urllib.parse import quote_plus from dotenv import load_dotenv BASE_DIR = Path(__file__).resolve().parent load_dotenv(BASE_DIR / '.env') def _q(value: str) -> str: return quote_plus(value or '') def _build_db_url() -> str: db_engine = os.getenv('DB_ENGINE', 'sqlite').strip().lower() db_host = os.getenv('DB_HOST', 'localhost').strip() db_port = os.getenv('DB_PORT', '').strip() db_name = os.getenv('DB_NAME', 'ksef').strip() db_user = os.getenv('DB_USER', '').strip() db_password = os.getenv('DB_PASSWORD', '').strip() if db_engine == 'sqlite': return f"sqlite:///{(BASE_DIR / 'db' / 'sqlite' / 'app.db').resolve()}" if db_engine in ('pgsql', 'postgres', 'postgresql'): port = db_port or '5432' return ( f"postgresql+psycopg://{_q(db_user)}:{_q(db_password)}" f"@{db_host}:{port}/{_q(db_name)}" ) if db_engine == 'mysql': port = db_port or '3306' return ( f"mysql+pymysql://{_q(db_user)}:{_q(db_password)}" f"@{db_host}:{port}/{_q(db_name)}" ) raise ValueError(f"Nieobsługiwany DB_ENGINE: {db_engine}") def _path_from_env(name: str, default: Path) -> Path: raw = os.getenv(name) if not raw: return default path = Path(raw) return path if path.is_absolute() else (BASE_DIR / path).resolve() def _normalize_redis_url(raw: str | None) -> str: if not raw: return 'memory://' raw = raw.strip() if '://' not in raw: raw = f'redis://{raw}' return raw class Config: SECRET_KEY = os.getenv('SECRET_KEY', 'change-me-please') APP_MASTER_KEY = os.getenv('APP_MASTER_KEY', SECRET_KEY) SQLALCHEMY_DATABASE_URI = _build_db_url() SQLALCHEMY_TRACK_MODIFICATIONS = False ARCHIVE_PATH = _path_from_env('ARCHIVE_PATH', BASE_DIR / 'storage' / 'archive') PDF_PATH = _path_from_env('PDF_PATH', BASE_DIR / 'storage' / 'pdf') BACKUP_PATH = _path_from_env('BACKUP_PATH', BASE_DIR / 'storage' / 'backups') CERTS_PATH = _path_from_env('CERTS_PATH', BASE_DIR / 'storage' / 'certs') APP_TIMEZONE = os.getenv('APP_TIMEZONE', 'Europe/Warsaw') LOG_LEVEL = os.getenv('LOG_LEVEL', 'INFO') APP_PORT = int(os.getenv('APP_PORT', '5000')) REDIS_URL = _normalize_redis_url(os.getenv('REDIS_URL', '')) WTF_CSRF_TIME_LIMIT = None RATELIMIT_STORAGE_URI = REDIS_URL APP_EXTERNAL_SCHEME = os.getenv('APP_EXTERNAL_SCHEME', 'http') APP_EXTERNAL_HOST = os.getenv('APP_EXTERNAL_HOST', '') PREFERRED_URL_SCHEME = APP_EXTERNAL_SCHEME SESSION_COOKIE_SECURE = APP_EXTERNAL_SCHEME == 'https' REMEMBER_COOKIE_SECURE = APP_EXTERNAL_SCHEME == 'https' SESSION_COOKIE_HTTPONLY = True REMEMBER_COOKIE_HTTPONLY = True SESSION_COOKIE_SAMESITE = 'Lax' APP_FOOTER_TEXT = 'KSeF Manager · linuxiarz.pl · Mateusz Gruszczyński' class TestConfig(Config): TESTING = True WTF_CSRF_ENABLED = False SQLALCHEMY_DATABASE_URI = 'sqlite:///:memory:' REDIS_URL = 'memory://' RATELIMIT_STORAGE_URI = 'memory://'