mirror of
https://github.com/MODSetter/SurfSense.git
synced 2026-05-17 18:35:19 +02:00
feat: implement sync notifications for Obsidian plugin
- Added functionality to create and update notifications during the Obsidian sync process. - Improved handling of sync completion and failure notifications. - Updated connector naming convention in various locations for consistency.
This commit is contained in:
parent
3b7f27cff9
commit
4a75603d4f
4 changed files with 134 additions and 8 deletions
|
|
@ -41,6 +41,7 @@ from app.schemas.obsidian_plugin import (
|
|||
SyncAckItem,
|
||||
SyncBatchRequest,
|
||||
)
|
||||
from app.services.notification_service import NotificationService
|
||||
from app.services.obsidian_plugin_indexer import (
|
||||
delete_note,
|
||||
get_manifest,
|
||||
|
|
@ -68,6 +69,103 @@ def _build_handshake() -> dict[str, object]:
|
|||
return {"capabilities": list(OBSIDIAN_CAPABILITIES)}
|
||||
|
||||
|
||||
def _connector_type_value(connector: SearchSourceConnector) -> str:
|
||||
connector_type = connector.connector_type
|
||||
if hasattr(connector_type, "value"):
|
||||
return str(connector_type.value)
|
||||
return str(connector_type)
|
||||
|
||||
|
||||
async def _start_obsidian_sync_notification(
|
||||
session: AsyncSession,
|
||||
*,
|
||||
user: User,
|
||||
connector: SearchSourceConnector,
|
||||
total_count: int,
|
||||
):
|
||||
"""Create/update the rolling inbox item for Obsidian plugin sync.
|
||||
|
||||
Obsidian sync is continuous and batched, so we keep one stable
|
||||
operation_id per connector instead of creating a new notification per batch.
|
||||
"""
|
||||
handler = NotificationService.connector_indexing
|
||||
operation_id = f"obsidian_sync_connector_{connector.id}"
|
||||
connector_name = connector.name or "Obsidian"
|
||||
notification = await handler.find_or_create_notification(
|
||||
session=session,
|
||||
user_id=user.id,
|
||||
operation_id=operation_id,
|
||||
title=f"Syncing: {connector_name}",
|
||||
message="Syncing from Obsidian plugin",
|
||||
search_space_id=connector.search_space_id,
|
||||
initial_metadata={
|
||||
"connector_id": connector.id,
|
||||
"connector_name": connector_name,
|
||||
"connector_type": _connector_type_value(connector),
|
||||
"sync_stage": "processing",
|
||||
"indexed_count": 0,
|
||||
"failed_count": 0,
|
||||
"total_count": total_count,
|
||||
"source": "obsidian_plugin",
|
||||
},
|
||||
)
|
||||
return await handler.update_notification(
|
||||
session=session,
|
||||
notification=notification,
|
||||
status="in_progress",
|
||||
metadata_updates={
|
||||
"sync_stage": "processing",
|
||||
"total_count": total_count,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
async def _finish_obsidian_sync_notification(
|
||||
session: AsyncSession,
|
||||
*,
|
||||
notification,
|
||||
indexed: int,
|
||||
failed: int,
|
||||
):
|
||||
"""Mark the rolling Obsidian sync inbox item complete or failed."""
|
||||
handler = NotificationService.connector_indexing
|
||||
connector_name = notification.notification_metadata.get("connector_name", "Obsidian")
|
||||
if failed > 0 and indexed == 0:
|
||||
title = f"Failed: {connector_name}"
|
||||
message = (
|
||||
f"Sync failed: {failed} file(s) failed"
|
||||
if failed > 1
|
||||
else "Sync failed: 1 file failed"
|
||||
)
|
||||
status_value = "failed"
|
||||
stage = "failed"
|
||||
else:
|
||||
title = f"Ready: {connector_name}"
|
||||
if failed > 0:
|
||||
message = f"Partially synced: {indexed} file(s) synced, {failed} failed."
|
||||
elif indexed == 0:
|
||||
message = "Already up to date!"
|
||||
elif indexed == 1:
|
||||
message = "Now searchable! 1 file synced."
|
||||
else:
|
||||
message = f"Now searchable! {indexed} files synced."
|
||||
status_value = "completed"
|
||||
stage = "completed"
|
||||
|
||||
await handler.update_notification(
|
||||
session=session,
|
||||
notification=notification,
|
||||
title=title,
|
||||
message=message,
|
||||
status=status_value,
|
||||
metadata_updates={
|
||||
"indexed_count": indexed,
|
||||
"failed_count": failed,
|
||||
"sync_stage": stage,
|
||||
},
|
||||
)
|
||||
|
||||
|
||||
async def _resolve_vault_connector(
|
||||
session: AsyncSession,
|
||||
*,
|
||||
|
|
@ -188,7 +286,7 @@ def _build_config(
|
|||
|
||||
|
||||
def _display_name(vault_name: str) -> str:
|
||||
return f"Obsidian \u2014 {vault_name}"
|
||||
return f"Obsidian - {vault_name}"
|
||||
|
||||
|
||||
@router.post("/connect", response_model=ConnectResponse)
|
||||
|
|
@ -335,6 +433,18 @@ async def obsidian_sync(
|
|||
connector = await _resolve_vault_connector(
|
||||
session, user=user, vault_id=payload.vault_id
|
||||
)
|
||||
notification = None
|
||||
try:
|
||||
notification = await _start_obsidian_sync_notification(
|
||||
session, user=user, connector=connector, total_count=len(payload.notes)
|
||||
)
|
||||
except Exception:
|
||||
logger.warning(
|
||||
"obsidian sync notification start failed connector=%s user=%s",
|
||||
connector.id,
|
||||
user.id,
|
||||
exc_info=True,
|
||||
)
|
||||
|
||||
items: list[SyncAckItem] = []
|
||||
indexed = 0
|
||||
|
|
@ -362,6 +472,22 @@ async def obsidian_sync(
|
|||
SyncAckItem(path=note.path, status="error", error=str(exc)[:300])
|
||||
)
|
||||
|
||||
if notification is not None:
|
||||
try:
|
||||
await _finish_obsidian_sync_notification(
|
||||
session,
|
||||
notification=notification,
|
||||
indexed=indexed,
|
||||
failed=failed,
|
||||
)
|
||||
except Exception:
|
||||
logger.warning(
|
||||
"obsidian sync notification finish failed connector=%s user=%s",
|
||||
connector.id,
|
||||
user.id,
|
||||
exc_info=True,
|
||||
)
|
||||
|
||||
return SyncAck(
|
||||
vault_id=payload.vault_id,
|
||||
indexed=indexed,
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue