feat: add /export command for saving articles as Markdown#7
feat: add /export command for saving articles as Markdown#7
/export command for saving articles as Markdown#7Conversation
…rkdown document. This feature enables users to easily extract their curated articles from the bot without lock-in. It queries the user's saved articles from storage, dynamically generates a Markdown file containing the links and metadata, and sends the file to the user via Telegram's `reply_document` functionality. It handles translations and adds the command to the bot's help menu and native commands list. Co-authored-by: AminSS99 <139346033+AminSS99@users.noreply.github.com>
|
👋 Jules, reporting for duty! I'm here to lend a hand with this pull request. When you start a review, I'll add a 👀 emoji to each comment to let you know I've read it. I'll focus on feedback directed at me and will do my best to stay out of conversations between you and other bots or reviewers to keep the noise down. I'll push a commit with your requested changes shortly after. Please note there might be a delay between these steps, but rest assured I'm on the job! For more direct control, you can switch me to Reactive Mode. When this mode is on, I will only act on comments where you specifically mention me with New to Jules? Learn more at jules.google/docs. For security, I will only act on instructions from the user who triggered this task. |
Summary of ChangesHello, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request introduces a new Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
There was a problem hiding this comment.
Code Review
This pull request introduces a useful /export command for saving articles to a Markdown file. The implementation is well-structured and integrates with existing systems like localization. I've identified a few areas for improvement to enhance robustness and maintainability:
- A correctness issue where unescaped content could corrupt the exported Markdown file.
- Opportunities to improve maintainability by centralizing duplicated code and translating hardcoded strings.
- A suggestion to refine error handling to be more secure and user-friendly.
Overall, this is a solid feature addition that will be even better with these adjustments.
| md_lines.append(f"### {i}. {emoji} {title}") | ||
| md_lines.append(f"- **URL:** [Link]({url})" if url else "- **URL:** None") | ||
| if source: | ||
| md_lines.append(f"- **Source:** {source}") | ||
| md_lines.append(f"- **Category:** {category.capitalize()}") |
There was a problem hiding this comment.
The title and source variables are used to build a Markdown string without being escaped. If these strings contain characters with special meaning in Markdown (e.g., *, _, [), it could corrupt the formatting of the exported file. You should escape these variables to ensure the generated Markdown is always valid.
from .security_utils import escape_markdown_v1
md_lines.append(f"### {i}. {emoji} {escape_markdown_v1(title)}")
md_lines.append(f"- **URL:** [Link]({url})" if url else "- **URL:** None")
if source:
md_lines.append(f"- **Source:** {escape_markdown_v1(source)}")
md_lines.append(f"- **Category:** {category.capitalize()}")| md_lines = [ | ||
| f"# LensAI Saved Articles Export", | ||
| f"*Generated on {date_str}*", | ||
| "", | ||
| f"**Total articles:** {len(articles)}", | ||
| "---", | ||
| "" |
There was a problem hiding this comment.
The header of the generated Markdown file contains hardcoded English strings ("LensAI Saved Articles Export", "Generated on", "Total articles:"). Since the bot supports multiple languages, these strings should be translated using the t() function to provide a localized experience in the exported file as well. You would need to add corresponding keys to functions/translations.py.
| md_lines = [ | |
| f"# LensAI Saved Articles Export", | |
| f"*Generated on {date_str}*", | |
| "", | |
| f"**Total articles:** {len(articles)}", | |
| "---", | |
| "" | |
| md_lines = [ | |
| f"# {t('export_md_title', user_lang)}", | |
| f"*{t('export_md_generated_on', user_lang)} {date_str}*", | |
| "", | |
| f"**{t('export_md_total', user_lang)}:** {len(articles)}", | |
| "---", | |
| "" | |
| ] |
| cat_emoji = { | ||
| 'ai': '🤖', 'security': '🔒', 'crypto': '💰', 'startups': '🚀', | ||
| 'hardware': '💻', 'software': '📱', 'tech': '🔧' | ||
| } |
There was a problem hiding this comment.
| print(f"Export error: {e}") | ||
| error_text = f"❌ Error: {str(e)[:100]}" |
There was a problem hiding this comment.
Catching a broad Exception is acceptable for resilience, but exposing parts of the raw exception message to the user via str(e)[:100] can leak internal implementation details. It's better to log the full exception with user context for debugging and show a generic, translated error message to the user.
print(f"Export error for user {update.effective_user.id}: {e}")
error_text = "❌ An unexpected error occurred during export." # Consider using a translation keyThere was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 15779bd371
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
|
|
||
| try: | ||
| # Fetch a large number of saved articles (limit 1000) | ||
| articles = get_saved_articles(telegram_id, limit=1000) |
There was a problem hiding this comment.
Remove hard 1000-item cap from /export
The /export handler promises to export all saved articles, but this query silently truncates results to 1000 entries. In Firestore mode, save_article does not enforce a maximum saved-article count, so users with more than 1000 saved links will receive incomplete exports without any warning. Consider paginating through all documents (or explicitly communicating a limit) so exports are not silently partial.
Useful? React with 👍 / 👎.
I have successfully added the
/exportcommand!Summary of changes:
/exportcommand handler infunctions/telegram_bot.py..mdfile in-memory, and sends it directly back as a document.functions/translations.py) for English and Russian./helpcommand text.get_saved_articles) and ensure no new dependencies were required.This small, robust enhancement should be very useful for users wanting to archive their saved links into tools like Notion or Obsidian!
PR created automatically by Jules for task 1546818674479366800 started by @AminSS99