Update to main

This commit is contained in:
Die Antwoord 2023-01-23 14:29:07 +02:00
parent c13c6826b0
commit d048fcef81
16 changed files with 2495 additions and 0 deletions

0
bot.py Normal file
View File

192
cogs/fun.py Normal file
View File

@ -0,0 +1,192 @@
import random
import aiohttp
import discord
from discord.ext import commands
from discord.ext.commands import Context
from helpers import checks
class Choice(discord.ui.View):
def __init__(self):
super().__init__()
self.value = None
@discord.ui.button(label="Heads", style=discord.ButtonStyle.blurple)
async def confirm(self, button: discord.ui.Button, interaction: discord.Interaction):
self.value = "heads"
self.stop()
@discord.ui.button(label="Tails", style=discord.ButtonStyle.blurple)
async def cancel(self, button: discord.ui.Button, interaction: discord.Interaction):
self.value = "tails"
self.stop()
class RockPaperScissors(discord.ui.Select):
def __init__(self):
options = [
discord.SelectOption(
label="Scissors", description="You choose scissors.", emoji=""
),
discord.SelectOption(
label="Rock", description="You choose rock.", emoji="🪨"
),
discord.SelectOption(
label="paper", description="You choose paper.", emoji="🧻"
),
]
super().__init__(
placeholder="Choose...",
min_values=1,
max_values=1,
options=options,
)
async def callback(self, interaction: discord.Interaction):
choices = {
"rock": 0,
"paper": 1,
"scissors": 2,
}
user_choice = self.values[0].lower()
user_choice_index = choices[user_choice]
bot_choice = random.choice(list(choices.keys()))
bot_choice_index = choices[bot_choice]
result_embed = discord.Embed(color=0x9C84EF)
result_embed.set_author(
name=interaction.user.name,
icon_url=interaction.user.avatar.url
)
if user_choice_index == bot_choice_index:
result_embed.description = f"**That's a draw!**\nYou've chosen {user_choice} and I've chosen {bot_choice}."
result_embed.colour = 0xF59E42
elif user_choice_index == 0 and bot_choice_index == 2:
result_embed.description = f"**You won!**\nYou've chosen {user_choice} and I've chosen {bot_choice}."
result_embed.colour = 0x9C84EF
elif user_choice_index == 1 and bot_choice_index == 0:
result_embed.description = f"**You won!**\nYou've chosen {user_choice} and I've chosen {bot_choice}."
result_embed.colour = 0x9C84EF
elif user_choice_index == 2 and bot_choice_index == 1:
result_embed.description = f"**You won!**\nYou've chosen {user_choice} and I've chosen {bot_choice}."
result_embed.colour = 0x9C84EF
else:
result_embed.description = f"**I won!**\nYou've chosen {user_choice} and I've chosen {bot_choice}."
result_embed.colour = 0xE02B2B
await interaction.response.edit_message(embed=result_embed, content=None, view=None)
class RockPaperScissorsView(discord.ui.View):
def __init__(self):
super().__init__()
self.add_item(RockPaperScissors())
class Fun(commands.Cog, name="fun"):
def __init__(self, bot):
self.bot = bot
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="randomfact",
description="Get a random fact."
)
@checks.not_blacklisted()
async def randomfact(self, context: Context) -> None:
# This will prevent your bot from stopping everything when doing a web request - see: https://discordpy.readthedocs.io/en/stable/faq.html#how-do-i-make-a-web-request
async with aiohttp.ClientSession() as session:
async with session.get("https://uselessfacts.jsph.pl/random.json?language=en") as request:
if request.status == 200:
data = await request.json()
embed = discord.Embed(
description=data["text"],
color=0xD75BF4
)
else:
embed = discord.Embed(
title="Error!",
description="There is something wrong with the API, please try again later",
color=0xE02B2B
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="randomquote",
description="Get a random quote."
)
@checks.not_blacklisted()
async def quote(self, context) -> None:
async with aiohttp.ClientSession() as cs:
async with cs.get("https://zenquotes.io/api/random") as r:
res = await r.json() # returns dict
quote = res[0]['q'] + " -" + res[0]['a']
await context.send(quote)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="randomtopic",
description="Get a random topic."
)
@checks.not_blacklisted()
async def topic(self, context) -> None:
"""Provides a question for users to talk about"""
topics = ["What is your favourite book?", "What is your favourite game?",
"What is your favourite song with a positive message?", "What is your favourite place to visit?",
"Did you apply what you learned in school?", "What is your favourite programming language?", "What is your favourite website?"]
number = random.randint(0, len(topics))
await context.send(topics[number])
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="coinflip",
description="Make a coin flip, but give your bet before."
)
@checks.not_blacklisted()
async def coinflip(self, context: Context) -> None:
buttons = Choice()
embed = discord.Embed(
description="What is your bet?",
color=0x9C84EF
)
message = await context.send(embed=embed, view=buttons)
await buttons.wait() # We wait for the user to click a button.
result = random.choice(["heads", "tails"])
if buttons.value == result:
embed = discord.Embed(
description=f"Correct! You guessed `{buttons.value}` and I flipped the coin to `{result}`.",
color=0x9C84EF
)
else:
embed = discord.Embed(
description=f"Woops! You guessed `{buttons.value}` and I flipped the coin to `{result}`, better luck next time!",
color=0xE02B2B
)
await message.edit(embed=embed, view=None, content=None)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="rps",
description="Play the rock paper scissors game against the bot."
)
@checks.not_blacklisted()
async def rock_paper_scissors(self, context: Context) -> None:
view = RockPaperScissorsView()
await context.send("Please make your choice", view=view)
async def setup(bot):
await bot.add_cog(Fun(bot))

457
cogs/general.py Normal file
View File

