Compare commits

...

4 Commits

Author SHA1 Message Date
Stijn De Clercq 7ad2bf351e Remove broken libraries & functionality, format slash command usage 2022-02-05 21:24:08 +01:00
Stijn De Clercq 06dc3d3fb9 Create updated leaderboards 2022-02-05 19:36:25 +01:00
Stijn De Clercq 829729c8db Disable IPC 2022-02-05 14:43:19 +01:00
Stijn De Clercq eaed08168c Inspire slash command, defer jpl table 2022-02-05 14:33:11 +01:00
22 changed files with 251 additions and 345 deletions

1
.gitignore vendored
View File

@ -9,3 +9,4 @@ files/ufora_notifications.json
__pycache__ __pycache__
.env .env
/venv/ /venv/
.pytest_cache

View File

@ -1,82 +0,0 @@
from discord.ext import ipc
from functions.database import custom_commands
import json
from quart import Quart, jsonify, request
from quart_cors import cors
from time import time
app = Quart(__name__)
# TODO allow_origin=re.compile(r"http://localhost:.*")
# needs higher Python & Quart version
app = cors(app, allow_origin="*")
app.config.from_object(__name__)
ipc_client = ipc.Client(secret_key="SOME_SECRET_KEY")
@app.route("/ping", methods=["GET"])
async def ping():
"""
Send a ping request, monitors bot latency and endpoint time
"""
latency = await ipc_client.request("get_bot_latency")
return jsonify({"bot_latency": latency, "response_sent": time()})
@app.route("/dm", methods=["POST"])
async def send_dm():
"""
Send a DM to the given user
"""
data = json.loads((await request.body).decode('UTF-8'))
dm = await ipc_client.request(
"send_dm",
user=int(data["userid"]),
message=data.get("message")
)
return jsonify({"response": dm})
@app.route("/custom", methods=["GET"])
async def get_all_custom_commands():
"""
Return a list of all custom commands in the bot
"""
commands = custom_commands.get_all()
return jsonify(commands)
@app.route("/custom/<command_id>")
async def get_custom_command(command_id):
try:
command_id = int(command_id)
except ValueError:
# Id is not an int
return unprocessable_entity("Parameter id was not a valid integer.")
command = custom_commands.get_by_id(command_id)
if command is None:
return page_not_found("")
return jsonify(command)
@app.errorhandler(404)
def page_not_found(e):
return jsonify({"error": "No resource could be found matching the given URL."}), 404
@app.errorhandler(422)
def unprocessable_entity(e):
return jsonify({"error": e}), 422
if __name__ == "__main__":
app.run()

View File

@ -1,11 +1,10 @@
from dislash import SlashInteraction from discord import Interaction
from data import constants from data import constants
from data.snipe import Snipe, Action, should_snipe from data.snipe import Snipe, Action, should_snipe
import datetime import datetime
import discord import discord
from discord.ext import commands from discord.ext import commands
from dislash.application_commands.errors import InteractionCheckFailure
from functions import checks, easterEggResponses, stringFormatters from functions import checks, easterEggResponses, stringFormatters
from functions.database import stats, muttn, custom_commands, commands as command_stats from functions.database import stats, muttn, custom_commands, commands as command_stats
import pytz import pytz
@ -86,6 +85,7 @@ class Events(commands.Cog):
Logs commands in your terminal. Logs commands in your terminal.
:param ctx: Discord Context :param ctx: Discord Context
""" """
print("a")
print(stringFormatters.format_command_usage(ctx)) print(stringFormatters.format_command_usage(ctx))
command_stats.invoked(command_stats.InvocationType.TextCommand) command_stats.invoked(command_stats.InvocationType.TextCommand)
@ -123,24 +123,27 @@ class Events(commands.Cog):
await self.sendErrorEmbed(err, "Command", usage) await self.sendErrorEmbed(err, "Command", usage)
@commands.Cog.listener() @commands.Cog.listener()
async def on_slash_command(self, interaction: SlashInteraction): async def on_interaction(self, interaction: Interaction):
""" """
Function called whenever someone uses a slash command Function called whenever someone uses a slash command
""" """
if not interaction.is_command():
return
print(stringFormatters.format_slash_command_usage(interaction)) print(stringFormatters.format_slash_command_usage(interaction))
command_stats.invoked(command_stats.InvocationType.SlashCommand) command_stats.invoked(command_stats.InvocationType.SlashCommand)
@commands.Cog.listener() @commands.Cog.listener()
async def on_slash_command_error(self, interaction, err): async def on_application_command_error(self, ctx: discord.ApplicationContext, err):
# Debugging Didier shouldn't spam the error logs # Debugging Didier shouldn't spam the error logs
if self.client.user.id != int(constants.didierId): if self.client.user.id != int(constants.didierId):
raise err raise err
if isinstance(err, InteractionCheckFailure): if isinstance(err, commands.CheckFailure):
return await interaction.reply("Je hebt geen toegang tot dit commando.", ephemeral=True) return await ctx.respond("Je hebt geen toegang tot dit commando.", ephemeral=True)
usage = stringFormatters.format_slash_command_usage(interaction) usage = stringFormatters.format_slash_command_usage(ctx.interaction)
await self.sendErrorEmbed(err, "Slash Command", usage) await self.sendErrorEmbed(err, "Slash Command", usage)
@commands.Cog.listener() @commands.Cog.listener()

