Skip to content

Commit aa6a118

Browse files
committed
refactor code
1 parent fda9165 commit aa6a118

2 files changed

Lines changed: 106 additions & 152 deletions

File tree

src/commands/club.py

Lines changed: 41 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
from typing import TYPE_CHECKING
44

5-
from discord import Interaction, Member, app_commands, utils
5+
from discord import Interaction, Member, app_commands
66
from discord.app_commands import Choice, Transform, Transformer
77
from discord.ext import commands
88
from discord.ext.commands import BadArgument
99

1010
from src.client import ClubSchema # noqa TC001
11-
from src.services.club import ClubService
11+
from src.services.club import ClubService, DiscordClub
1212
from src.settings import Settings
1313

1414
if TYPE_CHECKING:
@@ -56,27 +56,25 @@ async def remove_club_member(
5656
member: Member,
5757
):
5858
await interaction.response.defer(thinking=True)
59-
# look if the club exist in the JSON file
60-
if club.name in self.club_service.club_discord:
61-
club_ = self.club_service.club_discord[club.name]
62-
is_pres = interaction.user.get_role(club_["id_role_pres"])
63-
if is_pres is not None: # look if the user is the president of the club
64-
role = utils.get(member.guild.roles, id=club_["id_role_membre"])
65-
if role in member.roles:
66-
await self.club_service.remove_member(club_, role, member)
67-
await interaction.followup.send("Rôle supprimée :thumbs_up:")
68-
69-
else:
70-
await interaction.followup.send(
71-
"Cet utilisateur n'est pas dans le club"
72-
)
73-
74-
else:
75-
await interaction.followup.send(
76-
"Seul le président du club peut ajouter un membre"
77-
)
78-
else:
59+
discord_club = DiscordClub.load(club.id)
60+
if not discord_club:
7961
await interaction.followup.send(f"Le club : {club.name} n'existe pas")
62+
return
63+
if (
64+
not interaction.user.guild_permissions.manage_roles
65+
and not interaction.user.get_role(discord_club.president_role_id)
66+
):
67+
await interaction.followup.send(
68+
"Seul le président du club et les admins peuvent retirer un membre"
69+
)
70+
return
71+
if member.id not in discord_club.members:
72+
await interaction.followup.send("Cet utilisateur n'est pas dans le club")
73+
return
74+
await self.club_service.remove_member(discord_club, member)
75+
await interaction.followup.send(
76+
f"{member.name} a été retiré du club :thumbs_up:"
77+
)
8078

8179
@app_commands.command(name="add_member")
8280
@app_commands.autocomplete(club=autocomplete_club)
@@ -87,39 +85,33 @@ async def add_club_member(
8785
member: Member,
8886
):
8987
await interaction.response.defer(thinking=True)
90-
# look if the club exist in the JSON file
91-
if club.name in self.club_service.club_discord:
92-
club_ = self.club_service.club_discord[club.name]
93-
is_pres = interaction.user.get_role(club_["id_role_pres"])
94-
if is_pres is not None: # look if the user is the president of the club
95-
role = utils.get(member.guild.roles, id=club_["id_role_membre"])
96-
await self.club_service.add_member(club_, role, member)
97-
await interaction.followup.send("Rôle attribué :thumbs_up:")
98-
99-
else:
100-
await interaction.followup.send(
101-
"Seul le président du club peut ajouter un membre"
102-
)
103-
else:
88+
discord_club = DiscordClub.load(club.id)
89+
if not discord_club:
10490
await interaction.followup.send(f"Le club : {club.name} n'existe pas")
91+
return
92+
if (
93+
not interaction.user.guild_permissions.manage_roles
94+
and not interaction.user.get_role(discord_club.president_role_id)
95+
):
96+
await interaction.followup.send(
97+
"Seul le président du club et les admins peuvent ajouter un membre"
98+
)
99+
return
100+
await self.club_service.add_member(discord_club, member)
101+
await interaction.followup.send(
102+
f"{member.name} a été ajouté au club :thumbs_up:"
103+
)
105104

