forked from sh-edraft.de/sh_discord_bot
		
	Added logic to call statistics #46
This commit is contained in:
		| @@ -195,7 +195,17 @@ | ||||
|       } | ||||
|     }, | ||||
|     "database": {}, | ||||
|     "permission": { | ||||
|     "permission": {}, | ||||
|     "stats": { | ||||
|       "list": { | ||||
|         "statistic": "Statistik", | ||||
|         "description": "Beschreibung" | ||||
|       }, | ||||
|       "view": { | ||||
|         "statistic": "Statistik", | ||||
|         "description": "Beschreibung", | ||||
|         "failed": "Statistik kann nicht gezeigt werden :(" | ||||
|       } | ||||
|     } | ||||
|   }, | ||||
|   "api": { | ||||
|   | ||||
							
								
								
									
										1
									
								
								kdb-bot/src/modules/stats/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								kdb-bot/src/modules/stats/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| # imports:  | ||||
							
								
								
									
										1
									
								
								kdb-bot/src/modules/stats/command/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								kdb-bot/src/modules/stats/command/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| # imports | ||||
							
								
								
									
										133
									
								
								kdb-bot/src/modules/stats/command/stats_group.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										133
									
								
								kdb-bot/src/modules/stats/command/stats_group.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,133 @@ | ||||
| from typing import List as TList | ||||
|  | ||||
| import discord | ||||
| from cpl_discord.command import DiscordCommandABC | ||||
| from cpl_query.extension import List | ||||
| from cpl_translation import TranslatePipe | ||||
| from discord import app_commands | ||||
| from discord.ext import commands | ||||
| from discord.ext.commands import Context | ||||
|  | ||||
| from bot_core.abc.client_utils_service_abc import ClientUtilsServiceABC | ||||
| from bot_core.abc.message_service_abc import MessageServiceABC | ||||
| from bot_core.logging.command_logger import CommandLogger | ||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||
| from modules.permission.abc.permission_service_abc import PermissionServiceABC | ||||
| from modules.stats.model.statistic import Statistic | ||||
| from modules.stats.service.statistic_service import StatisticService | ||||
| from modules.stats.test.user_xp_asc import user_xp_asc | ||||
| from modules.stats.test.user_xp_desc import user_xp_desc | ||||
|  | ||||
|  | ||||
| class StatsGroup(DiscordCommandABC): | ||||
|  | ||||
|     def __init__( | ||||
|             self, | ||||
|             logger: CommandLogger, | ||||
|             message_service: MessageServiceABC, | ||||
|             client_utils: ClientUtilsServiceABC, | ||||
|             translate: TranslatePipe, | ||||
|             permission_service: PermissionServiceABC, | ||||
|             statistic: StatisticService, | ||||
|             servers: ServerRepositoryABC, | ||||
|     ): | ||||
|         DiscordCommandABC.__init__(self) | ||||
|  | ||||
|         self._logger = logger | ||||
|         self._client_utils = client_utils | ||||
|         self._message_service = message_service | ||||
|         self._t = translate | ||||
|         self._permissions = permission_service | ||||
|         self._statistic = statistic | ||||
|         self._servers = servers | ||||
|  | ||||
|         self._stats = List(Statistic, [ | ||||
|             Statistic('Benutzer XP Aufsteigend', 'Zeigt XP von jedem Benutzer, aufsteigend nach XP', user_xp_asc), | ||||
|             Statistic('Benutzer XP Absteigend', 'Zeigt XP von jedem Benutzer, absteigend nach XP', user_xp_desc) | ||||
|         ]) | ||||
|  | ||||
|     @commands.hybrid_group() | ||||
|     @commands.guild_only() | ||||
|     async def stats(self, ctx: Context): | ||||
|         pass | ||||
|  | ||||
|     @stats.command(alias='rules') | ||||
|     @commands.guild_only() | ||||
|     async def list(self, ctx: Context, wait: int = None): | ||||
|         self._logger.debug(__name__, f'Received command stats list {ctx}') | ||||
|         if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx): | ||||
|             return | ||||
|  | ||||
|         if not self._permissions.is_member_moderator(ctx.author): | ||||
|             await self._message_service.send_ctx_msg(ctx, self._t.transform('common.no_permission_message')) | ||||
|             self._logger.trace(__name__, f'Finished command stats list') | ||||
|             return | ||||
|  | ||||
|         embed = discord.Embed( | ||||
|             title=self._t.transform('modules.auto_role.list.title'), | ||||
|             description=self._t.transform('modules.auto_role.list.description'), | ||||
|             color=int('ef9d0d', 16) | ||||
|         ) | ||||
|  | ||||
|         statistics = '' | ||||
|         descriptions = '' | ||||
|         for statistic in self._stats: | ||||
|             statistics += f'\n{statistic["Name"]}' | ||||
|             descriptions += f'\n{statistic["Description"]}' | ||||
|  | ||||
|         embed.add_field(name=self._t.transform('modules.stats.list.statistic'), value=statistics, inline=True) | ||||
|         embed.add_field(name=self._t.transform('modules.stats.list.description'), value=statistics, inline=True) | ||||
|         await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait) | ||||
|         self._logger.trace(__name__, f'Finished command stats list') | ||||
|  | ||||
|     @stats.command() | ||||
|     @commands.guild_only() | ||||
|     async def view(self, ctx: Context, name: str, wait: int = None): | ||||
|         self._logger.debug(__name__, f'Received command stats {ctx}:{name}') | ||||
|         if not await self._client_utils.check_if_bot_is_ready_yet_and_respond(ctx): | ||||
|             return | ||||
|  | ||||
|         if ctx.guild is None: | ||||
|             return | ||||
|  | ||||
|         try: | ||||
|             server = self._servers.get_server_by_discord_id(ctx.guild.id) | ||||
|             statistic = self._stats.where(lambda s: s.name == name).single() | ||||
|             result = await self._statistic.execute(statistic.func, server) | ||||
|  | ||||
|             # headers = '' | ||||
|             # rows = '' | ||||
|             # for header in result.header: | ||||
|             #     headers += f'\n{header}' | ||||
|             # | ||||
|             # for row in result.values: | ||||
|             #     row_str = '' | ||||
|             #     for column in row: | ||||
|             #         row_str += f'\n{column}' | ||||
|             #     rows += f'\n{row_str}' | ||||
|  | ||||
|             embed = discord.Embed( | ||||
|                 title=statistic.name, | ||||
|                 description=statistic.description, | ||||
|                 color=int('ef9d0d', 16) | ||||
|             ) | ||||
|  | ||||
|             for i in range(result.header.count()): | ||||
|                 header = result.header[i] | ||||
|                 value = '' | ||||
|                 for row in result.values: | ||||
|                     value += f'\n{row[i]}' | ||||
|                 embed.add_field(name=header, value=value, inline=True) | ||||
|  | ||||
|             # embed.add_field(name=self._t.transform('modules.auto_role.list.message_id'), value=rows, inline=True) | ||||
|             await self._message_service.send_ctx_msg(ctx, embed, wait_before_delete=wait) | ||||
|             # await self._message_service.send_ctx_msg(ctx, name, wait_before_delete=wait) | ||||
|         except Exception as e: | ||||
|             self._logger.error(__name__, f'Cannot view statistic {name}', e) | ||||
|             await self._message_service.send_ctx_msg(ctx, self._t.transform('modules.stats.view.failed')) | ||||
|  | ||||
|         self._logger.trace(__name__, f'Finished stats command') | ||||
|  | ||||
|     @view.autocomplete('name') | ||||
|     async def view_autocomplete(self, interaction: discord.Interaction, current: str) -> TList[app_commands.Choice[str]]: | ||||
|         return [app_commands.Choice(name=f'{statistic.name}: {statistic.description}', value=statistic.name) for statistic in self._stats] | ||||
							
								
								
									
										1
									
								
								kdb-bot/src/modules/stats/model/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								kdb-bot/src/modules/stats/model/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| # imports | ||||
							
								
								
									
										21
									
								
								kdb-bot/src/modules/stats/model/statistic.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								kdb-bot/src/modules/stats/model/statistic.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,21 @@ | ||||
