Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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