@ -0,0 +1,457 @@
import platform
import os
import platform
import sys
import psutil
import math
import copy
import random
from random import randint
import datetime
import time
from time import time
from datetime import datetime
from datetime import datetime as dt
#from discord.utils import get
from discord.utils import *
import aiohttp
import discord
from discord import app_commands
from discord import Embed, Color
from discord.ext import commands
from discord.ext.commands import Context
from http.client import responses
from paginator import Paginator
from typing import Optional
from constants import (
LANGUAGES,
NEWLINES_LIMIT,
CHARACTERS_LIMIT,
Emoji,
JUDGE0_ICON,
START_TIME,
PREFIX,
)
from helpers import checks
class General(commands.Cog, name="general"):
def __init__(self, bot):
self.bot = bot
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="help",
description="List all commands the bot has loaded."
)
@checks.not_blacklisted()
async def help(self, context: Context) -> None:
prefix = self.bot.config["prefix"]
embed = discord.Embed(
title="Help", description="List of available commands:", color=0x9C84EF)
for i in self.bot.cogs:
cog = self.bot.get_cog(i.lower())
commands = cog.get_commands()
data = []
for command in commands:
description = command.description.partition('\n')[0]
data.append(f"{prefix}{command.name} - {description}")
help_text = "\n".join(data)
embed.add_field(name=i.capitalize(),
value=f'```{help_text}```', inline=False)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="sinfo",
description="List bot server status info."
)
@checks.not_blacklisted()
async def sinfo(self, ctx):
#Sends useful information about the bot and links.
uptime = int((dt.utcnow() - START_TIME).total_seconds())
d, h = divmod(uptime, 86400)
h, m = divmod(h, 3600)
m, s = divmod(m, 60)
mem = psutil.virtual_memory()
pid = os.getpid()
memory_use = psutil.Process(pid).memory_info()[0]
data = [
("Process memory", f"{memory_use / math.pow(1024, 2):.2f}MB"),
("CPU Usage", f"{psutil.cpu_percent()}%"),
("RAM Usage", f"{mem.percent}%"),
]
embed = Embed(
title="BOT System",
url="https://discord.gg/ScektXnyBe",
timestamp=dt.utcnow(),
description="Discord bot for single custom servers",
)
embed.set_author(name=f"{ctx.author} request", icon_url=ctx.author.avatar)
embed.add_field(
name=f"YADMB#9063 - {self.bot.config['application_id']}",
value=(
f"Uptime: {d}d {h}h {m}m {s}s\n"
f"Servers connected: {len(self.bot.guilds)}\n"
f"Unique users: {len(self.bot.users)}"
f"Running on: {platform.system()} {platform.release()} ({os.name})"
),
inline=False
)
embed.add_field(
name=":computer: System status:",
value="\n".join(f"**{x[0]}** {x[1]}" for x in data),
inline=False
)
embed.add_field(
name="Links",
value=(
f":link: Invite me by clicking [here](https://discordapp.com/oauth2/authorize?&client_id={self.bot.config['application_id']}&scope=bot+applications.commands&permissions={self.bot.config['permissions']}).\n"
f":mortar_board: [GitHub](https://github.com/Die-Antwoord)\n"
f":information_source: [Support server](https://discord.gg/ScektXnyBe)\n"
#f"<:paypal:707665144276320277> [Donation on PayPal](https://paypal.me/skilldeliver)\n"
#f"<:patreon:707663083866161232> [Support me on Patreon](https://www.patreon.com/vmihov)"
),
inline=False
)
embed.set_thumbnail(url=JUDGE0_ICON)
await ctx.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="botinfo",
description="Get some useful (or not) information about the bot.",
)
@checks.not_blacklisted()
async def botinfo(self, context: Context) -> None:
mem = psutil.virtual_memory()
pid = os.getpid()
memory_use = psutil.Process(pid).memory_info()[0]
data = [
("Process memory", f"{memory_use / math.pow(1024, 2):.2f}MB"),
("CPU Usage", f"{psutil.cpu_percent()}%"),
("RAM Usage", f"{mem.percent}%"),
]
embed = discord.Embed(
description=":id: GitHUB\n[Die-Antwoord](https://github.com/Die-Antwoord) ",
color=0x9C84EF
)
embed.set_author(
name="Bot Information"
)
embed.add_field(
name=":mortar_board: Bot Owner:",
value="Die Antwoord#1337",
inline=False
)
embed.add_field(
name=":keyboard: Python Version:",
value=f"Python {platform.python_version()}",
inline=True
)
embed.add_field(
name=":pager: OS Version:",
value=(f"Running on: {platform.system()} {platform.release()} ({os.name})"),
inline=True
)
embed.add_field(
name=":computer: System status:",
value="\n".join(f"**{x[0]}** {x[1]}" for x in data),
inline=False
)
embed.add_field(
name=":information_source: Prefix:",
value=f"`/` (Slash Commands)\nor\n`{self.bot.config['prefix']}` for normal commands",
inline=False
)
embed.set_footer(
text=f"Requested by {context.author}\nRequested at {context.guild.created_at}"
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
# @commands.hybrid_command(
# name="system",
# description="Get some useful (or not) information about the system.",
# )
# #@commands.command(aliases=["status"])
# async def system(self, ctx: commands.Context):
# """Get status of the host system"""
# process_uptime = time.time() - self.bot.start_time
# system_uptime = time.time() - psutil.boot_time()
# mem = psutil.virtual_memory()
# pid = os.getpid()
# memory_use = psutil.Process(pid).memory_info()[0]
# data = [
# ("Bot booted up in", util.stringfromtime(self.bot.boot_up_time)),
# ("Process uptime", util.stringfromtime(process_uptime, 2)),
# ("Process memory", f"{memory_use / math.pow(1024, 2):.2f}MB"),
# ("System uptime", util.stringfromtime(system_uptime, 2)),
# ("CPU Usage", f"{psutil.cpu_percent()}%"),
# ("RAM Usage", f"{mem.percent}%"),
# ]
# content = discord.Embed(
# title=":computer: System status",
# colour=int("5dadec", 16),
# description="\n".join(f"**{x[0]}** {x[1]}" for x in data),
# )
# await ctx.send(embed=content)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="serverinfo",
description="Get some useful (or not) information about the server.",
)
@checks.not_blacklisted()
async def serverinfo(self, context: Context) -> None:
roles = [role.mention for role in context.guild.roles]
if len(roles) > 30:
roles = roles[:30]
roles.append (f"Displaying[30/{len(roles)} Roles")
roles = ", ".join(roles)
embed = discord.Embed(
title="**Server Name:**",
description=f"{context.guild}",
color=0x9C84EF
)
if context.guild.icon is not None:
embed.set_thumbnail(
url=context.guild.icon.url
)
embed.add_field(
name="Server ID",
value=context.guild.id,
inline=True
)
embed.add_field(
name="Member Count",
value=context.guild.member_count,
inline=True
)
embed.add_field(
name="Text/Voice Channels",
value=f"{len(context.guild.channels)}",
inline=True
)
embed.add_field(
name=f"Roles ({len(context.guild.roles)})",
value=roles
)
embed.set_footer(
text=f"Created at: {context.guild.created_at}"
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="ping",
description="Check if the bot is alive.",
)
@checks.not_blacklisted()
async def ping(self, context: Context) -> None:
embed = discord.Embed(
title="The bot latency is ",
description=f"**{round(self.bot.latency * 1000)}ms.**",
color=0x9C84EF
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="invite",
description="Get the invite link of the bot to be able to invite it.",
)
@checks.not_blacklisted()
async def invite(self, context: Context) -> None:
embed = discord.Embed(
title="🔑 Permission Administrator",
description=f"Invite me by clicking [here](https://discordapp.com/oauth2/authorize?&client_id={self.bot.config['application_id']}&scope=bot+applications.commands&permissions={self.bot.config['permissions']}).",
color=0xD75BF4
)
try:
# To know what permissions to give to your bot, please see here: https://discordapi.com/permissions.html and remember to not give Administrator permissions.
await context.author.send(embed=embed)
await context.send("I sent you a private message!")
except discord.Forbidden:
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="server",
description="Get the invite link of the discord server of the bot for some support.",
)
@checks.not_blacklisted()
async def server(self, context: Context) -> None:
embed = discord.Embed(
description=f"Join the support server for the bot by clicking [here](https://discord.gg/ScektXnyBe).",
color=0xD75BF4
)
try:
await context.author.send(embed=embed)
await context.send("I sent you a private message!")
except discord.Forbidden:
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="8ball",
description="Ask any question to the bot.",
)
@checks.not_blacklisted()
@app_commands.describe(question="The question you want to ask.")
async def eight_ball(self, context: Context, *, question: str) -> None:
answers = ["It is certain.", "It is decidedly so.", "You may rely on it.", "Without a doubt.",
"Yes - definitely.", "As I see, yes.", "Most likely.", "Outlook good.", "Yes.",
"Signs point to yes.", "Reply hazy, try again.", "Ask again later.", "Better not tell you now.",
"Cannot predict now.", "Concentrate and ask again later.", "Don't count on it.", "My reply is no.",
"My sources say no.", "Outlook not so good.", "Very doubtful."]
embed = discord.Embed(
title="**My Answer:**",
description=f"{random.choice(answers)}",
color=0x9C84EF
)
embed.set_footer(
text=f"The question was: {question}"
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="bitcoin",
description="Get the current price of bitcoin.",
)
@checks.not_blacklisted()
async def bitcoin(self, context: Context) -> None:
# This will prevent your bot from stopping everything when doing a web request - see: https://discordpy.readthedocs.io/en/stable/faq.html#how-do-i-make-a-web-request
async with aiohttp.ClientSession() as session:
async with session.get("https://api.coindesk.com/v1/bpi/currentprice/BTC.json") as request:
if request.status == 200:
data = await request.json(
content_type="application/javascript") # For some reason the returned content is of type JavaScript
embed = discord.Embed(
title="Bitcoin price",
description=f"The current price is {data['bpi']['USD']['rate']} :dollar:",
color=0x9C84EF
)
else:
embed = discord.Embed(
title="Error!",
description="There is something wrong with the API, please try again later",
color=0xE02B2B
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="rolecount",
description="Get the current rolecount of the server.",
)
@checks.not_blacklisted()
@checks.is_owner()
async def rolecount(self, context) -> None:
data = format(len(context.guild.roles) - 1)
embed = discord.Embed(
title="Total Group Roles",
description=f"\n**`{data}`**",
color=0x9C84EF
)
embed.set_footer(
text=f"Created at: {context.guild.created_at}"
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
async def setup(bot):
await bot.add_cog(General(bot))

64
cogs/infomantion.py Normal file
View File

@ -0,0 +1,64 @@
import discord
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context
from helpers import checks
# Here we name the cog and create a new class for the cog.
class Infomantion(commands.Cog, name="infomantion"):
def __init__(self, bot):
self.bot = bot
# Here you can just add your own commands, you'll always need to provide "self" as first parameter.
@commands.hybrid_command(
name='links',
description="This is a testing command that does nothing.",
aliases=['link']
)
@checks.not_blacklisted()
async def links(self, context):
"""Lists all my important links in an embed."""
links = discord.Embed(
title="List of Links",
description="Here is a list of links. More will be added later. Enjoy!",
colour=0xFF0000
)
links.set_author(
name="Die-Antwoord"
)
links.add_field(
name="Aero#5703 - 432129282710700033",
value="https://aero.bot/",
inline=False
)
links.add_field(
name="Reputation#1740 - 550035183269838848",
value="https://discordrep.com/",
inline=False
)
links.add_field(
name="Blacklister#3409 - 866364881917837312",
value="https://discord.gg/FZxgNrwBS6",
inline=False
)
links.add_field(
name="DangerCord - 1007806961854726269",
value="▌<@1007806961854726269> | https://dangercord.com/",
inline=False
)
links.add_field(
name="GitHub",
value="https://github.com/Die-Antwoord",
inline=False
)
await context.send(embed=links)
pass
# And then we finally add the cog to the bot so that it can load, unload, reload and use it's content.
async def setup(bot):
await bot.add_cog(Infomantion(bot))

49
cogs/lockchannel.py Normal file
View File

@ -0,0 +1,49 @@
import discord
from discord.ext import commands
from discord.ext.commands import Context
from helpers import checks
class Lockchannel(commands.Cog, name="lockchannel"):
def __init__(self, bot):
self.bot = bot
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="lockchannel",
description="Lock Server Channel.",
)
@commands.has_permissions(manage_channels=True)
@checks.not_blacklisted()
@checks.is_owner()
async def lock(self, context, channel: discord.TextChannel = None, reason=None) -> None:
if reason == None:
reason = 'Channel Locked By Owner'
channel = context.channel or channel
await channel.set_permissions(context.guild.default_role, send_messages=False, add_reactions=False, create_public_threads=False)
await context.send(f"`{context.author}` - `{context.author.id}` has locked <#{channel.id}>\nReason: `{reason}`")
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="unlockchannel",
description="Unlock Server Channel.",
)
@commands.has_permissions(manage_channels=True)
@checks.not_blacklisted()
@checks.is_owner()
async def unlock(self, context, channel: discord.TextChannel = None, reason=None) -> None:
if reason == None:
reason = 'Channel Locked By Owner'
channel = context.channel
await channel.set_permissions(context.guild.default_role, send_messages=None, add_reactions=None, create_public_threads=None)
await context.send(f"`{context.author}` - `{context.author.id}` has unlocked <#{channel.id}>\nReason: `{reason}`")
#-------------------------------------------------------------------------------
async def setup(bot):
await bot.add_cog(Lockchannel(bot))