| from typing import Callable | ||||
|  | ||||
|  | ||||
| class Statistic: | ||||
|  | ||||
|     def __init__(self, name: str, description: str, func: Callable): | ||||
|         self._name = name | ||||
|         self._description = description | ||||
|         self._func = func | ||||
|          | ||||
|     @property | ||||
|     def name(self) -> str: | ||||
|         return self._name | ||||
|      | ||||
|     @property | ||||
|     def description(self) -> str: | ||||
|         return self._description | ||||
|      | ||||
|     @property | ||||
|     def func(self) -> Callable: | ||||
|         return self._func | ||||
							
								
								
									
										24
									
								
								kdb-bot/src/modules/stats/model/statistic_result.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										24
									
								
								kdb-bot/src/modules/stats/model/statistic_result.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,24 @@ | ||||
| from cpl_query.extension import List | ||||
|  | ||||
|  | ||||
| class StatisticResult: | ||||
|  | ||||
|     def __init__(self): | ||||
|         self._header = List(str) | ||||
|         self._values = List(List) | ||||
|  | ||||
|     @property | ||||
|     def header(self) -> List[str]: | ||||
|         return self._header | ||||
|  | ||||
|     @header.setter | ||||
|     def header(self, value: List[str]): | ||||
|         self._header = value | ||||
|  | ||||
|     @property | ||||
|     def values(self) -> List[List]: | ||||
|         return self._values | ||||
|  | ||||
|     @values.setter | ||||
|     def values(self, value: List[List]): | ||||
|         self._values = value | ||||
							
								
								
									
										1
									
								
								kdb-bot/src/modules/stats/service/__init__.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										1
									
								
								kdb-bot/src/modules/stats/service/__init__.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1 @@ | ||||