106105
@app_commands.command(name="create")
107106
@app_commands.autocomplete(club=autocomplete_club)
107+
@app_commands.checks.has_permissions(manage_guild=True)
108108
async def create_club(
109109
self, interaction: Interaction, club: Transform[ClubSchema, ClubTransformer]
110110
):
111111
await interaction.response.defer(thinking=True)
112-
is_pres = utils.get(interaction.guild.roles, name="Présidence AE")
113-
if is_pres in interaction.user.roles:
114-
serv = interaction.guild
115-
# look if the club is already create
116-
if club.name not in self.club_service.club_discord:
117-
await self.club_service.create_club(club.name, serv)
118-
await interaction.followup.send(f"Le club : {club.name} à été créé")
119-
120-
else:
121-
await interaction.followup.send(f"Le club : {club.name} existe déjà...")
112+
discord_club = DiscordClub.load(club.id)
113+
if discord_club is not None:
114+
await interaction.followup.send(f"Le club : {club.name} existe déjà...")
122115
else:
123-
await interaction.followup.send(
124-
"Vous n'avez pas les permission pour créer un club"
125-
)
116+
await self.club_service.create_club(club, interaction.guild)
117+
await interaction.followup.send(f"Le club : {club.name} à été créé")

src/services/club.py

Lines changed: 65 additions & 103 deletions
Original file line numberDiff line numberDiff line change
@@ -1,95 +1,62 @@
11
from __future__ import annotations
22

33
import json
4-
import os
5-
from typing import TYPE_CHECKING
4+
from typing import TYPE_CHECKING, Annotated, Self
65
from urllib.parse import urljoin
76

87
import discord
9-
from discord import Embed
8+
from discord import Embed, utils
9+
from pydantic import BaseModel, PlainSerializer
1010

1111
from src.settings import BASE_DIR, Settings
1212

1313
if TYPE_CHECKING:
14+
from discord import Guild, Member
15+
1416
from src.client import ClubSchema, SimpleClubSchema, SithClient
1517
from src.main import AeBot
1618

17-
PATH = os.path.dirname(__file__)
18-
19-
20-
class ClubDiscord:
21-
def __init__(
22-
self,
23-
id_,
24-
Name,
25-
id_role_pres,
26-
id_role_treso,
27-
id_role_membre,
28-
):
29-
self.id = id_
30-
self.name = Name
31-
self.id_role_pres = id_role_pres
32-
self.id_pres = None
33-
self.id_role_treso = id_role_treso
34-
self.id_treso = None
35-
self.id_role_membre = id_role_membre
36-
self.id_membre = []
37-
38-
def dico(self):
39-
return {
40-
"id": self.id,
41-
"name": self.name,
42-
"id_role_pres": self.id_role_pres,
43-
"id_pres": self.id_pres,
44-
"id_role_treso": self.id_role_treso,
45-
"id_treso": self.id_treso,
46-
"id_role_membre": self.id_role_membre,
47-
"id_membre": self.id_membre,
48-
}
4919

20+
class DiscordClub(BaseModel):
21+
"""Pydantic model representing data about a club on the discord guild.
5022
51-
class ClubDiscord:
52-
def __init__(
53-
self,
54-
id_,
55-
Name,
56-
id_role_pres,
57-
id_role_treso,
58-
id_role_membre,
59-
):
60-
self.id = id_
61-
self.name = Name
62-
self.id_role_pres = id_role_pres
63-
self.id_pres = None
64-
self.id_role_treso = id_role_treso
65-
self.id_treso = None
66-
self.id_role_membre = id_role_membre
67-
self.id_membre = []
68-
69-
def dico(self):
70-
return {
71-
"id": self.id,
72-
"name": self.name,
73-
"id_role_pres": self.id_role_pres,
74-
"id_pres": self.id_pres,
75-
"id_role_treso": self.id_role_treso,
76-
"id_treso": self.id_treso,
77-
"id_role_membre": self.id_role_membre,
78-
"id_membre": self.id_membre,
79-
}
23+
It can also manage interaction with the internal data cache.
24+
"""
25+
26+
name: str
27+
sith_id: int
28+
category_id: int
29+
president_role_id: int
30+
president_sith_id: int | None = None
31+
treasurer_role_id: int
32+
treasurer_sith_id: int | None = None
33+
member_role_id: int
34+
member_sith_id: int | None = None
35+
members: Annotated[set[int], PlainSerializer(list)]
36+
37+
@classmethod
38+
def load_all(cls) -> dict[str, dict]:
39+
return json.loads((BASE_DIR / "data/club.json").read_text())
40+
41+
@classmethod
42+
def load(cls, club_id: int) -> Self | None:
43+
club = cls.load_all().get(str(club_id))
44+
return cls.model_validate(club) if club is not None else club
45+
46+
def save(self):
47+
all_clubs = self.load_all()
48+
all_clubs[str(self.sith_id)] = self.model_dump()
49+
(BASE_DIR / "data/club.json").write_text(json.dumps(all_clubs))
8050