266
cogs/moderation.py Normal file
View File

@ -0,0 +1,266 @@
import discord
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context
from helpers import checks, db_manager
class Moderation(commands.Cog, name="moderation"):
def __init__(self, bot):
self.bot = bot
@commands.hybrid_command(
name="kick",
description="Kick a user out of the server.",
)
@commands.has_permissions(kick_members=True)
@commands.bot_has_permissions(kick_members=True)
@checks.not_blacklisted()
@app_commands.describe(user="The user that should be kicked.", reason="The reason why the user should be kicked.")
async def kick(self, context: Context, user: discord.User, *, reason: str = "Not specified") -> None:
member = context.guild.get_member(user.id) or await context.guild.fetch_member(user.id)
if member.guild_permissions.administrator:
embed = discord.Embed(
title="Error!",
description="User has Admin permissions.",
color=0xE02B2B
)
await context.send(embed=embed)
else:
try:
embed = discord.Embed(
title="User Kicked!",
description=f"**{member}** was kicked by **{context.author}**!",
color=0x9C84EF
)
embed.add_field(
name="Reason:",
value=reason
)
await context.send(embed=embed)
try:
await member.send(
f"You were kicked by **{context.author}**!\nReason: {reason}"
)
except:
# Couldn't send a message in the private messages of the user
pass
await member.kick(reason=reason)
except:
embed = discord.Embed(
title="Error!",
description="An error occurred while trying to kick the user. Make sure my role is above the role of the user you want to kick.",
color=0xE02B2B
)
await context.send(embed=embed)
@commands.hybrid_command(
name="nick",
description="Change the nickname of a user on a server.",
)
@commands.has_permissions(manage_nicknames=True)
@commands.bot_has_permissions(manage_nicknames=True)
@checks.not_blacklisted()
@app_commands.describe(user="The user that should have a new nickname.", nickname="The new nickname that should be set.")
async def nick(self, context: Context, user: discord.User, *, nickname: str = None) -> None:
member = context.guild.get_member(user.id) or await context.guild.fetch_member(user.id)
try:
await member.edit(nick=nickname)
embed = discord.Embed(
title="Changed Nickname!",
description=f"**{member}'s** new nickname is **{nickname}**!",
color=0x9C84EF
)
await context.send(embed=embed)
except:
embed = discord.Embed(
title="Error!",
description="An error occurred while trying to change the nickname of the user. Make sure my role is above the role of the user you want to change the nickname.",
color=0xE02B2B
)
await context.send(embed=embed)
@commands.hybrid_command(
name="ban",
description="Bans a user from the server.",
)
@commands.has_permissions(ban_members=True)
@commands.bot_has_permissions(ban_members=True)
@checks.not_blacklisted()
@app_commands.describe(user="The user that should be banned.", reason="The reason why the user should be banned.")
async def ban(self, context: Context, user: discord.User, *, reason: str = "Not specified") -> None:
member = context.guild.get_member(user.id) or await context.guild.fetch_member(user.id)
try:
if member.guild_permissions.administrator:
embed = discord.Embed(
title="Error!",
description="User has Admin permissions.",
color=0xE02B2B
)
await context.send(embed=embed)
else:
embed = discord.Embed(
title="User Banned!",
description=f"**{member}** was banned by **{context.author}**!",
color=0x9C84EF
)
embed.add_field(
name="Reason:",
value=reason
)
await context.send(embed=embed)
try:
await member.send(f"You were banned by **{context.author}**!\nReason: {reason}")
except:
# Couldn't send a message in the private messages of the user
pass
await member.ban(reason=reason)
except:
embed = discord.Embed(
title="Error!",
description="An error occurred while trying to ban the user. Make sure my role is above the role of the user you want to ban.",
color=0xE02B2B
)
await context.send(embed=embed)
@commands.hybrid_group(
name="warning",
description="Manage warnings of a user on a server.",
)
@commands.has_permissions(manage_messages=True)
@checks.not_blacklisted()
async def warning(self, context: Context) -> None:
if context.invoked_subcommand is None:
embed = discord.Embed(
title="Error!",
description="Please specify a subcommand.\n\n**Subcommands:**\n`add` - Add a warning to a user.\n`remove` - Remove a warning from a user.\n`list` - List all warnings of a user.",
color=0xE02B2B
)
await context.send(embed=embed)
@warning.command(
name="add",
description="Adds a warning to a user in the server.",
)
@checks.not_blacklisted()
@commands.has_permissions(manage_messages=True)
@app_commands.describe(user="The user that should be warned.", reason="The reason why the user should be warned.")
async def warning_add(self, context: Context, user: discord.User, *, reason: str = "Not specified") -> None:
member = context.guild.get_member(user.id) or await context.guild.fetch_member(user.id)
total = await db_manager.add_warn(
user.id, context.guild.id, context.author.id, reason)
embed = discord.Embed(
title="User Warned!",
description=f"**{member}** was warned by **{context.author}**!\nTotal warns for this user: {total}",
color=0x9C84EF
)
embed.add_field(
name="Reason:",
value=reason
)
await context.send(embed=embed)
try:
await member.send(f"You were warned by **{context.author}**!\nReason: {reason}")
except:
# Couldn't send a message in the private messages of the user
await context.send(f"{member.mention}, you were warned by **{context.author}**!\nReason: {reason}")
@warning.command(
name="remove",
description="Removes a warning from a user in the server.",
)
@checks.not_blacklisted()
@commands.has_permissions(manage_messages=True)
@app_commands.describe(user="The user that should get their warning removed.", warn_id="The ID of the warning that should be removed.")
async def warning_remove(self, context: Context, user: discord.User, warn_id: int) -> None:
member = context.guild.get_member(user.id) or await context.guild.fetch_member(user.id)
total = await db_manager.remove_warn(warn_id, user.id, context.guild.id)
embed = discord.Embed(
title="User Warn Removed!",
description=f"I've removed the warning **#{warn_id}** from **{member}**!\nTotal warns for this user: {total}",
color=0x9C84EF
)
await context.send(embed=embed)
@warning.command(
name="list",
description="Shows the warnings of a user in the server.",
)
@commands.has_guild_permissions(manage_messages=True)
@checks.not_blacklisted()
@app_commands.describe(user="The user you want to get the warnings of.")
async def warning_list(self, context: Context, user: discord.User):
warnings_list = await db_manager.get_warnings(user.id, context.guild.id)
embed = discord.Embed(
title=f"Warnings of {user}",
color=0x9C84EF
)
description = ""
if len(warnings_list) == 0:
description = "This user has no warnings."
else:
for warning in warnings_list:
description += f"• Warned by <@{warning[2]}>: **{warning[3]}** (<t:{warning[4]}>) - Warn ID #{warning[5]}\n"
embed.description = description
await context.send(embed=embed)
@commands.hybrid_command(
name="purge",
description="Delete a number of messages.",
)
@commands.has_guild_permissions(manage_messages=True)
@commands.bot_has_permissions(manage_messages=True)
@checks.not_blacklisted()
@app_commands.describe(amount="The amount of messages that should be deleted.")
async def purge(self, context: Context, amount: int) -> None:
await context.send("Deleting messages...") # Bit of a hacky way to make sure the bot responds to the interaction and doens't get a "Unknown Interaction" response
purged_messages = await context.channel.purge(limit=amount+1)
embed = discord.Embed(
title="Chat Cleared!",
description=f"**{context.author}** cleared **{len(purged_messages)-1}** messages!",
color=0x9C84EF
)
await context.channel.send(embed=embed)
@commands.hybrid_command(
name="hackban",
description="Bans a user without the user having to be in the server.",
)
@commands.has_permissions(ban_members=True)
@commands.bot_has_permissions(ban_members=True)
@checks.not_blacklisted()
@app_commands.describe(user_id="The user ID that should be banned.", reason="The reason why the user should be banned.")
async def hackban(self, context: Context, user_id: str, *, reason: str = "Not specified") -> None:
try:
await self.bot.http.ban(user_id, context.guild.id, reason=reason)
user = self.bot.get_user(int(user_id)) or await self.bot.fetch_user(int(user_id))
embed = discord.Embed(
title="User Banned!",
description=f"**{user} (ID: {user_id}) ** was banned by **{context.author}**!",
color=0x9C84EF
)
embed.add_field(
name="Reason:",
value=reason
)
await context.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title="Error!",
description="An error occurred while trying to ban the user. Make sure ID is an existing ID that belongs to a user.",
color=0xE02B2B
)
await context.send(embed=embed)
async def setup(bot):
await bot.add_cog(Moderation(bot))

