feat: mail phase 4 - IMAP folder create/delete + auto-sync
- Add imap_create_folder() and imap_delete_folder() service functions - Call IMAP CREATE/DELETE in folder create/delete endpoints - Add auto_sync_all_accounts() background task (every 5 min) - Start auto-sync loop on plugin activation via asyncio.create_task - Frontend: working sync button with isSyncing state and toast feedback - i18n: syncSuccess, syncFailed, syncing, autoSyncEnabled keys (de/en)
This commit is contained in:
@@ -2,13 +2,32 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import logging
|
||||
|
||||
from app.plugins.base import BasePlugin
|
||||
from app.plugins.manifest import PluginManifest, PluginRouteDef
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
async def _auto_sync_loop() -> None:
|
||||
"""Background loop: sync all active mail accounts every 5 minutes."""
|
||||
from app.plugins.builtins.mail.services import auto_sync_all_accounts
|
||||
|
||||
while True:
|
||||
try:
|
||||
await auto_sync_all_accounts()
|
||||
except Exception as exc:
|
||||
logger.warning("auto_sync error: %s", exc)
|
||||
await asyncio.sleep(300)
|
||||
|
||||
|
||||
class MailPlugin(BasePlugin):
|
||||
"""Mail plugin for email management: IMAP sync, SMTP send, threading, rules, PGP."""
|
||||
|
||||
_auto_sync_task: asyncio.Task | None = None
|
||||
|
||||
manifest = PluginManifest(
|
||||
name="mail",
|
||||
version="1.0.0",
|
||||
@@ -29,3 +48,28 @@ class MailPlugin(BasePlugin):
|
||||
migrations=["0001_initial.sql"],
|
||||
permissions=[],
|
||||
)
|
||||
|
||||
async def on_activate(
|
||||
self, db, service_container, event_bus
|
||||
) -> None:
|
||||
"""Activate plugin: register events + start auto-sync background task."""
|
||||
await super().on_activate(db, service_container, event_bus)
|
||||
|
||||
if self._auto_sync_task is None or self._auto_sync_task.done():
|
||||
self._auto_sync_task = asyncio.create_task(_auto_sync_loop())
|
||||
logger.info("Mail plugin: auto-sync background task started")
|
||||
|
||||
async def on_deactivate(
|
||||
self, db, service_container, event_bus
|
||||
) -> None:
|
||||
"""Deactivate plugin: stop auto-sync task + unregister events."""
|
||||
if self._auto_sync_task is not None and not self._auto_sync_task.done():
|
||||
self._auto_sync_task.cancel()
|
||||
try:
|
||||
await self._auto_sync_task
|
||||
except asyncio.CancelledError:
|
||||
pass
|
||||
self._auto_sync_task = None
|
||||
logger.info("Mail plugin: auto-sync background task stopped")
|
||||
|
||||
await super().on_deactivate(db, service_container, event_bus)
|
||||
|
||||
Reference in New Issue
Block a user