View File

@ -1,5 +1,5 @@
from data.embeds.xkcd import XKCDEmbed from data.embeds.xkcd import XKCDEmbed
from data.menus import paginatedLeaderboard from data.menus import paginated_leaderboard
from decorators import help from decorators import help
import discord import discord
from discord.ext import commands from discord.ext import commands
@ -124,8 +124,9 @@ class Fun(commands.Cog):
memeList = [": ".join([stringFormatters.title_case(meme[1]), memeList = [": ".join([stringFormatters.title_case(meme[1]),
str(meme[2])]) for meme in sorted(memeList, key=lambda x: x[1])] str(meme[2])]) for meme in sorted(memeList, key=lambda x: x[1])]
pages = paginatedLeaderboard.Pages(source=paginatedLeaderboard.Source(memeList, "Memes", discord.Colour.blue()), pages = paginated_leaderboard.Pages(
clear_reactions_after=True) source=paginated_leaderboard.Source(memeList, "Memes", discord.Colour.blue()),
clear_reactions_after=True)
await pages.start(ctx) await pages.start(ctx)
@commands.command(name="Pjoke") @commands.command(name="Pjoke")

View File

@ -1,26 +0,0 @@
from discord.ext import commands, ipc
class IPC(commands.Cog):
def __init__(self, client):
self.client = client
@ipc.server.route()
async def send_dm(self, data):
print("got here")
user = self.client.get_user(data.user)
await user.send(data.message)
print("sent")
return True
@ipc.server.route()
async def get_bot_latency(self, data):
"""
Get Didier's latency
"""
return self.client.latency * 1000
def setup(client):
client.add_cog(IPC(client))

View File

