Added user set command #22 #143

Merged
edraft merged 6 commits from #22 into 0.3 2022-12-23 15:48:38 +01:00
2 changed files with 49 additions and 30 deletions
Showing only changes of commit 1b9553e63b - Show all commits

View File

@ -161,19 +161,19 @@
"max_char_count_exceeded": "Der Text darf nicht mehr als 128 Zeichen lang sein!"
},
"user": {
"atr": {
"id": "Id",
"name": "Name",
"discord_join": "Discord beigetreten am",
"last_join": "Server beigetreten am",
"xp": "XP",
"ontime": "Ontime",
"roles": "Rollen",
"joins": "Beitritte",
"lefts": "Abgänge",
"warnings": "Verwarnungen"
},
"info": {
"fields": {
"id": "Id",
"name": "Name",
"discord_join": "Discord beigetreten am",
"last_join": "Server beigetreten am",
"xp": "XP",
"ontime": "Ontime",
"roles": "Rollen",
"joins": "Beitritte",
"lefts": "Abgänge",
"warnings": "Verwarnungen"
},
"footer": ""
},
"get": {
@ -184,7 +184,9 @@
"xp": "{} hat nun {} xp",
"error": {
"value_type_not_numeric": "Der angegebende Wert ist keine Ganzzahl! :(",
"set_xp": "Es kam zu einem Fehler bei der Zuweisung der XP :("
"type_error": "Der angegebene Wert konnte nicht als eine Ganzzahl interpretiert werden :(",
"database_error": "Beim Speichern des Wertes kam es zu einem Fehler :(",
"general_error": "Bei der Ausführung dieses Befehls kam es zu einen Fehler :("
}
},
"error": {

View File

@ -9,6 +9,7 @@ from cpl_translation import TranslatePipe
from discord import app_commands
from discord.ext import commands
from discord.ext.commands import Context
from mysql.connector.errors import DatabaseError
from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC
from bot_core.abc.message_service_abc import MessageServiceABC
@ -25,6 +26,10 @@ from modules.permission.abc.permission_service_abc import PermissionServiceABC
class UserGroup(DiscordCommandABC):
class _AtrClass:
xp: str
ontime: str
def __init__(
self,
config: ConfigurationABC,
@ -61,6 +66,10 @@ class UserGroup(DiscordCommandABC):
self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}')
self._atr_class = self._AtrClass
self._atr_class.xp = self._t.transform('modules.base.user.atr.xp')
self._atr_class.ontime = self._t.transform('modules.base.user.atr.ontime')
@commands.hybrid_group()
@commands.guild_only()
async def user(self, ctx: Context):
@ -93,25 +102,25 @@ class UserGroup(DiscordCommandABC):
ontime = self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(user.user_id).sum(
lambda join: round((join.leaved_on - join.joined_on).total_seconds() / 3600, 2))
embed.add_field(name=self._t.transform('modules.base.user.info.fields.id'), value=member.id)
embed.add_field(name=self._t.transform('modules.base.user.info.fields.name'), value=member.name)
embed.add_field(name=self._t.transform('modules.base.user.info.fields.discord_join'),
embed.add_field(name=self._t.transform('modules.base.user.atr.id'), value=member.id)
embed.add_field(name=self._t.transform('modules.base.user.atr.name'), value=member.name)
embed.add_field(name=self._t.transform('modules.base.user.atr.discord_join'),
value=self._date.transform(member.created_at), inline=False)
embed.add_field(name=self._t.transform('modules.base.user.info.fields.last_join'),
embed.add_field(name=self._t.transform('modules.base.user.atr.last_join'),
value=self._date.transform(member.joined_at), inline=False)
embed.add_field(name=self._t.transform('modules.base.user.info.fields.xp'), value=str(user.xp))
embed.add_field(name=self._t.transform('modules.base.user.info.fields.ontime'), value=str(ontime))
embed.add_field(name=self._t.transform('modules.base.user.atr.xp'), value=str(user.xp))
embed.add_field(name=self._t.transform('modules.base.user.atr.ontime'), value=str(ontime))
roles = ''
for role in member.roles:
roles += f'{role.name}\n'
embed.add_field(name=self._t.transform('modules.base.user.info.fields.roles'), value=roles, inline=False)
embed.add_field(name=self._t.transform('modules.base.user.atr.roles'), value=roles, inline=False)
if is_mod or member == ctx.author:
joins_string = ''
for join in joins:
joins_string += f'{self._date.transform(join.joined_on)}\n'
embed.add_field(name=self._t.transform('modules.base.user.info.fields.joins'), value=joins_string)
embed.add_field(name=self._t.transform('modules.base.user.atr.joins'), value=joins_string)
if is_mod or member == ctx.author:
lefts_string = ''
@ -122,10 +131,10 @@ class UserGroup(DiscordCommandABC):
continue
lefts_string += f'{self._date.transform(join.leaved_on)}\n'
embed.add_field(name=self._t.transform('modules.base.user.info.fields.lefts'), value=lefts_string)
embed.add_field(name=self._t.transform('modules.base.user.atr.lefts'), value=lefts_string)
if is_mod or member == ctx.author:
embed.add_field(name=self._t.transform('modules.base.user.info.fields.warnings'),
embed.add_field(name=self._t.transform('modules.base.user.atr.warnings'),
value=self._t.transform('common.not_implemented_yet'), inline=False)
# send to interaction because of sensitive data
@ -150,10 +159,10 @@ class UserGroup(DiscordCommandABC):
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id)
match atr:
case 'xp':
case self._atr_class.xp:
Ebola-Chan marked this conversation as resolved Outdated

Mach das bitte mit nem elif und als dict in der Klasse und keine weitere Klasse dafür einführen
https://stackoverflow.com/questions/72638083/python-match-case-dictionary-keys

Mach das bitte mit nem elif und als dict in der Klasse und keine weitere Klasse dafür einführen https://stackoverflow.com/questions/72638083/python-match-case-dictionary-keys

Match-Case-Statement gegen If-Else-Statement getauscht

Match-Case-Statement gegen If-Else-Statement getauscht
value = str(user.xp)
case 'ontime':
case self._atr_class.ontime:
value = str(round(
self._user_joined_voice_channel.get_user_joined_voice_channels_by_user_id(user.user_id)
.sum(lambda join: (join.leaved_on - join.joined_on).total_seconds() / 3600),
@ -171,7 +180,7 @@ class UserGroup(DiscordCommandABC):
@get.autocomplete('atr')
async def get_autocomplete(self, interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]:
atr_list = ['xp', 'ontime']
atr_list = [self._atr_class.xp, self._atr_class.ontime]
return [app_commands.Choice(name=atr, value=atr) for atr in atr_list]
@user.command()
@ -188,7 +197,7 @@ class UserGroup(DiscordCommandABC):
user = self._users.find_user_by_discord_id_and_server_id(member.id, server.server_id)
match atr:
case 'xp':
case self._atr_class.xp:
if not value.isnumeric():
await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform('modules.base.user.set.error.value_type_not_numeric'))
Ebola-Chan marked this conversation as resolved Outdated

Relativ ungenau. Entweder änderst du die beschreibung von dem error oder du machst zwei try except blöcke, einmal für den type cast und dann für die manipulation des users inkl. level check

Relativ ungenau. Entweder änderst du die beschreibung von dem error oder du machst zwei try except blöcke, einmal für den type cast und dann für die manipulation des users inkl. level check

Das Exceptionhandling für das "check_level" würde ich lieber dann in der Methode selber machen und das in einem separaten Issue, da ich dafür weitere Exceptionklassen erstellen möchte, um Exceptions in der Methode besser von den allgemeinen Databaseexceptions zu differenzieren.

Das Exceptionhandling für das "check_level" würde ich lieber dann in der Methode selber machen und das in einem separaten Issue, da ich dafür weitere Exceptionklassen erstellen möchte, um Exceptions in der Methode besser von den allgemeinen Databaseexceptions zu differenzieren.
return
@ -198,9 +207,17 @@ class UserGroup(DiscordCommandABC):
self._users.update_user(user)
self._db.save_changes()
await self._level.check_level(member)
except TypeError as te:
self._logger.error(__name__, f'String value couldn\'t be converted to int', te)
await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform('modules.base.user.set.error.type_error'))
return
except DatabaseError as de:
Ebola-Chan marked this conversation as resolved Outdated

Der ist bei weitem unnötig xD
Wenn wir mal in check_level reinschauen sehen wir, dass dort alle Fehler abefangen werden.

Des Weiteren ist DatabaseError um das update_user abzufangen ungenau bzw als solches auch nicht ötig.

Der ist bei weitem unnötig xD Wenn wir mal in check_level reinschauen sehen wir, dass dort alle Fehler abefangen werden. Des Weiteren ist DatabaseError um das update_user abzufangen ungenau bzw als solches auch nicht ötig.

Errorhandling entfernt. Nur TypeError wird behandelt.

Errorhandling entfernt. Nur TypeError wird behandelt.
self._logger.error(__name__, f'An error occurred while updating the user', de)
await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform('modules.base.user.set.error.database_error'))
return
except Exception as e:
Ebola-Chan marked this conversation as resolved
Review

Es wäre ne idee, dass diese strings irgendwie aus translation oder config kommen. Also das man da halt ne liste von diesen Strings hat. Ist auch diesen drei Befehlen immer der Fall

Es wäre ne idee, dass diese strings irgendwie aus translation oder config kommen. Also das man da halt ne liste von diesen Strings hat. Ist auch diesen drei Befehlen immer der Fall
self._logger.error(__name__, f'Value couldn\'t be converted to int', e)
await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform('modules.base.user.set.error.set_xp'))
self._logger.error(__name__, f'An error occurred while setting xp', e)
Ebola-Chan marked this conversation as resolved Outdated

DieseBlock ist wegen command error handling an und für auch nicht nötig. Hier könnte man wenn man wollte die Datenbankfehler abfangen

DieseBlock ist wegen command error handling an und für auch nicht nötig. Hier könnte man wenn man wollte die Datenbankfehler abfangen
await self._message_service.send_interaction_msg(ctx.interaction, self._t.transform('modules.base.user.set.error.general_error'))
return
case other:
@ -215,5 +232,5 @@ class UserGroup(DiscordCommandABC):
@set.autocomplete('atr')
async def set_autocomplete(self, interaction: discord.Interaction, current: str) -> List[app_commands.Choice[str]]:
atr_list = ['xp']
atr_list = [self._atr_class.xp]
return [app_commands.Choice(name=atr, value=atr) for atr in atr_list]