Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add api connection & refactor belts module #31

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .env.sample
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
BOT_TOKEN='<Your Token Here>'
GUILD_ID='<Your Guild ID Here>'
GONGO_CHANNEL_ID='<The Channel For The Daily Reports Here>'
BOKKEN_JWT='<Jason Web Token provided by the Bokken API here>'
API_URL='<API url to make the requests from>'
15 changes: 11 additions & 4 deletions bot/client.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import logging
import os
import sys

import discord
from discord.ext import commands
Expand All @@ -14,7 +14,7 @@
case_insensitive=True,
)

# Logging setup
# Logging to file
logger = logging.getLogger("discord")
logger.setLevel(logging.INFO)
handler = logging.FileHandler(
Expand All @@ -25,14 +25,21 @@
)
logger.addHandler(handler)

# Logging to stdout
stdout_handler = logging.StreamHandler(sys.stdout)
stdout_handler.setFormatter(
logging.Formatter("%(asctime)s:%(levelname)s:%(name)s: %(message)s")
)
logger.addHandler(stdout_handler)


@client.event
async def on_ready():
"""Client event that run when the program is ready."""

logger.info("The bot was logged in")
logger.info("The bot was logged in")
DailyReport(client).report.start()
logger.info("The task has been loaded")
logger.info("The bot is ready 🚀")


@client.command()
Expand Down
182 changes: 52 additions & 130 deletions bot/cogs/belts.py
Original file line number Diff line number Diff line change
@@ -1,15 +1,16 @@
import json
import asyncio
import time
from datetime import date
from enum import Enum, unique

import discord
from discord.ext import commands
from sqlalchemy import create_engine
from sqlalchemy.orm import sessionmaker

from bot.cogs.utils.constants import *
from bot.cogs.utils.file_handler import *
from bot.cogs.utils.logs import AttributionLogs, Base, log_attribution
from bot.cogs.utils.ninja import *
from bot.web import *

# sqlalchemy setup
engine = create_engine("sqlite:///bot/data/daily_logs.db")
Expand All @@ -21,84 +22,14 @@
session = DBSession()


class FileHandler:
"""
This is a class to handle a json file.

Attributes:
file (string): The path to the json file being handled.
"""

file = "bot/data/belts.json"

def __init__(self: str, belt: str):
"""
The constructor for the FileHandler class.

Parameters:
color (int): Color code to be displayed in discord embed.
"""
self.belt = belt
self.msg = self.get_info()[0]
self.color = self.get_info()[1]

def get_info(self) -> tuple:
"""
The function to get the info from the belts.json file.

Returns:
msg (string): Variable that contains the message of the respective belt.
color (int): Color code to be displayed in discord embed.
"""
with open(self.file) as json_file:
data = json.load(json_file)
msg = f"Subiste para {self.belt} :clap:\n\nPróximos objetivos:"
color = int(data[self.belt]["color"], 16)
for param in data[self.belt]["goals"]:
msg += "\n" + param

return (msg, color)


class Ninja:
"""This is a class to get information about a specific ninja."""

def __init__(self, guild: discord.Guild, member: discord.Member):
self.guild = guild
self.member = member
self.roles = list(member.roles)

def current_belt(self):
"""This function returns the current belt of the ninja."""

highest_belt = None
for role in self.roles:
for belt in Belts:
if belt.name == role.name:
highest_belt = belt

return highest_belt

return highest_belt

def next_belt(self) -> Belts:
"""This function returns the next belt of the ninja."""

value = self.current_belt().value + 1 if self.current_belt().value < 8 else 8

return Belts(value)


class BeltsAttributions(commands.Cog):
"""This is a class to handle the attribution of belts."""
"""This is a class to handle the discord attribution of belt roles."""

def __init__(self, client: commands.Bot):
self.client = client