| # imports | ||||
							
								
								
									
										69
									
								
								kdb-bot/src/modules/stats/service/statistic_service.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										69
									
								
								kdb-bot/src/modules/stats/service/statistic_service.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,69 @@ | ||||
| from abc import abstractmethod | ||||
| from typing import Callable | ||||
|  | ||||
| from cpl_discord.service import DiscordBotServiceABC | ||||
|  | ||||
| from bot_data.abc.auto_role_repository_abc import AutoRoleRepositoryABC | ||||
| from bot_data.abc.client_repository_abc import ClientRepositoryABC | ||||
| from bot_data.abc.known_user_repository_abc import KnownUserRepositoryABC | ||||
| from bot_data.abc.level_repository_abc import LevelRepositoryABC | ||||
| from bot_data.abc.server_repository_abc import ServerRepositoryABC | ||||
| from bot_data.abc.user_joined_server_repository_abc import UserJoinedServerRepositoryABC | ||||
| from bot_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC | ||||
| from bot_data.abc.user_repository_abc import UserRepositoryABC | ||||
| from bot_data.model.server import Server | ||||
| from modules.stats.model.statistic_result import StatisticResult | ||||
|  | ||||
|  | ||||
| class StatisticService: | ||||
|  | ||||
|     def __init__( | ||||
|             self, | ||||
|             auto_roles: AutoRoleRepositoryABC, | ||||
|             clients: ClientRepositoryABC, | ||||
|             known_users: KnownUserRepositoryABC, | ||||
|             levels: LevelRepositoryABC, | ||||
|             servers: ServerRepositoryABC, | ||||
|             user_joined_servers: UserJoinedServerRepositoryABC, | ||||
|             user_joined_voice_channel: UserJoinedVoiceChannelRepositoryABC, | ||||
|             users: UserRepositoryABC, | ||||
|             bot: DiscordBotServiceABC, | ||||
|     ): | ||||
|         self._auto_roles = auto_roles | ||||
|         self._clients = clients | ||||
|         self._known_users = known_users | ||||
|         self._levels = levels | ||||
|         self._servers = servers | ||||
|         self._user_joined_servers = user_joined_servers | ||||
|         self._user_joined_voice_channel = user_joined_voice_channel | ||||
|         self._users = users | ||||
|         self._bot = bot | ||||
|  | ||||
|     async def execute(self, _f: Callable, server: Server) -> StatisticResult: | ||||
|         guild = self._bot.guilds.where(lambda g: g.id == server.discord_server_id).single() | ||||
|  | ||||
|         return await _f( | ||||
|             self._auto_roles | ||||
|                 .get_auto_roles() | ||||
|                 .where(lambda x: x.server.server_id == server.server_id), | ||||
|             self._clients | ||||
|                 .get_clients() | ||||
|                 .where(lambda x: x.server.server_id == server.server_id), | ||||
|             self._known_users.get_users(), | ||||
|             self._levels | ||||
|                 .get_levels() | ||||
|                 .where(lambda x: x.server.server_id == server.server_id), | ||||
|             self._servers | ||||
|                 .get_servers() | ||||
|                 .where(lambda x: x.server_id == server.server_id), | ||||
|             self._user_joined_servers | ||||
|                 .get_user_joined_servers() | ||||
|                 .where(lambda x: x.user.server.server_id == server.server_id), | ||||
|             self._user_joined_voice_channel | ||||
|                 .get_user_joined_voice_channels() | ||||
|                 .where(lambda x: x.user.server.server_id == server.server_id), | ||||
|             self._users | ||||
|                 .get_users() | ||||
|                 .where(lambda x: x.server.server_id == server.server_id), | ||||
|             guild | ||||
|         ) | ||||
							
								
								
									
										46
									
								
								kdb-bot/src/modules/stats/stats.json
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										46
									
								
								kdb-bot/src/modules/stats/stats.json
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,46 @@ | ||||
| { | ||||
|   "ProjectSettings": { | ||||
|     "Name": "stats", | ||||
|     "Version": { | ||||
|       "Major": "0", | ||||
|       "Minor": "0", | ||||
|       "Micro": "0" | ||||
|     }, | ||||
|     "Author": "", | ||||
|     "AuthorEmail": "", | ||||
|     "Description": "", | ||||
|     "LongDescription": "", | ||||
|     "URL": "", | ||||
|     "CopyrightDate": "", | ||||
|     "CopyrightName": "", | ||||
|     "LicenseName": "", | ||||
|     "LicenseDescription": "", | ||||
|     "Dependencies": [ | ||||
|       "cpl-core>=2022.10.0.post7" | ||||
|     ], | ||||
|     "DevDependencies": [ | ||||
|       "cpl-cli>=2022.10.1" | ||||
|     ], | ||||
|     "PythonVersion": ">=3.10.4", | ||||
|     "PythonPath": { | ||||
|       "linux": "" | ||||
|     }, | ||||
|     "Classifiers": [] | ||||
|   }, | ||||
|   "BuildSettings": { | ||||
|     "ProjectType": "library", | ||||
|     "SourcePath": "", | ||||
|     "OutputPath": "../../dist", | ||||
|     "Main": "stats.main", | ||||
|     "EntryPoint": "stats", | ||||
|     "IncludePackageData": false, | ||||
|     "Included": [], | ||||
|     "Excluded": [ | ||||
|       "*/__pycache__", | ||||
|       "*/logs", | ||||
|       "*/tests" | ||||
|     ], | ||||
|     "PackageData": {}, | ||||
|     "ProjectReferences": [] | ||||
|   } | ||||
| } | ||||
							
								
								
									
										37
									
								
								kdb-bot/src/modules/stats/test/user_xp_asc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								kdb-bot/src/modules/stats/test/user_xp_asc.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| from cpl_discord.container import Guild | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_data.model.auto_role import AutoRole | ||||
