Skip to content

Commit

Permalink
ported to docker container
Browse files Browse the repository at this point in the history
  • Loading branch information
N00bcak committed Dec 27, 2023
1 parent 2a70e70 commit b4fd9c3
Show file tree
Hide file tree
Showing 8 changed files with 103 additions and 61 deletions.
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,5 @@ private_utils.py
__pycache__/
storage.db
.git
NotABot_log.txt
NotABot_log.txt
[dD]ocker*
15 changes: 7 additions & 8 deletions NotABot/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,19 @@
async def on_message(message):
#flag = await private_utils.func1(message)
pass

@bot.event
async def on_raw_message_edit(payload):
#flag = await private_utils.func2(payload)
pass

@bot.event
async def on_raw_reaction_add(payload):
#flag = await private_utils.func3(payload)
if not flag:
# The emoji checks are done here, so the functions themselves don't need to ascertain the identity of the emoji.
if payload.emoji.name in cfg.PIN_MSGS_CFG["emoji_list"]:
await pin_msgs.pin(payload)
elif payload.emoji.name in cfg.STARBOARD_CFG["emoji_list"]:
await starboard.check_sb(payload)
#if not flag:
# The emoji checks are done here, so the functions themselves don't need to ascertain the identity of the emoji.
if payload.emoji.name in cfg.PIN_MSGS_CFG["emoji_list"]:
await pin_msgs.pin(payload)
elif payload.emoji.name in cfg.STARBOARD_CFG["emoji_list"]:
await starboard.check_sb(payload)

@bot.event
async def on_raw_reaction_remove(payload):
Expand All @@ -39,6 +37,7 @@ async def on_ready():
#print(bot.commands)
guild, guild_channel_list = await general_utils.init_guild_variables()
log.info(f"We in the {guild.name} server.")

await meetups_handler.refresh_meetups()
await birthday_handler.birthday_loop()

Expand Down
7 changes: 7 additions & 0 deletions NotABot/common/general_utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,3 +31,10 @@ def get_db():

bot_db.commit()
return bot_db, cur

# Get only the alphanumeric characters of a string.
def get_alphanumeric_characters(s: str):
s1 = ""
for c in s:
if c.isalnum(): s1 = s1 + c
return s1
8 changes: 4 additions & 4 deletions NotABot/minigames/blackjack.py
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ def cleanup(self, author: str):
temp_memory.pop(author)

# "Hit" button
@discord.ui.button(label = "Hit", style = discord.ButtonStyle.primary)
@discord.ui.button(label = "Hit", style = discord.ButtonStyle.primary, custom_id = 'bjview:hit')
async def hit_button_callback(self, button, interaction):
ctx = await bot.get_application_context(interaction)
bj_model = await self.retrieve_game_data(ctx)
Expand All @@ -46,7 +46,7 @@ async def hit_button_callback(self, button, interaction):
await ctx.response.defer()

# "Stand" button
@discord.ui.button(label = "Stand", style = discord.ButtonStyle.primary)
@discord.ui.button(label = "Stand", style = discord.ButtonStyle.primary, custom_id = 'bjview:stand')
async def stand_button_callback(self, button, interaction):
ctx = await bot.get_application_context(interaction)
bj_model = await self.retrieve_game_data(ctx)
Expand All @@ -57,7 +57,7 @@ async def stand_button_callback(self, button, interaction):
await ctx.response.defer()

# "Fold" button
@discord.ui.button(label = "Fold", style = discord.ButtonStyle.red)
@discord.ui.button(label = "Fold", style = discord.ButtonStyle.red, custom_id = 'bjview:fold')
async def fold_button_callback(self, button, interaction):
ctx = await bot.get_application_context(interaction)
bj_model = await self.retrieve_game_data(ctx)
Expand Down Expand Up @@ -218,4 +218,4 @@ async def blackjack(ctx: discord.ApplicationContext):
bj_msg = await ctx.channel.send(embed = bj_embed, view = bj_view)
# Create an entry tagged to the invoker containing all information necessary.
temp_memory[ctx.author.mention] = {"msg_id": bj_msg.id, "model": bj_model}
await ctx.respond("Setting up your game...", ephemeral = True, delete_after = 1)
await ctx.respond("Setting up your game...", ephemeral = True, delete_after = 1)
10 changes: 5 additions & 5 deletions NotABot/server_misc/birthday_handler.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,6 @@
async def birthday_loop():