628
cogs/neko.py Normal file
View File

@ -0,0 +1,628 @@
import nekos
import urllib
import discord
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context
# from nekos import img
from nekos import *
from helpers import checks, db_manager
class Neko(commands.Cog, name="neko"):
def __init__(self, bot):
self.bot = bot
def img(target: str):
target == [
"wallpaper",
"ngif",
"tickle",
#"lewd", Provides 1 image
"feed",
"gecg",
"gasm",
"slap",
"avatar",
"lizard",
"waifu",
"pat",
"8ball",
"kiss",
"neko",
"spank",
"cuddle",
"fox_girl",
"hug",
"smug",
"goose",
"woof",
]
#-------------------------------------------------------------------------------
@commands.hybrid_group(
name="nekos",
description="All nekos commands.",
)
@checks.not_blacklisted()
async def nekos(self, context: Context) -> None:
if context.invoked_subcommand is None:
embed = discord.Embed(
title="All targets for nekos api",
description="Please specify a target.\n\n`wallpaper`, `ngif`, `tickle`, `feed`, `gecg`, `gasm`, `slap`, `avatar`, `lizard`, `waifu`, `pat`, `8ball`, `kiss`, `neko`, `spank`, `cuddle`, `fox_girl`, `hug`, `smug`, `goose`, `woof`",
color=0xE02B2B
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
base="nekos",
name="wallpaper",
description="Send a Random Anime image in channel.(NSFW included)",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def wallpaper(self, context: commands.Context, target: str = "Wallpaper") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos Wallpaper",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="ngif",
description="Ramdom ngif.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def ngif(self, context: commands.Context, target: str = "ngif") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos Wallpaper",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="tickle",
description="Ramdom tickle.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
@app_commands.describe(user="The user that that you want to tickle")
async def tickle(self, context: commands.Context, user: discord.User, target: str = "tickle") -> None:
url = (nekos.img(target))
data = (user.mention)
embed = discord.Embed(
title="Nekos tickle",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(data)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="feed",
description="Ramdom feed.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def feed(self, context: commands.Context, target: str = "feed") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos feed",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="gecg",
description="Ramdom gecg.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def gecg(self, context: commands.Context, target: str = "gecg") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos gecg",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="gasm",
description="Ramdom gasm.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def gasm(self, context: commands.Context, target: str = "gasm") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos gasm",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="slap",
description="Ramdom Anime slap.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def slap(self, context: commands.Context, target: str = "slap") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos slap",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="avatar",
description="Ramdom avatar.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def avatar(self, context: commands.Context, target: str = "avatar") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos avatar",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="lizard",
description="Ramdom lizard.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def lizard(self, context: commands.Context, target: str = "lizard") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos lizard",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="waifu",
description="Ramdom Anime waifu.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def waifu(self, context: commands.Context, target: str = "waifu") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos waifu",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="pat",
description="Ramdom pat.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def pat(self, context: commands.Context, target: str = "pat") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos pat",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="eightball",
description="Ramdom eightball.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def eightball(self, context: commands.Context, target: str = "8ball") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos eightball",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="neko",
description="Ramdom neko.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def neko(self, context: commands.Context, target: str = "neko") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos neko",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="kiss",
description="Ramdom kiss.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def kiss(self, context: commands.Context, target: str = "kiss") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos kiss",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="spank",
description="Ramdom spank.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def spank(self, context: commands.Context, target: str = "spank") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos spank",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="cuddle",
description="Ramdom cuddle.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def cuddle(self, context: commands.Context, target: str = "cuddle") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos cuddle",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="fox_girl",
description="Ramdom fox_girl.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def fox_girl(self, context: commands.Context, target: str = "fox_girl") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos fox_girl",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="hug",
description="Ramdom hug.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def hug(self, context: commands.Context, target: str = "hug") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos hug",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="smug",
description="Ramdom smug.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def smug(self, context: commands.Context, target: str = "smug") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos smug",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="goose",
description="Ramdom goose.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def goose(self, context: commands.Context, target: str = "goose") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos goose",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@nekos.command(
name="woof",
description="Ramdom woof.",
)
@checks.not_blacklisted()
@app_commands.describe(target="This can be left blank")
async def woof(self, context: commands.Context, target: str = "woof") -> None:
url = (nekos.img(target))
embed = discord.Embed(
title="Nekos woof",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="cat",
description="Send a random cat image",
)
@checks.not_blacklisted()
async def cat(self, context: Context) -> None:
url = (nekos.cat())
embed = discord.Embed(
title="Nekos Cat",
description=f"{context.author}",
color=0x9C84EF
)
embed.set_image(
url=url
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="name",
description="Ramdom Name Text.",
)
@checks.not_blacklisted()
async def name(self, context: Context) -> None:
description = (nekos.name())
embed = discord.Embed(
title="Nekos Cat",
description=description,
color=0x9C84EF
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="why",
description="Why.",
)
@checks.not_blacklisted()
async def why(self, context: Context) -> None:
description = (nekos.why())
embed = discord.Embed(
title="Nekos Why",
description=description,
color=0x9C84EF
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="nfact",
description="Returns a random Fact.",
)
@checks.not_blacklisted()
async def nfact(self, context: Context) -> None:
description = (nekos.fact())
embed = discord.Embed(
title="Nekos fact",
description=description,
color=0x9C84EF
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="textcat",
description="Ramdom Name Textcat.",
)
@checks.not_blacklisted()
async def textcat(self, context: Context) -> None:
description = (nekos.textcat())
embed = discord.Embed(
title="Nekos textcat",
description=description,
color=0x9C84EF
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="owoify",
description="Ramdom Name Textcat.",
)
@checks.not_blacklisted()
async def owoify(self, context: Context, text: str) -> None:
description = (nekos.owoify(text))
embed = discord.Embed(
title="Nekos owoify",
description=description,
color=0x9C84EF
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="lewd",
description="Ramdom lewd.",
)
@checks.not_blacklisted()
async def lewd(self, context: Context, target: str = 'lewd') -> None:
description = (nekos.img(target))
embed = discord.Embed(
title="Nekos lewd",
description=description,
color=0x9C84EF
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
async def setup(bot):
await bot.add_cog(Neko(bot))

353
cogs/owner.py Normal file
View File

@ -0,0 +1,353 @@
import discord
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context
from helpers import checks, db_manager
class Owner(commands.Cog, name="owner"):
def __init__(self, bot):
self.bot = bot
#-------------------------------------------------------------------------------
@commands.command(
name="sync",
description="Synchonizes the slash commands.",
)
@app_commands.describe(scope="The scope of the sync. Can be `global` or `guild`")
@checks.is_owner()
async def sync(self, context: Context, scope: str) -> None:
if scope == "global":
await context.bot.tree.sync()
embed = discord.Embed(
title="Slash Commands Sync",
description="Slash commands have been globally synchronized.",
color=0x9C84EF
)
await context.send(embed=embed)
return
elif scope == "guild":
context.bot.tree.copy_global_to(guild=context.guild)
await context.bot.tree.sync(guild=context.guild)
embed = discord.Embed(
title="Slash Commands Sync",
description="Slash commands have been synchronized in this guild.",
color=0x9C84EF
)
await context.send(embed=embed)
return
embed = discord.Embed(
title="Invalid Scope",
description="The scope must be `global` or `guild`.",
color=0xE02B2B
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.command(
name="unsync",
description="Unsynchonizes the slash commands.",
)
@app_commands.describe(scope="The scope of the sync. Can be `global`, `current_guild` or `guild`")
@checks.is_owner()
async def unsync(self, context: Context, scope: str) -> None:
if scope == "global":
context.bot.tree.clear_commands(guild=None)
await context.bot.tree.sync()
embed = discord.Embed(
title="Slash Commands Unsync",
description="Slash commands have been globally unsynchronized.",
color=0x9C84EF
)
await context.send(embed=embed)
return
elif scope == "guild":
context.bot.tree.clear_commands(guild=context.guild)
await context.bot.tree.sync(guild=context.guild)
embed = discord.Embed(
title="Slash Commands Unsync",
description="Slash commands have been unsynchronized in this guild.",
color=0x9C84EF
)
await context.send(embed=embed)
return
embed = discord.Embed(
title="Invalid Scope",
description="The scope must be `global` or `guild`.",
color=0xE02B2B
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="load",
description="Load a cog",
)
@app_commands.describe(cog="The name of the cog to load")
@checks.is_owner()
async def load(self, context: Context, cog: str) -> None:
try:
await self.bot.load_extension(f"cogs.{cog}")
except Exception:
embed = discord.Embed(
title="Error!",
description=f"Could not load the `{cog}` cog.",
color=0xE02B2B
)
await context.send(embed=embed)
return
embed = discord.Embed(
title="Load",
description=f"Successfully loaded the `{cog}` cog.",
color=0x9C84EF
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="unload",
description="Unloads a cog.",
)
@app_commands.describe(cog="The name of the cog to unload")
@checks.is_owner()
async def unload(self, context: Context, cog: str) -> None:
try:
await self.bot.unload_extension(f"cogs.{cog}")
except Exception:
embed = discord.Embed(
title="Error!",
description=f"Could not unload the `{cog}` cog.",
color=0xE02B2B
)
await context.send(embed=embed)
return
embed = discord.Embed(
title="Unload",
description=f"Successfully unloaded the `{cog}` cog.",
color=0x9C84EF
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="reload",
description="Reloads a cog.",
)
@app_commands.describe(cog="The name of the cog to reload")
@checks.is_owner()
async def reload(self, context: Context, cog: str) -> None:
try:
await self.bot.reload_extension(f"cogs.{cog}")
except Exception:
embed = discord.Embed(
title="Error!",
description=f"Could not reload the `{cog}` cog.",
color=0xE02B2B
)
await context.send(embed=embed)
return
embed = discord.Embed(
title="Reload",
description=f"Successfully reloaded the `{cog}` cog.",
color=0x9C84EF
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="shutdown",
description="Make the bot shutdown.",
)
@checks.is_owner()
async def shutdown(self, context: Context) -> None:
embed = discord.Embed(
description="Shutting down. Bye! :wave:",
color=0x9C84EF
)
await context.send(embed=embed)
await self.bot.close()
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="say",
description="The bot will say anything you want.",
)
@app_commands.describe(message="The message that should be repeated by the bot")
@checks.is_owner()
async def say(self, context: Context, *, message: str) -> None:
await context.send(message)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="embed",
description="The bot will say anything you want, but within embeds.",
)
@app_commands.describe(message="The message that should be repeated by the bot")
@checks.is_owner()
async def embed(self, context: Context, *, message: str) -> None:
embed = discord.Embed(
description=message,
color=0x9C84EF
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_group(
name="blacklist",
description="Get the list of all blacklisted users.",
)
@checks.is_owner()
async def blacklist(self, context: Context) -> None:
if context.invoked_subcommand is None:
embed = discord.Embed(
title="Blacklist",
description="You need to specify a subcommand.\n\n**Subcommands:**\n`add` - Add a user to the blacklist.\n`remove` - Remove a user from the blacklist.",
color=0xE02B2B
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@blacklist.command(
base="blacklist",
name="show",
description="Shows the list of all blacklisted users.",
)
@checks.is_owner()
async def blacklist_show(self, context: Context) -> None:
blacklisted_users = await db_manager.get_blacklisted_users()
if len(blacklisted_users) == 0:
embed = discord.Embed(
description="There are currently no blacklisted users.",
color=0xE02B2B
)
await context.send(embed=embed)
return
embed = discord.Embed(
title="Blacklisted users",
color=0x9C84EF
)
users = []
for bluser in blacklisted_users:
user = self.bot.get_user(int(bluser[0])) or await self.bot.fetch_user(int(bluser[0]))
users.append(
f"{user.mention} ({user}) - Blacklisted <t:{bluser[1]}>")
embed.description = "\n".join(users)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@blacklist.command(
base="blacklist",
name="add",
description="Lets you add a user from not being able to use the bot.",
)
@app_commands.describe(user="The user that should be added to the blacklist")
@checks.is_owner()
async def blacklist_add(self, context: Context, user: discord.User) -> None:
user_id = user.id
if await db_manager.is_blacklisted(user_id):
embed = discord.Embed(
title="Error!",
description=f"**{user.name}** is already in the blacklist.",
color=0xE02B2B
)
await context.send(embed=embed)
return
total = await db_manager.add_user_to_blacklist(user_id)
embed = discord.Embed(
title="User Blacklisted",
description=f"**{user.name}** has been successfully added to the blacklist",
color=0x9C84EF
)
embed.set_footer(
text=f"There {'is' if total == 1 else 'are'} now {total} {'user' if total == 1 else 'users'} in the blacklist"
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@blacklist.command(
base="blacklist",
name="remove",
description="Lets you remove a user from not being able to use the bot.",
)
@app_commands.describe(user="The user that should be removed from the blacklist.")
@checks.is_owner()
async def blacklist_remove(self, context: Context, user: discord.User) -> None:
user_id = user.id
if not await db_manager.is_blacklisted(user_id):
embed = discord.Embed(
title="Error!",
description=f"**{user.name}** is not in the blacklist.",
color=0xE02B2B
)
await context.send(embed=embed)
return
total = await db_manager.remove_user_from_blacklist(user_id)
embed = discord.Embed(
title="User removed from blacklist",
description=f"**{user.name}** has been successfully removed from the blacklist",
color=0x9C84EF
)
embed.set_footer(
text=f"There {'is' if total == 1 else 'are'} now {total} {'user' if total == 1 else 'users'} in the blacklist"
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
@commands.hybrid_command(
name="leave",
description="Lets you remove a the bot from a server.",
)
@checks.is_owner()
@app_commands.describe(guild_id="Supply a guild ID.")
async def leave(self, context, guild_id, reason: str = "This BOT is not allowed to be on other Guild other that the guild it was made for") -> None:
try:
await self.bot.get_guild(int(guild_id)).leave()
embed = discord.Embed(
title="BOT Removed frome guild",
description=f"I left: {guild_id}",
color=0x9C84EF
)
embed.add_field(
name="Reason:",
value=reason
)
await context.send(embed=embed)
except Exception as e:
embed = discord.Embed(
title="Error!",
description="An error occurred while trying to remove the bot. Make sure GUILD_ID is an existing ID.",
color=0xE02B2B
)
await context.send(embed=embed)
#-------------------------------------------------------------------------------
async def setup(bot):
await bot.add_cog(Owner(bot))

35
cogs/template.py Normal file
View File

@ -0,0 +1,35 @@
from discord.ext import commands
from discord.ext.commands import Context
from helpers import checks
# Here we name the cog and create a new class for the cog.
class Template(commands.Cog, name="template"):
def __init__(self, bot):
self.bot = bot
# Here you can just add your own commands, you'll always need to provide "self" as first parameter.
@commands.hybrid_command(
name="testcommand",
description="This is a testing command that does nothing.",
)
# This will only allow non-blacklisted members to execute the command
@checks.not_blacklisted()
# This will only allow owners of the bot to execute the command -> config.json
@checks.is_owner()
async def testcommand(self, context: Context):
"""
This is a testing command that does nothing.
:param context: The application command context.
"""
# Do your stuff here
# Don't forget to remove "pass", I added this just because there's no content in the method.
pass
# And then we finally add the cog to the bot so that it can load, unload, reload and use it's content.
async def setup(bot):
await bot.add_cog(Template(bot))

264
cogs/weather.py Normal file
View File

@ -0,0 +1,264 @@
import asyncio
import html
import json
import random
from time import time
from typing import Annotated, Any, Optional
from zoneinfo import ZoneInfo
import discord
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context
from discord.utils import get
from discord.utils import *
from helpers import checks, db_manager
# This is the Weather module
class Weather(commands.Cog, name="weather"):
def __init__(self, bot):
self.bot = bot
with open("data/weather.json") as f:
self.weather_constants = json.load(f)
@commands.group()
async def weather(self, ctx: commands.Context):
"""Show current weather in given location"""
if ctx.invoked_subcommand is None:
await util.command_group_help(ctx)
else:
ctx.location = await self.bot.db.fetch_value(
"SELECT location_string FROM user_settings WHERE user_id = %s",
ctx.author.id,
)
@weather.command(name="now")
async def weather_now(self, ctx: commands.Context, *, location: Optional[str] = None):
if location is None:
location = ctx.location
if ctx.location is None:
raise exceptions.CommandInfo(
f"Please save your location using `{ctx.prefix}weather save <location...>`"
)
lat, lon, address = await self.geolocate(location)
local_time, country_code = await self.get_country_information(lat, lon)
API_BASE_URL = "https://api.tomorrow.io/v4/timelines"
params = {
"apikey": self.bot.keychain.TOMORROWIO_TOKEN,
"location": f"{lat},{lon}",
"fields": ",".join(
[
"precipitationProbability",
"precipitationType",
"windSpeed",
"windGust",
"windDirection",
"temperature",
"temperatureApparent",
"cloudCover",
"weatherCode",
"humidity",
"temperatureMin",
"temperatureMax",
"sunriseTime",
"sunsetTime",
]
),
"units": "metric",
"timesteps": ",".join(["current", "1d"]),
"endTime": arrow.utcnow().shift(days=+1, minutes=+5).isoformat(),
}
if isinstance(local_time.tzinfo, ZoneInfo):
params["timezone"] = str(local_time.tzinfo)
else:
logger.warning("Arrow object must be constructed with ZoneInfo timezone object")
async with self.bot.session.get(API_BASE_URL, params=params) as response:
if response.status != 200:
logger.error(response.status)
logger.error(response.headers)
logger.error(await response.text())
raise exceptions.CommandError(f"Weather api returned HTTP ERROR {response.status}")
data = await response.json(loads=orjson.loads)
current_data = next(
filter(lambda t: t["timestep"] == "current", data["data"]["timelines"])
)
daily_data = next(filter(lambda t: t["timestep"] == "1d", data["data"]["timelines"]))
values_current = current_data["intervals"][0]["values"]
values_today = daily_data["intervals"][0]["values"]
# values_tomorrow = daily_data["intervals"][1]["values"]
temperature = values_current["temperature"]
temperature_apparent = values_current["temperatureApparent"]
sunrise = arrow.get(values_current["sunriseTime"]).to(local_time.tzinfo).format("HH:mm")
sunset = arrow.get(values_current["sunsetTime"]).to(local_time.tzinfo).format("HH:mm")
icon = self.weather_constants["id_to_icon"][str(values_current["weatherCode"])]
summary = self.weather_constants["id_to_description"][str(values_current["weatherCode"])]
if (
values_today["precipitationType"] != 0
and values_today["precipitationProbability"] != 0
):
precipitation_type = self.weather_constants["precipitation"][
str(values_today["precipitationType"])
]
summary += f", with {values_today['precipitationProbability']}% chance of {precipitation_type}"
content = discord.Embed(color=int("e1e8ed", 16))
content.title = f":flag_{country_code.lower()}: {address}"
content.set_footer(text=f"🕐 Local time {local_time.format('HH:mm')}")
def render(F: bool):
information_rows = [
f":thermometer: Currently **{temp(temperature, F)}**, feels like **{temp(temperature_apparent, F)}**",
f":calendar: Daily low **{temp(values_today['temperatureMin'], F)}**, high **{temp(values_today['temperatureMax'], F)}**",
f":dash: Wind speed **{values_current['windSpeed']} m/s** with gusts of **{values_current['windGust']} m/s**",
f":sunrise: Sunrise at **{sunrise}**, sunset at **{sunset}**",
f":sweat_drops: Air humidity **{values_current['humidity']}%**",
f":map: [See on map](https://www.google.com/maps/search/?api=1&query={lat},{lon})",
]
content.clear_fields().add_field(
name=f"{icon} {summary}",
value="\n".join(information_rows),
)
return content
await WeatherUnitToggler(render, False).run(ctx)
@weather.command(name="forecast")
async def weather_forecast(self, ctx: commands.Context, *, location: Optional[str] = None):
if location is None:
location = ctx.location
if ctx.location is None:
raise exceptions.CommandInfo(
f"Please save your location using `{ctx.prefix}weather save <location...>`"
)
lat, lon, address = await self.geolocate(location)
local_time, country_code = await self.get_country_information(lat, lon)
API_BASE_URL = "https://api.tomorrow.io/v4/timelines"
params = {
"apikey": self.bot.keychain.TOMORROWIO_TOKEN,
"location": f"{lat},{lon}",
"fields": ",".join(
[
"precipitationProbability",
"precipitationType",
"windSpeed",
"windGust",
"windDirection",
"temperature",
"temperatureApparent",
"cloudCover",
"weatherCode",
"humidity",
"temperatureMin",
"temperatureMax",
]
),
"units": "metric",
"timesteps": "1d",
"endTime": arrow.utcnow().shift(days=+7).isoformat(),
}
if isinstance(local_time.tzinfo, ZoneInfo):
params["timezone"] = str(local_time.tzinfo)
else:
logger.warning("Arrow object must be constructed with ZoneInfo timezone object")
async with self.bot.session.get(API_BASE_URL, params=params) as response:
if response.status != 200:
logger.error(response.status)
logger.error(response.headers)
logger.error(await response.text())
raise exceptions.CommandError(f"Weather api returned HTTP ERROR {response.status}")
data = await response.json(loads=orjson.loads)
content = discord.Embed(
title=f":flag_{country_code.lower()}: {address}",
color=int("ffcc4d", 16),
)
def render(F: bool):
days = []
for day in data["data"]["timelines"][0]["intervals"]:
date = arrow.get(day["startTime"]).format("**`ddd`** `D/M`")
values = day["values"]
minTemp = values["temperatureMin"]
maxTemp = values["temperatureMax"]
icon = self.weather_constants["id_to_icon"][str(values["weatherCode"])]
description = self.weather_constants["id_to_description"][
str(values["weatherCode"])
]
days.append(
f"{date} {icon} **{temp(maxTemp, F)}** / **{temp(minTemp, F)}** — {description}"
)
content.description = "\n".join(days)
return content
await WeatherUnitToggler(render, False).run(ctx)
@weather.command(name="save")
async def weather_save(self, ctx: commands.Context, *, location: str):
await self.bot.db.execute(
"""
INSERT INTO user_settings (user_id, location_string)
VALUES (%s, %s)
ON DUPLICATE KEY UPDATE
location_string = VALUES(location_string)
""",
ctx.author.id,
location,
)
return await util.send_success(ctx, f"Saved your location as `{location}`")
async def geolocate(self, location):
GOOGLE_GEOCODING_API_URL = "https://maps.googleapis.com/maps/api/geocode/json"
params = {"address": location, "key": self.bot.keychain.GCS_DEVELOPER_KEY}
async with self.bot.session.get(GOOGLE_GEOCODING_API_URL, params=params) as response:
geocode_data = await response.json(loads=orjson.loads)
try:
geocode_data = geocode_data["results"][0]
except IndexError:
raise exceptions.CommandWarning("Could not find that location!")
formatted_name = geocode_data["formatted_address"]
lat = geocode_data["geometry"]["location"]["lat"]
lon = geocode_data["geometry"]["location"]["lng"]
return lat, lon, formatted_name
async def get_country_information(self, lat, lon):
TIMEZONE_API_URL = "http://api.timezonedb.com/v2.1/get-time-zone"
params = {
"key": self.bot.keychain.TIMEZONEDB_API_KEY,
"format": "json",
"by": "position",
"lat": lat,
"lng": lon,
}
async with self.bot.session.get(TIMEZONE_API_URL, params=params) as response:
data = await response.json(loads=orjson.loads)
country_code = data["countryCode"]
try:
local_time = arrow.now(ZoneInfo(data["zoneName"]))
except ValueError:
# does not have a time zone
# most likely a special place such as antarctica
# use UTC
local_time = arrow.utcnow()
return local_time, country_code
async def setup(bot):
await bot.add_cog(Weather(bot))

13
database/schema.sql Normal file
View File

@ -0,0 +1,13 @@
CREATE TABLE IF NOT EXISTS `blacklist` (
`user_id` varchar(20) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
);
CREATE TABLE IF NOT EXISTS `warns` (
`id` int(11) NOT NULL,
`user_id` varchar(20) NOT NULL,
`server_id` varchar(20) NOT NULL,
`moderator_id` varchar(20) NOT NULL,
`reason` varchar(255) NOT NULL,
`created_at` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP
);

13
exceptions/__init__.py Normal file
View File

@ -0,0 +1,13 @@
from discord.ext import commands
class UserBlacklisted(commands.CheckFailure):
def __init__(self, message="User is blacklisted!"):
self.message = message
super().__init__(self.message)
class UserNotOwner(commands.CheckFailure):
def __init__(self, message="User is not an owner of the bot!"):
self.message = message
super().__init__(self.message)

30
helpers/checks.py Normal file
View File

@ -0,0 +1,30 @@
import json
import os
from typing import Callable, TypeVar
from discord.ext import commands
from exceptions import *
from helpers import db_manager
T = TypeVar("T")
def is_owner() -> Callable[[T], T]:
async def predicate(context: commands.Context) -> bool:
with open(f"{os.path.realpath(os.path.dirname(__file__))}/../config.json") as file:
data = json.load(file)
if context.author.id not in data["owners"]:
raise UserNotOwner
return True
return commands.check(predicate)
def not_blacklisted() -> Callable[[T], T]:
async def predicate(context: commands.Context) -> bool:
if await db_manager.is_blacklisted(context.author.id):
raise UserBlacklisted
return True
return commands.check(predicate)

106
helpers/db_manager.py Normal file
View File

@ -0,0 +1,106 @@
import os
import aiosqlite
DATABASE_PATH = f"{os.path.realpath(os.path.dirname(__file__))}/../database/database.db"
async def get_blacklisted_users() -> list:
"""
This function will return the list of all blacklisted users.
:param user_id: The ID of the user that should be checked.
:return: True if the user is blacklisted, False if not.
"""
async with aiosqlite.connect(DATABASE_PATH) as db:
async with db.execute("SELECT user_id, strftime('%s', created_at) FROM blacklist") as cursor:
result = await cursor.fetchall()
return result
async def is_blacklisted(user_id: int) -> bool:
"""
This function will check if a user is blacklisted.
:param user_id: The ID of the user that should be checked.
:return: True if the user is blacklisted, False if not.
"""
async with aiosqlite.connect(DATABASE_PATH) as db:
async with db.execute("SELECT * FROM blacklist WHERE user_id=?", (user_id,)) as cursor:
result = await cursor.fetchone()
return result is not None
async def add_user_to_blacklist(user_id: int) -> int:
"""
This function will add a user based on its ID in the blacklist.
:param user_id: The ID of the user that should be added into the blacklist.
"""
async with aiosqlite.connect(DATABASE_PATH) as db:
await db.execute("INSERT INTO blacklist(user_id) VALUES (?)", (user_id,))
await db.commit()
rows = await db.execute("SELECT COUNT(*) FROM blacklist")
async with rows as cursor:
result = await cursor.fetchone()
return result[0] if result is not None else 0
async def remove_user_from_blacklist(user_id: int) -> int:
"""
This function will remove a user based on its ID from the blacklist.
:param user_id: The ID of the user that should be removed from the blacklist.
"""
async with aiosqlite.connect(DATABASE_PATH) as db:
await db.execute("DELETE FROM blacklist WHERE user_id=?", (user_id,))
await db.commit()
rows = await db.execute("SELECT COUNT(*) FROM blacklist")
async with rows as cursor:
result = await cursor.fetchone()
return result[0] if result is not None else 0
async def add_warn(user_id: int, server_id: int, moderator_id: int, reason: str) -> int:
"""
This function will add a warn to the database.
:param user_id: The ID of the user that should be warned.
:param reason: The reason why the user should be warned.
"""
async with aiosqlite.connect(DATABASE_PATH) as db:
rows = await db.execute("SELECT id FROM warns WHERE user_id=? AND server_id=? ORDER BY id DESC LIMIT 1", (user_id, server_id,))
async with rows as cursor:
result = await cursor.fetchone()
warn_id = result[0] + 1 if result is not None else 1
await db.execute("INSERT INTO warns(id, user_id, server_id, moderator_id, reason) VALUES (?, ?, ?, ?, ?)", (warn_id, user_id, server_id, moderator_id, reason,))
await db.commit()
return warn_id
async def remove_warn(warn_id: int, user_id: int, server_id: int) -> int:
"""
This function will remove a warn from the database.
:param warn_id: The ID of the warn.
:param user_id: The ID of the user that was warned.
:param server_id: The ID of the server where the user has been warned
"""
async with aiosqlite.connect(DATABASE_PATH) as db:
await db.execute("DELETE FROM warns WHERE id=? AND user_id=? AND server_id=?", (warn_id, user_id, server_id,))
await db.commit()
rows = await db.execute("SELECT COUNT(*) FROM warns WHERE user_id=? AND server_id=?", (user_id, server_id,))
async with rows as cursor:
result = await cursor.fetchone()
return result[0] if result is not None else 0
async def get_warnings(user_id: int, server_id: int) -> list:
"""
This function will get all the warnings of a user.
:param user_id: The ID of the user that should be checked.
:param server_id: The ID of the server that should be checked.
:return: A list of all the warnings of the user.
"""
async with aiosqlite.connect(DATABASE_PATH) as db:
rows = await db.execute("SELECT user_id, server_id, moderator_id, reason, strftime('%s', created_at), id FROM warns WHERE user_id=? AND server_id=?", (user_id, server_id,))
async with rows as cursor:
result = await cursor.fetchall()
result_list = []
for row in result:
result_list.append(row)
return result_list

21
install.py Normal file
View File

@ -0,0 +1,21 @@
import os
os.system("pip3 install asyncio")
os.system("pip3 install aiohttp")
os.system("pip3 install aiosqlite")
os.system("pip3 install discord.py")
os.system("pip3 install discord_webhook")
os.system("pip3 install requests")
os.system("pip3 install nekos.py")
os.system("pip3 install psutil")
os.system("pip3 install pyparsing")
os.system("pip3 install pyquery")
os.system("pip3 install numpy")
os.system("pip3 install igdb_api_python")
os.system("pip3 install geopy")
os.system("pip3 install pyfiglet")
os.system("pip3 install flake8")
exec(open("main.py").read())

4
main.py Normal file
View File

@ -0,0 +1,4 @@
import bot
if __name__ == '__main__':
bot.run_discord_bot()