First commit
This commit is contained in:
commit
4e635b0042
59
bot.py
Executable file
59
bot.py
Executable file
@ -0,0 +1,59 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
from dotenv import load_dotenv
|
||||||
|
import simplematrixbotlib as botlib
|
||||||
|
|
||||||
|
# Load environment variables from .env file
|
||||||
|
load_dotenv()
|
||||||
|
|
||||||
|
# Bot configuration settings
|
||||||
|
MATRIX_URL = os.getenv("MATRIX_URL")
|
||||||
|
MATRIX_USER = os.getenv("MATRIX_USER")
|
||||||
|
MATRIX_PASS = os.getenv("MATRIX_PASS")
|
||||||
|
|
||||||
|
ADMIN_USER = "@hashborgir:mozilla.org"
|
||||||
|
|
||||||
|
PREFIX = '!'
|
||||||
|
|
||||||
|
creds = botlib.Creds(MATRIX_URL, MATRIX_USER, MATRIX_PASS)
|
||||||
|
bot = botlib.Bot(creds)
|
||||||
|
|
||||||
|
# Setup logging
|
||||||
|
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO)
|
||||||
|
|
||||||
|
# Load plugins
|
||||||
|
PLUGINS_DIR = "plugins"
|
||||||
|
|
||||||
|
def load_plugins():
|
||||||
|
plugins = []
|
||||||
|
for plugin_file in os.listdir(PLUGINS_DIR):
|
||||||
|
if plugin_file.endswith(".py"):
|
||||||
|
plugin_name = os.path.splitext(plugin_file)[0]
|
||||||
|
try:
|
||||||
|
plugin_module = __import__(f"{PLUGINS_DIR}.{plugin_name}", fromlist=[""])
|
||||||
|
plugins.append(plugin_module)
|
||||||
|
logging.info(f"Loaded plugin: {plugin_name}")
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error loading plugin {plugin_name}: {e}")
|
||||||
|
return plugins
|
||||||
|
|
||||||
|
plugins = load_plugins()
|
||||||
|
|
||||||
|
@bot.listener.on_message_event
|
||||||
|
async def handle_commands(room, message):
|
||||||
|
"""
|
||||||
|
Function to handle incoming command messages.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
room (Room): The Matrix room where the command was invoked.
|
||||||
|
message (RoomMessage): The message object containing the command.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None
|
||||||
|
"""
|
||||||
|
for plugin in plugins:
|
||||||
|
await plugin.handle_command(room, message, bot, PREFIX)
|
||||||
|
|
||||||
|
bot.run()
|
326
hcbot.py
Executable file
326
hcbot.py
Executable file
@ -0,0 +1,326 @@
|
|||||||
|
#!/usr/bin/env python
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import sqlite3
|
||||||
|
import time
|
||||||
|
import os
|
||||||
|
import random
|
||||||
|
import socket
|
||||||
|
from urllib.parse import urlparse
|
||||||
|
import datetime
|
||||||
|
import simplematrixbotlib as botlib
|
||||||
|
import requests
|
||||||
|
from pytube import YouTube
|
||||||
|
import logging
|
||||||
|
import inspect
|
||||||
|
|
||||||
|
|
||||||
|
MATRIX_URL = "https://matrix.org"
|
||||||
|
MATRIX_USER = "@hcbot:matrix.org"
|
||||||
|
MATRIX_PASS = "W4iy$nt^qp~&$K~$w@@jEhnT"
|
||||||
|
|
||||||
|
creds = botlib.Creds(MATRIX_URL, MATRIX_USER, MATRIX_PASS)
|
||||||
|
bot = botlib.Bot(creds)
|
||||||
|
|
||||||
|
PREFIX = '!'
|
||||||
|
|
||||||
|
# Setup logging
|
||||||
|
logging.basicConfig(format='%(asctime)s - %(levelname)s - %(message)s', level=logging.INFO)
|
||||||
|
|
||||||
|
# Database setup
|
||||||
|
conn = sqlite3.connect('karma.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''CREATE TABLE IF NOT EXISTS karma
|
||||||
|
(username TEXT PRIMARY KEY, points INTEGER)''')
|
||||||
|
conn.commit()
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
async def ping_proxy(proxy):
|
||||||
|
"""
|
||||||
|
Ping a proxy server to check its availability.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
proxy (str): The proxy server address in the format 'ip:port'.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
float or str: The ping time in milliseconds if the proxy is up, or 'N/A' if it's down.
|
||||||
|
"""
|
||||||
|
ip, port = proxy.split(':')
|
||||||
|
start_time = time.time()
|
||||||
|
try:
|
||||||
|
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
sock.settimeout(5)
|
||||||
|
result = sock.connect_ex((ip, int(port)))
|
||||||
|
if result == 0:
|
||||||
|
return round((time.time() - start_time) * 1000, 2)
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error pinging proxy {proxy}: {e}")
|
||||||
|
return "N/A"
|
||||||
|
|
||||||
|
@bot.listener.on_message_event
|
||||||
|
async def commands(room, message):
|
||||||
|
"""
|
||||||
|
Command to display the list of available commands and their descriptions.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("commands"):
|
||||||
|
logging.info("Fetching commands documentation")
|
||||||
|
commands_message = """
|
||||||
|
**Available Commands:**
|
||||||
|
|
||||||
|
**!fortune**
|
||||||
|
Returns a random fortune message.
|
||||||
|
|
||||||
|
**!date**
|
||||||
|
Displays the current date and time.
|
||||||
|
|
||||||
|
**!proxy**
|
||||||
|
Retrieves and tests random SOCKS5 and HTTP proxies.
|
||||||
|
|
||||||
|
**!isup <domain/ip>**
|
||||||
|
Checks if the specified domain or IP address is reachable.
|
||||||
|
|
||||||
|
**!karma <user>**
|
||||||
|
Retrieves the karma points for the specified user.
|
||||||
|
|
||||||
|
**!karma <user> up**
|
||||||
|
Increases the karma points for the specified user by 1.
|
||||||
|
|
||||||
|
**!karma <user> down**
|
||||||
|
Decreases the karma points for the specified user by 1.
|
||||||
|
"""
|
||||||
|
await bot.api.send_markdown_message(room.room_id, commands_message)
|
||||||
|
logging.info("Sent commands documentation to the room")
|
||||||
|
|
||||||
|
|
||||||
|
@bot.listener.on_message_event
|
||||||
|
async def fortune(room, message):
|
||||||
|
"""
|
||||||
|
Command to get a random fortune.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("fortune"):
|
||||||
|
logging.info("Received !fortune command")
|
||||||
|
fortune_output = subprocess.run(['/usr/games/fortune'], capture_output=True).stdout.decode('UTF-8')
|
||||||
|
await bot.api.send_text_message(room.room_id, fortune_output)
|
||||||
|
logging.info("Sent fortune to the room")
|
||||||
|
|
||||||
|
@bot.listener.on_message_event
|
||||||
|
async def date(room, message):
|
||||||
|
"""
|
||||||
|
Command to get the current date and time.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("date"):
|
||||||
|
logging.info("Fetching current date and time")
|
||||||
|
current_datetime = datetime.datetime.now()
|
||||||
|
day_of_week = current_datetime.strftime("%A")
|
||||||
|
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}**"
|
||||||
|
await bot.api.send_markdown_message(room.room_id, date_message)
|
||||||
|
logging.info("Sent current date and time to the room")
|
||||||
|
|
||||||
|
@bot.listener.on_message_event
|
||||||
|
async def proxy(room, message):
|
||||||
|
"""
|
||||||
|
Command to get random SOCKS5 and HTTP proxies.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("proxy"):
|
||||||
|
logging.info("Received !proxy command")
|
||||||
|
socks5_proxies = requests.get('https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/socks5.txt').text.splitlines()
|
||||||
|
http_proxies = requests.get('https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/http.txt').text.splitlines()
|
||||||
|
|
||||||
|
random_socks5_proxy = random.choice(socks5_proxies)
|
||||||
|
random_http_proxy = random.choice(http_proxies)
|
||||||
|
|
||||||
|
socks5_ping = await ping_proxy(random_socks5_proxy)
|
||||||
|
http_ping = await ping_proxy(random_http_proxy)
|
||||||
|
|
||||||
|
await bot.api.send_text_message(room.room_id, f"Random SOCKS5 Proxy: {random_socks5_proxy} - Ping time: {socks5_ping} ms")
|
||||||
|
await bot.api.send_text_message(room.room_id, f"Random HTTP Proxy: {random_http_proxy} - Ping time: {http_ping} ms")
|
||||||
|
logging.info("Sent proxies to the room")
|
||||||
|
|
||||||
|
@bot.listener.on_message_event
|
||||||
|
async def isup(room, message):
|
||||||
|
"""
|
||||||
|
Command to check if a website or server is up.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("isup"):
|
||||||
|
logging.info("Received !isup command")
|
||||||
|
args = match.args()
|
||||||
|
if len(args) != 1:
|
||||||
|
await bot.api.send_text_message(room.room_id, "Usage: !isup <ipv4/ipv6/domain>")
|
||||||
|
logging.info("Sent usage message to the room")
|
||||||
|
return
|
||||||
|
|
||||||
|
target = args[0]
|
||||||
|
try:
|
||||||
|
response = os.system(f"ping -c 1 {target}")
|
||||||
|
if response == 0:
|
||||||
|
await bot.api.send_text_message(room.room_id, f"{target} is up")
|
||||||
|
else:
|
||||||
|
await bot.api.send_text_message(room.room_id, f"{target} is down")
|
||||||
|
logging.info(f"Sent status of {target} to the room")
|
||||||
|
except Exception as e:
|
||||||
|
await bot.api.send_text_message(room.room_id, f"Error: {e}")
|
||||||
|
logging.error(f"Error occurred while checking {target}: {e}")
|
||||||
|
|
||||||
|
@bot.listener.on_message_event
|
||||||
|
async def karma(room, message):
|
||||||
|
"""
|
||||||
|
Command to manage karma points for users.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("karma"):
|
||||||
|
logging.info("Received !karma command")
|
||||||
|
args = match.args()
|
||||||
|
sender = str(message.sender)
|
||||||
|
|
||||||
|
if len(args) == 0:
|
||||||
|
# Query sender's own karma
|
||||||
|
conn = sqlite3.connect('karma.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''CREATE TABLE IF NOT EXISTS karma
|
||||||
|
(username TEXT PRIMARY KEY, points INTEGER)''')
|
||||||
|
c.execute('''INSERT OR IGNORE INTO karma (username, points) VALUES (?, ?)''', (sender, 0))
|
||||||
|
c.execute('''SELECT points FROM karma WHERE username = ?''', (sender,))
|
||||||
|
points = c.fetchone()[0]
|
||||||
|
conn.close()
|
||||||
|
await bot.api.send_text_message(room.room_id, f"{sender}'s karma points: {points}")
|
||||||
|
logging.info(f"Sent {sender}'s karma points ({points}) to the room")
|
||||||
|
elif len(args) == 1:
|
||||||
|
username = args[0]
|
||||||
|
|
||||||
|
if username == sender:
|
||||||
|
await bot.api.send_text_message(room.room_id, "You cannot modify your own karma.")
|
||||||
|
logging.info("Sent self-modification warning message to the room")
|
||||||
|
return
|
||||||
|
|
||||||
|
conn = sqlite3.connect('karma.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''CREATE TABLE IF NOT EXISTS karma
|
||||||
|
(username TEXT PRIMARY KEY, points INTEGER)''')
|
||||||
|
c.execute('''INSERT OR IGNORE INTO karma (username, points) VALUES (?, ?)''', (username, 0))
|
||||||
|
c.execute('''SELECT points FROM karma WHERE username = ?''', (username,))
|
||||||
|
points = c.fetchone()[0]
|
||||||
|
conn.close()
|
||||||
|
await bot.api.send_text_message(room.room_id, f"{username}'s karma points: {points}")
|
||||||
|
logging.info(f"Sent {username}'s karma points ({points}) to the room")
|
||||||
|
elif len(args) == 2:
|
||||||
|
username, action = args
|
||||||
|
if action not in ['up', 'down']:
|
||||||
|
await bot.api.send_text_message(room.room_id, "Invalid action. Use 'up' or 'down'.")
|
||||||
|
logging.info("Sent invalid action message to the room")
|
||||||
|
return
|
||||||
|
|
||||||
|
if username == sender:
|
||||||
|
await bot.api.send_text_message(room.room_id, "You cannot modify your own karma.")
|
||||||
|
logging.info("Sent self-modification warning message to the room")
|
||||||
|
return
|
||||||
|
|
||||||
|
conn = sqlite3.connect('karma.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''CREATE TABLE IF NOT EXISTS karma
|
||||||
|
(username TEXT PRIMARY KEY, points INTEGER)''')
|
||||||
|
|
||||||
|
if action == 'up':
|
||||||
|
c.execute('''UPDATE karma SET points = points + 1 WHERE username = ?''', (username,))
|
||||||
|
else:
|
||||||
|
c.execute('''UPDATE karma SET points = points - 1 WHERE username = ?''', (username,))
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
c.execute('''SELECT points FROM karma WHERE username = ?''', (username,))
|
||||||
|
points = c.fetchone()[0]
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
await bot.api.send_text_message(room.room_id, f"{username}'s karma points: {points}")
|
||||||
|
logging.info(f"Sent {username}'s karma points ({points}) to the room")
|
||||||
|
else:
|
||||||
|
await bot.api.send_text_message(room.room_id, "Usage: !karma [username] [up/down]")
|
||||||
|
logging.info("Sent usage message to the room")
|
||||||
|
|
||||||
|
|
||||||
|
import re
|
||||||
|
|
||||||
|
@bot.listener.on_message_event
|
||||||
|
async def youtube(room, message):
|
||||||
|
"""
|
||||||
|
Command to fetch 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)
|
||||||
|
if match.is_not_from_this_bot() and re.search(r'youtube\.com/watch\?v=', message.body):
|
||||||
|
logging.info("YouTube link detected")
|
||||||
|
video_id_match = re.search(r'youtube\.com/watch\?v=([^\s]+)', message.body)
|
||||||
|
if video_id_match:
|
||||||
|
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 = video.length
|
||||||
|
views = video.views
|
||||||
|
author = video.author
|
||||||
|
info_message = f"""Title: {title} | Length: {length} seconds | 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_text_message(room.room_id, "Error fetching YouTube video information.")
|
||||||
|
|
||||||
|
|
||||||
|
bot.run()
|
BIN
plugins/__pycache__/commands.cpython-310.pyc
Normal file
BIN
plugins/__pycache__/commands.cpython-310.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/date.cpython-310.pyc
Normal file
BIN
plugins/__pycache__/date.cpython-310.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/fortune.cpython-310.pyc
Normal file
BIN
plugins/__pycache__/fortune.cpython-310.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/isup.cpython-310.pyc
Normal file
BIN
plugins/__pycache__/isup.cpython-310.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/karma.cpython-310.pyc
Normal file
BIN
plugins/__pycache__/karma.cpython-310.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/proxy.cpython-310.pyc
Normal file
BIN
plugins/__pycache__/proxy.cpython-310.pyc
Normal file
Binary file not shown.
BIN
plugins/__pycache__/youtube.cpython-310.pyc
Normal file
BIN
plugins/__pycache__/youtube.cpython-310.pyc
Normal file
Binary file not shown.
45
plugins/commands.py
Normal file
45
plugins/commands.py
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
# plugins/commands.py
|
||||||
|
|
||||||
|
import logging
|
||||||
|
import simplematrixbotlib as botlib
|
||||||
|
|
||||||
|
async def handle_command(room, message, bot, PREFIX):
|
||||||
|
"""
|
||||||
|
Function to handle the !commands command.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("commands"):
|
||||||
|
logging.info("Fetching commands documentation")
|
||||||
|
commands_message = """
|
||||||
|
**Available Commands:**
|
||||||
|
|
||||||
|
**!fortune**
|
||||||
|
Returns a random fortune message.
|
||||||
|
|
||||||
|
**!date**
|
||||||
|
Displays the current date and time.
|
||||||
|
|
||||||
|
**!proxy**
|
||||||
|
Retrieves and tests random SOCKS5 and HTTP proxies.
|
||||||
|
|
||||||
|
**!isup <domain/ip>**
|
||||||
|
Checks if the specified domain or IP address is reachable.
|
||||||
|
|
||||||
|
**!karma <user>**
|
||||||
|
Retrieves the karma points for the specified user.
|
||||||
|
|
||||||
|
**!karma <user> up**
|
||||||
|
Increases the karma points for the specified user by 1.
|
||||||
|
|
||||||
|
**!karma <user> down**
|
||||||
|
Decreases the karma points for the specified user by 1.
|
||||||
|
"""
|
||||||
|
await bot.api.send_markdown_message(room.room_id, commands_message)
|
||||||
|
logging.info("Sent commands documentation to the room")
|
28
plugins/date.py
Normal file
28
plugins/date.py
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
# plugins/date.py
|
||||||
|
|
||||||
|
import datetime
|
||||||
|
import logging
|
||||||
|
import simplematrixbotlib as botlib
|
||||||
|
|
||||||
|
async def handle_command(room, message, bot, PREFIX):
|
||||||
|
"""
|
||||||
|
Function to handle the !date command.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("date"):
|
||||||
|
logging.info("Fetching current date and time")
|
||||||
|
current_datetime = datetime.datetime.now()
|
||||||
|
day_of_week = current_datetime.strftime("%A")
|
||||||
|
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}**"
|
||||||
|
await bot.api.send_markdown_message(room.room_id, date_message)
|
||||||
|
logging.info("Sent current date and time to the room")
|
23
plugins/fortune.py
Normal file
23
plugins/fortune.py
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# plugins/fortune.py
|
||||||
|
|
||||||
|
import subprocess
|
||||||
|
import logging
|
||||||
|
import simplematrixbotlib as botlib
|
||||||
|
|
||||||
|
async def handle_command(room, message, bot, PREFIX):
|
||||||
|
"""
|
||||||
|
Function to handle the !fortune command.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("fortune"):
|
||||||
|
logging.info("Received !fortune command")
|
||||||
|
fortune_output = subprocess.run(['/usr/games/fortune'], capture_output=True).stdout.decode('UTF-8')
|
||||||
|
await bot.api.send_text_message(room.room_id, fortune_output)
|
||||||
|
logging.info("Sent fortune to the room")
|
37
plugins/isup.py
Normal file
37
plugins/isup.py
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
# plugins/isup.py
|
||||||
|
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import simplematrixbotlib as botlib
|
||||||
|
|
||||||
|
async def handle_command(room, message, bot, PREFIX):
|
||||||
|
"""
|
||||||
|
Function to handle the !isup command.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("isup"):
|
||||||
|
logging.info("Received !isup command")
|
||||||
|
args = match.args()
|
||||||
|
if len(args) != 1:
|
||||||
|
await bot.api.send_text_message(room.room_id, "Usage: !isup <ipv4/ipv6/domain>")
|
||||||
|
logging.info("Sent usage message to the room")
|
||||||
|
return
|
||||||
|
|
||||||
|
target = args[0]
|
||||||
|
try:
|
||||||
|
response = os.system(f"ping -c 1 {target}")
|
||||||
|
if response == 0:
|
||||||
|
await bot.api.send_text_message(room.room_id, f"{target} is up")
|
||||||
|
else:
|
||||||
|
await bot.api.send_text_message(room.room_id, f"{target} is down")
|
||||||
|
logging.info(f"Sent status of {target} to the room")
|
||||||
|
except Exception as e:
|
||||||
|
await bot.api.send_text_message(room.room_id, f"Error: {e}")
|
||||||
|
logging.error(f"Error occurred while checking {target}: {e}")
|
85
plugins/karma.py
Normal file
85
plugins/karma.py
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
# plugins/karma.py
|
||||||
|
|
||||||
|
import sqlite3
|
||||||
|
import logging
|
||||||
|
import simplematrixbotlib as botlib
|
||||||
|
|
||||||
|
async def handle_command(room, message, bot, PREFIX):
|
||||||
|
"""
|
||||||
|
Function to handle the !karma command.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("karma"):
|
||||||
|
logging.info("Received !karma command")
|
||||||
|
args = match.args()
|
||||||
|
sender = str(message.sender)
|
||||||
|
|
||||||
|
if len(args) == 0:
|
||||||
|
# Query sender's own karma
|
||||||
|
conn = sqlite3.connect('karma.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''CREATE TABLE IF NOT EXISTS karma
|
||||||
|
(username TEXT PRIMARY KEY, points INTEGER)''')
|
||||||
|
c.execute('''INSERT OR IGNORE INTO karma (username, points) VALUES (?, ?)''', (sender, 0))
|
||||||
|
c.execute('''SELECT points FROM karma WHERE username = ?''', (sender,))
|
||||||
|
points = c.fetchone()[0]
|
||||||
|
conn.close()
|
||||||
|
await bot.api.send_text_message(room.room_id, f"{sender}'s karma points: {points}")
|
||||||
|
logging.info(f"Sent {sender}'s karma points ({points}) to the room")
|
||||||
|
elif len(args) == 1:
|
||||||
|
username = args[0]
|
||||||
|
|
||||||
|
if username == sender:
|
||||||
|
await bot.api.send_text_message(room.room_id, "You cannot modify your own karma.")
|
||||||
|
logging.info("Sent self-modification warning message to the room")
|
||||||
|
return
|
||||||
|
|
||||||
|
conn = sqlite3.connect('karma.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''CREATE TABLE IF NOT EXISTS karma
|
||||||
|
(username TEXT PRIMARY KEY, points INTEGER)''')
|
||||||
|
c.execute('''INSERT OR IGNORE INTO karma (username, points) VALUES (?, ?)''', (username, 0))
|
||||||
|
c.execute('''SELECT points FROM karma WHERE username = ?''', (username,))
|
||||||
|
points = c.fetchone()[0]
|
||||||
|
conn.close()
|
||||||
|
await bot.api.send_text_message(room.room_id, f"{username}'s karma points: {points}")
|
||||||
|
logging.info(f"Sent {username}'s karma points ({points}) to the room")
|
||||||
|
elif len(args) == 2:
|
||||||
|
username, action = args
|
||||||
|
if action not in ['up', 'down']:
|
||||||
|
await bot.api.send_text_message(room.room_id, "Invalid action. Use 'up' or 'down'.")
|
||||||
|
logging.info("Sent invalid action message to the room")
|
||||||
|
return
|
||||||
|
|
||||||
|
if username == sender:
|
||||||
|
await bot.api.send_text_message(room.room_id, "You cannot modify your own karma.")
|
||||||
|
logging.info("Sent self-modification warning message to the room")
|
||||||
|
return
|
||||||
|
|
||||||
|
conn = sqlite3.connect('karma.db')
|
||||||
|
c = conn.cursor()
|
||||||
|
c.execute('''CREATE TABLE IF NOT EXISTS karma
|
||||||
|
(username TEXT PRIMARY KEY, points INTEGER)''')
|
||||||
|
|
||||||
|
if action == 'up':
|
||||||
|
c.execute('''UPDATE karma SET points = points + 1 WHERE username = ?''', (username,))
|
||||||
|
else:
|
||||||
|
c.execute('''UPDATE karma SET points = points - 1 WHERE username = ?''', (username,))
|
||||||
|
|
||||||
|
conn.commit()
|
||||||
|
c.execute('''SELECT points FROM karma WHERE username = ?''', (username,))
|
||||||
|
points = c.fetchone()[0]
|
||||||
|
conn.close()
|
||||||
|
|
||||||
|
await bot.api.send_text_message(room.room_id, f"{username}'s karma points: {points}")
|
||||||
|
logging.info(f"Sent {username}'s karma points ({points}) to the room")
|
||||||
|
else:
|
||||||
|
await bot.api.send_text_message(room.room_id, "Usage: !karma [username] [up/down]")
|
||||||
|
logging.info("Sent usage message to the room")
|
103
plugins/proxy.py
Normal file
103
plugins/proxy.py
Normal file
@ -0,0 +1,103 @@
|
|||||||
|
# plugins/proxy.py
|
||||||
|
|
||||||
|
import os
|
||||||
|
import logging
|
||||||
|
import random
|
||||||
|
import requests
|
||||||
|
import socket
|
||||||
|
import asyncio
|
||||||
|
import time
|
||||||
|
import simplematrixbotlib as botlib
|
||||||
|
|
||||||
|
# Function to test SOCKS4 proxies
|
||||||
|
async def test_socks4_proxy(proxy):
|
||||||
|
try:
|
||||||
|
start_time = time.time()
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
s.settimeout(5)
|
||||||
|
s.connect((proxy.split(':')[0], int(proxy.split(':')[1])))
|
||||||
|
latency = round((time.time() - start_time) * 1000, 2)
|
||||||
|
logging.info(f"Tested SOCKS4 proxy {proxy}. Latency: {latency} ms")
|
||||||
|
return True, latency
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error testing SOCKS4 proxy {proxy}: {e}")
|
||||||
|
return False, None
|
||||||
|
|
||||||
|
# Function to test SOCKS5 proxies
|
||||||
|
async def test_socks5_proxy(proxy):
|
||||||
|
try:
|
||||||
|
start_time = time.time()
|
||||||
|
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
|
||||||
|
s.settimeout(5)
|
||||||
|
s.connect((proxy.split(':')[0], int(proxy.split(':')[1])))
|
||||||
|
latency = round((time.time() - start_time) * 1000, 2)
|
||||||
|
logging.info(f"Tested SOCKS5 proxy {proxy}. Latency: {latency} ms")
|
||||||
|
return True, latency
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error testing SOCKS5 proxy {proxy}: {e}")
|
||||||
|
return False, None
|
||||||
|
|
||||||
|
# Function to test HTTP proxies
|
||||||
|
async def test_http_proxy(proxy):
|
||||||
|
local_ip = requests.get("https://api.ipify.org").text
|
||||||
|
try:
|
||||||
|
response = requests.get("https://api.ipify.org", proxies={"http": proxy}, timeout=5).text
|
||||||
|
if response.strip() != local_ip.strip():
|
||||||
|
logging.info(f"Tested anonymous HTTP proxy {proxy}")
|
||||||
|
return True
|
||||||
|
else:
|
||||||
|
logging.info(f"HTTP proxy {proxy} is not anonymous")
|
||||||
|
return False
|
||||||
|
except Exception as e:
|
||||||
|
logging.error(f"Error testing HTTP proxy {proxy}: {e}")
|
||||||
|
return False
|
||||||
|
|
||||||
|
async def handle_command(room, message, bot, PREFIX):
|
||||||
|
"""
|
||||||
|
Function to handle the !proxy command.
|
||||||
|
|
||||||
|
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 match.prefix() and match.command("proxy"):
|
||||||
|
logging.info("Received !proxy command")
|
||||||
|
try:
|
||||||
|
# Fetch SOCKS4 proxy
|
||||||
|
socks4_proxies = requests.get('https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/socks4.txt', timeout=5).text.splitlines()
|
||||||
|
random.shuffle(socks4_proxies)
|
||||||
|
for proxy in socks4_proxies:
|
||||||
|
is_working, latency = await test_socks4_proxy(proxy)
|
||||||
|
if is_working:
|
||||||
|
await bot.api.send_text_message(room.room_id, f"SOCKS4 Proxy: {proxy} - Latency: {latency} ms")
|
||||||
|
break
|
||||||
|
|
||||||
|
# Fetch SOCKS5 proxy
|
||||||
|
socks5_proxies = requests.get('https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/socks5.txt', timeout=5).text.splitlines()
|
||||||
|
random.shuffle(socks5_proxies)
|
||||||
|
for proxy in socks5_proxies:
|
||||||
|
is_working, latency = await test_socks5_proxy(proxy)
|
||||||
|
if is_working:
|
||||||
|
await bot.api.send_text_message(room.room_id, f"SOCKS5 Proxy: {proxy} - Latency: {latency} ms")
|
||||||
|
break
|
||||||
|
|
||||||
|
# Fetch HTTP proxy
|
||||||
|
http_proxies = requests.get('https://raw.githubusercontent.com/TheSpeedX/SOCKS-List/master/http.txt', timeout=5).text.splitlines()
|
||||||
|
random.shuffle(http_proxies)
|
||||||
|
for proxy in http_proxies:
|
||||||
|
is_working = await test_http_proxy(proxy)
|
||||||
|
if is_working:
|
||||||
|
await bot.api.send_text_message(room.room_id, f"HTTP Proxy: {proxy}")
|
||||||
|
break
|
||||||
|
|
||||||
|
logging.info("Sent proxies to the room")
|
||||||
|
except asyncio.TimeoutError:
|
||||||
|
await bot.api.send_text_message(room.room_id, "Failed to fetch or test proxies. The operation timed out.")
|
||||||
|
logging.error("Proxy fetch and test operation timed out")
|
||||||
|
except Exception as e:
|
||||||
|
await bot.api.send_text_message(room.room_id, f"An error occurred: {e}")
|
||||||
|
logging.error(f"Error fetching or testing proxies: {e}")
|
39
plugins/youtube.py
Normal file
39
plugins/youtube.py
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
# plugins/youtube.py
|
||||||
|
|
||||||
|
import re
|
||||||
|
import logging
|
||||||
|
from pytube import YouTube
|
||||||
|
import simplematrixbotlib as botlib
|
||||||
|
|
||||||
|
async def handle_command(room, message, bot, PREFIX):
|
||||||
|
"""
|
||||||
|
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)
|
||||||
|
if match.is_not_from_this_bot() and re.search(r'youtube\.com/watch\?v=', message.body):
|
||||||
|
logging.info("YouTube link detected")
|
||||||
|
video_id_match = re.search(r'youtube\.com/watch\?v=([^\s]+)', message.body)
|
||||||
|
if video_id_match:
|
||||||
|
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 = video.length
|
||||||
|
views = video.views
|
||||||
|
author = video.author
|
||||||
|
info_message = f"""Title: {title} | Length: {length} seconds | 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_text_message(room.room_id, "Error fetching YouTube video information.")
|
3
requirements.txt
Normal file
3
requirements.txt
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
simplematrixbotlib
|
||||||
|
python-dotenv
|
||||||
|
pathlib
|
Loading…
x
Reference in New Issue
Block a user