[REPO REFACTOR]: changed to a better git repository structure with branches

This commit is contained in:
2025-11-01 06:12:45 +01:00
parent b218dd3f77
commit f0b04fcaad
36 changed files with 1366 additions and 0 deletions

0
commands/admin.py Normal file
View File

41
commands/help.py Normal file
View File

@@ -0,0 +1,41 @@
from telegram import Update, InlineKeyboardButton, InlineKeyboardMarkup
from telegram.ext import ContextTypes, Application, CommandHandler, CallbackQueryHandler
from settings import VARIOS, INTERACCION, MATEMATICAS
from util.messages import delete_user_message
PAGES = [VARIOS, INTERACCION, MATEMATICAS]
ITEMS_PER_PAGE = 1
class Help:
def __init__(self, app: Application):
self.app = app
app.add_handler(CommandHandler("help", self.help))
app.add_handler(CallbackQueryHandler(self.callback, pattern="^help_"))
@delete_user_message
async def help(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
await self.send_help(update, page=0)
async def send_help(self, update: Update, page: int):
start_idx = page * ITEMS_PER_PAGE
end_idx = start_idx + ITEMS_PER_PAGE
text = "\n".join(PAGES[start_idx:end_idx])
keyboard = []
if page > 0:
keyboard.append(InlineKeyboardButton("⬅️ Anterior", callback_data=f"help_{page-1}"))
if end_idx < len(PAGES):
keyboard.append(InlineKeyboardButton("➡️ Siguiente", callback_data=f"help_{page+1}"))
reply_markup = InlineKeyboardMarkup([keyboard]) if keyboard else None
if update.message:
await update.message.reply_text(f"**Ayuda {page+1}/{(len(PAGES)-1)//ITEMS_PER_PAGE + 1}**\n\n{text}", parse_mode="Markdown", reply_markup=reply_markup)
elif update.callback_query:
await update.callback_query.edit_message_text(f"**Ayuda {page+1}/{(len(PAGES)-1)//ITEMS_PER_PAGE + 1}**\n\n{text}", parse_mode="Markdown", reply_markup=reply_markup)
await update.callback_query.answer()
async def callback(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
query = update.callback_query
page = int(query.data.split("_")[1])
await self.send_help(update, page=page)

553
commands/interaction.py Normal file
View File

@@ -0,0 +1,553 @@
from telegram import Update
from telegram.ext import ContextTypes, Application, CommandHandler
from time import time
from settings import BOT_OWNER, BOT_NAME, BOT_VERSION, BOT_LANG, BOT_TYPE, BOT_OWNER_ID
from random import randint, choice
from util.messages import delete_user_message
from util.anime import Anime
class Interaction:
def __init__(self, app: Application):
self.app = app
self.anime = Anime()
app.add_handler(CommandHandler("waifu", self.waifu))
app.add_handler(CommandHandler("neko", self.neko))
app.add_handler(CommandHandler("shinobu", self.shinobu))
app.add_handler(CommandHandler("megumin", self.megumin))
app.add_handler(CommandHandler("bully", self.bully))
app.add_handler(CommandHandler("cuddle", self.cuddle))
app.add_handler(CommandHandler("cry", self.cry))
app.add_handler(CommandHandler("hug", self.hug))
app.add_handler(CommandHandler("awoo", self.awoo))
app.add_handler(CommandHandler("kiss", self.kiss))
app.add_handler(CommandHandler("lick", self.lick))
app.add_handler(CommandHandler("pat", self.pat))
app.add_handler(CommandHandler("smug", self.smug))
app.add_handler(CommandHandler("bonk", self.bonk))
app.add_handler(CommandHandler("yeet", self.yeet))
app.add_handler(CommandHandler("blush", self.blush))
app.add_handler(CommandHandler("smile", self.smile))
app.add_handler(CommandHandler("wave", self.wave))
app.add_handler(CommandHandler("highfive", self.highfive))
app.add_handler(CommandHandler("handhold", self.handhold))
app.add_handler(CommandHandler("nom", self.nom))
app.add_handler(CommandHandler("bite", self.bite))
app.add_handler(CommandHandler("glomp", self.glomp))
app.add_handler(CommandHandler("slap", self.slap))
app.add_handler(CommandHandler("kill", self.kill))
app.add_handler(CommandHandler("kick", self.kick))
app.add_handler(CommandHandler("happy", self.happy))
app.add_handler(CommandHandler("wink", self.wink))
app.add_handler(CommandHandler("poke", self.poke))
app.add_handler(CommandHandler("dance", self.dance))
app.add_handler(CommandHandler("cringe", self.cringe))
app.add_handler(CommandHandler("run", self.run))
app.add_handler(CommandHandler("fbi", self.fbi))
app.add_handler(CommandHandler("spank", self.spank))
app.add_handler(CommandHandler("ship", self.ship))
app.add_handler(CommandHandler("moan", self.moan))
app.add_handler(CommandHandler("femboize", self.femboize))
@delete_user_message
async def waifu(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = self.anime.sfw("waifu")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha pedido una waifu"
)
@delete_user_message
async def neko(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = self.anime.sfw("neko")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha pedido un neko"
)
@delete_user_message
async def shinobu(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = self.anime.sfw("shinobu")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha pedido una shinobu"
)
@delete_user_message
async def megumin(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = self.anime.sfw("megumin")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha pedido una megumin"
)
@delete_user_message
async def bully(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("bully")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} le ha hecho bullying a {user}"
)
@delete_user_message
async def cuddle(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("cuddle")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} se ha acurrucado con {user} uwu"
)
@delete_user_message
async def cry(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = self.anime.sfw("cry")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} se ha puesto a llorar :("
)
@delete_user_message
async def hug(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("hug")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha abrazado a {user}"
)
@delete_user_message
async def awoo(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = self.anime.sfw("awoo")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} es un puto furro y ha pedido una foto de un furro"
)
@delete_user_message
async def kiss(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("kiss")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha besado a {user} >///<"
)
@delete_user_message
async def lick(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("lick")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha lamido a {user} OwO"
)
@delete_user_message
async def pat(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("pat")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha acariciado a {user} >.<"
)
@delete_user_message
async def smug(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("smug")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} se ha chuleado de {user}"
)
@delete_user_message
async def bonk(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("bonk")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} le ha hecho bonk a {user}"
)
@delete_user_message
async def yeet(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("yeet")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha lanzado a {user} a chuparla XD"
)
@delete_user_message
async def blush(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = self.anime.sfw("blush")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} se ha sonrojado >///<"
)
@delete_user_message
async def smile(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = self.anime.sfw("smile")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha sonreido"
)
@delete_user_message
async def wave(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("wave")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha saludado a {user}"
)
@delete_user_message
async def highfive(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("highfive")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} a chocado a {user} ;D"
)
@delete_user_message
async def handhold(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("handhold")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} le ha cogido la manita a {user} u.u"
)
@delete_user_message
async def nom(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = self.anime.sfw("nom")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} se ha puesto a comer algo rico"
)
@delete_user_message
async def bite(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("bite")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha mordido a {user} ùwú"
)
@delete_user_message
async def glomp(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("glomp")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} se ha abalanzado sobre {user}"
)
@delete_user_message
async def slap(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("slap")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} le ha dado una bofetada a {user}"
)
@delete_user_message
async def kill(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("kill")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} ha matado a {user} 💀"
)
@delete_user_message
async def kick(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("kick")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} le ha pegado una patada a {user}"
)
@delete_user_message
async def happy(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = self.anime.sfw("happy")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} está feliz :D"
)
@delete_user_message
async def wink(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("wink")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} le ha guiñado el ojo a {user} ;)"
)
@delete_user_message
async def poke(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
url = self.anime.sfw("poke")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} está molestando a {user} ù.ú"
)
@delete_user_message
async def dance(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
url = self.anime.sfw("dance")
await update.effective_chat.send_animation(
animation=url,
caption=f"{update.effective_sender.first_name} se ha puesto a bailar"
)
@delete_user_message
async def cringe(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
caption=f"{update.effective_sender.first_name} le ha dado cringe lo que ha dicho {user}"
with open("data/images/interaction/cringe.gif", "rb") as gif:
await update.effective_chat.send_animation(
animation=gif,
caption=caption,
disable_notification=True
)
@delete_user_message
async def run(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
caption = f"{update.effective_sender.first_name} ha huido"
with open("data/images/interaction/run.gif", "rb") as gif:
await update.effective_chat.send_animation(
animation=gif,
caption=caption,
disable_notification=True
)
@delete_user_message
async def fbi(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
caption = f"{update.effective_sender.first_name} ha llamado al FBI! Corre {user}!!!!"
with open("data/images/interaction/fbi.gif", "rb") as gif:
await update.effective_chat.send_animation(
animation=gif,
caption=caption,
disable_notification=True
)
@delete_user_message
async def spank(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
caption = f"{update.effective_sender.first_name} le ha dado una nalgada a {user}"
with open("data/images/interaction/spank.gif", "rb") as gif:
await update.effective_chat.send_animation(
animation=gif,
caption=caption,
disable_notification=True
)
@delete_user_message
async def ship(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar dos usuarios"
)
return
user1 = context.args[0]
user2 = context.args[1]
caption = f"{user1} x {user2} tienen una compatibilidad del {randint(0,100)}%"
with open("data/images/interaction/ship.gif", "rb") as gif:
await update.effective_chat.send_animation(
animation=gif,
caption=caption,
disable_notification=True
)
@delete_user_message
async def moan(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
caption = f"{update.effective_sender.first_name} ha gemido como una perra"
with open("data/images/interaction/moan.gif", "rb") as gif:
await update.effective_chat.send_animation(
animation=gif,
caption=caption,
disable_notification=True
)
@delete_user_message
async def femboize(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text=f"Debes especificar un usuario"
)
return
user = context.args[0]
caption = f"{update.effective_sender.first_name} ha convertido en femboy a {user}"
with open("data/images/interaction/femboy.png", "rb") as png:
await update.effective_chat.send_photo(
photo=png,
caption=caption,
disable_notification=True
)

175
commands/math.py Normal file
View File

@@ -0,0 +1,175 @@
from telegram import Update
from telegram.ext import ContextTypes, Application, CommandHandler
from random import randint, choice
from util.messages import delete_user_message
import matplotlib.pyplot as plt
import numpy as np
from util.numbers import is_even, is_prime
from settings import GRAPH_PATH
from matplotlib.patches import Circle
class Math:
def __init__(self, app: Application):
self.app = app
app.add_handler(CommandHandler("calcular", self.calculate))
app.add_handler(CommandHandler("par", self.even))
app.add_handler(CommandHandler("primo", self.prime))
app.add_handler(CommandHandler("seno", self.sine))
app.add_handler(CommandHandler("coseno", self.cosine))
app.add_handler(CommandHandler("recta", self.rect))
app.add_handler(CommandHandler("parabola", self.parable))
app.add_handler(CommandHandler("circunferencia", self.circle))
app.add_handler(CommandHandler("log", self.log))
app.add_handler(CommandHandler("exp", self.exp))
@delete_user_message
async def calculate(self, update:Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text="Debes especificar una expresión matemática",
disable_notification=True
)
return
expression = " ".join(context.args)
try:
result = eval(expression)
await update.effective_chat.send_message(
text=f"El resultado de {expression} es {result}",
disable_notification=True
)
except Exception as e:
await update.effective_chat.send_message(
text=f"Error al calcular la expresión: {e}",
disable_notification=True
)
@delete_user_message
async def even(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text="Debes especificar un número",
disable_notification=True
)
return
number = int(context.args[0])
await update.effective_chat.send_message(
text=f"{number} es un número par." if is_even(number) else f"{number} es un número impar.",
disable_notification=True
)
@delete_user_message
async def prime(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text="Debes especificar un número",
disable_notification=True
)
return
number = int(context.args[0])
await update.effective_chat.send_message(
text=f"{number} es un número primo." if is_prime(number) else f"{number} es un número compuesto.",
disable_notification=True
)
async def send_graph(self, update: Update):
await update.effective_chat.send_photo(open(GRAPH_PATH, "rb"))
plt.clf()
@delete_user_message
async def sine(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
if len(context.args) < 2:
await update.effective_chat.send_message("Debes dar a y k: /grafseno a k")
return
a, k = map(int, context.args[:2])
x = np.linspace(0, 2*np.pi, 400)
y = a * np.sin(k*x)
plt.axhline(0, color="black")
plt.plot(x, y, color="#b2122f")
plt.savefig(GRAPH_PATH)
await self.send_graph(update)
@delete_user_message
async def cosine(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
if len(context.args) < 2:
await update.effective_chat.send_message("Debes dar a y k: /grafcoseno a k")
return
a, k = map(int, context.args[:2])
x = np.linspace(0, 2*np.pi, 400)
y = a * np.cos(k*x)
plt.axhline(0, color="black")
plt.plot(x, y, color="#b2122f")
plt.savefig(GRAPH_PATH)
await self.send_graph(update)
@delete_user_message
async def rect(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
if len(context.args) < 2:
await update.effective_chat.send_message("Debes dar m y n: /grafrecta m n")
return
m, n = map(int, context.args[:2])
x = np.linspace(-10, 10, 400)
y = m*x + n
plt.axhline(0, color="black")
plt.axvline(0, color="black")
plt.plot(x, y, color="#b2122f")
plt.savefig(GRAPH_PATH)
await self.send_graph(update)
@delete_user_message
async def parable(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
if len(context.args) < 3:
await update.effective_chat.send_message("Debes dar a, b, c: /grafparabola a b c")
return
a, b, c = map(int, context.args[:3])
x = np.linspace(-10, 10, 400)
y = a*x**2 + b*x + c
plt.axhline(0, color="black")
plt.axvline(0, color="black")
plt.plot(x, y, color="#b2122f")
plt.savefig(GRAPH_PATH)
await self.send_graph(update)
@delete_user_message
async def circle(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
if not context.args:
await update.effective_chat.send_message("Debes dar el radio: /grafcircunferencia r")
return
r = int(context.args[0])
fig, ax = plt.subplots()
ax.set_aspect('equal')
ax.add_artist(Circle((0, 0), r, color='r'))
plt.xlim(-10, 10)
plt.ylim(-10, 10)
plt.savefig(GRAPH_PATH)
await self.send_graph(update)
@delete_user_message
async def log(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
if len(context.args) < 2:
await update.effective_chat.send_message("Debes dar a y b: /graflog a b")
return
a, b = map(int, context.args[:2])
x = np.linspace(0.01, 10, 400)
y = a*np.log(x) + b
plt.axhline(0, color="black")
plt.axvline(0, color="black")
plt.plot(x, y, color="#b2122f")
plt.savefig(GRAPH_PATH)
await self.send_graph(update)
@delete_user_message
async def exp(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
if len(context.args) < 2:
await update.effective_chat.send_message("Debes dar a y b: /grafexp a b")
return
a, b = map(int, context.args[:2])
x = np.linspace(-10, 10, 400)
y = a*np.exp(b*x)
plt.axhline(0, color="black")
plt.axvline(0, color="black")
plt.plot(x, y, color="#b2122f")
plt.savefig(GRAPH_PATH)
await self.send_graph(update)

162
commands/misc.py Normal file
View File

@@ -0,0 +1,162 @@
from telegram import Update
from telegram.ext import ContextTypes, Application, CommandHandler
from time import time
from settings import BOT_OWNER, BOT_NAME, BOT_VERSION, BOT_LANG, BOT_TYPE, BOT_OWNER_ID
from random import randint, choice
from util.messages import delete_user_message
class Misc:
def __init__(self, app: Application):
self.app = app
app.add_handler(CommandHandler("ping", self.ping))
app.add_handler(CommandHandler("info", self.info))
app.add_handler(CommandHandler("say", self.say))
app.add_handler(CommandHandler("banana", self.banana))
app.add_handler(CommandHandler("dado", self.dice))
app.add_handler(CommandHandler("moneda", self.coin))
app.add_handler(CommandHandler("paredes", self.walls))
app.add_handler(CommandHandler("oooh", self.oooh))
app.add_handler(CommandHandler("beber", self.drink))
app.add_handler(CommandHandler("bombardeen", self.bomb))
@delete_user_message
async def ping(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
before = update.message.date.timestamp()
now = time()
await update.effective_chat.send_message(
text=f"<b>🏓 Pong!</b> Latency is <i>{round((now - before) * 1000, 2)} ms</i>",
parse_mode="HTML",
disable_notification=True
)
@delete_user_message
async def info(self, update:Update, context: ContextTypes.DEFAULT_TYPE) -> None:
group = update.effective_chat.title
chat_id = update.effective_chat.id
member_count = await context.bot.get_chat_member_count(chat_id)
command_count = sum(1 for c in context.application.handlers[0] if isinstance(c, CommandHandler))
info_text = f"""
<b>Grupo: {group}</b>
Miembros: {member_count}
Creador: {BOT_OWNER}
Nº Comandos: {command_count}
<b>Info técnica:</b>
Nombre: {BOT_NAME}
Lenguaje: {BOT_LANG}
Tipo: {BOT_TYPE}
Versión: {BOT_VERSION}
"""
await update.effective_chat.send_message(
text=info_text,
parse_mode="HTML",
disable_notification=True
)
@delete_user_message
async def say(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text="Pero dime lo que tengo que decir puta",
disable_notification=True
)
return
await update.effective_chat.send_message(
text=" ".join(arg for arg in context.args),
disable_notification=True
)
@delete_user_message
async def banana(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if update.effective_sender.id == BOT_OWNER_ID:
await update.effective_chat.send_message(
text=f"La banana de {update.effective_user.first_name} mide 21 cm 😳",
disable_notification=True
)
else:
await update.effective_chat.send_message(
text=f"La banana de {update.effective_user.first_name} mide {randint(-5, 21)} cm 😳",
disable_notification=True
)
@delete_user_message
async def dice(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
await update.effective_chat.send_dice(
emoji='🎲',
disable_notification=True
)
@delete_user_message
async def coin(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
html =f"""
<b>🪙 Se ha lanzado la moneda</b>
Resultado: {choice(("Cara 😀", "Cruz ❌"))}
"""
await update.effective_chat.send_message(
text=html,
parse_mode="HTML",
disable_notification=True
)
@delete_user_message
async def walls(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text="Debes especificar un usuario",
disable_notification=True
)
return
if not context.args[0].startswith("@"):
await update.effective_chat.send_message(
text="Debes mencionar a un usuario",
disable_notification=True
)
return
user = context.args[0]
caption = f"{user} está por las paredes"
with open("data/images/interaction/paredes.gif", "rb") as gif:
await update.effective_chat.send_animation(
animation=gif,
caption=caption,
disable_notification=True
)
@delete_user_message
async def oooh(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
with open("data/images/interaction/oooh.gif", "rb") as gif:
await update.effective_chat.send_animation(
animation=gif,
disable_notification=True
)
@delete_user_message
async def drink(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
drinks = ["cerveza", "vino", "whisky", "ron", "vodka", "tequila", "ginebra", "sidra", "champán", "cava", "sake", "absenta", "brandy", "licor", "vermut", "mezcal", "pacharán", "anís", "aguardiente", "coñac", "cóctel", "cubata", "cóctel", "cubalibre"]
with open("data/images/interaction/beber.gif", "rb") as gif:
await update.effective_chat.send_animation(
animation=gif,
caption=f"@{update.effective_sender.username} ha bebido {choice(drinks)}",
disable_notification=True
)
@delete_user_message
async def bomb(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
if not context.args:
await update.effective_chat.send_message(
text="Debes especificar algo que bombardear",
disable_notification=True
)
return
with open("data/images/interaction/bombardeen.gif") as gif:
await update.effective_chat.send_animation(
animation=gif,
caption=f"Bombardeen {context.args[0]}",
disable_notification=True
)

1
data/files/counter.csv Normal file
View File

@@ -0,0 +1 @@
1
1 1

60
data/files/grupos.txt Normal file
View File

@@ -0,0 +1,60 @@
Imagine Dragons
Lil Nas X
Ed Sheeran
OneRepublic
Harry Styles
Mägo de Oz
Black Eyed Peas
Måneskin
BoyWithUke
Bad Bunny
Bizarrap
The Score
bbno$
The Weeknd
Green Day
Queen
AC/DC
Elton John
Coldplay
LiSA
Glass Animals
Post Malone
KSI
Cardi B
JBalvin
Marshmello
Farruko
Dua Lipa
Ava Max
Armin van Buuren
Panic! At The Disco
Billie Eilish
Alan Walker
Bebe Rexha
Bruno Mars
Miley Cyrus
Maroon 5
Tones And I
Why don't we
Ali Gatie
Canserbero
Residente
Dire Straits
Pink Floyd
Prince
The Police
Guns N' Roses
Linkin Park
Scorpion
Status Quo
Justin Bieber
Michael Jackson
Ariana Grande
Beyoncé
Lady Gaga
Katy Perry
Adele
Drake
Taylor Swift
Rihanna

0
data/files/hugs.json Normal file
View File

60
data/files/juegos.txt Normal file
View File

@@ -0,0 +1,60 @@
Dishonored 2
The Witness
Journey
Uncharted 2: Among Thieves
Overwatch
Apex Legends
Hollow Knig
Ms. Pac-Man
Counter-Strike 1.6
Left 4 Dead 2
EarthBound
Diablo II
StarCraft
World of Warcraft
Star Wars: Knights of the Old Republic
Fallout: New Vegas
Final Fantasy VI
Pokémon Yellow
Metroid Prime
The Elder Scrolls V: Skyrim
Resident Evil 4
Shadow of the Colossus
The Last of Us Part 2
Red Dead Redemption
Metal Gear Solid
Sid Meier's Civilization IV
The Legend of Zelda: Ocarina of Time
Minecraft
Halo: Combat Evolved
Half-Life
Final Fantasy XIV
Doom
Tetris
Metal Gear Solid 3: Snake Eater
Half-Life: Alyx
God of War
Chrono Trigger
Portal
Street Fighter II
Super Mario Bros.
Undertale
Bloodborne
BioShock
The Last of Us
The Witcher 3: Wild Hunt
Halo 2
Castlevania: Symphony of the Night
Hades
Grand Theft Auto V
Super Mario Bros. 3
Disco Elysium
Half-Life 2
Red Dead Redemption 2
Super Mario 64
Mass Effect 2
Super Metroid
The Legend of Zelda: A Link to the Past
Portal 2
Super Mario World
The Legend of Zelda: Breath of the Wild

60
data/files/shows.txt Normal file
View File

@@ -0,0 +1,60 @@
Squid Game
La Casa de Papel
Lupin
Avatar
Los Simpson
Lightyear
Tadeo Jones
Los Minions
Doraemon
Shin-Chan
JoJo's Bizarre Adventures
Boku no Hero Academia
Fullmetal Alchemist
SPY X FAMILY
Black Clover
My Dress-up Darling
New Amsterdam
Death Note
Cobra Kai
Karate Kid
Interstellar
Cómo entrenar a tu dragón
Free Guy
Spider Man
Dr Strange
Matrix
John Wick
Iron Man
The Good Doctor
Komi-san can't communicate
Big Mouth
(Des)encanto
Rick y Morty
Historias Corrientes
Hora de Aventuras
Chowder
Star Trek
Star Wars
Lost in Space
Tokyo Revengers
Gladiator
The Crown
Peaky Blinders
Sex Education
Enola Holmes
Los Juegos del Hambre
Juego de Tronos
El Señor de los Anillos
La princesa mononoke
Hitman
Los Croods
Plan de Escape
Código Lyoko
El Padrino
El viaje de Chihiro
El castillo ambulante
Coach Carter
Mascotas
Aida
La que se avecina

0
data/files/warns.json Normal file
View File

BIN
data/images/djpype.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 224 KiB

BIN
data/images/graph.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.3 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 MiB

Binary file not shown.

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.2 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 262 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 105 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.7 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 258 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.0 MiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 833 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 MiB

BIN
data/images/logo.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 MiB

BIN
data/images/pype.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 163 KiB

33
main.py Normal file
View File

@@ -0,0 +1,33 @@
import os
from pathlib import Path
from dotenv import load_dotenv
from telegram import Update
from telegram.ext import ApplicationBuilder, CommandHandler, ContextTypes
# importing command classes
from commands.misc import Misc
from commands.math import Math
from commands.interaction import Interaction
from commands.help import Help
class PypeBot:
def __init__(self):
load_dotenv()
self.app = ApplicationBuilder().token(os.getenv("TOKEN")).build()
# command registering
Misc(self.app)
Math(self.app)
Interaction(self.app)
Help(self.app)
async def start(self, update: Update, context: ContextTypes.DEFAULT_TYPE) -> None:
await update.message.reply_text("Tamo' activo B)")
def main() -> None:
bot = PypeBot()
bot.app.add_handler(CommandHandler("start", bot.start))
bot.app.run_polling()
if __name__ == '__main__':
main()

4
requirements.txt Normal file
View File

@@ -0,0 +1,4 @@
matplotlib
telegram
python-telegram-bot
numpy

92
settings.py Normal file
View File

@@ -0,0 +1,92 @@
##### ####### # # ####### ### ##### # # ###### # ##### ### ####### # #
# # # # ## # # # # # # # # # # # # # # # # ## #
# # # # # # # # # # # # # # # # # # # # # #
# # # # # # ##### # # #### # # ###### # # # # # # # # #
# # # # # # # # # # # # # # ####### # # # # # # #
# # # # # ## # # # # # # # # # # # # # # # # ##
##### ####### # # # ### ##### ##### # # # # ##### ### ####### # #
# Configuración de parámetros del bot
GUILD_NAME = "The Boys" # nombre del servidor
BOT_OWNER = "Gallardo7761"
BOT_OWNER_ID = 8068730345
BOT_LOGO ="data/images/pype.png" # png/jpg
BOT_NAME = "Pype" # nombre a elegir
BOT_LANG = "Python" # lenguaje
BOT_TYPE = "Multipropósito" # tipo
BOT_VERSION = "1.0.0" # versión del bot
LAVALINK_URI = '' # ip del servidor de Lavalink
LAVALINK_PASSWORD = ''
TIMEZONE = "Europe/Madrid" # zona horaria
GRAPH_PATH = "data/images/graph.png" # ruta para guardar gráficos
# Cofiguración de parámetros del comando /help
VARIOS = """
**MISCELÁNEA**
**/ping** - Ping de Pype.
**/info** - Info del discord.
**/say <cosa>** - Pype dice algo.
**/platano** - Banana!
**/dado** - Tira un dado de 6 caras.
**/moneda** - Tira una moneda al aire.
**/paredes <usuario>** - Están por las paredes.
**/oooh** - Ooooooooh! .- Exclamaron Mordecai y Rigby.
**/beber** - Bebe algo.
**/bombardeen <cosa>** - Bombardeen algo.
"""
INTERACCION = """
**INTERACCIÓN**
**/waifu** - Te da una waifu aleatoria en GIF.
**/neko** - Te da un neko aleatorio en GIF.
**/shinobu** - Te da un GIF de Shinobu.
**/megumin** - Te da un GIF de Megumin.
**/bully <usuario>** - Haz bullying a alguien (GIF).
**/cuddle <usuario>** - Acurrúcate con alguien (GIF).
**/cry** - Llora con un GIF.
**/hug <usuario>** - Abraza a alguien (GIF).
**/awoo** - Pide un GIF de furro.
**/kiss <usuario>** - Besa a alguien (GIF).
**/lick <usuario>** - Lame a alguien (GIF).
**/pat <usuario>** - Acaricia a alguien (GIF).
**/smug <usuario>** - Presume ante alguien (GIF).
**/bonk <usuario>** - Da un bonk a alguien (GIF).
**/yeet <usuario>** - Lanza a alguien (GIF).
**/blush** - Sonrojarse (GIF).
**/smile** - Sonríe (GIF).
**/wave <usuario>** - Saluda a alguien (GIF).
**/highfive <usuario>** - Choca la mano con alguien (GIF).
**/handhold <usuario>** - Cógela mano a mano con alguien (GIF).
**/nom** - Come algo rico (GIF).
**/bite <usuario>** - Muérdele a alguien (GIF).
**/glomp <usuario>** - Abalánzate sobre alguien (GIF).
**/slap <usuario>** - Da una bofetada a alguien (GIF).
**/kill <usuario>** - Mata a alguien (GIF).
**/kick <usuario>** - Patea a alguien (GIF).
**/happy** - Estás feliz (GIF).
**/wink <usuario>** - Guiña el ojo a alguien (GIF).
**/poke <usuario>** - Molesta a alguien (GIF).
**/dance <usuario>** - Baila (GIF).
**/cringe <usuario>** - Da cringe lo que hizo alguien (GIF).
**/run** - Huyes (GIF local).
**/fbi <usuario>** - Llama al FBI para alguien (GIF local).
**/spank <usuario>** - Da una nalgada a alguien (GIF local).
**/ship <usuario1> <usuario2>** - Comprueba compatibilidad entre dos personas (GIF local).
**/moan** - Gemido (GIF local).
**/femboize <usuario>** - Convierte a alguien en femboy (PNG local).
"""
MATEMATICAS = """
**MATEMÁTICAS**
**/calcular <operacion>** - Calcula expresiones matemáticas varias.
**/par <numero>** - Comprueba si un número es par o no.
**/primo <numero>** - Comprueba si un número es primo o no.
**/seno <a> <k>** - Grafica una función seno.
**/coseno <a> <k>** - Grafica una función coseno.
**/recta <m> <n>** - Grafica una función lineal.
**/parabola <a> ** <c>** - Grafica una función cuadrática.
**/circunferencia <r>** - Grafica una circunferencia.
**/log <a> **** - Grafica una función logarítmica.
**/exp <a> **** - Grafica una función exponencial.
"""

24
util/anime.py Normal file
View File

@@ -0,0 +1,24 @@
import requests
class Anime:
def __init__(self):
self.base_url = f"https://api.waifu.pics/"
def get(self, type: str, category: str) -> None:
if type != "nsfw" and type != "sfw":
raise Exception("Type not supported!")
if not isinstance(category, str):
raise Exception("Category must be a string!")
response = requests.get(f"{self.base_url}/{type}/{category}")
if response.status_code != 200:
raise Exception("Failed to retrieve data from API!")
return response.json()["url"]
def sfw(self, category: str) -> str:
return self.get("sfw", category)
def nsfw(self, category: str) -> str:
return self.get("nsfw", category)

17
util/files.py Normal file
View File

@@ -0,0 +1,17 @@
import json
def read(file: str) -> str:
with open(file, "r") as f:
return f.read()
def read_json(file: str) -> dict:
with open(file, "r") as f:
return json.load(f)
def write(file: str, content: str) -> None:
with open(file, "w") as f:
f.write(content)
def write_json(file: str, content: dict) -> None:
with open(file, "w") as f:
json.dump(content, f, indent=4, sort_keys=True, separators=(',', ': '), ensure_ascii=False)

13
util/logger/colors.py Normal file
View File

@@ -0,0 +1,13 @@
class Colors:
RED = "\033[91m"
GREEN = "\033[92m"
YELLOW = "\033[93m"
BLUE = "\033[94m"
MAGENTA = "\033[95m"
CYAN = "\033[96m"
WHITE = "\033[97m"
RESET = "\033[0m"
BOLD = "\033[1m"
UNDERLINE = "\033[4m"
LIME = "\033[32m"
GRAY = "\033[90m"

43
util/logger/logger.py Normal file
View File

@@ -0,0 +1,43 @@
from .colors import Colors
from datetime import datetime
import pytz
import traceback
class PypeLogger:
@staticmethod
def info(message):
now = datetime.now(tz=pytz.timezone("Europe/Madrid")).strftime("%H:%M:%S")
print(f"{Colors.GRAY}[{now}] {Colors.GREEN}[INFO] {message}{Colors.RESET}")
@staticmethod
def error(message, exception=None):
now = datetime.now(tz=pytz.timezone("Europe/Madrid")).strftime("%H:%M:%S")
main_error = f"{Colors.GRAY}[{now}] {Colors.RED}[ERROR] {message}{Colors.RESET}"
error_messages = [main_error]
if exception:
exception_message = f"\n{Colors.GRAY}[{now}] {Colors.RED}[ERROR] - Exception: {exception}"
traceback_message = f"\n{Colors.GRAY}[{now}] {Colors.RED}[ERROR] - Traceback: {traceback.format_exc()}"
error_messages.append(exception_message)
error_messages.append(traceback_message)
for error_message in error_messages:
print(error_message)
@staticmethod
def debug(message):
now = datetime.now(tz=pytz.timezone("Europe/Madrid")).strftime("%H:%M:%S")
print(f"{Colors.GRAY}[{now}] {Colors.BLUE}[DEBUG] {message}{Colors.RESET}")
@staticmethod
def warning(message):
now = datetime.now(tz=pytz.timezone("Europe/Madrid")).strftime("%H:%M:%S")
print(f"{Colors.GRAY}[{now}] {Colors.YELLOW}[WARNING] {message}{Colors.RESET}")
@staticmethod
def success(message):
now = datetime.now(tz=pytz.timezone("Europe/Madrid")).strftime("%H:%M:%S")
print(f"{Colors.GRAY}[{now}] {Colors.LIME}[SUCCESS] {message}{Colors.RESET}")
@staticmethod
def command(message):
now = datetime.now(tz=pytz.timezone("Europe/Madrid")).strftime("%H:%M:%S")
print(f"{Colors.GRAY}[{now}] {Colors.MAGENTA}[COMMAND] {message}{Colors.RESET}")

18
util/messages.py Normal file
View File

@@ -0,0 +1,18 @@
from telegram import Update
from telegram.ext import ContextTypes
async def respond(context: ContextTypes.DEFAULT_TYPE, chat_id: int, message: str):
await context.bot.send_message(
chat_id=chat_id,
text="✅ Mensaje recibido",
disable_notification=True
)
def delete_user_message(func):
async def wrapper(self, update: Update, context: ContextTypes.DEFAULT_TYPE):
await func(self, update, context)
try:
await context.bot.delete_message(update.effective_chat.id, update.message.message_id)
except:
pass
return wrapper

10
util/numbers.py Normal file
View File

@@ -0,0 +1,10 @@
def is_even(n: int) -> bool:
return n % 2 == 0
def is_prime(n: int) -> bool:
if n <= 1:
return False
for i in range(2, int(n**0.5) + 1):
if n % i == 0:
return False
return True