Files
Christian Krakau-Louis 4b46c4baf8 feat(storage): add Evernote destination (#862)
* feat(storage): add Evernote destination

* style: apply ruff auto-fix

- Auto-formatted code with ruff format
- Applied ruff linting fixes with --fix

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>

---------

Co-authored-by: Christian Krakau-Louis <christian@Christians-Mac-mini-7.local>
Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
2026-05-22 12:13:46 +02:00

429 lines
20 KiB
Python
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
"""
Module for handling provider status information
"""
from app.config import settings
from app.utils.config_validator.masking import mask_sensitive_value
def get_provider_status() -> dict[str, dict[str, object]]:
"""
Returns status information for all configured providers
"""
providers = {}
# Add Authentication configuration
auth_enabled = getattr(settings, "auth_enabled", False)
using_oidc = bool(
getattr(settings, "authentik_client_id", None)
and getattr(settings, "authentik_client_secret", None)
and getattr(settings, "authentik_config_url", None)
)
auth_method = "OIDC" if using_oidc else "Basic Auth" if auth_enabled else "None"
providers["Authentication"] = {
"name": "Authentication",
"icon": "fa-solid fa-lock",
"configured": bool(auth_enabled and (getattr(settings, "admin_username", None) or using_oidc)),
"enabled": auth_enabled,
"description": "Access control and user authentication",
"details": {
"method": auth_method,
"provider_name": getattr(settings, "oauth_provider_name", "Not set") if using_oidc else "N/A",
"session_security": "Configured" if getattr(settings, "session_secret", None) else "Not configured",
},
}
# Add Notification configuration - Make sure this provider is near the top of the list
providers["Notifications"] = {
"name": "Notifications",
"icon": "fa-solid fa-bell",
"configured": bool(getattr(settings, "notification_urls", None)),
"enabled": True,
"description": "Send system notifications via various services",
"details": {
"services": (
str(len(getattr(settings, "notification_urls", []))) + " service(s) configured"
if getattr(settings, "notification_urls", None)
else "Not configured"
),
"task_failure": getattr(settings, "notify_on_task_failure", True),
"credential_failure": getattr(settings, "notify_on_credential_failure", True),
"startup": getattr(settings, "notify_on_startup", True),
"shutdown": getattr(settings, "notify_on_shutdown", False),
},
"testable": True,
"test_endpoint": "/api/diagnostic/test-notification",
}
# Add AI provider (dynamic reflects whichever provider is configured)
ai_provider_name = getattr(settings, "ai_provider", "openai").lower()
model = getattr(settings, "ai_model", None) or getattr(settings, "openai_model", "gpt-4o-mini")
# Determine whether the active provider has its required credentials set
def _ai_configured() -> bool:
if ai_provider_name in ("openai", "azure", "litellm"):
return bool(getattr(settings, "openai_api_key", None))
elif ai_provider_name == "anthropic":
return bool(getattr(settings, "anthropic_api_key", None))
elif ai_provider_name == "gemini":
return bool(getattr(settings, "gemini_api_key", None))
elif ai_provider_name == "ollama":
return bool(getattr(settings, "ollama_base_url", None))
elif ai_provider_name == "openrouter":
return bool(getattr(settings, "openrouter_api_key", None))
elif ai_provider_name == "portkey":
return bool(getattr(settings, "portkey_api_key", None))
return False
# Build provider-specific detail rows
def _ai_details() -> dict:
base = {"provider": ai_provider_name, "model": model}
if ai_provider_name in ("openai", "azure", "litellm"):
base["api_key"] = mask_sensitive_value(getattr(settings, "openai_api_key", None))
base["base_url"] = getattr(settings, "openai_base_url", "https://api.openai.com/v1")
elif ai_provider_name == "anthropic":
base["api_key"] = mask_sensitive_value(getattr(settings, "anthropic_api_key", None))
elif ai_provider_name == "gemini":
base["api_key"] = mask_sensitive_value(getattr(settings, "gemini_api_key", None))
elif ai_provider_name == "ollama":
base["base_url"] = getattr(settings, "ollama_base_url", "http://localhost:11434")
elif ai_provider_name == "openrouter":
base["api_key"] = mask_sensitive_value(getattr(settings, "openrouter_api_key", None))
base["base_url"] = getattr(settings, "openrouter_base_url", "https://openrouter.ai/api/v1")
elif ai_provider_name == "portkey":
base["api_key"] = mask_sensitive_value(getattr(settings, "portkey_api_key", None))
if getattr(settings, "portkey_virtual_key", None):
base["virtual_key"] = mask_sensitive_value(settings.portkey_virtual_key)
if getattr(settings, "portkey_config", None):
base["config"] = settings.portkey_config
return base
_PROVIDER_ICONS = {
"openai": "fa-brands fa-openai",
"azure": "fa-brands fa-microsoft",
"anthropic": "fa-solid fa-robot",
"gemini": "fa-brands fa-google",
"ollama": "fa-solid fa-server",
"openrouter": "fa-solid fa-route",
"portkey": "fa-solid fa-key",
"litellm": "fa-solid fa-layer-group",
}
providers["AI Provider"] = {
"name": "AI Provider",
"icon": _PROVIDER_ICONS.get(ai_provider_name, "fa-solid fa-microchip"),
"configured": _ai_configured(),
"enabled": True,
"description": f"AI-powered metadata extraction and OCR refinement ({ai_provider_name})",
"details": _ai_details(),
"testable": True,
"test_endpoint": "/api/ai/test",
}
providers["Azure AI"] = {
"name": "Azure AI",
"icon": "fa-solid fa-robot",
"configured": bool(getattr(settings, "azure_ai_key", None) and getattr(settings, "azure_endpoint", None)),
"enabled": True,
"description": "Microsoft Azure Document Intelligence",
"details": {
"api_key": mask_sensitive_value(getattr(settings, "azure_ai_key", None)),
"endpoint": getattr(settings, "azure_endpoint", "Not set"),
"region": getattr(settings, "azure_region", "Not set"),
},
}
# Add Dropbox configuration - alphabetically ordered providers
providers["Dropbox"] = {
"name": "Dropbox",
"icon": "fa-brands fa-dropbox",
"configured": bool(
getattr(settings, "dropbox_app_key", None)
and getattr(settings, "dropbox_app_secret", None)
and getattr(settings, "dropbox_refresh_token", None)
),
"enabled": getattr(settings, "dropbox_enabled", True),
"description": "Upload files to Dropbox cloud storage",
"details": {
"folder": getattr(settings, "dropbox_folder", "Not set"),
"app_key": getattr(settings, "dropbox_app_key", "Not set"),
"app_secret": mask_sensitive_value(getattr(settings, "dropbox_app_secret", None)),
"refresh_token": mask_sensitive_value(getattr(settings, "dropbox_refresh_token", None)),
},
}
# Add Email destination configuration (dedicated settings for document delivery)
providers["Email"] = {
"name": "Email",
"icon": "fa-solid fa-envelope",
"configured": bool(
getattr(settings, "dest_email_host", None) and getattr(settings, "dest_email_default_recipient", None)
),
"enabled": getattr(settings, "dest_email_enabled", True),
"description": "Send documents via email",
"details": {
"host": getattr(settings, "dest_email_host", "Not set"),
"port": getattr(settings, "dest_email_port", "Not set"),
"username": getattr(settings, "dest_email_username", "Not set"),
"password": mask_sensitive_value(getattr(settings, "dest_email_password", None)),
"use_tls": getattr(settings, "dest_email_use_tls", "Not set"),
"sender": getattr(settings, "dest_email_sender", "Not set"),
"default_recipient": getattr(settings, "dest_email_default_recipient", "Not set"),
},
}
providers["Evernote"] = {
"name": "Evernote",
"icon": "fa-brands fa-evernote",
"configured": bool(getattr(settings, "evernote_auth_token", None)),
"enabled": getattr(settings, "evernote_enabled", True),
"description": "Create Evernote notes with document metadata and PDF attachments",
"details": {
"auth_token": mask_sensitive_value(getattr(settings, "evernote_auth_token", None)),
"sandbox": getattr(settings, "evernote_sandbox", False),
"notebook_guid": getattr(settings, "evernote_notebook_guid", "Not set"),
"default_tags": getattr(settings, "evernote_default_tags", "Not set"),
"include_metadata": getattr(settings, "evernote_include_metadata", True),
},
}
# Add FTP configuration to providers
providers["FTP Storage"] = {
"name": "FTP Storage",
"icon": "fa-solid fa-server",
"configured": bool(
getattr(settings, "ftp_host", None)
and getattr(settings, "ftp_username", None)
and getattr(settings, "ftp_password", None)
),
"enabled": getattr(settings, "ftp_enabled", True),
"description": "Upload files to FTP server",
"details": {
"host": getattr(settings, "ftp_host", "Not set"),
"port": getattr(settings, "ftp_port", "Not set"),
"username": getattr(settings, "ftp_username", "Not set"),
"password": mask_sensitive_value(getattr(settings, "ftp_password", None)),
"folder": getattr(settings, "ftp_folder", "Not set"),
"tls": getattr(settings, "ftp_use_tls", True),
"allow_plaintext": getattr(settings, "ftp_allow_plaintext", True),
},
}
# Check Google Drive configuration
gdrive_oauth_configured = bool(
getattr(settings, "google_drive_client_id", None)
and getattr(settings, "google_drive_client_secret", None)
and getattr(settings, "google_drive_refresh_token", None)
)
gdrive_sa_configured = bool(getattr(settings, "google_drive_credentials_json", None))
# Determine if using OAuth or service account
use_oauth = getattr(settings, "google_drive_use_oauth", False)
is_configured = (use_oauth and gdrive_oauth_configured) or (not use_oauth and gdrive_sa_configured)
providers["Google Drive"] = {
"name": "Google Drive",
"icon": "fa-brands fa-google-drive",
"configured": is_configured and bool(getattr(settings, "google_drive_folder_id", None)),
"enabled": getattr(settings, "google_drive_enabled", True),
"description": "Store documents in Google Drive",
"details": {
"auth_type": "OAuth" if use_oauth else "Service Account",
"client_id": getattr(settings, "google_drive_client_id", "Not set") if use_oauth else "N/A",
"client_secret": (
mask_sensitive_value(getattr(settings, "google_drive_client_secret", None)) if use_oauth else "N/A"
),
"refresh_token": (
mask_sensitive_value(getattr(settings, "google_drive_refresh_token", None)) if use_oauth else "N/A"
),
"credentials_json": (
mask_sensitive_value(getattr(settings, "google_drive_credentials_json", None))
if not use_oauth
else "N/A"
),
"folder_id": getattr(settings, "google_drive_folder_id", "Not set"),
"delegate": getattr(settings, "google_drive_delegate_to", "Not set") if not use_oauth else "N/A",
},
}
# Check NextCloud configuration
nextcloud_url = getattr(settings, "nextcloud_upload_url", "Not set")
# Extract base URL from WebDAV URL (remove the /remote.php part and everything after it)
nextcloud_base_url = nextcloud_url
if nextcloud_url != "Not set" and nextcloud_url is not None and "/remote.php" in nextcloud_url:
nextcloud_base_url = nextcloud_url.split("/remote.php")[0]
providers["NextCloud"] = {
"name": "NextCloud",
"icon": "fa-solid fa-cloud",
"configured": bool(
getattr(settings, "nextcloud_upload_url", None)
and getattr(settings, "nextcloud_username", None)
and getattr(settings, "nextcloud_password", None)
),
"enabled": getattr(settings, "nextcloud_enabled", True),
"description": "Store documents in NextCloud",
"details": {
"url": getattr(settings, "nextcloud_upload_url", "Not set"),
"base_url": nextcloud_base_url,
"username": getattr(settings, "nextcloud_username", "Not set"),
"password": mask_sensitive_value(getattr(settings, "nextcloud_password", None)),
"folder": getattr(settings, "nextcloud_folder", "Not set"),
},
}
# Check OneDrive configuration
providers["OneDrive"] = {
"name": "OneDrive",
"icon": "fa-brands fa-microsoft",
"configured": bool(
getattr(settings, "onedrive_client_id", None)
and getattr(settings, "onedrive_client_secret", None)
and getattr(settings, "onedrive_refresh_token", None)
),
"enabled": getattr(settings, "onedrive_enabled", True),
"description": "Store documents in Microsoft OneDrive",
"details": {
"client_id": getattr(settings, "onedrive_client_id", "Not set"),
"client_secret": mask_sensitive_value(getattr(settings, "onedrive_client_secret", None)),
"tenant_id": getattr(settings, "onedrive_tenant_id", "Not set"),
"refresh_token": mask_sensitive_value(getattr(settings, "onedrive_refresh_token", None)),
"folder": getattr(settings, "onedrive_folder_path", "Not set"),
},
}
# Check Paperless configuration
providers["Paperless-ngx"] = {
"name": "Paperless-ngx",
"icon": "fa-solid fa-file-lines",
"configured": bool(
getattr(settings, "paperless_host", None) and getattr(settings, "paperless_ngx_api_token", None)
),
"enabled": getattr(settings, "paperless_enabled", True),
"description": "Document management system for digital archives",
"details": {
"host": getattr(settings, "paperless_host", "Not set"),
"api_token": mask_sensitive_value(getattr(settings, "paperless_ngx_api_token", None)),
},
}
# Check SharePoint configuration
providers["SharePoint"] = {
"name": "SharePoint",
"icon": "fa-brands fa-microsoft",
"configured": bool(
getattr(settings, "sharepoint_client_id", None)
and getattr(settings, "sharepoint_client_secret", None)
and getattr(settings, "sharepoint_site_url", None)
),
"enabled": True,
"description": "Store documents in Microsoft SharePoint Online",
"details": {
"client_id": getattr(settings, "sharepoint_client_id", "Not set"),
"client_secret": mask_sensitive_value(getattr(settings, "sharepoint_client_secret", None)),
"tenant_id": getattr(settings, "sharepoint_tenant_id", "Not set"),
"refresh_token": mask_sensitive_value(getattr(settings, "sharepoint_refresh_token", None)),
"site_url": getattr(settings, "sharepoint_site_url", "Not set"),
"document_library": getattr(settings, "sharepoint_document_library", "Not set"),
"folder_path": getattr(settings, "sharepoint_folder_path", "Not set"),
},
}
# Check S3 configuration
providers["S3 Storage"] = {
"name": "S3 Storage",
"icon": "fa-brands fa-aws",
"configured": bool(
getattr(settings, "s3_bucket_name", None)
and getattr(settings, "aws_access_key_id", None)
and getattr(settings, "aws_secret_access_key", None)
),
"enabled": getattr(settings, "s3_enabled", True),
"description": "Store documents in S3-compatible object storage",
"details": {
"bucket": getattr(settings, "s3_bucket_name", "Not set"),
"region": getattr(settings, "aws_region", "Not set"),
"access_key_id": getattr(settings, "aws_access_key_id", "Not set"),
"secret_access_key": mask_sensitive_value(getattr(settings, "aws_secret_access_key", None)),
"folder_prefix": getattr(settings, "s3_folder_prefix", "Not set"),
"storage_class": getattr(settings, "s3_storage_class", "Not set"),
"acl": getattr(settings, "s3_acl", "Not set"),
},
}
# Check SFTP configuration
providers["SFTP Storage"] = {
"name": "SFTP Storage",
"icon": "fa-solid fa-lock",
"configured": bool(
getattr(settings, "sftp_host", None)
and getattr(settings, "sftp_username", None)
and (getattr(settings, "sftp_password", None) or getattr(settings, "sftp_private_key", None))
),
"enabled": getattr(settings, "sftp_enabled", True),
"description": "Upload files to SFTP server",
"details": {
"host": getattr(settings, "sftp_host", "Not set"),
"port": getattr(settings, "sftp_port", "Not set"),
"username": getattr(settings, "sftp_username", "Not set"),
"password": mask_sensitive_value(getattr(settings, "sftp_password", None)),
"private_key": getattr(settings, "sftp_private_key", "Not set"),
"private_key_passphrase": mask_sensitive_value(getattr(settings, "sftp_private_key_passphrase", None)),
"folder": getattr(settings, "sftp_folder", "Not set"),
},
}
# Add Uptime Kuma configuration
providers["Uptime Kuma"] = {
"name": "Uptime Kuma",
"icon": "fa-solid fa-heart-pulse",
"configured": bool(getattr(settings, "uptime_kuma_url", None)),
"enabled": True,
"description": "Server monitoring and status page",
"details": {
"url": getattr(settings, "uptime_kuma_url", "Not set"),
"ping_interval": getattr(settings, "uptime_kuma_ping_interval", "Not set"),
},
}
# Check WebDAV configuration
providers["WebDAV"] = {
"name": "WebDAV",
"icon": "fa-solid fa-globe",
"configured": bool(
getattr(settings, "webdav_url", None)
and getattr(settings, "webdav_username", None)
and getattr(settings, "webdav_password", None)
),
"enabled": getattr(settings, "webdav_enabled", True),
"description": "Store documents on WebDAV servers",
"details": {
"url": getattr(settings, "webdav_url", "Not set"),
"username": getattr(settings, "webdav_username", "Not set"),
"password": mask_sensitive_value(getattr(settings, "webdav_password", None)),
"folder": getattr(settings, "webdav_folder", "Not set"),
"verify_ssl": getattr(settings, "webdav_verify_ssl", "Not set"),
},
}
# Check iCloud Drive configuration
providers["iCloud Drive"] = {
"name": "iCloud Drive",
"icon": "fa-brands fa-apple",
"configured": bool(getattr(settings, "icloud_username", None) and getattr(settings, "icloud_password", None)),
"enabled": getattr(settings, "icloud_enabled", True),
"description": "Store documents in Apple iCloud Drive",
"details": {
"username": getattr(settings, "icloud_username", "Not set"),
"password": mask_sensitive_value(getattr(settings, "icloud_password", None)),
"folder": getattr(settings, "icloud_folder", "Not set"),
"cookie_directory": getattr(settings, "icloud_cookie_directory", "Not set"),
},
}
return providers