import os import asyncio import logging from typing import Optional, Dict, Any from imago_client import HubClient from imago_client.exceptions import ImagoError logger = logging.getLogger(__name__) class ShaarliHubPlugin: """ A reference integration class demonstrating how to use the Imago SDK to process incoming Shaarli bookmarks. """ def __init__(self, api_url: str, api_key: str): self.api_url = api_url self.api_key = api_key # The HubClient manages the session and resources self.client = HubClient(base_url=self.api_url, api_key=self.api_key) async def initialize(self): """Async initialization if required.""" pass async def process_bookmark(self, url: str, title: str, description: str) -> Dict[str, Any]: """ Process a new Shaarli bookmark by analyzing the URL through Imago AI. Returns suggested tags or enhanced description. """ logger.info(f"Processing bookmark: {url}") try: async with self.client as client: # 1. Ask Immago AI to summarize the URL or draft a task ai_task = await client.ai.draft_task(url=url, prompt=description or title) logger.info(f"Successfully processed bookmark via Imago AI. Suggested tags: {ai_task.get('suggested_tags', [])}") return ai_task except ImagoError as e: logger.error(f"Imago processing failed for bookmark {url}: {e}") return {"error": str(e)} async def upload_bookmark_screenshot(self, filepath: str) -> Optional[Dict[str, Any]]: """ Uploads an image (screenshot) associated with a Shaarli bookmark. """ if not os.path.exists(filepath): logger.warning(f"File not found: {filepath}") return None try: async with self.client as client: hub_image = await client.images.upload(filepath) logger.info(f"Uploaded image to Imago hub: {hub_image.uuid}") # Fetch details, which might include OCR if enabled details = await client.images.get(hub_image.uuid) return { "uuid": details.uuid, "url": f"{self.api_url}/images/{details.uuid}/file", "ocr_text": details.ocr.text if details.ocr and details.ocr.has_text else None } except ImagoError as e: logger.error(f"Failed to upload screenshot to Imago hub: {e}") return None