From 23b5cde07fa5e6feac033d5b8e6e61742e711718 Mon Sep 17 00:00:00 2001 From: mac-zhou Date: Tue, 19 Mar 2024 19:46:44 +0800 Subject: [PATCH 1/6] Add IpLocationPlugin to PluginManager --- bot/plugin_manager.py | 4 +++- bot/plugins/iplocation.py | 44 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 47 insertions(+), 1 deletion(-) create mode 100644 bot/plugins/iplocation.py diff --git a/bot/plugin_manager.py b/bot/plugin_manager.py index 370b1c3e..6cd62e80 100644 --- a/bot/plugin_manager.py +++ b/bot/plugin_manager.py @@ -15,6 +15,7 @@ from plugins.worldtimeapi import WorldTimeApiPlugin from plugins.whois_ import WhoisPlugin from plugins.webshot import WebshotPlugin +from plugins.iplocation import IpLocationPlugin class PluginManager: @@ -40,6 +41,7 @@ def __init__(self, config): 'auto_tts': AutoTextToSpeech, 'whois': WhoisPlugin, 'webshot': WebshotPlugin, + 'iplocation': IpLocationPlugin, } self.plugins = [plugin_mapping[plugin]() for plugin in enabled_plugins if plugin in plugin_mapping] @@ -69,4 +71,4 @@ def get_plugin_source_name(self, function_name) -> str: def __get_plugin_by_function_name(self, function_name): return next((plugin for plugin in self.plugins - if function_name in map(lambda spec: spec.get('name'), plugin.get_spec())), None) + if function_name in map(lambda spec: spec.get('name'), plugin.get_spec())), None) diff --git a/bot/plugins/iplocation.py b/bot/plugins/iplocation.py new file mode 100644 index 00000000..6933ef86 --- /dev/null +++ b/bot/plugins/iplocation.py @@ -0,0 +1,44 @@ +import requests +from typing import Dict + +from .plugin import Plugin + +class IpLocationPlugin(Plugin): + """ + A plugin to get geolocation and other information for a given IP address + """ + + def get_source_name(self) -> str: + return "IP.FM" + + def get_spec(self) -> [Dict]: + return [{ + "name": "iplocaion", + "description": "Get information for an IP address using the IP.FM API.", + "parameters": { + "type": "object", + "properties": { + "ip": {"type": "string", "description": "IP Address"} + }, + "required": ["ip"], + }, + }] + + async def execute(self, function_name, helper, **kwargs) -> Dict: + ip = kwargs.get('ip') + BASE_URL = "https://api.ip.fm/?ip={}" + url = BASE_URL.format(ip) + try: + response = requests.get(url) + response_data = response.json() + country = response_data.get('data', {}).get('country', "None") + subdivisions = response_data.get('data', {}).get('subdivisions', "None") + city = response_data.get('data', {}).get('city', "None") + location = ', '.join(filter(None, [country, subdivisions, city])) or "None" + + asn = response_data.get('data', {}).get('asn', "None") + as_name = response_data.get('data', {}).get('as_name', "None") + as_domain = response_data.get('data', {}).get('as_domain', "None") + return {"Location": location, "ASN": asn, "AS Name": as_name, "AS Domain": as_domain} + except Exception as e: + return {"Error": str(e)} From 237b0840fa7825e88ade13f74250cd7d2377799c Mon Sep 17 00:00:00 2001 From: ShadovvBeast Date: Fri, 5 Apr 2024 16:00:02 +0300 Subject: [PATCH 2/6] Add Hebrew to translations.json Add the Hebrew language to the bot --- translations.json | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) diff --git a/translations.json b/translations.json index 449b3417..d4e2d58a 100644 --- a/translations.json +++ b/translations.json @@ -293,6 +293,55 @@ "loading":"Lataa...", "function_unavailable_in_inline_mode": "Tämä toiminto ei ole käytettävissä sisäisessä tilassa" }, + "he": { + "help_description": "הצג הודעת עזרה", + "reset_description": "אתחל את השיחה. ניתן להעביר הוראות ברמה גבוהה (למשל, /reset אתה עוזר מועיל)", + "image_description": "צור תמונה מהפרומפט (למשל, /image חתול)", + "tts_description": "צור דיבור מטקסט (למשל, /tts הבית שלי)", + "stats_description": "קבל את סטטיסטיקות השימוש הנוכחיות שלך", + "resend_description": "שלח מחדש את ההודעה האחרונה", + "chat_description": "שוחח עם הבוט!", + "disallowed": "מצטערים, אינך מורשה להשתמש בבוט זה. תוכל לבדוק את הקוד המקור ב https://github.com/n3d1117/chatgpt-telegram-bot", + "budget_limit": "מצטערים, הגעת למגבלת השימוש שלך.", + "help_text": ["אני בוט של ChatGPT, דבר איתי!", "שלח לי הודעה קולית או קובץ ואני אתרגם אותו בשבילך", "קוד פתוח ב https://github.com/n3d1117/chatgpt-telegram-bot"], + "stats_conversation": ["שיחה נוכחית", "הודעות צ'אט בהיסטוריה", "אסימוני צ'אט בהיסטוריה"], + "usage_today": "שימוש היום", + "usage_month": "שימוש החודש", + "stats_tokens": "אסימונים", + "stats_images": "תמונות שנוצרו", + "stats_vision": "אסימוני תמונה שפורשו", + "stats_tts": "תווים שהומרו לדיבור", + "stats_transcribe": ["דקות ו", "שניות שהוקלטו"], + "stats_total": "💰 לסך כל של $", + "stats_budget": "התקציב הנותר שלך", + "monthly": " לחודש זה", + "daily": " להיום", + "all-time": "", + "stats_openai": "החשבון שלך ב-OpenAI חויב החודש ב-$", + "resend_failed": "אין לך מה לשלוח מחדש", + "reset_done": "בוצע!", + "image_no_prompt": "נא לספק פרומפט! (למשל, /image חתול)", + "image_fail": "נכשל ביצירת התמונה", + "vision_fail": "נכשל בפרשנות התמונה", + "tts_no_prompt": "נא לספק טקסט! (למשל, /tts הבית שלי)", + "tts_fail": "נכשל ביצירת הדיבור", + "media_download_fail": ["נכשל בהורדת קובץ השמע", "ודא שהקובץ אינו גדול מדי. (מקסימום 20MB)"], + "media_type_fail": "סוג קובץ לא נתמך", + "transcript": "תמליל", + "answer": "תשובה", + "transcribe_fail": "נכשל בתרגום הטקסט", + "chat_fail": "נכשל בקבלת תגובה", + "prompt": "פרומפט", + "completion": "השלמה", + "openai_rate_limit": "חריגה מהגבלת השימוש של OpenAI", + "openai_invalid": "בקשה לא חוקית של OpenAI", + "error": "אירעה שגיאה", + "try_again": "נא לנסות שוב מאוחר יותר", + "answer_with_chatgpt": "ענה באמצעות ChatGPT", + "ask_chatgpt": "שאל את ChatGPT", + "loading": "טוען...", + "function_unavailable_in_inline_mode": "הפונקציה לא זמינה במצב inline" + } "id": { "help_description": "Menampilkan pesan bantuan", "reset_description": "Merestart percakapan. Opsional memasukkan instruksi tingkat tinggi (misalnya /reset Anda adalah asisten yang membantu)", From 63589a81fb494185650d21d157bc1afc02dd71f9 Mon Sep 17 00:00:00 2001 From: Oleg Lebedev Date: Sat, 6 Apr 2024 01:08:48 +0000 Subject: [PATCH 3/6] add gpt-4-turbo-preview support --- bot/openai_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/openai_helper.py b/bot/openai_helper.py index 24eaa49f..a2e7c35d 100644 --- a/bot/openai_helper.py +++ b/bot/openai_helper.py @@ -24,7 +24,7 @@ # Models gpt-3.5-turbo-0613 and gpt-3.5-turbo-16k-0613 will be deprecated on June 13, 2024 GPT_3_MODELS = ("gpt-3.5-turbo", "gpt-3.5-turbo-0301", "gpt-3.5-turbo-0613") GPT_3_16K_MODELS = ("gpt-3.5-turbo-16k", "gpt-3.5-turbo-16k-0613", "gpt-3.5-turbo-1106", "gpt-3.5-turbo-0125") -GPT_4_MODELS = ("gpt-4", "gpt-4-0314", "gpt-4-0613") +GPT_4_MODELS = ("gpt-4", "gpt-4-0314", "gpt-4-0613", "gpt-4-turbo-preview") GPT_4_32K_MODELS = ("gpt-4-32k", "gpt-4-32k-0314", "gpt-4-32k-0613") GPT_4_VISION_MODELS = ("gpt-4-vision-preview",) GPT_4_128K_MODELS = ("gpt-4-1106-preview","gpt-4-0125-preview","gpt-4-turbo-preview") From a6e0cb02ccd40defa893c35407023cfc053deb74 Mon Sep 17 00:00:00 2001 From: UPSTREAM <36982019+upstream-team@users.noreply.github.com> Date: Fri, 12 Apr 2024 11:16:20 +0300 Subject: [PATCH 4/6] support gpt-4-turbo GPT-4 Turbo with Vision The latest GPT-4 Turbo model with vision capabilities. Vision requests can now use JSON mode and function calling. Currently points to gpt-4-turbo-2024-04-09. --- bot/openai_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/openai_helper.py b/bot/openai_helper.py index 24eaa49f..1f42ef1b 100644 --- a/bot/openai_helper.py +++ b/bot/openai_helper.py @@ -27,7 +27,7 @@ GPT_4_MODELS = ("gpt-4", "gpt-4-0314", "gpt-4-0613") GPT_4_32K_MODELS = ("gpt-4-32k", "gpt-4-32k-0314", "gpt-4-32k-0613") GPT_4_VISION_MODELS = ("gpt-4-vision-preview",) -GPT_4_128K_MODELS = ("gpt-4-1106-preview","gpt-4-0125-preview","gpt-4-turbo-preview") +GPT_4_128K_MODELS = ("gpt-4-1106-preview","gpt-4-0125-preview","gpt-4-turbo-preview", "gpt-4-turbo") GPT_ALL_MODELS = GPT_3_MODELS + GPT_3_16K_MODELS + GPT_4_MODELS + GPT_4_32K_MODELS + GPT_4_VISION_MODELS + GPT_4_128K_MODELS From 3dc01df7ff7d34d6004312d5aded7d4cf5d74d68 Mon Sep 17 00:00:00 2001 From: UPSTREAM <36982019+upstream-team@users.noreply.github.com> Date: Fri, 12 Apr 2024 11:24:46 +0300 Subject: [PATCH 5/6] Support gpt-4-turbo-2024-04-09 --- bot/openai_helper.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/bot/openai_helper.py b/bot/openai_helper.py index 1f42ef1b..17144000 100644 --- a/bot/openai_helper.py +++ b/bot/openai_helper.py @@ -27,7 +27,7 @@ GPT_4_MODELS = ("gpt-4", "gpt-4-0314", "gpt-4-0613") GPT_4_32K_MODELS = ("gpt-4-32k", "gpt-4-32k-0314", "gpt-4-32k-0613") GPT_4_VISION_MODELS = ("gpt-4-vision-preview",) -GPT_4_128K_MODELS = ("gpt-4-1106-preview","gpt-4-0125-preview","gpt-4-turbo-preview", "gpt-4-turbo") +GPT_4_128K_MODELS = ("gpt-4-1106-preview","gpt-4-0125-preview","gpt-4-turbo-preview", "gpt-4-turbo", "gpt-4-turbo-2024-04-09") GPT_ALL_MODELS = GPT_3_MODELS + GPT_3_16K_MODELS + GPT_4_MODELS + GPT_4_32K_MODELS + GPT_4_VISION_MODELS + GPT_4_128K_MODELS From b526d48dbdb9a6b7b473fee3c74ac2742f8abcc4 Mon Sep 17 00:00:00 2001 From: "pixeebot[bot]" <104101892+pixeebot[bot]@users.noreply.github.com> Date: Mon, 15 Apr 2024 15:31:05 +0000 Subject: [PATCH 6/6] Remove Unnecessary F-strings --- bot/main.py | 2 +- bot/plugins/weather.py | 2 +- bot/plugins/worldtimeapi.py | 4 ++-- bot/telegram_bot.py | 20 ++++++++++---------- 4 files changed, 14 insertions(+), 14 deletions(-) diff --git a/bot/main.py b/bot/main.py index 41604c84..8e0118d2 100644 --- a/bot/main.py +++ b/bot/main.py @@ -64,7 +64,7 @@ def main(): if openai_config['enable_functions'] and not functions_available: logging.error(f'ENABLE_FUNCTIONS is set to true, but the model {model} does not support it. ' - f'Please set ENABLE_FUNCTIONS to false or use a model that supports it.') + 'Please set ENABLE_FUNCTIONS to false or use a model that supports it.') exit(1) if os.environ.get('MONTHLY_USER_BUDGETS') is not None: logging.warning('The environment variable MONTHLY_USER_BUDGETS is deprecated. ' diff --git a/bot/plugins/weather.py b/bot/plugins/weather.py index 7b2b1f29..53e5948b 100644 --- a/bot/plugins/weather.py +++ b/bot/plugins/weather.py @@ -58,7 +58,7 @@ def get_spec(self) -> [Dict]: ] async def execute(self, function_name, helper, **kwargs) -> Dict: - url = f'https://api.open-meteo.com/v1/forecast' \ + url = 'https://api.open-meteo.com/v1/forecast' \ f'?latitude={kwargs["latitude"]}' \ f'&longitude={kwargs["longitude"]}' \ f'&temperature_unit={kwargs["unit"]}' diff --git a/bot/plugins/worldtimeapi.py b/bot/plugins/worldtimeapi.py index 2e09e366..6b735faa 100644 --- a/bot/plugins/worldtimeapi.py +++ b/bot/plugins/worldtimeapi.py @@ -21,13 +21,13 @@ def get_source_name(self) -> str: def get_spec(self) -> [Dict]: return [{ "name": "worldtimeapi", - "description": f"Get the current time from a given timezone", + "description": "Get the current time from a given timezone", "parameters": { "type": "object", "properties": { "timezone": { "type": "string", - "description": f"The timezone identifier (e.g: `Europe/Rome`). Infer this from the location." + "description": "The timezone identifier (e.g: `Europe/Rome`). Infer this from the location." f"Use {self.default_timezone} if not specified." } }, diff --git a/bot/telegram_bot.py b/bot/telegram_bot.py index 7a536b1f..4cf9fa4c 100644 --- a/bot/telegram_bot.py +++ b/bot/telegram_bot.py @@ -84,12 +84,12 @@ async def stats(self, update: Update, context: ContextTypes.DEFAULT_TYPE): """ if not await is_allowed(self.config, update, context): logging.warning(f'User {update.message.from_user.name} (id: {update.message.from_user.id}) ' - f'is not allowed to request their usage statistics') + 'is not allowed to request their usage statistics') await self.send_disallowed_message(update, context) return logging.info(f'User {update.message.from_user.name} (id: {update.message.from_user.id}) ' - f'requested their usage statistics') + 'requested their usage statistics') user_id = update.message.from_user.id if user_id not in self.usage: @@ -112,7 +112,7 @@ async def stats(self, update: Update, context: ContextTypes.DEFAULT_TYPE): f"*{localized_text('stats_conversation', bot_language)[0]}*:\n" f"{chat_messages} {localized_text('stats_conversation', bot_language)[1]}\n" f"{chat_token_length} {localized_text('stats_conversation', bot_language)[2]}\n" - f"----------------------------\n" + "----------------------------\n" ) # Check if image generation is enabled and, if so, generate the image statistics for today @@ -137,7 +137,7 @@ async def stats(self, update: Update, context: ContextTypes.DEFAULT_TYPE): f"{transcribe_minutes_today} {localized_text('stats_transcribe', bot_language)[0]} " f"{transcribe_seconds_today} {localized_text('stats_transcribe', bot_language)[1]}\n" f"{localized_text('stats_total', bot_language)}{current_cost['cost_today']:.2f}\n" - f"----------------------------\n" + "----------------------------\n" ) text_month_images = "" @@ -190,14 +190,14 @@ async def resend(self, update: Update, context: ContextTypes.DEFAULT_TYPE): """ if not await is_allowed(self.config, update, context): logging.warning(f'User {update.message.from_user.name} (id: {update.message.from_user.id})' - f' is not allowed to resend the message') + ' is not allowed to resend the message') await self.send_disallowed_message(update, context) return chat_id = update.effective_chat.id if chat_id not in self.last_message: logging.warning(f'User {update.message.from_user.name} (id: {update.message.from_user.id})' - f' does not have anything to resend') + ' does not have anything to resend') await update.effective_message.reply_text( message_thread_id=get_thread_id(update), text=localized_text('resend_failed', self.config['bot_language']) @@ -218,7 +218,7 @@ async def reset(self, update: Update, context: ContextTypes.DEFAULT_TYPE): """ if not await is_allowed(self.config, update, context): logging.warning(f'User {update.message.from_user.name} (id: {update.message.from_user.id}) ' - f'is not allowed to reset the conversation') + 'is not allowed to reset the conversation') await self.send_disallowed_message(update, context) return @@ -339,7 +339,7 @@ async def transcribe(self, update: Update, context: ContextTypes.DEFAULT_TYPE): return if is_group_chat(update) and self.config['ignore_group_transcriptions']: - logging.info(f'Transcription coming from group chat, ignoring...') + logging.info('Transcription coming from group chat, ignoring...') return chat_id = update.effective_chat.id @@ -463,13 +463,13 @@ async def vision(self, update: Update, context: ContextTypes.DEFAULT_TYPE): if is_group_chat(update): if self.config['ignore_group_vision']: - logging.info(f'Vision coming from group chat, ignoring...') + logging.info('Vision coming from group chat, ignoring...') return else: trigger_keyword = self.config['group_trigger_keyword'] if (prompt is None and trigger_keyword != '') or \ (prompt is not None and not prompt.lower().startswith(trigger_keyword.lower())): - logging.info(f'Vision coming from group chat with wrong keyword, ignoring...') + logging.info('Vision coming from group chat with wrong keyword, ignoring...') return image = update.message.effective_attachment[-1]