@ -1,4 +1,4 @@
from data.menus import paginatedLeaderboard from data.menus import paginated_leaderboard
from decorators import help from decorators import help
import discord import discord
from discord.ext import commands from discord.ext import commands
@ -45,35 +45,36 @@ class Leaderboards(commands.Cog):
user[1] += platDinks[str(user[0])] * Numbers.q.value user[1] += platDinks[str(user[0])] * Numbers.q.value
entries[i] = user entries[i] = user
boardTop = [] data = []
for i, user in enumerate(sorted(entries, key=lambda x: (float(x[1]) + float(x[3])), reverse=True)): for i, user in enumerate(sorted(entries, key=lambda x: (float(x[1]) + float(x[3])), reverse=True)):
if i == 0 and float(user[1]) + float(user[3]) == 0.0: if i == 0 and float(user[1]) + float(user[3]) == 0.0:
return await self.emptyLeaderboard(ctx, "Dinks Leaderboard", "Er zijn nog geen personen met Didier Dinks.") return await self.empty_leaderboard(ctx, "Dinks Leaderboard",
"Er zijn nog geen personen met Didier Dinks.")
elif float(user[1]) + float(user[3]) > 0.0: elif float(user[1]) + float(user[3]) > 0.0:
total_dinks = math.floor(float(user[1]) + float(user[3]))
data.append((user[0], total_dinks,))
# Get the username in this guild lb = paginated_leaderboard.Leaderboard(
name = self.utilsCog.getDisplayName(ctx, user[0]) ctx=ctx, title="Dinks Leaderboard", data=data, fetch_names=True
)
if int(user[0]) == int(ctx.author.id): await lb.send(ctx)
boardTop.append("**{} ({:,})**".format(name, math.floor(float(user[1]) + float(user[3]))))
else:
boardTop.append("{} ({:,})".format(name, math.floor(float(user[1]) + float(user[3]))))
await self.startPaginated(ctx, boardTop, "Dinks Leaderboard")
@leaderboard.command(name="Corona", hidden=True) @leaderboard.command(name="Corona", hidden=True)
async def corona(self, ctx): async def corona(self, ctx):
result = requests.get("http://corona.lmao.ninja/v2/countries").json() result = requests.get("https://disease.sh/v3/covid-19/countries").json()
result.sort(key=lambda x: int(x["cases"]), reverse=True) result.sort(key=lambda x: int(x["cases"]), reverse=True)
board = []
for land in result:
if land["country"] == "Belgium": data = []
board.append("**{} ({:,})**".format(land["country"], land["cases"])) for country in result:
else: data.append((country["country"], f"{country['cases']:,}",))
board.append("{} ({:,})".format(land["country"], land["cases"]))
await self.startPaginated(ctx, board, "Corona Leaderboard", discord.Colour.red()) lb = paginated_leaderboard.Leaderboard(
ctx=ctx, title="Corona Leaderboard", data=data, highlight="Belgium",
colour=discord.Colour.red()
)
await lb.send(ctx)
@leaderboard.command(name="Bitcoin", aliases=["Bc"], hidden=True) @leaderboard.command(name="Bitcoin", aliases=["Bc"], hidden=True)
async def bitcoin(self, ctx): async def bitcoin(self, ctx):
@ -82,7 +83,8 @@ class Leaderboards(commands.Cog):
for i, user in enumerate(sorted(users, key=lambda x: x[8], reverse=True)): for i, user in enumerate(sorted(users, key=lambda x: x[8], reverse=True)):
# Don't create an empty leaderboard # Don't create an empty leaderboard
if i == 0 and float(user[8]) == 0.0: if i == 0 and float(user[8]) == 0.0:
return await self.emptyLeaderboard(ctx, "Bitcoin Leaderboard", "Er zijn nog geen personen met Bitcoins.") return await self.empty_leaderboard(ctx, "Bitcoin Leaderboard",
"Er zijn nog geen personen met Bitcoins.")
elif float(user[8]) > 0.0: elif float(user[8]) > 0.0:
# Only add people with more than 0 # Only add people with more than 0
# Get the username in this guild # Get the username in this guild
@ -101,7 +103,8 @@ class Leaderboards(commands.Cog):
for i, user in enumerate(sorted(users, key=lambda x: x[4], reverse=True)): for i, user in enumerate(sorted(users, key=lambda x: x[4], reverse=True)):
# Don't create an empty leaderboard # Don't create an empty leaderboard
if i == 0 and float(user[4]) == 0.0: if i == 0 and float(user[4]) == 0.0:
return await self.emptyLeaderboard(ctx, "Rob Leaderboard", "Er heeft nog niemand Didier Dinks gestolen.") return await self.empty_leaderboard(ctx, "Rob Leaderboard",
"Er heeft nog niemand Didier Dinks gestolen.")
elif float(user[4]) > 0.0: elif float(user[4]) > 0.0:
# Only add people with more than 0 # Only add people with more than 0
# Get the username in this guild # Get the username in this guild
@ -119,7 +122,7 @@ class Leaderboards(commands.Cog):
boardTop = [] boardTop = []
for i, user in enumerate(sorted(s, key=lambda x: x[1], reverse=True)): for i, user in enumerate(sorted(s, key=lambda x: x[1], reverse=True)):
if i == 0 and int(user[1]) == 0: if i == 0 and int(user[1]) == 0:
return await self.emptyLeaderboard(ctx, "Poke Leaderboard", "Er is nog niemand getikt.") return await self.empty_leaderboard(ctx, "Poke Leaderboard", "Er is nog niemand getikt.")
elif int(user[1]) == 0: elif int(user[1]) == 0:
break break
@ -177,7 +180,7 @@ class Leaderboards(commands.Cog):
boardTop = [] boardTop = []
for i, user in enumerate(sorted(users, key=lambda x: x[1], reverse=True)): for i, user in enumerate(sorted(users, key=lambda x: x[1], reverse=True)):
if i == 0 and int(user[1]) == 0: if i == 0 and int(user[1]) == 0:
return await self.emptyLeaderboard(ctx, "Muttn Leaderboard", "Der zittn nog geen muttns in de server.") return await self.empty_leaderboard(ctx, "Muttn Leaderboard", "Der zittn nog geen muttns in de server.")
if float(user[1]) == 0: if float(user[1]) == 0:
break break
@ -190,14 +193,15 @@ class Leaderboards(commands.Cog):
await self.startPaginated(ctx, boardTop, "Muttn Leaderboard") await self.startPaginated(ctx, boardTop, "Muttn Leaderboard")
async def callLeaderboard(self, name, ctx): async def callLeaderboard(self, name, ctx):
await [command for command in self.leaderboard.commands if command.name.lower() == name.lower()][0](ctx) command = [command for command in self.leaderboard.commands if command.name.lower() == name.lower()][0]
await command(ctx)
async def startPaginated(self, ctx, source, name, colour=discord.Colour.blue()): async def startPaginated(self, ctx, source, name, colour=discord.Colour.blue()):
pages = paginatedLeaderboard.Pages(source=paginatedLeaderboard.Source(source, name, colour), pages = paginated_leaderboard.Pages(source=paginated_leaderboard.Source(source, name, colour),
clear_reactions_after=True) clear_reactions_after=True)
await pages.start(ctx) await pages.start(ctx)
async def emptyLeaderboard(self, ctx, name, message, colour=discord.Colour.blue()): async def empty_leaderboard(self, ctx, name, message, colour=discord.Colour.blue()):
embed = discord.Embed(colour=colour) embed = discord.Embed(colour=colour)
embed.set_author(name=name) embed.set_author(name=name)
embed.description = message embed.description = message

