import time import logging from yuxi.channel.extensions.tlon.story import markdown_to_story from yuxi.channel.extensions.tlon.utils import format_at_ud logger = logging.getLogger(__name__) async def add_item(api, nest: str, author: str, title: str, content: str, image_url: str = "") -> str: item_id = f"{author}/{int(time.time() * 1000)}" story = markdown_to_story(content) action = { "add-curio": { "id": item_id, "title": title, "content": story, "author": author, "sent": int(time.time() * 1000), } } if image_url: action["add-curio"]["image"] = image_url payload = {"channel": {"nest": nest, "action": action}} await api.poke(app="heap", mark="heap-action", json_data=payload) return item_id async def edit_item(api, nest: str, item_id: str, title: str = "", content: str = "") -> None: action = { "edit-curio": { "id": format_at_ud(item_id), } } if title: action["edit-curio"]["title"] = title if content: action["edit-curio"]["content"] = markdown_to_story(content) payload = {"channel": {"nest": nest, "action": action}} await api.poke(app="heap", mark="heap-action", json_data=payload) async def delete_item(api, nest: str, item_id: str) -> None: payload = { "channel": { "nest": nest, "action": {"del-curio": format_at_ud(item_id)}, } } await api.poke(app="heap", mark="heap-action", json_data=payload) async def add_curator(api, nest: str, ship: str) -> None: payload = { "channel": { "nest": nest, "action": {"add-curator": ship}, } } await api.poke(app="heap", mark="heap-action", json_data=payload) async def del_curator(api, nest: str, ship: str) -> None: payload = { "channel": { "nest": nest, "action": {"del-curator": ship}, } } await api.poke(app="heap", mark="heap-action", json_data=payload) async def fetch_items(api, nest: str, limit: int = 20) -> list[dict]: try: data = await api.scry(f"/{nest}/curios/v1.json") curios = data.get("curios", {}) result = [] for cid, curio in curios.items(): result.append({ "id": cid, "title": curio.get("title", ""), "author": curio.get("author", ""), "sent": curio.get("sent", 0), "image": curio.get("image", ""), }) return sorted(result, key=lambda c: c["sent"], reverse=True)[:limit] except Exception: return []