8151

8252
class ClubService:
8353
"""Manage features directly related to clubs."""
8454

8555
def __init__(self, client: SithClient, bot: AeBot):
86-
with open(BASE_DIR / "data/club.json") as f:
87-
data = json.load(f)
8856
self._config = Settings()
8957
self._client = client
9058
self._club_cache = {}
9159
self._bot = bot
92-
self.club_discord = data
9360

9461
async def search_club(self, current: str) -> list[SimpleClubSchema]:
9562
clubs = await self._client.search_clubs(current)
@@ -118,49 +85,44 @@ def embed(self, club: ClubSchema) -> Embed:
11885
)
11986
return embed
12087

121-
async def create_club(self, club_name: str, serv):
88+
async def create_club(self, club: ClubSchema, guild: Guild):
12289
# create the role for member, presidence and treasurer
123-
president = await serv.create_role(name=f"Président {club_name}")
124-
tresorier = await serv.create_role(name=f"Trésorier {club_name}")
125-
membre = await serv.create_role(name=f"Membre {club_name}", mentionable=True)
90+
president = await guild.create_role(name=f"Président {club.name}")
91+
treasurer = await guild.create_role(name=f"Trésorier {club.name}")
92+
member = await guild.create_role(name=f"Membre {club.name}", mentionable=True)
12693

12794
# create the clubs category
12895
overwrites = {
129-
serv.default_role: discord.PermissionOverwrite(read_messages=False),
96+
guild.default_role: discord.PermissionOverwrite(read_messages=False),
13097
president: discord.PermissionOverwrite(
13198
read_messages=True, manage_channels=True
13299
),
133-
membre: discord.PermissionOverwrite(read_messages=True),
134-
tresorier: discord.PermissionOverwrite(read_messages=True),
100+
member: discord.PermissionOverwrite(read_messages=True),
101+
treasurer: discord.PermissionOverwrite(read_messages=True),
135102
}
136103

137-
categorie = await serv.create_category(club_name, overwrites=overwrites)
138-
139-
# create default channel
140-
await serv.create_text_channel(f"Général-{club_name}", category=categorie)
141-
await serv.create_voice_channel(f"Général-{club_name}", category=categorie)
142-
# store the new club into the JSON file
143-
new_club = ClubDiscord(
144-
self.club_discord["id_max"],
145-
club_name,
146-
president.id,
147-
tresorier.id,
148-
membre.id,
104+
category = await guild.create_category(club.name, overwrites=overwrites)
105+
await category.create_text_channel(f"Général-{club.name}")
106+
await category.create_voice_channel(f"Général-{club.name}")
107+
new_club = DiscordClub(
108+
sith_id=club.id,
109+
name=club.name,
110+
president_role_id=president.id,
111+
treasurer_role_id=treasurer.id,
112+
member_role_id=member.id,
113+
category_id=category.id,
114+
members=set(),
149115
)
150-
self.club_discord[club_name] = new_club.dico()
151-
self.club_discord["id_max"] += 1
152-
153-
with open(PATH + "/club.json", "w") as f:
154-
json.dump(self.club_discord, f)
155-
156-
async def add_member(self, club: dict, role, member):
157-
self.club_discord[club["name"]]["id_membre"].append(member.id)
158-
await member.add_roles(role)
159-
with open(PATH + "/club.json", "w") as f:
160-
json.dump(self.club_discord, f)
161-
162-
async def remove_member(self, club, role, member):
163-
self.club_discord[club["name"]]["id_membre"].remove(member.id)
164-
await member.remove_roles(role)
165-
with open(str(BASE_DIR / "data/club.json"), "w") as f:
166-
json.dump(self.club_discord, f)
116+
new_club.save()
117+
118+
async def add_member(self, club: DiscordClub, member: Member):
119+
role = utils.get(member.guild.roles, id=club.member_role_id)
120+
await member.add_roles(role, reason=f"{member.name} joined club {club.name}")
121+
club.members.add(member.id)
122+
club.save()
123+
124+
async def remove_member(self, club: DiscordClub, member: Member):
125+
role = utils.get(member.guild.roles, id=club.member_role_id)
126+
await member.remove_roles(role, reason=f"{member.name} leaved club {club.name}")
127+
club.members.remove(member.id)
128+
club.save()

0 commit comments

Comments
 (0)