View File

@ -151,7 +151,7 @@ class Oneliners(commands.Cog):
@commands.command(name="Inspire") @commands.command(name="Inspire")
@help.Category(Category.Other) @help.Category(Category.Other)
async def inspire(self, ctx): async def inspire(self, ctx):
image = get("http://inspirobot.me/api?generate=true") image = get("https://inspirobot.me/api?generate=true")
if image.status_code == 200: if image.status_code == 200:
await ctx.send(image.text) await ctx.send(image.text)

View File

@ -1,88 +0,0 @@
import datetime
import json
from discord.ext import commands
from dislash import SlashInteraction, slash_command, Option, OptionType, check
from functions.checks import isMe
from functions.timeFormatters import fromString
from startup.didier import Didier
class DBSlash(commands.Cog):
def __init__(self, client: Didier):
self.client: Didier = client
@slash_command(name="db")
@check(isMe)
async def _db_slash(self, interaction: SlashInteraction):
pass
@_db_slash.sub_command_group(name="add")
async def _add_slash(self, interaction: SlashInteraction):
pass
@_add_slash.sub_command(
name="deadline",
options=[
Option(
"year",
description="Year (1-based)",
type=OptionType.INTEGER,
required=True
),
Option(
"course",
description="Course (abbreviated)",
type=OptionType.STRING,
required=True
),
Option(
"name",
description="Name of the deadline/project",
type=OptionType.STRING,
required=True
),
Option(
"date",
description="Date (DD/MM)",
type=OptionType.STRING,
required=True
),
Option(
"time",
description="Timestamp (HH:MM or HH:MM:SS)",
type=OptionType.STRING,
required=False
)
]
)
async def _add_deadline_slash(self, interaction: SlashInteraction, year: int, course: str, name: str, date: str, time: str = "00:00:00"):
with open("files/deadlines.json", "r") as f:
deadlines = json.load(f)
date += "/" + str(datetime.datetime.now().year)
# Fix format
if time.count(":") == 1:
time += ":00"
dt = fromString(f"{date} {time}", formatString="%d/%m/%Y %H:%M:%S", tzinfo=None)
# Add year & course if necessary
if str(year) not in deadlines:
deadlines[str(year)] = {}
if course not in deadlines[str(year)]:
deadlines[str(year)][course] = {}
deadlines[str(year)][course][name] = round(dt.timestamp())
with open("files/deadlines.json", "w") as f:
json.dump(deadlines, f)
await interaction.reply("Addition successful", ephemeral=True)
def setup(client: Didier):
# client.add_cog(DBSlash(client))
pass

View File

