Compare commits
10 Commits
testing-co
...
25f9159155
Author | SHA1 | Date | |
---|---|---|---|
25f9159155 | |||
803acf514b | |||
542bb5d5cd | |||
5962eb53ad | |||
eb81f7aa67 | |||
c996168543 | |||
784409cef6 | |||
e9a853c31a | |||
669fd361d4 | |||
58fa16663e |
2
.gitignore
vendored
2
.gitignore
vendored
@@ -1,5 +1,4 @@
|
||||
.env
|
||||
.gitignore
|
||||
karma.db
|
||||
proxies.db
|
||||
session.txt
|
||||
@@ -10,3 +9,4 @@ simplematrixbotlib*/
|
||||
chromedriver
|
||||
store
|
||||
funguybot.service
|
||||
stats.db
|
@@ -87,7 +87,7 @@ To use the bot, invite it to a Matrix room and interact with it by sending comma
|
||||
- `!karma <user>`: View or modify karma points for a user.
|
||||
- `!funguy <prompt>` Talk to the Tech AI LLM
|
||||
- `!music <prompt>` Talk to the music knowledge LLM
|
||||
|
||||
- `!yt <search terms>` Search Youtube
|
||||
For a complete list of available commands and their descriptions, use the `!commands` command.
|
||||
|
||||
# 🍄 Funguy Bot Commands 🍄
|
||||
|
128
funguy.py
128
funguy.py
@@ -10,78 +10,86 @@ import time
|
||||
import sys
|
||||
from plugins.config import FunguyConfig
|
||||
|
||||
# Setup logging
|
||||
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO)
|
||||
class FunguyBot:
|
||||
|
||||
# Load plugins (defined before plugin load/reload functions)
|
||||
PLUGINS_DIR = "plugins"
|
||||
PLUGINS = {}
|
||||
bot = None
|
||||
config = None
|
||||
|
||||
def load_plugins():
|
||||
for plugin_file in os.listdir(PLUGINS_DIR):
|
||||
if plugin_file.endswith(".py"):
|
||||
plugin_name = os.path.splitext(plugin_file)[0]
|
||||
try:
|
||||
module = importlib.import_module(f"{PLUGINS_DIR}.{plugin_name}")
|
||||
PLUGINS[plugin_name] = module
|
||||
logging.info(f"Loaded plugin: {plugin_name}")
|
||||
except Exception as e:
|
||||
logging.error(f"Error loading plugin {plugin_name}: {e}")
|
||||
def __init__(self):
|
||||
self.PLUGINS_DIR = "plugins"
|
||||
self.PLUGINS = {}
|
||||
self.config = None
|
||||
self.bot = None
|
||||
self.load_dotenv()
|
||||
self.setup_logging()
|
||||
self.load_plugins()
|
||||
self.load_config()
|
||||
|
||||
def reload_plugins():
|
||||
global PLUGINS
|
||||
PLUGINS = {}
|
||||
# Unload modules from sys.modules
|
||||
for plugin_name in list(sys.modules.keys()):
|
||||
if plugin_name.startswith(PLUGINS_DIR + "."):
|
||||
del sys.modules[plugin_name]
|
||||
load_plugins()
|
||||
def load_dotenv(self):
|
||||
load_dotenv()
|
||||
|
||||
def rehash_config(config):
|
||||
del config
|
||||
config = FunguyConfig()
|
||||
def setup_logging(self):
|
||||
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO)
|
||||
logging.getLogger().setLevel(logging.INFO)
|
||||
|
||||
def load_plugins(self):
|
||||
for plugin_file in os.listdir(self.PLUGINS_DIR):
|
||||
if plugin_file.endswith(".py"):
|
||||
plugin_name = os.path.splitext(plugin_file)[0]
|
||||
try:
|
||||
module = importlib.import_module(f"{self.PLUGINS_DIR}.{plugin_name}")
|
||||
self.PLUGINS[plugin_name] = module
|
||||
logging.info(f"Loaded plugin: {plugin_name}")
|
||||
except Exception as e:
|
||||
logging.error(f"Error loading plugin {plugin_name}: {e}")
|
||||
|
||||
# Load environment variables from .env file
|
||||
load_dotenv()
|
||||
def reload_plugins(self):
|
||||
self.PLUGINS = {}
|
||||
# Unload modules from sys.modules
|
||||
for plugin_name in list(sys.modules.keys()):
|
||||
if plugin_name.startswith(self.PLUGINS_DIR + "."):
|
||||
del sys.modules[plugin_name]
|
||||
self.load_plugins()
|
||||
|
||||
# Load plugins
|
||||
load_plugins()
|
||||
def load_config(self):
|
||||
self.config = FunguyConfig()
|
||||
|
||||
# Bot configuration settings
|
||||
MATRIX_URL = os.getenv("MATRIX_URL")
|
||||
MATRIX_USER = os.getenv("MATRIX_USER")
|
||||
MATRIX_PASS = os.getenv("MATRIX_PASS")
|
||||
async def handle_commands(self, room, message):
|
||||
match = botlib.MessageMatch(room, message, self.bot, self.config.prefix)
|
||||
if match.is_not_from_this_bot() and match.prefix() and match.command("reload"):
|
||||
if str(message.sender) == self.config.admin_user:
|
||||
self.reload_plugins()
|
||||
await self.bot.api.send_text_message(room.room_id, "Plugins reloaded successfully")
|
||||
else:
|
||||
await self.bot.api.send_text_message(room.room_id, "You are not authorized to reload plugins.")
|
||||
|
||||
# Get credentials from env
|
||||
creds = botlib.Creds(MATRIX_URL, MATRIX_USER, MATRIX_PASS)
|
||||
for plugin_name, plugin_module in self.PLUGINS.items():
|
||||
await plugin_module.handle_command(room, message, self.bot, self.config.prefix, self.config)
|
||||
|
||||
# Bot configuration
|
||||
config = FunguyConfig()
|
||||
bot = botlib.Bot(creds, config)
|
||||
if match.is_not_from_this_bot() and match.prefix() and match.command("rehash"):
|
||||
if str(message.sender) == self.config.admin_user:
|
||||
self.rehash_config()
|
||||
await self.bot.api.send_text_message(room.room_id, "Config rehashed")
|
||||
else:
|
||||
await self.bot.api.send_text_message(room.room_id, "You are not authorized to reload plugins.")
|
||||
|
||||
@bot.listener.on_message_event
|
||||
async def handle_commands(room, message):
|
||||
match = botlib.MessageMatch(room, message, bot, config.prefix)
|
||||
if match.is_not_from_this_bot() and match.prefix() and match.command("reload"):
|
||||
if str(message.sender) == config.admin_user:
|
||||
reload_plugins()
|
||||
await bot.api.send_text_message(room.room_id, "Plugins reloaded successfully")
|
||||
else:
|
||||
await bot.api.send_text_message(room.room_id, "You are not authorized to reload plugins.")
|
||||
def rehash_config(self):
|
||||
del self.config
|
||||
self.config = FunguyConfig()
|
||||
|
||||
for plugin_name, plugin_module in PLUGINS.items():
|
||||
await plugin_module.handle_command(room, message, bot, config.prefix, config)
|
||||
def run(self):
|
||||
MATRIX_URL = os.getenv("MATRIX_URL")
|
||||
MATRIX_USER = os.getenv("MATRIX_USER")
|
||||
MATRIX_PASS = os.getenv("MATRIX_PASS")
|
||||
creds = botlib.Creds(MATRIX_URL, MATRIX_USER, MATRIX_PASS)
|
||||
self.bot = botlib.Bot(creds, self.config)
|
||||
|
||||
@self.bot.listener.on_message_event
|
||||
async def wrapper_handle_commands(room, message):
|
||||
await self.handle_commands(room, message)
|
||||
|
||||
if match.is_not_from_this_bot() and match.prefix() and match.command("rehash"):
|
||||
if str(message.sender) == config.admin_user:
|
||||
rehash_config(config)
|
||||
await bot.api.send_text_message(room.room_id, "Config rehashed")
|
||||
else:
|
||||
await bot.api.send_text_message(room.room_id, "You are not authorized to reload plugins.")
|
||||
self.bot.run()
|
||||
|
||||
|
||||
|
||||
|
||||
bot.run()
|
||||
if __name__ == "__main__":
|
||||
bot = FunguyBot()
|
||||
bot.run()
|
||||
|
4
g
Executable file
4
g
Executable file
@@ -0,0 +1,4 @@
|
||||
#!/bin/bash
|
||||
git add .;
|
||||
git commit -a -m "$1";
|
||||
git push -u origin "$2"
|
@@ -8,6 +8,7 @@ import requests
|
||||
import json
|
||||
import simplematrixbotlib as botlib
|
||||
import re
|
||||
import markdown2
|
||||
|
||||
async def handle_command(room, message, bot, prefix, config):
|
||||
"""
|
||||
@@ -56,9 +57,12 @@ async def handle_command(room, message, bot, prefix, config):
|
||||
response.raise_for_status() # Raise HTTPError for bad responses
|
||||
payload = response.json()
|
||||
new_text = payload['choices'][0]['text']
|
||||
if new_text.count('\n') > 1: # Check if new_text has more than one paragraph
|
||||
new_text = new_text.replace("\n", '<br>')
|
||||
new_text = re.sub(r"\*\*(.*?)\*\*", r"<strong>\1</strong>", new_text)
|
||||
new_text = markdown_to_html(new_text)
|
||||
print(new_text)
|
||||
|
||||
if new_text.count('<p>') > 1 or new_text.count('<li>') > 1: # Check if new_text has more than one paragraph
|
||||
#new_text = new_text.replace("\n", '<br>')
|
||||
#new_text = re.sub(r"\*\*(.*?)\*\*", r"<strong>\1</strong>", new_text)
|
||||
new_text = "<details><summary><strong>🎵Funguy Music GPT🎵<br>⤵︎Click Here To See Funguy's Response⤵︎</strong></summary>" + new_text + "</details>"
|
||||
await bot.api.send_markdown_message(room.room_id, new_text)
|
||||
else:
|
||||
@@ -67,3 +71,8 @@ async def handle_command(room, message, bot, prefix, config):
|
||||
except requests.exceptions.RequestException as e:
|
||||
logging.error(f"HTTP request failed for '{prompt}': {e}")
|
||||
await bot.api.send_text_message(room.room_id, f"Error generating text: {e}")
|
||||
|
||||
|
||||
def markdown_to_html(markdown_text):
|
||||
html_content = markdown2.markdown(markdown_text)
|
||||
return html_content
|
||||
|
@@ -9,6 +9,7 @@ import requests
|
||||
import json
|
||||
import simplematrixbotlib as botlib
|
||||
import re
|
||||
import markdown2
|
||||
|
||||
async def handle_command(room, message, bot, prefix, config):
|
||||
"""
|
||||
@@ -57,9 +58,10 @@ async def handle_command(room, message, bot, prefix, config):
|
||||
response.raise_for_status() # Raise HTTPError for bad responses
|
||||
payload = response.json()
|
||||
new_text = payload['choices'][0]['text']
|
||||
if new_text.count('\n') > 2: # Check if new_text has more than one paragraph
|
||||
new_text = new_text.replace("\n", '<br>')
|
||||
new_text = re.sub(r"\*\*(.*?)\*\*", r"<strong>\1</strong>", new_text)
|
||||
new_text = markdown_to_html(new_text)
|
||||
if new_text.count('<p>') > 2: # Check if new_text has more than one paragraph
|
||||
#new_text = new_text.replace("\n", '<br>')
|
||||
#new_text = re.sub(r"\*\*(.*?)\*\*", r"<strong>\1</strong>", new_text)
|
||||
new_text = "<details><summary><strong>🍄Funguy Tech GPT🍄<br>⤵︎Click Here To See Funguy's Response⤵︎</strong></summary>" + new_text + "</details>"
|
||||
await bot.api.send_markdown_message(room.room_id, new_text)
|
||||
else:
|
||||
@@ -68,3 +70,7 @@ async def handle_command(room, message, bot, prefix, config):
|
||||
except requests.exceptions.RequestException as e:
|
||||
logging.error(f"HTTP request failed for '{prompt}': {e}")
|
||||
await bot.api.send_text_message(room.room_id, f"Error generating text: {e}")
|
||||
|
||||
def markdown_to_html(markdown_text):
|
||||
html_content = markdown2.markdown(markdown_text)
|
||||
return html_content
|
||||
|
@@ -1,3 +1,6 @@
|
||||
"""
|
||||
Custom configuration class for the Funguy bot.
|
||||
"""
|
||||
# plugins/config.py
|
||||
|
||||
import os
|
||||
|
@@ -23,10 +23,39 @@ async def handle_command(room, message, bot, prefix, config):
|
||||
if match.is_not_from_this_bot() and match.prefix() and match.command("date"):
|
||||
logging.info("Fetching current date and time")
|
||||
current_datetime = datetime.datetime.now()
|
||||
|
||||
# Extract individual date components
|
||||
day_of_week = current_datetime.strftime("%A")
|
||||
date_of_month = current_datetime.strftime("%d") # Day with leading zero
|
||||
month = current_datetime.strftime("%B")
|
||||
year = current_datetime.strftime("%Y")
|
||||
time = current_datetime.strftime("%I:%M:%S %p")
|
||||
date_message = f"📅 Today is **{day_of_week}** of **{month}** in **{year}**. The time is **⏰ {time}**"
|
||||
|
||||
# Format date with ordinal suffix
|
||||
date_with_ordinal = f"{date_of_month}{get_ordinal_suffix(date_of_month)}"
|
||||
|
||||
# Construct the message
|
||||
date_message = f"Date: **{day_of_week}** the {date_with_ordinal}, **{month} {year}**. \nTime: **⏰ {time}**"
|
||||
|
||||
await bot.api.send_markdown_message(room.room_id, date_message)
|
||||
logging.info("Sent current date and time to the room")
|
||||
|
||||
|
||||
def get_ordinal_suffix(day_of_month):
|
||||
"""
|
||||
Helper function to get the ordinal suffix for a day number.
|
||||
|
||||
Args:
|
||||
day_of_month (str): The day number as a string (e.g., "1", "13")
|
||||
|
||||
Returns:
|
||||
str: The ordinal suffix (e.g., "st", "th", "nd")
|
||||
"""
|
||||
if day_of_month.endswith("11") or day_of_month.endswith("12") or day_of_month.endswith("13"):
|
||||
return "th"
|
||||
elif day_of_month.endswith("1") or day_of_month.endswith("3"):
|
||||
return "st"
|
||||
elif day_of_month.endswith("2"):
|
||||
return "nd"
|
||||
else:
|
||||
return "th"
|
||||
|
@@ -21,51 +21,52 @@ async def handle_command(room, message, bot, prefix, config):
|
||||
match = botlib.MessageMatch(room, message, bot, prefix)
|
||||
if match.is_not_from_this_bot() and match.prefix() and match.command("help"):
|
||||
logging.info("Fetching command help documentation")
|
||||
commands_message = """<details><summary><strong>🍄Funguy Bot Commands🍄<br>⤵︎Click Here To See Help Text⤵︎</strong></summary>
|
||||
<br>
|
||||
<br>🃏 **!fortune**
|
||||
<br>Returns a random fortune message.
|
||||
<br>Executes the `/usr/games/fortune` utility and sends the output as a message to the chat room.
|
||||
<br>
|
||||
<br>⏰ **!date**
|
||||
<br>Displays the current date and time.
|
||||
<br>Fetches the current date and time using Python's `datetime` module and sends it in a formatted message to the chat room.
|
||||
<br>
|
||||
<br>💻 **!proxy**
|
||||
<br>Retrieves a tested/working random SOCKS5 proxy.
|
||||
<br>Fetches a list of SOCKS5 proxies, tests their availability, and sends the first working proxy to the chat room.
|
||||
<br>
|
||||
<br>📶 **!isup [domain/ip]**
|
||||
<br>Checks if the specified domain or IP address is reachable.
|
||||
<br>Checks if the specified domain or IP address is reachable by attempting to ping it. If DNS resolution is successful, it checks HTTP and HTTPS service availability by sending requests to the domain.
|
||||
<br>
|
||||
<br>☯ **!karma [user]**
|
||||
<br>Retrieves the karma points for the specified user.
|
||||
<br>Retrieves the karma points for the specified user from a database and sends them as a message to the chat room.
|
||||
<br>
|
||||
<br>⇧ **!karma [user] up**
|
||||
<br>Increases the karma points for the specified user by 1.
|
||||
<br>Increases the karma points for the specified user by 1 in the database and sends the updated points as a message to the chat room.
|
||||
<br>
|
||||
<br>⇩ **!karma [user] down**
|
||||
<br>Decreases the karma points for the specified user by 1.
|
||||
<br>Decreases the karma points for the specified user by 1 in the database and sends the updated points as a message to the chat room.
|
||||
<br>
|
||||
<br>📄 **!funguy [prompt]
|
||||
<br>An AI large language model designed to serve as a chatbot within a vibrant and diverse community chat room hosted on the Matrix platform.
|
||||
<br>(Currently loaded model: **TheBloke_Mistral-7B-Instruct-v0.2-GPTQ**
|
||||
<br>
|
||||
<br>🎝 **!music [prompt]**
|
||||
<br>Your music expert! Try it out.
|
||||
<br> 🌟 Funguy Bot Credits 🌟
|
||||
<br>
|
||||
<br>🧙♂️ Creator & Developer:
|
||||
<br> Hash Borgir is the author of 🍄Funguy Bot🍄. (@hashborgir:mozilla.org)
|
||||
<br>
|
||||
<br> Join our Matrix Room:
|
||||
<br>
|
||||
<br>[Self-hosting | Security | Sysadmin | Homelab | Programming](https://matrix.to/#/#selfhosting:mozilla.org)
|
||||
<br>
|
||||
<br></details>"""
|
||||
commands_message = """
|
||||
<details><summary><strong>🍄Funguy Bot Commands🍄<br>⤵︎Click Here To See Help Text⤵︎</strong></summary>
|
||||
<p>
|
||||
<details><summary>🃏 <strong>!fortune</strong></summary>
|
||||
<p>Returns a random fortune message. Executes the `/usr/games/fortune` utility and sends the output as a message to the chat room.</p>
|
||||
</details>
|
||||
|
||||
<details><summary>⏰ <strong>!date</strong></summary>
|
||||
<p>Displays the current date and time. Fetches the current date and time using Python's `datetime` module and sends it in a formatted message to the chat room.</p>
|
||||
</details>
|
||||
|
||||
<details><summary>💻 <strong>!proxy</strong></summary>
|
||||
<p>Retrieves a tested/working random SOCKS5 proxy. Fetches a list of SOCKS5 proxies, tests their availability, and sends the first working proxy to the chat room.</p>
|
||||
</details>
|
||||
|
||||
<details><summary>📶 <strong>!isup [domain/ip]</strong></summary>
|
||||
<p>Checks if the specified domain or IP address is reachable. Checks if the specified domain or IP address is reachable by attempting to ping it. If DNS resolution is successful, it checks HTTP and HTTPS service availability by sending requests to the domain.</p>
|
||||
</details>
|
||||
|
||||
<details><summary>☯ <strong>!karma [user]</strong></summary>
|
||||
<p>Retrieves the karma points for the specified user. Retrieves the karma points for the specified user from a database and sends them as a message to the chat room.</p>
|
||||
</details>
|
||||
|
||||
<details><summary>⇧ <strong>!karma [user] up</strong></summary>
|
||||
<p>Increases the karma points for the specified user by 1. Increases the karma points for the specified user by 1 in the database and sends the updated points as a message to the chat room.</p>
|
||||
</details>
|
||||
|
||||
<details><summary>⇩ <strong>!karma [user] down</strong></summary>
|
||||
<p>Decreases the karma points for the specified user by 1. Decreases the karma points for the specified user by 1 in the database and sends the updated points as a message to the chat room.</p>
|
||||
</details>
|
||||
|
||||
<details><summary>📄 <strong>!funguy [prompt]</strong></summary>
|
||||
<p>An AI large language model designed to serve as a chatbot within a vibrant and diverse community chat room hosted on the Matrix platform. (Currently loaded model: <strong>TheBloke_Mistral-7B-Instruct-v0.2-GPTQ</strong>)</p>
|
||||
</details>
|
||||
|
||||
<details><summary>🎝 <strong>!music [prompt]</strong></summary>
|
||||
<p>Your music expert! Try it out.</p>
|
||||
</details>
|
||||
|
||||
<details><summary>🌟 <strong>Funguy Bot Credits</strong> 🌟</summary>
|
||||
<p>🧙♂️ Creator & Developer: Hash Borgir is the author of 🍄Funguy Bot🍄. (@hashborgir:mozilla.org)</p>
|
||||
<p>Join our Matrix Room: [Self-hosting | Security | Sysadmin | Homelab | Programming](https://matrix.to/#/#selfhosting:mozilla.org)</p>
|
||||
</details>
|
||||
</p>
|
||||
</details>
|
||||
"""
|
||||
|
||||
await bot.api.send_markdown_message(room.room_id, commands_message)
|
||||
logging.info("Sent help documentation to the room")
|
||||
|
@@ -1,3 +1,6 @@
|
||||
"""
|
||||
This plugin provides a command for the admin to load a plugin
|
||||
"""
|
||||
# plugins/load_plugin.py
|
||||
|
||||
import os
|
||||
|
@@ -26,9 +26,9 @@ async def handle_command(room, message, bot, prefix, config):
|
||||
plugin_descriptions = get_plugin_descriptions()
|
||||
|
||||
# Prepend custom string before the output
|
||||
plugin_descriptions.insert(0, "<details><summary><strong>🔌Plugins List🔌<br>⤵︎Click Here to Expand⤵︎</strong></summary><br>")
|
||||
plugin_descriptions.insert(0, "<details><summary><strong>🔌Plugins List🔌<br>⤵︎Click Here to Expand⤵︎</strong></summary>")
|
||||
|
||||
plugins_message = "<br><br>".join(plugin_descriptions)
|
||||
plugins_message = "<br>".join(plugin_descriptions)
|
||||
plugins_message += "</details>"
|
||||
await bot.api.send_markdown_message(room.room_id, plugins_message)
|
||||
logging.info("Sent plugin list to the room")
|
||||
|
42
plugins/stable-diffusion.py
Normal file
42
plugins/stable-diffusion.py
Normal file
@@ -0,0 +1,42 @@
|
||||
"""
|
||||
This plugin provides a command to generate images using self hosted Stable Diffusion and send to the room
|
||||
"""
|
||||
# plugins/stable-diffusion.py
|
||||
import requests
|
||||
import base64
|
||||
from asyncio import Queue
|
||||
import simplematrixbotlib as botlib
|
||||
|
||||
# Queue to store pending commands
|
||||
command_queue = Queue()
|
||||
|
||||
async def process_command(room, message, bot, prefix, config):
|
||||
match = botlib.MessageMatch(room, message, bot, prefix)
|
||||
if match.prefix() and match.command("sd"):
|
||||
if command_queue.empty():
|
||||
await handle_command(room, message, bot, prefix, config)
|
||||
else:
|
||||
await command_queue.put((room, message, bot, prefix, config))
|
||||
|
||||
async def handle_command(room, message, bot, prefix, config):
|
||||
match = botlib.MessageMatch(room, message, bot, prefix)
|
||||
if match.prefix() and match.command("sd"):
|
||||
prompt = message.body[len(prefix) + len("sd"):].strip() # Extract prompt from message body
|
||||
payload = {
|
||||
"prompt": prompt,
|
||||
"steps": 16
|
||||
}
|
||||
url = "http://127.0.0.1:7860/sdapi/v1/txt2img"
|
||||
try:
|
||||
response = requests.post(url=url, json=payload)
|
||||
r = response.json()
|
||||
with open("/tmp/output.png", 'wb') as f:
|
||||
f.write(base64.b64decode(r['images'][0]))
|
||||
await bot.api.send_image_message(room_id=room.room_id, image_filepath="/tmp/output.png") # Corrected argument name
|
||||
except Exception as e:
|
||||
await bot.api.send_text_message(room.room_id, f"Error processing the command: {str(e)}")
|
||||
finally:
|
||||
if not command_queue.empty():
|
||||
next_command = await command_queue.get()
|
||||
await handle_command(*next_command)
|
||||
|
@@ -6,25 +6,31 @@ This plugin provides a command to fetch YouTube video information from links.
|
||||
|
||||
import re
|
||||
import logging
|
||||
from pytube import YouTube
|
||||
from pytubefix import YouTube
|
||||
import simplematrixbotlib as botlib
|
||||
import asyncio
|
||||
|
||||
def seconds_to_minutes_seconds(seconds):
|
||||
minutes = seconds // 60
|
||||
seconds %= 60
|
||||
return f"{minutes:02d}:{seconds:02d}"
|
||||
|
||||
async def fetch_youtube_info(youtube_url):
|
||||
try:
|
||||
video = YouTube(youtube_url)
|
||||
title = video.title
|
||||
description = video.description
|
||||
length = seconds_to_minutes_seconds(video.length)
|
||||
views = video.views
|
||||
author = video.author
|
||||
description_with_breaks = description.replace('\n', '<br>')
|
||||
info_message = f"""<strong>🎬🎝 Title:</strong> {title} | <strong>Length</strong>: {length} minutes | <strong>Views</strong>: {views}\n<details><summary><strong>⤵︎Click Here For Description⤵︎</strong></summary>{description_with_breaks}</details>"""
|
||||
return info_message
|
||||
except Exception as e:
|
||||
logging.error(f"Error fetching YouTube video information: {str(e)}")
|
||||
return None
|
||||
|
||||
async def handle_command(room, message, bot, prefix, config):
|
||||
"""
|
||||
Function to handle YouTube video information from links.
|
||||
|
||||
Args:
|
||||
room (Room): The Matrix room where the command was invoked.
|
||||
message (RoomMessage): The message object containing the command.
|
||||
|
||||
Returns:
|
||||
None
|
||||
"""
|
||||
match = botlib.MessageMatch(room, message, bot, prefix)
|
||||
if match.is_not_from_this_bot() and re.search(r'youtube\.com/watch\?v=', message.body):
|
||||
logging.info("YouTube link detected")
|
||||
@@ -33,16 +39,18 @@ async def handle_command(room, message, bot, prefix, config):
|
||||
video_id = video_id_match.group(1)
|
||||
youtube_url = f"https://www.youtube.com/watch?v={video_id}"
|
||||
logging.info(f"Fetching information for YouTube video: {youtube_url}")
|
||||
try:
|
||||
video = YouTube(youtube_url)
|
||||
title = video.title
|
||||
description = video.description
|
||||
length = seconds_to_minutes_seconds(video.length)
|
||||
views = video.views
|
||||
author = video.author
|
||||
info_message = f"""**🎬🎝 Title:** {title} | **Length**: {length} minutes| **Views:** {views} | **Description:** {description}"""
|
||||
await bot.api.send_markdown_message(room.room_id, info_message)
|
||||
logging.info("Sent YouTube video information to the room")
|
||||
except Exception as e:
|
||||
logging.error(f"Error fetching YouTube video information: {str(e)}")
|
||||
# await bot.api.send__message(room.room_id, "Error fetching YouTube video information.")
|
||||
retry_count = 3
|
||||
while retry_count > 0:
|
||||
info_message = await fetch_youtube_info(youtube_url)
|
||||
if info_message:
|
||||
await bot.api.send_markdown_message(room.room_id, info_message)
|
||||
logging.info("Sent YouTube video information to the room")
|
||||
break
|
||||
else:
|
||||
logging.info("Retrying...")
|
||||
retry_count -= 1
|
||||
await asyncio.sleep(1) # wait for 1 second before retrying
|
||||
else:
|
||||
logging.error("Failed to fetch YouTube video information after retries")
|
||||
|
||||
|
||||
|
@@ -1,3 +1,6 @@
|
||||
"""
|
||||
This plugin provides a command to search for YouTube videos in the room
|
||||
"""
|
||||
# plugins/youtube_search.py
|
||||
|
||||
import logging
|
||||
|
@@ -1,5 +1,8 @@
|
||||
python-dotenv
|
||||
requests
|
||||
pytube
|
||||
pytubefix
|
||||
duckduckgo_search
|
||||
nio
|
||||
markdown2
|
||||
watchdog
|
||||
emoji
|
||||
|
Reference in New Issue
Block a user