Compare commits
24 Commits
72b45d9ef8
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
| 733563d243 | |||
| a32eb42998 | |||
|
bbe1c0aec6
|
|||
| 16d760f2f4 | |||
|
33e5df4dfe
|
|||
|
ef24032b68
|
|||
|
74bfe6c116
|
|||
|
930919bbae
|
|||
|
7e5a6c35e0
|
|||
|
c1854cc893
|
|||
|
933ab384e1
|
|||
|
41f1160fc3
|
|||
|
1315cb294f
|
|||
|
090d370ce1
|
|||
|
97a3ae22fa
|
|||
|
9b7c70576b
|
|||
|
aca7358af8
|
|||
|
6b2421e55c
|
|||
|
5b58c6e8ea
|
|||
|
26276b0989
|
|||
|
a928fa54d4
|
|||
|
c19125894f
|
|||
|
b328d325f6
|
|||
|
c563d745d1
|
@@ -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.
|
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
|
## 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!
|
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!
|
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!
|
||||||
|
|||||||
@@ -6,7 +6,6 @@ This automation will be run on a daily basis, through a cron job + docker.
|
|||||||
@author: Gabriella 'contrastellar' Agathon
|
@author: Gabriella 'contrastellar' Agathon
|
||||||
"""
|
"""
|
||||||
import argparse
|
import argparse
|
||||||
import os
|
|
||||||
import discord
|
import discord
|
||||||
import helper.db_helper
|
import helper.db_helper
|
||||||
|
|
||||||
@@ -37,11 +36,22 @@ async def on_ready():
|
|||||||
|
|
||||||
print(f'{client.user} has connected.')
|
print(f'{client.user} has connected.')
|
||||||
print(args.guild_id)
|
print(args.guild_id)
|
||||||
|
|
||||||
guild: discord.Guild = client.get_guild(args.guild_id)
|
guild: discord.Guild = client.get_guild(args.guild_id)
|
||||||
channel: discord.TextChannel = guild.get_channel(args.channel_id)
|
channel: discord.TextChannel = guild.get_channel(args.channel_id)
|
||||||
|
|
||||||
callouts = DATABASE_CONN.query_callouts(NUMBER_OF_DAYS)
|
callouts = DATABASE_CONN.query_callouts(NUMBER_OF_DAYS)
|
||||||
formatted_callouts = DATABASE_CONN.formatted_list_of_callouts(callouts)
|
formatted_callouts = DATABASE_CONN.formatted_list_of_callouts(callouts)
|
||||||
output = f'Callouts for the next {NUMBER_OF_DAYS} days:\n' + formatted_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 channel.send(output)
|
||||||
await client.close() # Another way to exit, a little bit cleaner than exit(0)
|
await client.close() # Another way to exit, a little bit cleaner than exit(0)
|
||||||
return
|
return
|
||||||
|
|||||||
@@ -160,7 +160,8 @@ async def ping(interaction: discord.Interaction) -> None:
|
|||||||
delete_invalidate()
|
delete_invalidate()
|
||||||
cleanup_invalidate()
|
cleanup_invalidate()
|
||||||
user_id = interaction.user.id
|
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
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -263,17 +264,13 @@ async def add_break(interaction: discord.Interaction, start_day: int, start_mont
|
|||||||
try:
|
try:
|
||||||
DATABASE_CONN.add_break(user_id=uid, break_start=start_date, break_end=end_date)
|
DATABASE_CONN.add_break(user_id=uid, break_start=start_date, break_end=end_date)
|
||||||
except UNIQUEVIOLATION:
|
except UNIQUEVIOLATION:
|
||||||
await interaction.response.send_message(f'{user_char_name} -- you have already added a callout for {callout_date} with reason: {reason}')
|
await interaction.response.send_message(f'{user_char_name} -- you have already added a break for {start_date} through {end_date}!')
|
||||||
except INVALIDDATETIMEFORMAT:
|
|
||||||
await interaction.response.send_message(f'{user_char_name} -- please format the date as the following format: MM/DD/YYYY')
|
|
||||||
except FOREIGNKEYVIOLATION:
|
|
||||||
await interaction.response.send_message(f'{user_nick} -- please register with the bot using the following command!\n`/registercharacter`\n Please use your in-game name!')
|
|
||||||
except helper.db_helper.DateTimeError:
|
except helper.db_helper.DateTimeError:
|
||||||
await interaction.response.send_message(f'{user_nick}, you\'re trying to submit a callout for a time in the past! Please verify that this is what you want to do!')
|
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:
|
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}')
|
await interaction.response.send_message(f'{user_nick} -- an error has occured!\nNotifying <@{CONTRASTELLAR}> of this error. Error is as follows --\n{e}')
|
||||||
else:
|
else:
|
||||||
await interaction.response.send_message(f'{user_char_name} -- you added a callout for {callout_date} with reason: {reason}')
|
await interaction.response.send_message(f'{user_char_name} -- you added a break for for {start_date} through {end_date}!')
|
||||||
|
|
||||||
|
|
||||||
@client.tree.command()
|
@client.tree.command()
|
||||||
@@ -291,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}')
|
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()
|
@client.tree.command()
|
||||||
async def schedule(interaction: discord.Interaction, days: int = DAYS_FOR_CALLOUTS) -> None:
|
async def schedule(interaction: discord.Interaction, days: int = DAYS_FOR_CALLOUTS) -> None:
|
||||||
delete_invalidate()
|
delete_invalidate()
|
||||||
@@ -301,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}')
|
await interaction.followup.send(f'Callouts for the next {days} days:\n{callouts}')
|
||||||
return
|
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()
|
@client.tree.command()
|
||||||
async def self_callouts(interaction: discord.Interaction, days: int = 365) -> None:
|
async def self_callouts(interaction: discord.Interaction, days: int = 365) -> None:
|
||||||
delete_invalidate()
|
delete_invalidate()
|
||||||
@@ -310,7 +337,8 @@ async def self_callouts(interaction: discord.Interaction, days: int = 365) -> No
|
|||||||
await interaction.response.defer(thinking=True)
|
await interaction.response.defer(thinking=True)
|
||||||
callouts: list = DATABASE_CONN.query_self_callouts(user_id=uid, days=days)
|
callouts: list = DATABASE_CONN.query_self_callouts(user_id=uid, days=days)
|
||||||
callouts: str = DATABASE_CONN.formatted_list_of_callouts(callouts)
|
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()
|
args: argparse.Namespace = parser.parse_args()
|
||||||
|
|||||||
@@ -58,4 +58,12 @@ class TestClass():
|
|||||||
formatted_callouts = self.DATABASE_CONN.format_list_of_callouts(callouts=callouts)
|
formatted_callouts = self.DATABASE_CONN.format_list_of_callouts(callouts=callouts)
|
||||||
assert formatted_callouts.__class__ is str
|
assert formatted_callouts.__class__ is str
|
||||||
|
|
||||||
# TODO write tests for the break addition/removal
|
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
|
||||||
|
|||||||
@@ -100,15 +100,17 @@ class DBHelper():
|
|||||||
|
|
||||||
return cursor.fetchall()
|
return cursor.fetchall()
|
||||||
|
|
||||||
def query_breaks(self) -> list:
|
|
||||||
|
def query_breaks(self, days) -> list:
|
||||||
self.__CONN = connect_config(self._config)
|
self.__CONN = connect_config(self._config)
|
||||||
self.__CONN.autocommit = True
|
self.__CONN.autocommit = True
|
||||||
cursor = self.__CONN.cursor()
|
cursor = self.__CONN.cursor()
|
||||||
cursor.execute(f"SELECT * FROM breaks")
|
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()
|
self.__CONN.commit()
|
||||||
|
|
||||||
return cursor.fetchall()
|
return cursor.fetchall()
|
||||||
|
|
||||||
|
|
||||||
def query_self_callouts(self, user_id: int, days: int = 365):
|
def query_self_callouts(self, user_id: int, days: int = 365):
|
||||||
self.__CONN = connect_config(self._config)
|
self.__CONN = connect_config(self._config)
|
||||||
self.__CONN.autocommit = True
|
self.__CONN.autocommit = True
|
||||||
@@ -137,16 +139,18 @@ class DBHelper():
|
|||||||
|
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
def add_break(self, user_id: int, break_start: datetime.date, break_end: datetime.date) -> None:
|
def add_break(self, user_id: int, break_start: datetime.date, break_end: datetime.date) -> None:
|
||||||
|
|
||||||
self.__CONN = connect_config(self._config)
|
self.__CONN = connect_config(self._config)
|
||||||
self.__CONN.autocommit = True
|
self.__CONN.autocommit = True
|
||||||
cursor = self.__CONN.cursor()
|
cursor = self.__CONN.cursor()
|
||||||
is_range: int = 1
|
is_range: bool = True
|
||||||
if break_start == break_end:
|
if break_start == break_end:
|
||||||
is_range = 0
|
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))
|
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:
|
def remove_callout(self, user_id: int, callout: datetime.date) -> None:
|
||||||
@@ -166,6 +170,76 @@ class DBHelper():
|
|||||||
return
|
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:
|
def formatted_list_of_callouts(self, callouts: list) -> str:
|
||||||
"""Format the python list of callouts.
|
"""Format the python list of callouts.
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user