@ -23,6 +23,7 @@ class FootballSlash(commands.Cog):
@_jpl_group.command(name="table", description="Huidige rangschikking") @_jpl_group.command(name="table", description="Huidige rangschikking")
async def _jpl_table_slash(self, ctx: ApplicationContext): async def _jpl_table_slash(self, ctx: ApplicationContext):
await ctx.response.defer()
await ctx.respond(get_table()) await ctx.respond(get_table())
@_jpl_group.command(name="update", description="Update de code voor deze competitie (owner-only)", default_permission=False) @_jpl_group.command(name="update", description="Update de code voor deze competitie (owner-only)", default_permission=False)

View File

@ -0,0 +1,23 @@
from discord.ext import commands
from discord.commands import slash_command, ApplicationContext
from requests import get
from startup.didier import Didier
class OtherSlash(commands.Cog):
def __init__(self, client: Didier):
self.client: Didier = client
@slash_command(name="inspire", description="Genereer quotes via Inspirobot.")
async def _inspire_slash(self, ctx: ApplicationContext):
image = get("https://inspirobot.me/api?generate=true")
if image.status_code == 200:
await ctx.respond(image.text)
else:
await ctx.respond("Uh oh API down.")
def setup(client: Didier):
client.add_cog(OtherSlash(client))

View File

@ -1,5 +1,4 @@
from converters.numbers import Abbreviated from converters.numbers import Abbreviated
from data.menus import storePages
from decorators import help from decorators import help
import discord import discord
from discord.ext import commands from discord.ext import commands
@ -22,11 +21,12 @@ class Store(commands.Cog):
@commands.check(checks.allowedChannels) @commands.check(checks.allowedChannels)
@help.Category(Category.Currency) @help.Category(Category.Currency)
async def store(self, ctx): async def store(self, ctx):
entries = store.getAllItems() pass
await storePages.Pages(source=storePages.Source(entries), clear_reactions_after=True).start(ctx) # entries = store.getAllItems()
# await storePages.Pages(source=storePages.Source(entries), clear_reactions_after=True).start(ctx)
@store.command(name="Buy", aliases=["Get"], hidden=True) @store.command(name="Buy", aliases=["Get"], hidden=True)
async def storeBuy(self, ctx, item, amount: Abbreviated = 1): async def store_buy(self, ctx, item, amount: Abbreviated = 1):
if amount is None: if amount is None:
return return
@ -56,7 +56,7 @@ class Store(commands.Cog):
)) ))
@store.command(name="Sell", hidden=True) @store.command(name="Sell", hidden=True)
async def storeSell(self, ctx, itemid, amount: Abbreviated = 1): async def store_sell(self, ctx, itemid, amount: Abbreviated = 1):
if amount is None: if amount is None:
return return
await self.sell(ctx, itemid, amount) await self.sell(ctx, itemid, amount)

View File

@ -1,4 +1,4 @@
from data.menus import paginatedLeaderboard from data.menus import paginated_leaderboard
from decorators import help from decorators import help
import discord import discord
from discord.ext import commands, menus from discord.ext import commands, menus
@ -36,10 +36,10 @@ class Train(commands.Cog):
await self.sendEmbed(ctx, embed) await self.sendEmbed(ctx, embed)
return return
pages = paginatedLeaderboard.Pages(source=TrainPagination(self.formatConnections(req["connection"]), pages = paginated_leaderboard.Pages(source=TrainPagination(self.formatConnections(req["connection"]),
self.formatCity(departure), self.formatCity(departure),
self.formatCity(destination)), self.formatCity(destination)),
clear_reactions_after=True) clear_reactions_after=True)
await pages.start(ctx) await pages.start(ctx)
def formatConnections(self, connections): def formatConnections(self, connections):

View File

@ -1,31 +0,0 @@
import discord
from discord.ext import menus
# https://github.com/Rapptz/discord-ext-menus
class Source(menus.ListPageSource):
def __init__(self, data, name, colour=discord.Colour.blue()):
super().__init__(data, per_page=10)
self.name = name
self.colour = colour
async def format_page(self, menu: menus.MenuPages, entries):
offset = menu.current_page * self.per_page
description = ""
for i, v in enumerate(entries, start=offset):
# Check if the person's name has to be highlighted
if v.startswith("**") and v.endswith("**"):
description += "**"
v = v[2:]
description += "{}: {}\n".format(i + 1, v)
embed = discord.Embed(colour=self.colour)
embed.set_author(name=self.name)
embed.description = description
embed.set_footer(text="{}/{}".format(menu.current_page + 1, self.get_max_pages()))
return embed
class Pages(menus.MenuPages):
def __init__(self, source, clear_reactions_after, timeout=30.0):
super().__init__(source, timeout=timeout, delete_message_after=True, clear_reactions_after=clear_reactions_after)