@commands.command(name="promove")
@commands.has_any_role(
Roles["ADMIN"].name, Roles["CHAMPION"].name, Roles["MENTOR"].name
)
@commands.has_any_role(Roles["ADMIN"].name, Roles["CHAMPION"].name)
async def promove(
self, ctx: discord.ext.commands.Context, user: str, belt: str
) -> None:
Expand All @@ -109,73 +40,64 @@ async def promove(
member = guild.get_member(mentions[0])
ninja = Ninja(guild, member)

if belt == "Branco" and ninja.current_belt() == None:
if belt == ninja.next_belt().name:
role = get_role_from_name(guild, belt)

await member.add_roles(guild.get_role(role.id), reason=None, atomic=True)

# Public message
await ctx.send(f"{user} agora és cinturão {belt} :tada:")
# send request to update ninja belt
ninja_username = member.name + "#" + member.discriminator
status = await update_belt(ninja_username, belt)

# Private message
file_handler = FileHandler(belt)
emoji = translator_to_emoji[belt]
user = member
embed = discord.Embed(
title=f"{emoji} Parabéns, subiste de cinturão :tada:",
description=file_handler.msg,
color=file_handler.color,
)
if status == 200:
await member.add_roles(
guild.get_role(role.id), reason=None, atomic=True
)

await user.send(embed=embed)
# Public message
asyncio.create_task(ctx.send(f"{user} agora és cinturão {belt} :tada:"))

# Adding the log to the database
new_log = AttributionLogs(
ninja_id=str(member),
mentor_id=str(ctx.author),
belt_attributed=belt,
timestamp=int(time.time()),
)
# Private message
asyncio.create_task(self.send_private_message(member, belt))

session.add(new_log)
session.commit()
# Adding the log to the database
asyncio.create_task(self.log(ctx, member, belt))
else:
await ctx.reply(
f"Ocorreu um erro ao atualizar o cinturão do ninja {user} no site :(\nPor favor tente mais tarde."
)

elif belt == ninja.current_belt().name:
await ctx.reply(f"Esse já é o cinturão do ninja {user}!")

elif belt == ninja.next_belt().name:
role = get_role_from_name(guild, belt)
await member.add_roles(guild.get_role(role.id), reason=None, atomic=True)

# Public message
await ctx.send(f"{user} agora és cinturão {belt} :tada:")

# Private message
file_handler = FileHandler(belt)
emoji = translator_to_emoji[belt]
user = member
embed = discord.Embed(
title=f"{emoji} Parabéns, subiste de cinturão :tada:",
description=file_handler.msg,
color=file_handler.color,
)

await user.send(embed=embed)

# Adding the log to the database
new_log = AttributionLogs(
ninja_id=str(member),
mentor_id=str(ctx.author),
belt_attributed=belt,
timestamp=int(time.time()),
)

session.add(new_log)
session.commit()

elif belt != ninja.next_belt().name:
else:
await ctx.send(f"{user} esse cinturão não é valido de se ser atribuido.")

async def log(self, ctx, member, belt):
"""This function logs the belt attribution."""

new_log = AttributionLogs(
ninja_id=str(member),
mentor_id=str(ctx.author),
belt_attributed=belt,
timestamp=int(time.time()),
)

session.add(new_log)
session.commit()

async def send_private_message(self, member, belt):
"""This function sends a private message to the member."""

file_handler = FileHandler(belt)
emoji = translator_to_emoji[belt]
user = member
embed = discord.Embed(
title=f"{emoji} Parabéns, subiste de cinturão :tada:",
description=file_handler.msg,
color=file_handler.color,
)

await user.send(embed=embed)


def setup(client: commands.Bot) -> None:
client.add_cog(BeltsAttributions(client))
10 changes: 10 additions & 0 deletions bot/cogs/utils/constants.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import json
from enum import Enum, unique

import discord
Expand Down Expand Up @@ -54,3 +55,12 @@ def get_role_from_name(guild: discord.Guild, belt: str) -> discord.Role:
for role in guild.roles:
if role.name == belt:
return role


def translate_belt_name(belt: str) -> str:
file = "bot/data/belts.json"
with open(file) as json_file:
data = json.load(json_file)
belt = data[belt]["translation"]

return belt
40 changes: 40 additions & 0 deletions bot/cogs/utils/file_handler.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import json


class FileHandler:
"""
This is a class to handle a json file.

Attributes:
file (string): The path to the json file being handled.
"""

file = "bot/data/belts.json"

def __init__(self: str, belt: str):
"""
The constructor for the FileHandler class.

Parameters:
color (int): Color code to be displayed in discord embed.
"""
self.belt = belt
self.msg = self.get_info()[0]
self.color = self.get_info()[1]

def get_info(self) -> tuple:
"""
The function to get the info from the belts.json file.

Returns:
msg (string): Variable that contains the message of the respective belt.
color (int): Color code to be displayed in discord embed.
"""
with open(self.file) as json_file:
data = json.load(json_file)
msg = f"Subiste para {self.belt} :clap:\n\nPróximos objetivos:"
color = int(data[self.belt]["color"], 16)
for param in data[self.belt]["goals"]:
msg += "\n" + param

return (msg, color)
37 changes: 37 additions & 0 deletions bot/cogs/utils/ninja.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import discord

from bot.cogs.utils.constants import *
from bot.cogs.utils.file_handler import *


class Ninja:
"""This is a class to get information about a specific ninja."""

def __init__(self, guild: discord.Guild, member: discord.Member):
self.guild = guild
self.member = member
self.roles = list(member.roles)

def current_belt(self):
"""This function returns the current belt of the ninja."""

highest_belt = None
for role in self.roles:
for belt in Belts:
if belt.name == role.name:
highest_belt = belt

return highest_belt

def next_belt(self) -> Belts:
"""This function returns the next belt of the ninja."""

if self.current_belt() == None:
value = 1
elif self.current_belt().value < 8:
value = self.current_belt().value + 1

else:
value = 8

return Belts(value)
Loading