feat(06-02): add /export command handler
- export_command handles /export and /export project - Sends markdown as Telegram document attachment - Registered in handlers/__init__.py - Updated HELP_TEXT with export options
This commit is contained in:
parent
152d6173d6
commit
e5108c6705
3 changed files with 89 additions and 1 deletions
|
|
@ -16,6 +16,7 @@ from moai.bot.handlers.discussion import (
|
|||
open_command,
|
||||
stop_command,
|
||||
)
|
||||
from moai.bot.handlers.export import export_command
|
||||
from moai.bot.handlers.projects import project_command, projects_command
|
||||
from moai.bot.handlers.status import status_command
|
||||
|
||||
|
|
@ -44,6 +45,7 @@ def register_handlers(app: Application) -> None:
|
|||
app.add_handler(CommandHandler("next", next_command))
|
||||
app.add_handler(CommandHandler("stop", stop_command))
|
||||
app.add_handler(CommandHandler("consensus", consensus_command))
|
||||
app.add_handler(CommandHandler("export", export_command))
|
||||
|
||||
# @mention handler - MessageHandler registered AFTER CommandHandlers
|
||||
# Matches messages starting with @claude, @gpt, or @gemini followed by content
|
||||
|
|
|
|||
|
|
@ -28,7 +28,8 @@ Multi-AI collaborative brainstorming platform.
|
|||
|
||||
*Output Commands:*
|
||||
/consensus - Generate consensus summary
|
||||
/export - Export project as markdown
|
||||
/export - Export current discussion as markdown
|
||||
/export project - Export entire project as markdown
|
||||
|
||||
*Utility:*
|
||||
/status - Show current state
|
||||
|
|
|
|||
85
src/moai/bot/handlers/export.py
Normal file
85
src/moai/bot/handlers/export.py
Normal file
|
|
@ -0,0 +1,85 @@
|
|||
"""Export command handlers for MoAI bot.
|
||||
|
||||
Provides /export command to export discussions and projects as markdown documents.
|
||||
"""
|
||||
|
||||
import io
|
||||
|
||||
from telegram import Update
|
||||
from telegram.ext import ContextTypes
|
||||
|
||||
from moai.core.exporter import export_discussion, export_project
|
||||
from moai.core.services.discussion import get_active_discussion, get_discussion, list_discussions
|
||||
from moai.core.services.project import get_project
|
||||
|
||||
|
||||
def get_selected_project(context: ContextTypes.DEFAULT_TYPE) -> str | None:
|
||||
"""Get the currently selected project ID from user data."""
|
||||
return context.user_data.get("selected_project_id")
|
||||
|
||||
|
||||
async def export_command(update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
|
||||
"""Handle /export command - export discussion or project as markdown.
|
||||
|
||||
Usage:
|
||||
/export - Export current active discussion
|
||||
/export project - Export entire project with all discussions
|
||||
"""
|
||||
project_id = get_selected_project(context)
|
||||
if not project_id:
|
||||
await update.message.reply_text("No project selected. Use /project select first.")
|
||||
return
|
||||
|
||||
project = await get_project(project_id)
|
||||
if not project:
|
||||
await update.message.reply_text("Selected project not found. Use /project select.")
|
||||
return
|
||||
|
||||
args = context.args
|
||||
export_full_project = args and args[0].lower() == "project"
|
||||
|
||||
if export_full_project:
|
||||
# Export entire project
|
||||
discussions_list = await list_discussions(project_id)
|
||||
if not discussions_list:
|
||||
await update.message.reply_text("No discussions in this project to export.")
|
||||
return
|
||||
|
||||
# Fetch each discussion with full eager loading
|
||||
loaded_discussions = []
|
||||
for disc in discussions_list:
|
||||
full_disc = await get_discussion(disc.id)
|
||||
if full_disc:
|
||||
loaded_discussions.append(full_disc)
|
||||
|
||||
markdown = export_project(project, loaded_discussions)
|
||||
filename = f"{project.name.replace(' ', '_')}-export.md"
|
||||
|
||||
await update.message.reply_document(
|
||||
document=io.BytesIO(markdown.encode("utf-8")),
|
||||
filename=filename,
|
||||
caption=f"📄 Full project export: {project.name}",
|
||||
)
|
||||
else:
|
||||
# Export active discussion
|
||||
discussion = await get_active_discussion(project_id)
|
||||
if not discussion:
|
||||
await update.message.reply_text(
|
||||
"No active discussion. Start one with /open or /discuss."
|
||||
)
|
||||
return
|
||||
|
||||
# Re-fetch with full loading including consensus
|
||||
full_discussion = await get_discussion(discussion.id)
|
||||
if not full_discussion:
|
||||
await update.message.reply_text("Failed to load discussion.")
|
||||
return
|
||||
|
||||
markdown = export_discussion(full_discussion)
|
||||
filename = f"{project.name.replace(' ', '_')}-discussion.md"
|
||||
|
||||
await update.message.reply_document(
|
||||
document=io.BytesIO(markdown.encode("utf-8")),
|
||||
filename=filename,
|
||||
caption=f"📄 Discussion export: {full_discussion.question[:50]}...",
|
||||
)
|
||||
Loading…
Add table
Reference in a new issue