View File

@ -0,0 +1,127 @@
from typing import Callable
import discord
from discord import ApplicationContext
from discord.ext import menus, pages
from dataclasses import dataclass
from discord.ext.commands import Context
from functions.utils import get_display_name
@dataclass
class Leaderboard:
ctx: Context
title: str
data: list
highlight: str = None
format_f: Callable = None
per_page: int = 10
colour: discord.Colour = discord.Colour.blue()
fetch_names: bool = False
def __post_init__(self):
if self.format_f is None:
self.format_f = self._format
def _should_highlight(self, data) -> bool:
"""Check if an entry should be highlighted"""
if self.fetch_names:
return data == self.ctx.author.id
return data == self.highlight
def _format(self, index: int, data: tuple) -> str:
name = data[0]
if self.fetch_names:
name = get_display_name(self.ctx, int(data[0]))
s = f"{index + 1}: {name} ({data[1]})"
return s
def _get_page_count(self) -> int:
"""Get the amount of pages required to represent this data"""
count = len(self.data) // self.per_page
if len(self.data) % self.per_page != 0:
count += 1
return count
def _create_embed(self, description: str) -> discord.Embed:
embed = discord.Embed(colour=self.colour)
embed.set_author(name=self.title)
embed.description = description
return embed
def create_pages(self) -> list[discord.Embed]:
# Amount of entries added to this page
added = 0
page_list = []
description = ""
for i, v in enumerate(self.data):
s = self.format_f(i, v)
if self._should_highlight(v[0]):
s = f"**{s}**"
description += s + "\n"
added += 1
# Page full, create an embed & change counters
if added == self.per_page:
embed = self._create_embed(description)
description = ""
added = 0
page_list.append(embed)
# Add final embed
if added != 0:
embed = self._create_embed(description)
page_list.append(embed)
return page_list
def create_paginator(self) -> pages.Paginator:
return pages.Paginator(pages=self.create_pages(), show_disabled=False, disable_on_timeout=True, timeout=30)
async def respond(self, ctx: ApplicationContext, **kwargs) -> discord.Message:
paginator = self.create_paginator()
return await paginator.respond(ctx.interaction, **kwargs)
async def send(self, ctx: Context, **kwargs) -> discord.Message:
paginator = self.create_paginator()
return await paginator.send(ctx, **kwargs)
class Source(menus.ListPageSource):
def __init__(self, data, name, colour=discord.Colour.blue()):
super().__init__(data, per_page=10)
self.name = name
self.colour = colour
async def format_page(self, menu: menus.MenuPages, entries):
offset = menu.current_page * self.per_page
description = ""
for i, v in enumerate(entries, start=offset):
# Check if the person's name has to be highlighted
if v.startswith("**") and v.endswith("**"):
description += "**"
v = v[2:]
description += "{}: {}\n".format(i + 1, v)
embed = discord.Embed(colour=self.colour)
embed.set_author(name=self.name)
embed.description = description
embed.set_footer(text="{}/{}".format(menu.current_page + 1, self.get_max_pages()))
return embed
class Pages(menus.MenuPages):
def __init__(self, source, clear_reactions_after, timeout=30.0):
super().__init__(source, timeout=timeout, delete_message_after=True, clear_reactions_after=clear_reactions_after)

View File

@ -1,28 +0,0 @@
import discord
from discord.ext import menus
# https://github.com/Rapptz/discord-ext-menus
class Source(menus.ListPageSource):
def __init__(self, data):
super().__init__(data, per_page=10)
self.name = "Didier Store"
self.colour = discord.Colour.blue()
async def format_page(self, menu: menus.MenuPages, entries):
offset = menu.current_page * self.per_page
embed = discord.Embed(colour=self.colour)
embed.set_author(name=self.name)
embed.description = "Heb je een idee voor een item? DM DJ STIJN met je idee!"
embed.set_footer(text="{}/{}".format(menu.current_page + 1, self.get_max_pages()))
for i, v in enumerate(entries, start=offset):
embed.add_field(name="#{} - {}".format(v[0], v[1]), value="{:,} Didier Dinks".format(v[2]))
return embed
class Pages(menus.MenuPages):
def __init__(self, source, clear_reactions_after, timeout=30.0):
super().__init__(source, timeout=timeout, delete_message_after=True, clear_reactions_after=clear_reactions_after)

