diff --git a/bot/plugin_manager.py b/bot/plugin_manager.py index 0e4998e..2180565 100644 --- a/bot/plugin_manager.py +++ b/bot/plugin_manager.py @@ -1,5 +1,7 @@ import json +from plugins.images import ImageSearchPlugin +from plugins.translate import TranslatePlugin from plugins.spotify import SpotifyPlugin from plugins.crypto import CryptoPlugin from plugins.weather import WeatherPlugin @@ -19,6 +21,8 @@ class PluginManager: 'crypto': CryptoPlugin(), 'web_search': WebSearchPlugin(), 'spotify': SpotifyPlugin(), + 'translate': TranslatePlugin(), + 'image_search': ImageSearchPlugin(), } self.plugins = [plugin_mapping[plugin] for plugin in enabled_plugins] diff --git a/bot/plugins/images.py b/bot/plugins/images.py new file mode 100644 index 0000000..d0d52ce --- /dev/null +++ b/bot/plugins/images.py @@ -0,0 +1,43 @@ +from itertools import islice +from typing import Dict + +from duckduckgo_search import DDGS + +from .plugin import Plugin + + +class ImageSearchPlugin(Plugin): + """ + A plugin to search images and GIFs for a given query, using DuckDuckGo + """ + def get_source_name(self) -> str: + return "DuckDuckGo Images" + + def get_spec(self) -> [Dict]: + return [{ + "name": "search_images", + "description": "Search image or GIFs for a given query", + "parameters": { + "type": "object", + "properties": { + "query": {"type": "string", "description": "The query to search for"}, + "type": { + "type": "string", + "enum": ["photo", "gif"], + "description": "The type of image to search for. Default to photo if not specified", + } + }, + "required": ["query", "type"], + }, + }] + + async def execute(self, function_name, **kwargs) -> Dict: + with DDGS() as ddgs: + ddgs_images_gen = ddgs.images( + kwargs['query'], + region="wt-wt", + safesearch='off', + type_image=kwargs['type'], + ) + results = list(islice(ddgs_images_gen, 1)) + return {"result": results[0]["image"]} diff --git a/bot/plugins/translate.py b/bot/plugins/translate.py new file mode 100644 index 0000000..c7ee3c3 --- /dev/null +++ b/bot/plugins/translate.py @@ -0,0 +1,31 @@ +from typing import Dict + +from duckduckgo_search import DDGS + +from .plugin import Plugin + + +class TranslatePlugin(Plugin): + """ + A plugin to translate a given text from a language to another, using DuckDuckGo + """ + def get_source_name(self) -> str: + return "DuckDuckGo Translate" + + def get_spec(self) -> [Dict]: + return [{ + "name": "translate", + "description": "Translate a given text from a language to another", + "parameters": { + "type": "object", + "properties": { + "text": {"type": "string", "description": "The text to translate"}, + "to_language": {"type": "string", "description": "The language to translate to (e.g. 'it')"} + }, + "required": ["text", "to_language"], + }, + }] + + async def execute(self, function_name, **kwargs) -> Dict: + with DDGS() as ddgs: + return ddgs.translate(kwargs['text'], to=kwargs['to_language']) diff --git a/bot/telegram_bot.py b/bot/telegram_bot.py index 842528b..5385977 100644 --- a/bot/telegram_bot.py +++ b/bot/telegram_bot.py @@ -435,7 +435,6 @@ class ChatGPTTelegramBot: message_thread_id=get_thread_id(update), reply_to_message_id=get_reply_to_message_id(self.config, update), text=content, - disable_web_page_preview=True ) except: continue diff --git a/bot/utils.py b/bot/utils.py index 4144c6d..7dafc12 100644 --- a/bot/utils.py +++ b/bot/utils.py @@ -118,7 +118,6 @@ async def edit_message_with_retry(context: ContextTypes.DEFAULT_TYPE, chat_id: i inline_message_id=message_id if is_inline else None, text=text, parse_mode=constants.ParseMode.MARKDOWN if markdown else None, - disable_web_page_preview=True ) except telegram.error.BadRequest as e: if str(e).startswith("Message is not modified"): @@ -129,7 +128,6 @@ async def edit_message_with_retry(context: ContextTypes.DEFAULT_TYPE, chat_id: i message_id=int(message_id) if not is_inline else None, inline_message_id=message_id if is_inline else None, text=text, - disable_web_page_preview=True ) except Exception as e: logging.warning(f'Failed to edit message: {str(e)}')