27 Commits

Author SHA1 Message Date
733563d243 Merge pull request 'Add break readout for the bot-aux' (#2) from gabby-dev into main
All checks were successful
test and deploy / test (3.11.5) (push) Successful in 1m45s
test and deploy / push-and-build (push) Successful in 33s
Reviewed-on: #2
2025-12-23 13:15:05 +00:00
a32eb42998 Merge branch 'main' into gabby-dev
All checks were successful
Test Helper Module / test (3.11.5) (push) Successful in 1m44s
2025-12-23 13:12:44 +00:00
bbe1c0aec6 Add break readout for the bot-aux
All checks were successful
Test Helper Module / test (3.11.5) (push) Successful in 2m9s
Test Helper Module / test (3.11.5) (pull_request) Successful in 1m35s
2025-12-22 11:01:28 -06:00
16d760f2f4 Merge pull request 'Add "breaks" functionality to bot.' (#1) from gabby-dev into main
All checks were successful
test and deploy / test (3.11.5) (push) Successful in 1m37s
test and deploy / push-and-build (push) Successful in 32s
Reviewed-on: #1
2025-10-17 17:53:54 +00:00
33e5df4dfe Enhancement/db_helper: Add extra newline to end of message for formatted_list_of_breaks
All checks were successful
Test Helper Module / test (3.11.5) (push) Successful in 1m33s
Test Helper Module / test (3.11.5) (pull_request) Successful in 1m33s
2025-10-17 11:47:40 -06:00
ef24032b68 Enhancement/db_helper: Clean up linebreaks
Some checks failed
Test Helper Module / test (3.11.5) (push) Has been cancelled
2025-10-17 11:45:20 -06:00
74bfe6c116 Bugfix/db_helper: Fix bug with the query_break() 2025-10-17 11:40:49 -06:00
930919bbae Enhancement: bot_core breaks() now uses a formatted list 2025-10-17 11:35:50 -06:00
7e5a6c35e0 Enhancement: Update db_helper to take in days parameter 2025-10-17 11:35:24 -06:00
c1854cc893 db_helper addition: Add functionality to format list of breaks 2025-10-17 11:32:00 -06:00
933ab384e1 Enhancement: edit ping command to use charname rather than UID 2025-10-17 11:18:56 -06:00
41f1160fc3 Bugfix: Change interaction to followup for breaks() in bot_core 2025-10-17 11:16:57 -06:00
1315cb294f Add 'breaks' command to bot_core
All checks were successful
Test Helper Module / test (3.11.5) (push) Successful in 1m31s
2025-10-17 11:09:58 -06:00
090d370ce1 Add remove_break command 2025-10-17 11:08:19 -06:00
97a3ae22fa Remove todo message 2025-10-17 11:05:30 -06:00
9b7c70576b Finish remove_break test 2025-10-17 11:04:01 -06:00
aca7358af8 Fix Boolean issue in add_break 2025-10-17 10:58:25 -06:00
6b2421e55c Add break-related tests 2025-10-17 10:58:06 -06:00
5b58c6e8ea Add return to add_break for db_helper.py 2025-10-17 10:41:36 -06:00
26276b0989 Add remove_break method for db_helper.py 2025-10-17 10:41:20 -06:00
a928fa54d4 Remove unused import from posting module 2025-10-17 10:40:39 -06:00
c19125894f Edit contributing.md 2025-10-16 16:17:39 -06:00
b328d325f6 Edit the self_callouts interaction.followup 2025-10-16 16:13:19 -06:00
c563d745d1 Update try/except/else interaction responses 2025-10-16 16:11:24 -06:00
72b45d9ef8 remove old todo from bot_core
All checks were successful
Test Helper Module / test (3.11.5) (push) Successful in 1m26s
2025-10-16 16:08:27 -06:00
2bfe73a703 Add todo to db_helper_tests 2025-10-16 16:08:07 -06:00
b39de87e4b Add barebones "break" additions 2025-10-16 16:06:22 -06:00
5 changed files with 174 additions and 4 deletions

View File

@@ -7,7 +7,7 @@ This is primarily open-source so that others can implement the code that we've w
Currently, we use GitHub actions to test the database portion of the codebase. It's a bit harder to test the Discord-centric commands otherwise.
## Submitting changes
Please send a [new GitHub Pull Request](https://github.com/contrastellar/raid-callouts/compare) with a clear list of what's been done!
Please send a [new Pull Request](https://git.contrastellar.com/contrastellar/raid-callouts/pulls) with a clear list of what's been done!
When you send in a Pull Request (PR), we'll be super happy if you've made tests or otherwise commented your code clearly with what it does, and what libraries it uses in addition to our base libraries!
Please always write a clear commit message for your commits. One-line messages are fine for smaller changes, but bigger changes should be more details!

View File

@@ -6,7 +6,6 @@ This automation will be run on a daily basis, through a cron job + docker.
@author: Gabriella 'contrastellar' Agathon
"""
import argparse
import os
import discord
import helper.db_helper
@@ -37,11 +36,22 @@ async def on_ready():
print(f'{client.user} has connected.')
print(args.guild_id)
guild: discord.Guild = client.get_guild(args.guild_id)
channel: discord.TextChannel = guild.get_channel(args.channel_id)
callouts = DATABASE_CONN.query_callouts(NUMBER_OF_DAYS)
formatted_callouts = DATABASE_CONN.formatted_list_of_callouts(callouts)
output = f'Callouts for the next {NUMBER_OF_DAYS} days:\n' + formatted_callouts
output += '\n\n'
output += f'Breaks for the next {NUMBER_OF_DAYS} days:\n'
breaks: str = DATABASE_CONN.query_breaks(NUMBER_OF_DAYS)
formatted_breaks: str = DATABASE_CONN.formatted_list_of_breaks(breaks)
output += formatted_breaks
await channel.send(output)
await client.close() # Another way to exit, a little bit cleaner than exit(0)
return

View File

@@ -160,7 +160,8 @@ async def ping(interaction: discord.Interaction) -> None:
delete_invalidate()
cleanup_invalidate()
user_id = interaction.user.id
await interaction.response.send_message(f'Pong! {user_id} -- the bot is active, please message contrastellar with issues!')
charname = DATABASE_CONN.return_char_name(uid=user_id)
await interaction.response.send_message(f'Pong! {charname} -- the bot is active, please message contrastellar with issues!')
return
@@ -247,6 +248,30 @@ async def callout(interaction: discord.Interaction, day: int, month: int, year:
await interaction.response.send_message(f'{user_char_name} -- you added a callout for {callout_date} with reason: {reason}')
await interaction.followup.send(f'{DATABASE_CONN.format_list_of_callouts(DATABASE_CONN.query_callouts(7))}')
@client.tree.command()
async def add_break(interaction: discord.Interaction, start_day: int, start_month: int,
start_year: int, end_day: int, end_month: int, end_year: int) -> None:
delete_invalidate()
cleanup_invalidate()
uid = interaction.user.id
user_nick = interaction.user.display_name
user_char_name = DATABASE_CONN.return_char_name(uid)
start_date: datetime.date = datetime.date(year=start_year, month=start_month, day=start_day)
end_date: datetime.date = datetime.date(year=end_year, month=end_month, day=end_day)
try:
DATABASE_CONN.add_break(user_id=uid, break_start=start_date, break_end=end_date)
except UNIQUEVIOLATION:
await interaction.response.send_message(f'{user_char_name} -- you have already added a break for {start_date} through {end_date}!')
except helper.db_helper.DateTimeError:
await interaction.response.send_message(f'{user_nick}, you\'re trying to submit a break for a time in the past! Please verify that this is what you want to do!')
except psycopg2.Error as e:
await interaction.response.send_message(f'{user_nick} -- an error has occured!\nNotifying <@{CONTRASTELLAR}> of this error. Error is as follows --\n{e}')
else:
await interaction.response.send_message(f'{user_char_name} -- you added a break for for {start_date} through {end_date}!')
@client.tree.command()
async def remove_callout(interaction: discord.Interaction, day: int, month: int, year: int) -> None:
@@ -263,6 +288,24 @@ async def remove_callout(interaction: discord.Interaction, day: int, month: int,
await interaction.response.send_message(f'{user_char_name} removed a callout for {callout_date}')
@client.tree.command()
async def remove_break(interaction: discord.Interaction, day: int, month: int, year: int) -> None:
delete_invalidate()
cleanup_invalidate()
user_id = interaction.user.id
user_char_name = DATABASE_CONN.return_char_name(user_id)
break_date: datetime.date = datetime.date(year=year, month=month, day=day)
try:
DATABASE_CONN.remove_break(user_id=user_id, break_date=break_date)
except psycopg2.Error:
await interaction.response.send_message(f'{user_char_name} -- no break was added for {break_date}')
else:
await interaction.response.send_message(f'{user_char_name} -- you removed the break starting on {break_date}')
return
@client.tree.command()
async def schedule(interaction: discord.Interaction, days: int = DAYS_FOR_CALLOUTS) -> None:
delete_invalidate()
@@ -273,6 +316,18 @@ async def schedule(interaction: discord.Interaction, days: int = DAYS_FOR_CALLOU
await interaction.followup.send(f'Callouts for the next {days} days:\n{callouts}')
return
@client.tree.command()
async def breaks(interaction: discord.Interaction, days: int = 365) -> None:
delete_invalidate()
cleanup_invalidate()
await interaction.response.defer(thinking=True)
breaks: list = DATABASE_CONN.query_breaks(days=days)
break_output: str = DATABASE_CONN.format_list_of_breaks(breaks=breaks)
await interaction.followup.send(f'Breaks for the next {days} days:\n{break_output}')
return
@client.tree.command()
async def self_callouts(interaction: discord.Interaction, days: int = 365) -> None:
delete_invalidate()
@@ -282,7 +337,8 @@ async def self_callouts(interaction: discord.Interaction, days: int = 365) -> No
await interaction.response.defer(thinking=True)
callouts: list = DATABASE_CONN.query_self_callouts(user_id=uid, days=days)
callouts: str = DATABASE_CONN.formatted_list_of_callouts(callouts)
await interaction.followup.send(f'Callouts for the next **{days}** for user **{DATABASE_CONN.return_char_name(uid)}**:\n{callouts}')
character_name: str = DATABASE_CONN.return_char_name(uid)
await interaction.followup.send(f'Callouts for the next **{days}** for user **{character_name}**:\n{callouts}')
args: argparse.Namespace = parser.parse_args()

View File

@@ -57,3 +57,13 @@ class TestClass():
callouts = self.DATABASE_CONN.query_callouts(days=7)
formatted_callouts = self.DATABASE_CONN.format_list_of_callouts(callouts=callouts)
assert formatted_callouts.__class__ is str
def test_add_break(self) -> None:
today: datetime.date = datetime.date.today()
new_break = self.DATABASE_CONN.add_break(user_id=1, break_start=today, break_end=today)
assert new_break is None
def test_remove_break(self) -> None:
today: datetime.date = datetime.date.today()
remove_break = self.DATABASE_CONN.remove_break(user_id=1, start_date=today)
assert remove_break is None

View File

@@ -100,6 +100,17 @@ class DBHelper():
return cursor.fetchall()
def query_breaks(self, days) -> list:
self.__CONN = connect_config(self._config)
self.__CONN.autocommit = True
cursor = self.__CONN.cursor()
cursor.execute(f"SELECT * FROM breaks WHERE open_range >= NOW() - INTERVAL '1 day' and open_range <= NOW() + interval '{days} days' ORDER BY open_range ASC;")
self.__CONN.commit()
return cursor.fetchall()
def query_self_callouts(self, user_id: int, days: int = 365):
self.__CONN = connect_config(self._config)
self.__CONN.autocommit = True
@@ -129,6 +140,19 @@ class DBHelper():
return
def add_break(self, user_id: int, break_start: datetime.date, break_end: datetime.date) -> None:
self.__CONN = connect_config(self._config)
self.__CONN.autocommit = True
cursor = self.__CONN.cursor()
is_range: bool = True
if break_start == break_end:
is_range = False
cursor.execute("INSERT INTO breaks (created_user, is_range, open_range, close_range) VALUES (%s, %s, %s, %s)", (user_id, is_range, break_start, break_end))
return
def remove_callout(self, user_id: int, callout: datetime.date) -> None:
"""Remove a callout based on user + date, which form the primary key in the db
@@ -146,6 +170,76 @@ class DBHelper():
return
def remove_break(self, user_id: int, start_date: datetime.date) -> None:
"""Remove a callout based on user + date, which form the primary key in the db
Args:
user_id (int): The Discord UUID of the user removing something from the db
callout (datetime.datetime): The date of the callout
"""
self.__CONN = connect_config(self._config)
self.__CONN.autocommit = True
cursor = self.__CONN.cursor()
cursor.execute("DELETE FROM breaks WHERE created_user = %s AND open_range = %s", (user_id, start_date))
self.__CONN.commit()
return
def formatted_list_of_breaks(self, breaks: list) -> str:
"""Format the python list of breaks.
Args:
breaks (list): The list that needs to be formatted
Returns:
str: the list as an outputtable string
"""
length = len(breaks)
output: str = ''
if length == 0:
return 'No breaks have been scheduled!'
for entry in breaks:
for item in range(4):
if item == 0:
output += f"Break submitted by: {self.return_char_name(entry[0])}"
if item == 1:
# is_range boolean
if entry[1] == True:
# if it is a range, format as a range
output += f' • Break from: {entry[2]} until... '
else:
# if it is not a range, format as a single date
output += f' • We are taking a break on: {entry[2]}'
if item == 2:
if entry[1] == True:
output += f'{entry[3]}.\n'
else:
output += '\n'
output += "\nEND OF MESSAGE"
return output
def format_list_of_breaks(self, breaks: list) -> str:
"""Format the list of breaks
Args:
breaks (list): The list that needs to be formatted
Returns:
str: The formatted list to the bot_core or bot_aux
"""
return self.formatted_list_of_breaks(breaks=breaks)
def formatted_list_of_callouts(self, callouts: list) -> str:
"""Format the python list of callouts.