Skip to content

Commit

Permalink
Merge pull request #88 from Vatsim-Scandinavia/feature/training-roles
Browse files Browse the repository at this point in the history
Added rate limit check, new roles API + restrict event spam
  • Loading branch information
Marko259 authored Sep 14, 2024
2 parents 97e9f5e + 96225e9 commit 85b2162
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 29 deletions.
12 changes: 10 additions & 2 deletions cogs/events.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
from helpers.message import embed, event_description, get_image
from helpers.database import db_connection
from helpers.event import Event
from helpers.error import Error

class EventsCog(commands.Cog):
#
Expand Down Expand Up @@ -105,7 +106,7 @@ async def post_events(self):
text = f'{role.mention}\n:clock2: **{event.name}** is starting in two hours!'
message = await channel.send(text, embed=msg)

if DEBUG == False: await message.publish()
if DEBUG == False: await Error.crosspost(message=message)

event.mark_as_published()
await self.store_message_expire(message, event._get_expire_datetime())
Expand Down Expand Up @@ -225,6 +226,10 @@ async def fetch_api(self):
None
)

is_recurring = new_event.get('parent_id')
if is_recurring is not None:
continue

# Publish the newly scheduled event in channel
channel = self.bot.get_channel(EVENTS_CHANNEL)
e = self.events[new_event.get('id')]
Expand All @@ -239,7 +244,7 @@ async def fetch_api(self):

text = f':calendar_spiral: A new event has been scheduled.'
message = await channel.send(text, embed=msg)
if DEBUG == False: await message.publish()
if DEBUG == False: await Error.crosspost(message=message)

await self.store_message_expire(message, e._get_expire_datetime())

Expand All @@ -264,6 +269,9 @@ async def save_data(self):
mydb = db_connection()
cursor = mydb.cursor()

print(event.id, flush=True)
print(event.url, flush=True)

cursor.execute(
"INSERT INTO events (id, name, img, url, description, start_time, end_time, published) VALUES (%s, %s, %s, %s, %s, %s, %s, %s) ON DUPLICATE KEY UPDATE name = VALUES(name), img = VALUES(img), url = VALUES(url), description = VALUES(description), start_time = VALUES(start_time), end_time = VALUES(end_time), published = VALUES(published)",
(
Expand Down
25 changes: 12 additions & 13 deletions cogs/roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,9 +44,7 @@ async def check_roles(self, override=False):

training_staff_role = discord.utils.get(guild.roles, id=TRAINING_STAFF_ROLE)

mentors = await Roles.get_mentors(self)

moderators = await Roles.get_moderators(self)
roles = await Roles.get_roles(self)

trainings = await Roles.get_training(self)

Expand All @@ -58,20 +56,21 @@ async def check_roles(self, override=False):
raise ValueError

should_be_mentor = False
should_be_training_staff = False

belong_to = []

for mentor in mentors:
if int(mentor['id']) == int(cid[0]):
should_be_mentor = True
for fir in mentor['fir']:
belong_to.append(fir)
for role in roles:
if int(role['id']) == int(cid[0]):
for item in role['roles']:
print(role['roles'][item])
if role['roles'][item] is not None:
if 'Mentor' in role['roles'][item]:
should_be_mentor = True
belong_to.append(item)
if 'Moderator' in role['roles'][item]:
should_be_training_staff = True

should_be_training_staff = False

for moderator in moderators:
if int(moderator['id']) == int(cid[0]):
should_be_training_staff = True

student_data = {}
should_be_student = False
Expand Down
35 changes: 35 additions & 0 deletions helpers/error.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
import asyncio
from discord.errors import HTTPException


class Error:
def __init__(self) -> None:
pass

async def crosspost(message, retries=3):
"""
Safely crossposts a message, with rate limit handling.
:param message: The discord message to crosspost.
:param retries: Number of retries allowed in case of rate limiting.
"""
for attempt in range(retries):
try:
# Try publishing the message
await message.publish()
return # Exit when the message has successfully been published

except HTTPException as e:
if e.status == 429:
retry_after = e.retry_after if hasattr(e, 'retry_after') else 500 # Default to 500 seconds if not provided
print(f'Rate limit hit! Retrying in {retry_after:.2f} seconds...', flush=True)
await asyncio.sleep(retry_after) # Wait for the rate limit to reset

else:
#If another HTTP Exception is thrown reraise it
raise

except Exception as e:
print(f"An Error occurred while trying to publish a message: {e}", flush=True)
break

print(f"Failed to publish message after {retries} attempts", flush=True)
20 changes: 6 additions & 14 deletions helpers/roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,25 +14,17 @@ def __init__(self):
Create a Roles object
"""

async def get_mentors(self):
async def get_roles(self):
"""
Get all mentors from the API
"""
request = requests.get(CC_API_URL + '/roles', headers={'Authorization': 'Bearer ' + CC_API_TOKEN, 'Accept': 'application/json'})
if request.status_code == requests.codes.ok:
feedback = request.json()
return feedback["data"]["mentors"]
else:
return False

async def get_moderators(self):
"""
Get all moderators from the API
"""
request = requests.get(CC_API_URL + '/roles', headers={'Authorization': 'Bearer ' + CC_API_TOKEN, 'Accept': 'application/json'})
request = requests.get(CC_API_URL + '/users', headers={'Authorization': 'Bearer ' + CC_API_TOKEN, 'Accept': 'application/json'},
params={
'include[]': 'roles'
})
if request.status_code == requests.codes.ok:
feedback = request.json()
return feedback["data"]["moderators"]
return feedback["data"]
else:
return False

Expand Down

0 comments on commit 85b2162

Please sign in to comment.