while True:

tmwdatetime = dt.datetime.combine(dt.date.today() + dt.timedelta(days = 1), dt.time())
wait_sec = dt.timedelta(seconds = (tmwdatetime - dt.datetime.now()).seconds, microseconds = (tmwdatetime - dt.datetime.now()).microseconds)
log.info(f"We will update the birthday again on {dt.datetime.now() + wait_sec}.")
await asyncio.sleep(wait_sec.seconds + wait_sec.microseconds / 1000000)

# When it is midnight, run this routine:
log.info(f"Oh boy, it's time to report birthdays for the date {dt.date.today().strftime('%d/%m')}!")
Expand All @@ -36,6 +31,11 @@ async def birthday_loop():

msg_channel = discord.utils.get(guild_channel_list, name = cfg.BIRTHDAY_CFG["birthday_channel"])
await msg_channel.send(embed = birthday_embed)

tmwdatetime = dt.datetime.combine(dt.date.today() + dt.timedelta(days = 1), dt.time())
wait_sec = dt.timedelta(seconds = (tmwdatetime - dt.datetime.now()).seconds, microseconds = (tmwdatetime - dt.datetime.now()).microseconds)
log.info(f"We will update the birthday again on {dt.datetime.now() + wait_sec}.")
await asyncio.sleep(wait_sec.seconds + wait_sec.microseconds / 1000000)
else:
log.info(f"It's nobody's birthday today :(. {dt.date.today()}")
bot_db.close()
Expand Down
5 changes: 3 additions & 2 deletions NotABot/server_misc/image_flipper.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ async def image_flip(ctx: discord.ApplicationContext, \
return

try:
await ctx.defer(invisible = False)
# Basically, we rotate the image as desired, and try to fit the whole rotated image into the, well, Image.
# We then use a black image to work out (approximately) where we should crop the target image.
target_image = target_image.rotate(orientation_dict[orientation], expand = 1)
Expand All @@ -54,10 +55,10 @@ async def image_flip(ctx: discord.ApplicationContext, \
target_image.resize(target_image_size, box = scaffold.getbbox())
print("Great success!")
except KeyError:
await ctx.send_response("Invalid orientation >:( (Don't tell Twitter I said that.)", ephemeral = True)
await ctx.send_followup("Invalid orientation >:( (Don't tell Twitter I said that.)", ephemeral = True)
return

with io.BytesIO() as buffer:
target_image.save(buffer, "png")
buffer.seek(0)
await ctx.send_response(file = discord.File(fp = buffer, filename = "image.png"))
await ctx.send_followup(file = discord.File(fp = buffer, filename = "image.png"))
111 changes: 70 additions & 41 deletions NotABot/server_misc/meetups_handler.py
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
from NotABot.common import bot, log, cfg, general_utils, GUILD
from Crypto.Hash import MD5
import discord
import asyncio
import sqlite3
import json
import re
import base64

# TODO: There are also sections containing repeated code. KIV for truncation opportunities.

Expand All @@ -13,9 +15,10 @@ class MeetupView(discord.ui.View):
# A subclass of Pycord's View that includes buttons to interact with meetups.

# "Join meetup" button
@discord.ui.button(label = "Join this meetup", style = discord.ButtonStyle.green)
@discord.ui.button(label = "Join this meetup", style = discord.ButtonStyle.green, custom_id = 'meetupview:join')
async def join_button_callback(self, button, interaction):
ctx = await bot.get_application_context(interaction)
await ctx.response.defer(invisible = False, ephemeral = True)
try:
msg_meetup_id = re.search("(\(Meetup ID: )(\w+)(\))", interaction.message.embeds[0].footer.text).group(2)
except TypeError as err:
Expand All @@ -25,9 +28,10 @@ async def join_button_callback(self, button, interaction):
await ctx.invoke(join_meetup, meetup_id = msg_meetup_id)

# "Leave meetup" button
@discord.ui.button(label = "Leave this meetup", style = discord.ButtonStyle.red)
@discord.ui.button(label = "Leave this meetup", style = discord.ButtonStyle.red, custom_id = 'meetupview:leave')
async def leave_button_callback(self, button, interaction):
ctx = await bot.get_application_context(interaction)
await ctx.response.defer(invisible = False, ephemeral = True)
try:
msg_meetup_id = re.search("(\(Meetup ID: )(\w+)(\))", interaction.message.embeds[0].footer.text).group(2)
except TypeError as err:
Expand All @@ -44,7 +48,9 @@ def construct_meetup_embed(author: discord.User, \
meetup_desc: str, \
meetup_time: str, \
meetup_location: str, \
participants_ser: str):
participants_ser: str,
author_name = None,
author_avatar = None):

# Helper function that creates the meetup embed.
# This is so I don't have to write the same code over and over again.
Expand All @@ -53,7 +59,10 @@ def construct_meetup_embed(author: discord.User, \
title = "proposes a meetup!",
description = f"{meetup_desc}"
)
meetup_embed.set_author(name = author, icon_url = author.display_avatar)
if author is None:
meetup_embed.set_author(name = author_name, icon_url = author_avatar)
else:
meetup_embed.set_author(name = author, icon_url = author.display_avatar)
meetup_embed.set_footer(text = f"Join me by typing `/meetup join_meetup` or clicking the buttons below! (Meetup ID: {meetup_id})")

participants = json.loads(participants_ser)
Expand All @@ -72,66 +81,86 @@ async def refresh_meetups():

for row in bot_db.execute("SELECT * FROM meetups").fetchall():
meetup_id, author_mention, meetup_msg_id, meetup_desc, meetup_time, meetup_location, participants_ser = row

print(f"Refreshing meetup {row}")

meetup_author = discord.utils.get(guild.members, mention = author_mention)
meetup_embed = construct_meetup_embed(meetup_author, meetup_id, meetup_desc, meetup_time, meetup_location, participants_ser)
meetups_channel = discord.utils.get(guild_channel_list, name = cfg.MEETUPS_CFG["meetups_channel"])
meetup_msg = await meetups_channel.fetch_message(meetup_msg_id)
await meetup_msg.edit(embed = meetup_embed, view = MeetupView())
try:
meetups_channel = discord.utils.get(guild_channel_list, name = cfg.MEETUPS_CFG["meetups_channel"])
meetup_msg = await meetups_channel.fetch_message(meetup_msg_id)
meetup_author = discord.utils.get(guild.members, mention = author_mention)

if meetup_author is None:
author_proxy = meetup_msg.embeds[0].author
# Retrieve the author from the previous embed.
meetup_embed = construct_meetup_embed(None, meetup_id, meetup_desc, meetup_time, meetup_location, participants_ser,
author_name = author.name, author_avatar = author.icon_url)
else:
meetup_embed = construct_meetup_embed(meetup_author, meetup_id, meetup_desc, meetup_time, meetup_location, participants_ser)
await meetup_msg.edit(embed = meetup_embed, view = MeetupView())
except discord.errors.NotFound as e:
log.warning(e)
continue

@meetups.command(description = "Add a new meetup!")
async def add_meetup(ctx: discord.ApplicationContext, \
meetup_id: discord.Option(str, "Name your meetup!"), \
meetup_desc: discord.Option(str, "Describe your meetup!"), \
meetup_time: discord.Option(str, "Set a time!"), \
meetup_location: discord.Option(str, "Where shall we all meet?")):

await ctx.response.defer(invisible = False, ephemeral = True)
log.info(f"{ctx.author.name} is trying to add a meetup!")
guild, guild_channel_list = await general_utils.init_guild_variables()
bot_db, cur = general_utils.get_db()


# Ensure our meetup_id is unique in the database since we are using it as our primary key.
# Also, that it is alphanumeric and it is not longer than 16 characters.
if not meetup_id.isalnum():
await ctx.send_response("Not a valid ID! (Please use only numbers and letters for your ID!)", ephemeral = True)
elif len(meetup_id) > 16:
await ctx.send_response("Not a valid ID! (Please make your ID between 8 and 16 characters long!)", ephemeral = True)
elif len(cur.execute("SELECT * FROM meetups WHERE id = ?", (meetup_id,)).fetchall()):
await ctx.send_response("There is already a meetup with this name! Choose another name please!", ephemeral = True)
# Our participants list will basically be a collection of the names of individuals attending the meetup.
participants = [ctx.author.mention]
# Participants, SERialized.
participants_ser = json.dumps(participants)

# Generate a random meetup id that is distinct from all existing meetup IDs.
h = MD5.new()
trunc_meetup_desc = general_utils.get_alphanumeric_characters(meetup_desc)
if len(trunc_meetup_desc) > 16:
orig_meetup_id = trunc_meetup_desc[:16]
else:
# Our participants list will basically be a collection of the names of individuals attending the meetup.
participants = [ctx.author.mention]
# Participants, SERialized.
participants_ser = json.dumps(participants)

meetup_embed = construct_meetup_embed(ctx.author, meetup_id, meetup_desc, meetup_time, meetup_location, participants_ser)
meetups_channel = discord.utils.get(guild_channel_list, name = cfg.MEETUPS_CFG["meetups_channel"])
meetup_msg = await meetups_channel.send(embed = meetup_embed, view = MeetupView())

cur.execute("INSERT INTO meetups (id, meetup_owner, message_id, meetup_desc, meetup_time, meetup_location, participants) VALUES (?, ?, ?, ?, ?, ?, ?)",
(meetup_id, ctx.author.mention, meetup_msg.id, meetup_desc, meetup_time, meetup_location, participants_ser))
bot_db.commit()
bot_db.close()
await ctx.send_response(f"Meetup created! Check <#{meetups_channel.id}> for the meetup!", ephemeral = True)
h.update(f"{meetup_desc}_{meetup_time}".encode())
orig_meetup_id = h.hexdigest()[:16]

meetup_id = orig_meetup_id
i = 0
# While meetup exists, just increment to get an id. I really don't care enough.
while len(cur.execute("SELECT * FROM meetups WHERE id = ?", (meetup_id,)).fetchall()):
i += 1
meetup_id = f"{orig_meetup_id}_{str(i)}"

meetup_embed = construct_meetup_embed(ctx.author, meetup_id, meetup_desc, meetup_time, meetup_location, participants_ser)
meetups_channel = discord.utils.get(guild_channel_list, name = cfg.MEETUPS_CFG["meetups_channel"])
meetup_msg = await meetups_channel.send(embed = meetup_embed, view = MeetupView())

cur.execute("INSERT INTO meetups (id, meetup_owner, message_id, meetup_desc, meetup_time, meetup_location, participants) VALUES (?, ?, ?, ?, ?, ?, ?)",
(meetup_id, ctx.author.mention, meetup_msg.id, meetup_desc, meetup_time, meetup_location, participants_ser))
bot_db.commit()
bot_db.close()
await ctx.send_followup(f"Meetup created! Check <#{meetups_channel.id}> for the meetup!", ephemeral = True)

@meetups.command(description = "Edit an existing meetup.")
async def edit_meetup(ctx, meetup_id: discord.Option(str), \
meetup_desc: discord.Option(str, "Enter a new description!", required = False, default = ''), \
meetup_time: discord.Option(str, "Enter a new time! (WIP: there are no input restrictions for now.)", required = False, default = ''), \
meetup_location: discord.Option(str, "Enter a new location!", required = False, default = '')):

await ctx.response.defer(invisible = False, ephemeral = True)
guild, guild_channel_list = await general_utils.init_guild_variables()
bot_db, cur = general_utils.get_db()

try:
_, author_mention, meetup_msg_id, old_meetup_desc, old_meetup_time, old_meetup_location, participants_ser = cur.execute("SELECT * FROM meetups WHERE id = ?", (meetup_id,)).fetchone()
except (sqlite3.Error, TypeError) as err:
await ctx.send_response("This meetup doesn't exist :(", ephemeral = True)
await ctx.send_followup("This meetup doesn't exist :(", ephemeral = True)
return
else:
if ctx.author.mention != author_mention:
await ctx.send_response("You don't have perms to edit this message (ownership transfers coming soon). Please ask the person who created this meetup to edit it!", ephemeral = True)
await ctx.send_followup("You don't have perms to edit this message (ownership transfers coming soon). Please ask the person who created this meetup to edit it!", ephemeral = True)
return

new_meetup_desc = meetup_desc if len(meetup_desc) else old_meetup_desc
Expand Down Expand Up @@ -161,12 +190,12 @@ async def join_meetup(ctx, meetup_id = discord.Option(str)):
try:
_, author, meetup_msg_id, meetup_desc, meetup_time, meetup_location, participants_ser = cur.execute("SELECT * FROM meetups WHERE id = ?", (meetup_id,)).fetchone()
except (sqlite3.Error, TypeError) as err:
await ctx.send_response("This meetup doesn't exist :(", ephemeral = True)
await ctx.send_followup("This meetup doesn't exist :(", ephemeral = True)
return

participants = json.loads(participants_ser)
if ctx.author.mention in participants:
await ctx.send_response("You already joined this meetup! Maybe you wanted to join another one instead? :O", ephemeral = True)
await ctx.send_followup("You already joined this meetup! Maybe you wanted to join another one instead? :O", ephemeral = True)
return
else:
participants.append(ctx.author.mention)
Expand All @@ -184,7 +213,7 @@ async def join_meetup(ctx, meetup_id = discord.Option(str)):

bot_db.commit()
bot_db.close()
await ctx.send_response("Done! Welcome aboard!", ephemeral = True)
await ctx.send_followup("Done! Welcome aboard!", ephemeral = True)

@meetups.command(description = "Leave a meetup you're in!")
async def leave_meetup(ctx, meetup_id = discord.Option(str)):
Expand All @@ -194,12 +223,12 @@ async def leave_meetup(ctx, meetup_id = discord.Option(str)):
try:
_, author, meetup_msg_id, meetup_desc, meetup_time, meetup_location, participants_ser = cur.execute("SELECT * FROM meetups WHERE id = ?", (meetup_id,)).fetchone()
except (sqlite3.Error, TypeError) as err:
await ctx.send_response("This meetup doesn't exist :(", ephemeral = True)
await ctx.send_followup("This meetup doesn't exist :(", ephemeral = True)
return

participants = json.loads(participants_ser)
if ctx.author.mention not in participants:
await ctx.send_response("You weren't already in this meetup! sus.", ephemeral = True)
await ctx.send_followup("You weren't already in this meetup! sus.", ephemeral = True)
return
else:
participants.remove(ctx.author.mention)
Expand All @@ -217,4 +246,4 @@ async def leave_meetup(ctx, meetup_id = discord.Option(str)):

bot_db.commit()
bot_db.close()
await ctx.send_response("Sorry to see you go :(", ephemeral = True)
await ctx.send_followup("Sorry to see you go :(", ephemeral = True)
5 changes: 5 additions & 0 deletions requirements.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
py-cord==2.0.0
python-dotenv
pycryptodome==3.10.1
requests
Pillow

0 comments on commit b4fd9c3

Please sign in to comment.