| from bot_data.model.client import Client | ||||
| from bot_data.model.known_user import KnownUser | ||||
| from bot_data.model.level import Level | ||||
| from bot_data.model.server import Server | ||||
| from bot_data.model.user import User | ||||
| from bot_data.model.user_joined_server import UserJoinedServer | ||||
| from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel | ||||
| from modules.stats.model.statistic_result import StatisticResult | ||||
|  | ||||
|  | ||||
| async def user_xp_asc( | ||||
|         auto_roles: List[AutoRole], | ||||
|         clients: List[Client], | ||||
|         known_users: List[KnownUser], | ||||
|         levels: List[Level], | ||||
|         servers: List[Server], | ||||
|         user_joined_servers: List[UserJoinedServer], | ||||
|         user_joined_voice_channel: List[UserJoinedVoiceChannel], | ||||
|         users: List[User], | ||||
|         guild: Guild | ||||
| ) -> StatisticResult: | ||||
|     result = StatisticResult() | ||||
|     result.header.append('Name') | ||||
|     result.header.append('XP') | ||||
|  | ||||
|     for user in users.order_by(lambda u: u.xp): | ||||
|         row = List(str) | ||||
|         member = guild.get_member(user.discord_id) | ||||
|         row.append(member.name) | ||||
|         row.append(str(user.xp)) | ||||
|         result.values.append(row) | ||||
|  | ||||
|     return result | ||||
							
								
								
									
										37
									
								
								kdb-bot/src/modules/stats/test/user_xp_desc.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										37
									
								
								kdb-bot/src/modules/stats/test/user_xp_desc.py
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,37 @@ | ||||
| from cpl_discord.container import Guild | ||||
| from cpl_query.extension import List | ||||
|  | ||||
| from bot_data.model.auto_role import AutoRole | ||||
| from bot_data.model.client import Client | ||||
| from bot_data.model.known_user import KnownUser | ||||
| from bot_data.model.level import Level | ||||
| from bot_data.model.server import Server | ||||
| from bot_data.model.user import User | ||||
| from bot_data.model.user_joined_server import UserJoinedServer | ||||
| from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel | ||||
| from modules.stats.model.statistic_result import StatisticResult | ||||
|  | ||||
|  | ||||
| async def user_xp_desc( | ||||
|         auto_roles: List[AutoRole], | ||||
|         clients: List[Client], | ||||
|         known_users: List[KnownUser], | ||||
|         levels: List[Level], | ||||
|         servers: List[Server], | ||||
|         user_joined_servers: List[UserJoinedServer], | ||||
|         user_joined_voice_channel: List[UserJoinedVoiceChannel], | ||||
|         users: List[User], | ||||
|         guild: Guild | ||||
| ) -> StatisticResult: | ||||
|     result = StatisticResult() | ||||
|     result.header.append('Name') | ||||
|     result.header.append('XP') | ||||
|  | ||||
|     for user in users.order_by_descending(lambda u: u.xp): | ||||
|         row = List(str) | ||||
|         member = guild.get_member(user.discord_id) | ||||
|         row.append(member.name) | ||||
|         row.append(str(user.xp)) | ||||
|         result.values.append(row) | ||||
|  | ||||
|     return result | ||||
		Reference in New Issue
	
	Block a user