View File

@ -1,12 +1,9 @@
import discord import discord
from dotenv import load_dotenv
from functions.prefixes import get_prefix from functions.prefixes import get_prefix
from settings import STATUS_MESSAGE, TOKEN from settings import STATUS_MESSAGE, TOKEN
from startup.didier import Didier from startup.didier import Didier
if __name__ == "__main__": if __name__ == "__main__":
load_dotenv(verbose=True)
# Activities # Activities
activity = discord.Activity(type=discord.ActivityType.playing, name=STATUS_MESSAGE) activity = discord.Activity(type=discord.ActivityType.playing, name=STATUS_MESSAGE)
status = discord.Status.online status = discord.Status.online
@ -16,9 +13,4 @@ if __name__ == "__main__":
intents.members = True intents.members = True
client = Didier(command_prefix=get_prefix, case_insensitive=True, intents=intents, activity=activity, status=status) client = Didier(command_prefix=get_prefix, case_insensitive=True, intents=intents, activity=activity, status=status)
# Run IPC server if necessary
if client.ipc is not None:
client.ipc.start()
client.run(TOKEN) client.run(TOKEN)

View File

@ -52,7 +52,7 @@
"hangman start": "Start een nieuwe Hangman game indien er nog geen bezig is. Indien je geen woord opgeeft, wordt er een willekeurig woord gekozen.\n**Indien je wel een woord opgeeft, werkt dit enkel in DM.**", "hangman start": "Start een nieuwe Hangman game indien er nog geen bezig is. Indien je geen woord opgeeft, wordt er een willekeurig woord gekozen.\n**Indien je wel een woord opgeeft, werkt dit enkel in DM.**",
"hangman guess": "Probeer het woord te raden.", "hangman guess": "Probeer het woord te raden.",
"claim": "Claim [Aantal] Didier Dinks uit je profit.\nIndien je geen aantal opgeeft (of \"all\"), claim je alles, inclusief je investering.", "claim": "Claim [Aantal] Didier Dinks uit je profit.\nIndien je geen aantal opgeeft (of \"all\"), claim je alles, inclusief je investering.",
"inspire": "Generate quotes via [InspiroBot](https://inspirobot.me/).", "inspire": "Genereer quotes via [InspiroBot](https://inspirobot.me/).",
"inventory": "Bekijk de items in jouw inventory.", "inventory": "Bekijk de items in jouw inventory.",
"invest": "Investeer [Aantal] Didier Dinks in jouw Didier Bank om rente te vergaren.", "invest": "Investeer [Aantal] Didier Dinks in jouw Didier Bank om rente te vergaren.",
"jpl": "Informatie over de Jupiler Pro League.", "jpl": "Informatie over de Jupiler Pro League.",

View File

@ -1,7 +1,7 @@
import traceback import traceback
from discord import Interaction
from discord.ext.commands import Context from discord.ext.commands import Context
from dislash import SlashInteraction
def title_case(string): def title_case(string):
@ -42,16 +42,15 @@ def format_command_usage(ctx: Context) -> str:
return f"{ctx.author.display_name} in {_format_error_location(ctx)}: {ctx.message.content}" return f"{ctx.author.display_name} in {_format_error_location(ctx)}: {ctx.message.content}"
def format_slash_command_usage(interaction: SlashInteraction) -> str: def format_slash_command_usage(interaction: Interaction) -> str:
# Create a string with the options used # Create a string with the options used
# TODO look into the format used by the lib because it's terrible
options = " ".join(list(map( options = " ".join(list(map(
lambda option: f"{option.name}: \"{option.value}\"", lambda o: f"{o['name']}: \"{o['value']}\"",
interaction.data.options.values() interaction.data.get("options", [])
))) )))
command = f"{interaction.slash_command.name} {options or ''}" command = f"{interaction.data['name']} {options or ''}"
return f"{interaction.author.display_name} in {_format_error_location(interaction)}: /{command}" return f"{interaction.user.display_name} in {_format_error_location(interaction)}: /{command}"
def get_edu_year(index: int) -> str: def get_edu_year(index: int) -> str:

33
functions/utils.py 100644
View File

@ -0,0 +1,33 @@
from typing import Union
from discord import ApplicationContext
from discord.ext.commands import Context
from data import constants
def get_display_name(ctx: Union[ApplicationContext, Context], user_id: int) -> str:
author = ctx.author if isinstance(ctx, Context) else ctx.user
# Check if this is a DM, or the user is not in the guild
if ctx.guild is None or ctx.guild.get_member(user_id) is None:
# User is the author, no need to fetch their name
if user_id == author.id:
return author.display_name
# Get member instance from CoC
COC = ctx.bot.get_guild(int(constants.DeZandbak))
member = COC.get_member(user_id)
if member is not None:
return member.display_name
# Try to fetch the user
user = ctx.bot.get_user(user_id)
if user is not None:
return user.name
# User couldn't be found
return f"[? | {user_id}]"
mem = ctx.guild.get_member(user_id)
return mem.display_name

View File

@ -3,9 +3,6 @@ py-cord==2.0.0b1
python-dotenv==0.14.0 python-dotenv==0.14.0
beautifulsoup4==4.9.1 beautifulsoup4==4.9.1
# discord.py==1.7.3
git+https://github.com/Rapptz/discord-ext-menus@master
discord-ext-ipc==2.0.0
psycopg2==2.8.5 psycopg2==2.8.5
psycopg2-binary==2.8.5 psycopg2-binary==2.8.5
python-dateutil==2.6.1 python-dateutil==2.6.1
@ -16,8 +13,6 @@ tabulate==0.8.7
yarl==1.4.2 yarl==1.4.2
feedparser==6.0.2 feedparser==6.0.2
googletrans==4.0.0rc1 googletrans==4.0.0rc1
quart==0.15.1
Quart-CORS==0.5.0
attrs~=21.2.0 attrs~=21.2.0
dacite~=1.6.0 dacite~=1.6.0
pytest==6.2.4 pytest==6.2.4

View File

@ -4,7 +4,7 @@ from dotenv import load_dotenv
import os import os
load_dotenv() load_dotenv(verbose=True)
def _to_bool(value: str) -> bool: def _to_bool(value: str) -> bool:
@ -31,7 +31,6 @@ DB_NAME = os.getenv("DBNAME", "")
# Discord-related # Discord-related
TOKEN = os.getenv("TOKEN", "") TOKEN = os.getenv("TOKEN", "")
HOST_IPC = _to_bool(os.getenv("HOSTIPC", "false"))
READY_MESSAGE = os.getenv("READYMESSAGE", "I'M READY I'M READY I'M READY I'M READY") # Yes, this is a Spongebob reference READY_MESSAGE = os.getenv("READYMESSAGE", "I'M READY I'M READY I'M READY I'M READY") # Yes, this is a Spongebob reference
STATUS_MESSAGE = os.getenv("STATUSMESSAGE", "with your Didier Dinks.") STATUS_MESSAGE = os.getenv("STATUSMESSAGE", "with your Didier Dinks.")

View File

@ -1,8 +1,6 @@
from data.snipe import Snipe from data.snipe import Snipe
from discord.ext import commands, ipc from discord.ext import commands
from dislash import InteractionClient
import os import os
from settings import HOST_IPC
from startup.init_files import check_all from startup.init_files import check_all
from typing import Dict from typing import Dict
@ -11,23 +9,14 @@ class Didier(commands.Bot):
""" """
Main Bot class for Didier Main Bot class for Didier
""" """
# Reference to interactions client
interactions: InteractionClient
# Dict to store the most recent Snipe info per channel # Dict to store the most recent Snipe info per channel
snipe: Dict[int, Snipe] = {} snipe: Dict[int, Snipe] = {}
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self._host_ipc = HOST_IPC
# IPC Server
# TODO secret key
self.ipc = ipc.Server(self, secret_key="SOME_SECRET_KEY") if self._host_ipc else None
# Cogs that should be loaded before the others # Cogs that should be loaded before the others
self._preload = ("ipc", "utils", "failedchecks", "events",) self._preload = ("utils", "failedchecks", "events",)
# Remove default help command # Remove default help command
self.remove_command("help") self.remove_command("help")
@ -62,9 +51,3 @@ class Didier(commands.Bot):
# Subdirectory # Subdirectory
# Also walrus operator hype # Also walrus operator hype
self._init_directory(new_path) self._init_directory(new_path)
async def on_ipc_ready(self):
print("IPC server is ready.")
async def on_ipc_error(self, endpoint, error):
print(endpoint, "raised", error)