Merge pull request '0.4 - Befehlsstruktur' (#37) from 0.4 into Alpha

Reviewed-on: #37 closed #6
This commit is contained in:
Sven Heidemann 2021-12-31 12:10:04 +01:00
commit ffa2f9d446
87 changed files with 679 additions and 377 deletions

View File

@ -6,12 +6,12 @@
"gismo-cli": "src/gismo_cli/gismo-cli.json", "gismo-cli": "src/gismo_cli/gismo-cli.json",
"gismo-core": "src/gismo_core/gismo-core.json", "gismo-core": "src/gismo_core/gismo-core.json",
"gismo-data": "src/gismo_data/gismo-data.json", "gismo-data": "src/gismo_data/gismo-data.json",
"modules-core": "src/modules_core/modules-core.json",
"boot-log": "src/modules/boot_log/boot-log.json", "boot-log": "src/modules/boot_log/boot-log.json",
"level-generator": "tools/level_generator/level-generator.json", "level-generator": "tools/level_generator/level-generator.json",
"ontime-calculator": "tools/ontime_calculator/ontime-calculator.json", "ontime-calculator": "tools/ontime_calculator/ontime-calculator.json",
"database": "src/modules/database/database.json", "database": "src/modules/database/database.json",
"base": "src/modules/base/base.json" "base": "src/modules/base/base.json",
"permission": "src/modules/permission/permission.json"
}, },
"Scripts": { "Scripts": {
"build-start": "cd src/gismo_cli; echo 'gismo-cli:'; cpl build; cd ../gismo; echo 'gismo:'; cpl build; cd ../../dist/gismo/build/gismo; bash gismo", "build-start": "cd src/gismo_cli; echo 'gismo-cli:'; cpl build; cd ../gismo; echo 'gismo:'; cpl build; cd ../../dist/gismo/build/gismo; bash gismo",

View File

@ -1,36 +0,0 @@
{
"TimeFormatSettings": {
"DateFormat": "%Y-%m-%d",
"TimeFormat": "%H:%M:%S",
"DateTimeFormat": "%Y-%m-%d %H:%M:%S.%f",
"DateTimeLogFormat": "%Y-%m-%d_%H-%M-%S"
},
"LoggingSettings": {
"Path": "logs/",
"Filename": "log_$start_time.log",
"ConsoleLogLevel": "ERROR",
"FileLogLevel": "WARN"
},
"Discord": {
"Token": ""
},
"Bot": {
"Prefix": "!g",
"Servers": [
{
"Id": "",
"LoginMessageChannelId": "",
"LoginMessage": "",
"MessageDeleteTimer": 0,
"WelcomeMessage": "",
"GoodbyeMessage": "",
"MaxVoiceStateHours": 0,
"XpPerMessage": 0,
"XpPerOntimeHour": 0,
"AFKChannelIds": [],
"AdminRoleIds": [],
"ModeratorRoleIds": []
}
]
}
}

View File

@ -0,0 +1,16 @@
{
"910199451145076828": {
"WelcomeMessage": "Hello There!\nIch bin Gismo und heiße dich bei {} herzlichst willkommen!",
"WelcomeMessageForTeam": "{} hat gerade das Irrenhaus betreten.",
"GoodbyeMessage": "Schade das du uns so schnell verlässt :(",
"MaxVoiceStateHours": 24,
"XpPerMessage": 2,
"XpPerOntimeHour": 4,
"AFKChannelIds": [
910199452915093593,
910199452915093594
],
"PurgeMessage": "Ja mein Herr, ich lösche alle Nachrichten!",
"NoPermissionsMessage": "Nein!\nIch höre nicht auf dich ¯\\_(ツ)_/¯"
}
}

View File

@ -0,0 +1,6 @@
{
"910199451145076828": {
"LoginMessageChannelId": "910199452915093588",
"LoginMessage": "Ich bin on the line :D\nDer Start hat {} Sekunden gedauert"
}
}

View File

@ -0,0 +1,2 @@
{
}

View File

@ -0,0 +1,10 @@
{
"910199451145076828": {
"AdminRoleIds": [
925072155203477584
],
"ModeratorRoleIds": [
925072209884635167
]
}
}

View File

@ -47,7 +47,6 @@
"ProjectReferences": [ "ProjectReferences": [
"../gismo_core/gismo-core.json", "../gismo_core/gismo-core.json",
"../gismo_data/gismo-data.json", "../gismo_data/gismo-data.json",
"../modules_core/modules-core.json",
"../modules/boot_log/boot-log.json", "../modules/boot_log/boot-log.json",
"../modules/base/base.json", "../modules/base/base.json",
"../modules/database/database.json" "../modules/database/database.json"

View File

@ -43,3 +43,5 @@ if __name__ == '__main__':
# / ) ) ~ edraft # / ) ) ~ edraft
# ___// | / # ___// | /
# `--' \_~-, # `--' \_~-,
# happy new year :)

View File

@ -11,6 +11,7 @@ from cpl_core.environment import ApplicationEnvironment
from cpl_core.logging import LoggerABC from cpl_core.logging import LoggerABC
from gismo_core.abc.bot_service_abc import BotServiceABC from gismo_core.abc.bot_service_abc import BotServiceABC
from gismo_core.abc.command_abc import CommandABC
from gismo_core.abc.message_service_abc import MessageServiceABC from gismo_core.abc.message_service_abc import MessageServiceABC
from gismo_core.service.bot_service import BotService from gismo_core.service.bot_service import BotService
from gismo_core.service.message_service import MessageService from gismo_core.service.message_service import MessageService
@ -35,11 +36,15 @@ from gismo_data.service.user_joined_server_repository_service import UserJoinedS
from gismo_data.service.user_joined_voice_channel_service import UserJoinedVoiceChannelRepositoryService from gismo_data.service.user_joined_voice_channel_service import UserJoinedVoiceChannelRepositoryService
from gismo_data.service.user_repository_service import UserRepositoryService from gismo_data.service.user_repository_service import UserRepositoryService
from modules.base.base import Base from modules.base.base import Base
from modules.base.service.base_command_service import BaseCommandService
from modules.boot_log.boot_log import BootLog from modules.boot_log.boot_log import BootLog
from modules.database.database import Database from modules.database.database import Database
from modules_core.abc.module_abc import ModuleABC from modules.permission.abc.permission_service_abc import PermissionServiceABC
from modules_core.abc.module_service_abc import ModuleServiceABC from modules.permission.permission import Permission
from modules_core.service.module_service import ModuleService from modules.permission.service.permission_service import PermissionService
from gismo_core.abc.module_abc import ModuleABC
from gismo_core.abc.module_service_abc import ModuleServiceABC
from gismo_core.service.module_service import ModuleService
class Startup(StartupABC): class Startup(StartupABC):
@ -54,9 +59,9 @@ class Startup(StartupABC):
environment.set_working_directory(os.path.dirname(os.path.realpath(__file__))) environment.set_working_directory(os.path.dirname(os.path.realpath(__file__)))
configuration.add_environment_variables('GISMO_') configuration.add_environment_variables('GISMO_')
configuration.add_json_file(f'appsettings.json', optional=False) configuration.add_json_file(f'config/appsettings.json', optional=False)
configuration.add_json_file(f'appsettings.{environment.environment_name}.json', optional=True) configuration.add_json_file(f'config/appsettings.{environment.environment_name}.json', optional=True)
configuration.add_json_file(f'appsettings.{environment.host_name}.json', optional=True) configuration.add_json_file(f'config/appsettings.{environment.host_name}.json', optional=True)
configuration.add_configuration('Startup_StartTime', self._start_time) configuration.add_configuration('Startup_StartTime', self._start_time)
@ -68,12 +73,10 @@ class Startup(StartupABC):
services.add_db_context(DBContext, self._config.get_configuration(DatabaseSettings)) services.add_db_context(DBContext, self._config.get_configuration(DatabaseSettings))
# modules # general services
services.add_singleton(ModuleServiceABC, ModuleService) services.add_singleton(ModuleServiceABC, ModuleService)
services.add_singleton(BotServiceABC, BotService) services.add_singleton(BotServiceABC, BotService)
services.add_transient(MessageServiceABC, MessageService) services.add_transient(MessageServiceABC, MessageService)
# services
services.add_transient(MigrationService) services.add_transient(MigrationService)
# data services # data services
@ -84,10 +87,17 @@ class Startup(StartupABC):
services.add_transient(UserJoinedServerRepositoryABC, UserJoinedServerRepositoryService) services.add_transient(UserJoinedServerRepositoryABC, UserJoinedServerRepositoryService)
services.add_transient(UserJoinedVoiceChannelRepositoryABC, UserJoinedVoiceChannelRepositoryService) services.add_transient(UserJoinedVoiceChannelRepositoryABC, UserJoinedVoiceChannelRepositoryService)
# module services
services.add_singleton(PermissionServiceABC, PermissionService)
# commands
services.add_singleton(CommandABC, BaseCommandService)
# modules # modules
services.add_transient(ModuleABC, Database) services.add_transient(ModuleABC, Database)
services.add_transient(ModuleABC, Base)
services.add_transient(ModuleABC, BootLog) services.add_transient(ModuleABC, BootLog)
services.add_singleton(ModuleABC, Permission)
services.add_singleton(ModuleABC, Base)
# migrations # migrations
services.add_transient(MigrationABC, InitialMigration) services.add_transient(MigrationABC, InitialMigration)

View File

@ -0,0 +1,11 @@
from abc import ABC, abstractmethod
from discord.ext import commands
from gismo_core.commands_meta import CommandsMeta
class CommandABC(ABC, commands.Cog, metaclass=CommandsMeta):
@abstractmethod
def __init__(self): pass

View File

@ -1,12 +1,23 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Optional
from cpl_core.configuration import ConfigurationModelABC
class ModuleABC(ABC): class ModuleABC(ABC):
@abstractmethod @abstractmethod
def __init__(self): def __init__(self, priorities: dict[type, int], settings_type: type):
self._priorities = {} self._priorities = priorities
self._success = True self._success = True
self._settings_type = settings_type
@property
def success(self) -> bool:
return self._success
@property
def settings_type(self) -> type:
return self._settings_type
def get_priority(self, t: type) -> int: def get_priority(self, t: type) -> int:
if t not in self._priorities: if t not in self._priorities:
@ -15,7 +26,3 @@ class ModuleABC(ABC):
def stop_propagation(self): def stop_propagation(self):
self._success = False self._success = False
@property
def success(self) -> bool:
return self._success

View File

@ -0,0 +1,5 @@
from abc import ABCMeta
from discord.ext import commands
class CommandsMeta(ABCMeta, commands.CogMeta): pass

View File

@ -19,5 +19,5 @@ class DiscordSettings(ConfigurationModelABC):
try: try:
self._token = settings['Token'] self._token = settings['Token']
except Exception as e: except Exception as e:
Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings') Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {__name__} settings')
Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')

View File

@ -11,17 +11,6 @@ class ServerSettings(ConfigurationModelABC):
self._id: int = 0 self._id: int = 0
self._message_delete_timer: int = 0 self._message_delete_timer: int = 0
self._login_message_channel_id: int = 0
self._login_message: str = ''
self._welcome_message: str = ''
self._welcome_message_for_team: str = ''
self._goodbye_message: str = ''
self._max_voice_state_hours: int = 0
self._xp_per_message: int = 0
self._xp_per_ontime_hour: int = 0
self._afk_channel_ids: list[int] = []
self._admin_roles: list[int] = []
self._moderator_roles: list[int] = []
@property @property
def id(self) -> str: def id(self) -> str:
@ -31,70 +20,10 @@ class ServerSettings(ConfigurationModelABC):
def message_delete_timer(self) -> int: def message_delete_timer(self) -> int:
return self._message_delete_timer return self._message_delete_timer
@property
def login_message_channel_id(self) -> int:
return self._login_message_channel_id
@property
def login_message(self) -> str:
return self._login_message
@property
def welcome_message(self) -> str:
return self._welcome_message
@property
def welcome_message_for_team(self) -> str:
return self._welcome_message_for_team
@property
def goodbye_message(self) -> str:
return self._goodbye_message
@property
def max_voice_state_hours(self) -> int:
return self._max_voice_state_hours
@property
def xp_per_message(self) -> int:
return self._xp_per_message
@property
def xp_per_ontime_hour(self) -> int:
return self._xp_per_ontime_hour
@property
def afk_channel_ids(self) -> list[int]:
return self._afk_channel_ids
@property
def admin_roles(self) -> list[int]:
return self._admin_roles
@property
def moderator_roles(self) -> list[int]:
return self._moderator_roles
def from_dict(self, settings: dict): def from_dict(self, settings: dict):
try: try:
self._id = int(settings['Id']) self._id = int(settings['Id'])
self._message_delete_timer = int(settings['MessageDeleteTimer']) self._message_delete_timer = int(settings['MessageDeleteTimer'])
self._login_message_channel_id = int(settings['LoginMessageChannelId'])
self._login_message = settings['LoginMessage']
self._welcome_message = settings['WelcomeMessage']
self._welcome_message_for_team = settings['WelcomeMessageForTeam']
self._goodbye_message = settings['GoodbyeMessage']
self._max_voice_state_hours = int(settings['MaxVoiceStateHours'])
self._xp_per_message = int(settings['XpPerMessage'])
self._xp_per_ontime_hour = int(settings['XpPerOntimeHour'])
for id in settings['AFKChannelIds']:
self._afk_channel_ids.append(int(id))
for id in settings['AdminRoleIds']:
self._admin_roles.append(int(id))
for id in settings['ModeratorRoleIds']:
self._moderator_roles.append(int(id))
except Exception as e: except Exception as e:
Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in settings') Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in settings')
Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}') Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')

View File

@ -8,8 +8,8 @@ from gismo_core.abc.bot_service_abc import BotServiceABC
from gismo_core.configuration.bot_settings import BotSettings from gismo_core.configuration.bot_settings import BotSettings
from gismo_core.configuration.discord_settings import DiscordSettings from gismo_core.configuration.discord_settings import DiscordSettings
from gismo_core.configuration.server_settings import ServerSettings from gismo_core.configuration.server_settings import ServerSettings
from modules_core.abc.module_service_abc import ModuleServiceABC from gismo_core.abc.module_service_abc import ModuleServiceABC
from modules_core.service.module_service import ModuleService from gismo_core.service.module_service import ModuleService
class BotService(BotServiceABC, commands.Bot): class BotService(BotServiceABC, commands.Bot):

View File

@ -26,12 +26,15 @@ class MessageService(MessageServiceABC):
async def delete_messages(self, messages: List[discord.Message]): async def delete_messages(self, messages: List[discord.Message]):
self._logger.debug(__name__, f'Try to delete {messages.count()} messages') self._logger.debug(__name__, f'Try to delete {messages.count()} messages')
for message in messages: for message in messages:
await self.delete_message(message) server_st: ServerSettings = self._config.get_configuration(f'DSERVER_{message.guild.id}')
await asyncio.sleep(server_st.message_delete_timer)
await self.delete_message(message, mass_delete=True)
self._logger.debug(__name__, 'Deleting messages finished') self._logger.debug(__name__, 'Deleting messages finished')
async def delete_message(self, message: discord.Message): async def delete_message(self, message: discord.Message, mass_delete=False):
server_st: ServerSettings = self._config.get_configuration(f'DSERVER_{message.guild.id}') server_st: ServerSettings = self._config.get_configuration(f'DSERVER_{message.guild.id}')
await asyncio.sleep(server_st.message_delete_timer) if not mass_delete:
await asyncio.sleep(server_st.message_delete_timer)
self._logger.debug(__name__, f'Try to delete message:\n\t{message}\n\t{message.content}') self._logger.debug(__name__, f'Try to delete message:\n\t{message}\n\t{message.content}')
guild_id = message.guild.id guild_id = message.guild.id
try: try:
@ -86,4 +89,4 @@ class MessageService(MessageServiceABC):
self._logger.info(__name__, f'Sent message to channel {ctx.channel.id}') self._logger.info(__name__, f'Sent message to channel {ctx.channel.id}')
self._clients.apppend_sent_message_count(self._bot.user.id, ctx.guild.id, 1) self._clients.apppend_sent_message_count(self._bot.user.id, ctx.guild.id, 1)
self._db.save_changes() self._db.save_changes()
await self.delete_message(msg) await self.delete_messages(List(discord.Message, [msg, ctx.message]))

View File

@ -1,71 +1,72 @@
from abc import ABC, ABCMeta from abc import ABC, ABCMeta
from datetime import datetime from datetime import datetime
import json
from typing import Optional, Sequence, Union from typing import Optional, Sequence, Union
import discord import discord
from cpl_core.configuration import ConfigurationModelABC, ConfigurationABC
from cpl_core.dependency_injection import ServiceProviderABC from cpl_core.dependency_injection import ServiceProviderABC
from cpl_core.environment import ApplicationEnvironmentABC from cpl_core.environment import ApplicationEnvironmentABC
from cpl_core.logging import LoggerABC from cpl_core.logging import LoggerABC
from cpl_core.utils import String from cpl_core.utils import String
from cpl_query.extension import List from cpl_query.extension import List
from discord.ext import commands from discord.ext import commands
from modules_core.abc.events.on_bulk_message_delete_abc import OnBulkMessageDeleteABC from gismo_core.abc.events.on_bulk_message_delete_abc import OnBulkMessageDeleteABC
from modules_core.abc.events.on_connect_abc import OnConnectABC from gismo_core.abc.events.on_connect_abc import OnConnectABC
from modules_core.abc.events.on_disconnect_abc import OnDisconnectABC from gismo_core.abc.events.on_disconnect_abc import OnDisconnectABC
from modules_core.abc.events.on_group_join_abc import OnGroupJoinABC from gismo_core.abc.events.on_group_join_abc import OnGroupJoinABC
from modules_core.abc.events.on_group_remove_abc import OnGroupRemoveABC from gismo_core.abc.events.on_group_remove_abc import OnGroupRemoveABC
from modules_core.abc.events.on_guild_available_abc import OnGuildAvailableABC from gismo_core.abc.events.on_guild_available_abc import OnGuildAvailableABC
from modules_core.abc.events.on_guild_channel_create_abc import OnGuildChannelCreateABC from gismo_core.abc.events.on_guild_channel_create_abc import OnGuildChannelCreateABC
from modules_core.abc.events.on_guild_channel_delete_abc import OnGuildChannelDeleteABC from gismo_core.abc.events.on_guild_channel_delete_abc import OnGuildChannelDeleteABC
from modules_core.abc.events.on_guild_channel_pins_update_abc import OnGuildChannelPinsUpdateABC from gismo_core.abc.events.on_guild_channel_pins_update_abc import OnGuildChannelPinsUpdateABC
from modules_core.abc.events.on_guild_channel_update_abc import OnGuildChannelUpdateABC from gismo_core.abc.events.on_guild_channel_update_abc import OnGuildChannelUpdateABC
from modules_core.abc.events.on_guild_emojis_update_abc import OnGuildEmojisUpdateABC from gismo_core.abc.events.on_guild_emojis_update_abc import OnGuildEmojisUpdateABC
from modules_core.abc.events.on_guild_integrations_update_abc import OnGuildIntegrationsUpdateABC from gismo_core.abc.events.on_guild_integrations_update_abc import OnGuildIntegrationsUpdateABC
from modules_core.abc.events.on_guild_join_abc import OnGuildJoinABC from gismo_core.abc.events.on_guild_join_abc import OnGuildJoinABC
from modules_core.abc.events.on_guild_remove_abc import OnGuildRemoveABC from gismo_core.abc.events.on_guild_remove_abc import OnGuildRemoveABC
from modules_core.abc.events.on_guild_role_create_abc import OnGuildRoleCreateABC from gismo_core.abc.events.on_guild_role_create_abc import OnGuildRoleCreateABC
from modules_core.abc.events.on_guild_role_delete_abc import OnGuildRoleDeleteABC from gismo_core.abc.events.on_guild_role_delete_abc import OnGuildRoleDeleteABC
from modules_core.abc.events.on_guild_role_update_abc import OnGuildRoleUpdateABC from gismo_core.abc.events.on_guild_role_update_abc import OnGuildRoleUpdateABC
from modules_core.abc.events.on_guild_unavailable_abc import OnGuildUnavailableABC from gismo_core.abc.events.on_guild_unavailable_abc import OnGuildUnavailableABC
from modules_core.abc.events.on_guild_update_abc import OnGuildUpdateABC from gismo_core.abc.events.on_guild_update_abc import OnGuildUpdateABC
from modules_core.abc.events.on_invite_create_abc import OnInviteCreateABC from gismo_core.abc.events.on_invite_create_abc import OnInviteCreateABC
from modules_core.abc.events.on_invite_delete_abc import OnInviteDeleteABC from gismo_core.abc.events.on_invite_delete_abc import OnInviteDeleteABC
from modules_core.abc.events.on_member_ban_abc import OnMemberBanABC from gismo_core.abc.events.on_member_ban_abc import OnMemberBanABC
from modules_core.abc.events.on_member_join_abc import OnMemberJoinABC from gismo_core.abc.events.on_member_join_abc import OnMemberJoinABC
from modules_core.abc.events.on_member_remove_abc import OnMemberRemoveABC from gismo_core.abc.events.on_member_remove_abc import OnMemberRemoveABC
from modules_core.abc.events.on_member_unban_abc import OnMemberUnbanABC from gismo_core.abc.events.on_member_unban_abc import OnMemberUnbanABC
from modules_core.abc.events.on_member_update_abc import OnMemberUpdateABC from gismo_core.abc.events.on_member_update_abc import OnMemberUpdateABC
from modules_core.abc.events.on_message_abc import OnMessageABC from gismo_core.abc.events.on_message_abc import OnMessageABC
from modules_core.abc.events.on_message_delete_abc import OnMessageDeleteABC from gismo_core.abc.events.on_message_delete_abc import OnMessageDeleteABC
from modules_core.abc.events.on_message_edit_abc import OnMessageEditABC from gismo_core.abc.events.on_message_edit_abc import OnMessageEditABC
from modules_core.abc.events.on_private_channel_create_abc import OnPrivateChannelCreateABC from gismo_core.abc.events.on_private_channel_create_abc import OnPrivateChannelCreateABC
from modules_core.abc.events.on_private_channel_delete_abc import OnPrivateChannelDeleteABC from gismo_core.abc.events.on_private_channel_delete_abc import OnPrivateChannelDeleteABC
from modules_core.abc.events.on_private_channel_pins_update_abc import OnPrivateChannelPinsUpdateABC from gismo_core.abc.events.on_private_channel_pins_update_abc import OnPrivateChannelPinsUpdateABC
from modules_core.abc.events.on_private_channel_update_abc import OnPrivateChannelUpdateABC from gismo_core.abc.events.on_private_channel_update_abc import OnPrivateChannelUpdateABC
from modules_core.abc.events.on_reaction_add_abc import OnReactionAddABC from gismo_core.abc.events.on_reaction_add_abc import OnReactionAddABC
from modules_core.abc.events.on_reaction_clear_abc import OnReactionClearABC from gismo_core.abc.events.on_reaction_clear_abc import OnReactionClearABC
from modules_core.abc.events.on_reaction_clear_emoji_abc import OnReactionClearEmojiABC from gismo_core.abc.events.on_reaction_clear_emoji_abc import OnReactionClearEmojiABC
from modules_core.abc.events.on_reaction_remove_abc import OnReactionRemoveABC from gismo_core.abc.events.on_reaction_remove_abc import OnReactionRemoveABC
from modules_core.abc.events.on_ready_abc import OnReadyABC from gismo_core.abc.events.on_ready_abc import OnReadyABC
from modules_core.abc.events.on_relationship_add_abc import OnRelationshipAddABC from gismo_core.abc.events.on_relationship_add_abc import OnRelationshipAddABC
from modules_core.abc.events.on_relationship_remove_abc import OnRelationshipRemoveABC from gismo_core.abc.events.on_relationship_remove_abc import OnRelationshipRemoveABC
from modules_core.abc.events.on_relationship_update_abc import OnRelationshipUpdateABC from gismo_core.abc.events.on_relationship_update_abc import OnRelationshipUpdateABC
from modules_core.abc.events.on_resume_abc import OnResumeABC from gismo_core.abc.events.on_resume_abc import OnResumeABC
from modules_core.abc.events.on_typing_abc import OnTypingABC from gismo_core.abc.events.on_typing_abc import OnTypingABC
from modules_core.abc.events.on_user_update_abc import OnUserUpdateABC from gismo_core.abc.events.on_user_update_abc import OnUserUpdateABC
from modules_core.abc.events.on_voice_state_update_abc import OnVoiceStateUpdateABC from gismo_core.abc.events.on_voice_state_update_abc import OnVoiceStateUpdateABC
from modules_core.abc.events.on_webhooks_update_abc import OnWebhooksUpdateABC from gismo_core.abc.events.on_webhooks_update_abc import OnWebhooksUpdateABC
from modules_core.abc.module_abc import ModuleABC from gismo_core.abc.module_abc import ModuleABC
from modules_core.abc.module_service_abc import ModuleServiceABC from gismo_core.abc.module_service_abc import ModuleServiceABC
from gismo_core.commands_meta import CommandsMeta
class _MetaCogABC(ABCMeta, commands.CogMeta): pass class ModuleService(ModuleServiceABC, commands.Cog, metaclass=CommandsMeta):
def __init__(self, logger: LoggerABC, config: ConfigurationABC, services: ServiceProviderABC, env: ApplicationEnvironmentABC):
class ModuleService(ModuleServiceABC, commands.Cog, metaclass=_MetaCogABC):
def __init__(self, logger: LoggerABC, services: ServiceProviderABC, env: ApplicationEnvironmentABC):
self._logger = logger self._logger = logger
self._config = config
self._services = services self._services = services
self._env = env self._env = env
self._modules: List[ModuleABC] = List() self._modules: List[ModuleABC] = List()
@ -75,10 +76,20 @@ class ModuleService(ModuleServiceABC, commands.Cog, metaclass=_MetaCogABC):
module_types = self._modules.where(lambda m: issubclass(m, t)) module_types = self._modules.where(lambda m: issubclass(m, t))
modules = List(t) modules = List(t)
for module_type in module_types: for module_type in module_types:
module = self._services.get_service(module_type) module: ModuleABC = self._services.get_service(module_type)
if module is None: if module is None:
self._logger.warn(__name__, f'Module {module_type} not found in services!') self._logger.warn(__name__, f'Module {module_type} not found in services!')
break break
if (module.settings_type is not None):
with open(f'config/{String.convert_to_snake_case(type(module).__name__).lower()}.json', encoding='utf-8') as cfg:
json_cfg = json.load(cfg)
for id in json_cfg:
settings: ConfigurationModelABC = module.settings_type()
settings.from_dict(json_cfg[id])
self._config.add_configuration(f'{type(module).__name__}_{id}', settings)
self._logger.debug(__name__, f'Added config: {type(module).__name__}_{id}')
modules.append(module) modules.append(module)
return modules.order_by(lambda m: m.get_priority(t)) return modules.order_by(lambda m: m.get_priority(t))
@ -91,13 +102,17 @@ class ModuleService(ModuleServiceABC, commands.Cog, metaclass=_MetaCogABC):
self._logger.debug(__name__, f'Stopped {event} modules') self._logger.debug(__name__, f'Stopped {event} modules')
return return
func_name = String.convert_to_snake_case(event.__name__.split('ABC')[0]) try:
for module in modules: func_name = String.convert_to_snake_case(event.__name__.split('ABC')[0])
func = getattr(module, func_name) for module in modules:
await func(*args) self._logger.trace(__name__, f'Start {type(module)} module')
if not module.success: func = getattr(module, func_name)
self._logger.debug(__name__, f'Stopped propagation for {event} from {type(module)}') await func(*args)
break if not module.success:
self._logger.debug(__name__, f'Stopped propagation for {event} from {type(module)}')
break
except Exception as e:
self._logger.error(__name__, f'Start {event} modules failed', e)
self._logger.debug(__name__, f'Stopped {event} modules') self._logger.debug(__name__, f'Stopped {event} modules')

View File

@ -0,0 +1 @@
# imports

View File

@ -8,7 +8,6 @@ from cpl_core.logging.logger_abc import LoggerABC
from gismo_core.abc.bot_service_abc import BotServiceABC from gismo_core.abc.bot_service_abc import BotServiceABC
from gismo_core.abc.message_service_abc import MessageServiceABC from gismo_core.abc.message_service_abc import MessageServiceABC
from gismo_core.configuration.server_settings import ServerSettings
from gismo_data.abc.client_repository_abc import ClientRepositoryABC from gismo_data.abc.client_repository_abc import ClientRepositoryABC
from gismo_data.abc.known_user_repository_abc import KnownUserRepositoryABC from gismo_data.abc.known_user_repository_abc import KnownUserRepositoryABC
from gismo_data.abc.server_repository_abc import ServerRepositoryABC from gismo_data.abc.server_repository_abc import ServerRepositoryABC
@ -17,15 +16,19 @@ from gismo_data.abc.user_joined_server_repository_abc import \
from gismo_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC from gismo_data.abc.user_joined_voice_channel_abc import UserJoinedVoiceChannelRepositoryABC
from gismo_data.abc.user_repository_abc import UserRepositoryABC from gismo_data.abc.user_repository_abc import UserRepositoryABC
from gismo_data.model.known_user import KnownUser from gismo_data.model.known_user import KnownUser
from gismo_data.model.server import Server
from gismo_data.model.user import User from gismo_data.model.user import User
from gismo_data.model.user_joined_server import UserJoinedServer from gismo_data.model.user_joined_server import UserJoinedServer
from gismo_data.model.user_joined_voice_channel import UserJoinedVoiceChannel from gismo_data.model.user_joined_voice_channel import UserJoinedVoiceChannel
from modules_core.abc.events.on_member_join_abc import OnMemberJoinABC from modules.base.base_settings import BaseSettings
from modules_core.abc.events.on_member_remove_abc import OnMemberRemoveABC from modules.base.service.base_command_service import BaseCommandService
from modules_core.abc.events.on_message_abc import OnMessageABC from modules.permission.abc.permission_service_abc import PermissionServiceABC
from modules_core.abc.events.on_voice_state_update_abc import \ from gismo_core.abc.events.on_member_join_abc import OnMemberJoinABC
from gismo_core.abc.events.on_member_remove_abc import OnMemberRemoveABC
from gismo_core.abc.events.on_message_abc import OnMessageABC
from gismo_core.abc.events.on_voice_state_update_abc import \
OnVoiceStateUpdateABC OnVoiceStateUpdateABC
from modules_core.abc.module_abc import ModuleABC from gismo_core.abc.module_abc import ModuleABC
class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceStateUpdateABC): class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceStateUpdateABC):
@ -42,7 +45,9 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
user_joins_vc: UserJoinedVoiceChannelRepositoryABC, user_joins_vc: UserJoinedVoiceChannelRepositoryABC,
bot: BotServiceABC, bot: BotServiceABC,
db: DatabaseContextABC, db: DatabaseContextABC,
messenger: MessageServiceABC messenger: MessageServiceABC,
permission_service: PermissionServiceABC,
base_command_service: BaseCommandService
): ):
self._config = config self._config = config
self._logger = logger self._logger = logger
@ -55,13 +60,23 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
self._bot = bot self._bot = bot
self._db = db self._db = db
self._messenger = messenger self._messenger = messenger
self._permission_service = permission_service
ModuleABC.__init__(self) ModuleABC.__init__(
self._priorities[OnMemberJoinABC] = 1 self,
self._priorities[OnMemberRemoveABC] = 1 {
self._priorities[OnMessageABC] = 30 OnMemberJoinABC: 1,
self._priorities[OnVoiceStateUpdateABC] = 10 OnMemberRemoveABC: 1,
self._logger.trace(__name__, f'Module {type(self)} loaded') OnMessageABC: 30,
OnVoiceStateUpdateABC: 10
},
BaseSettings
)
self._bot.add_cog(base_command_service)
self._logger.info(__name__, f'Module {type(self)} loaded')
def _get_config(self, g_id: int) -> BaseSettings:
return self._config.get_configuration(f'{type(self).__name__}_{g_id}')
def _apppend_received_message_count(self, g_id: int): def _apppend_received_message_count(self, g_id: int):
try: try:
@ -92,20 +107,14 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
async def _add_if_not_exists_user(self, member: Union[discord.User, discord.Member]): async def _add_if_not_exists_user(self, member: Union[discord.User, discord.Member]):
self._logger.debug(__name__, f'Check if user exists {member}') self._logger.debug(__name__, f'Check if user exists {member}')
settings: ServerSettings = self._config.get_configuration(f'DSERVER_{member.guild.id}') settings: BaseSettings = self._get_config(member.guild.id)
await self._messenger.send_dm_message(settings.welcome_message.format(member.guild.name), member) await self._messenger.send_dm_message(settings.welcome_message.format(member.guild.name), member)
for roleId in settings.admin_roles: for admin in self._permission_service.get_admins():
g: discord.Guild = member.guild await self._messenger.send_dm_message(settings.welcome_message_for_team.format(member.name), admin)
role: discord.Role = g.get_role(roleId)
for admin in role.members:
await self._messenger.send_dm_message(settings.welcome_message_for_team.format(member.name), admin)
for roleId in settings.moderator_roles: for moderator in self._permission_service.get_moderators():
g: discord.Guild = member.guild await self._messenger.send_dm_message(settings.welcome_message_for_team.format(member.name), moderator)
role: discord.Role = g.get_role(roleId)
for mod in role.members:
await self._messenger.send_dm_message(settings.welcome_message_for_team.format(member.name), mod)
try: try:
server = self._servers.get_server_by_discord_id(member.guild.id) server = self._servers.get_server_by_discord_id(member.guild.id)
@ -126,7 +135,7 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
async def _remove_user(self, member: Union[discord.User, discord.Member]): async def _remove_user(self, member: Union[discord.User, discord.Member]):
self._logger.debug(__name__, f'Remove user {member}') self._logger.debug(__name__, f'Remove user {member}')
settings: ServerSettings = self._config.get_configuration(f'DSERVER_{member.guild.id}') settings: BaseSettings = self._get_config(member.guild.id)
await self._messenger.send_dm_message(settings.goodbye_message, member) await self._messenger.send_dm_message(settings.goodbye_message, member)
try: try:
@ -144,10 +153,10 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
except Exception as e: except Exception as e:
self._logger.error(__name__, f'Cannot get user {member.id}', e) self._logger.error(__name__, f'Cannot get user {member.id}', e)
def _update_voice_state(self, joined: bool, dc_user_id: int, dc_channel_id: int, srv_id: int): def _update_voice_state(self, joined: bool, dc_user_id: int, dc_channel_id: int, server: Server):
user: User = None user: User = None
try: try:
user = self._users.get_user_by_discord_id_and_server_id(dc_user_id, srv_id) user = self._users.get_user_by_discord_id_and_server_id(dc_user_id, server.server_id)
except Exception as e: except Exception as e:
self._logger.error(__name__, f'Cannot get user {dc_user_id}', e) self._logger.error(__name__, f'Cannot get user {dc_user_id}', e)
return return
@ -163,7 +172,7 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
self._db.save_changes() self._db.save_changes()
return return
server_st: ServerSettings = self._config.get_configuration(f'DSERVER_{user.server.discord_server_id}') settings: BaseSettings = self._get_config(server.discord_server_id)
join = self._user_joins_vc.get_active_user_joined_voice_channel_by_user_id(user.user_id) join = self._user_joins_vc.get_active_user_joined_voice_channel_by_user_id(user.user_id)
join.leaved_on = datetime.now() join.leaved_on = datetime.now()
@ -171,7 +180,7 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
# ontime as hours # ontime as hours
ontime = round((join.leaved_on - join.joined_on).total_seconds()/3600, 2) ontime = round((join.leaved_on - join.joined_on).total_seconds()/3600, 2)
old_xp = user.xp old_xp = user.xp
user.xp += round(ontime * server_st.xp_per_ontime_hour) user.xp += round(ontime * settings.xp_per_ontime_hour)
self._user_joins_vc.update_user_joined_voice_channel(join) self._user_joins_vc.update_user_joined_voice_channel(join)
self._users.update_user(user) self._users.update_user(user)
@ -200,9 +209,9 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
self._logger.error(__name__, f'User not found {dc_user_id}') self._logger.error(__name__, f'User not found {dc_user_id}')
return return
server_st: ServerSettings = self._config.get_configuration(f'DSERVER_{user.server.discord_server_id}') settings: BaseSettings = self._get_config(message.guild.id)
old_xp = user.xp old_xp = user.xp
user.xp += server_st._xp_per_message user.xp += settings._xp_per_message
self._users.update_user(user) self._users.update_user(user)
self._db.save_changes() self._db.save_changes()
@ -230,29 +239,29 @@ class Base(ModuleABC, OnMemberJoinABC, OnMemberRemoveABC, OnMessageABC, OnVoiceS
self._logger.debug(__name__, f'Module {type(self)} started') self._logger.debug(__name__, f'Module {type(self)} started')
self._logger.trace(__name__, f'Detected on_voice_state_update {member.id} from {before} to {after}') self._logger.trace(__name__, f'Detected on_voice_state_update {member.id} from {before} to {after}')
u: discord.User = member u: discord.User = member
server_st: ServerSettings = self._config.get_configuration(f'DSERVER_{member.guild.id}') settings: BaseSettings = self._get_config(member.guild.id)
server = self._servers.get_server_by_discord_id(member.guild.id) server = self._servers.get_server_by_discord_id(member.guild.id)
try: try:
# join # join
if before.channel is None and after.channel is not None and after.channel.id not in server_st.afk_channel_ids: if before.channel is None and after.channel is not None and after.channel.id not in settings.afk_channel_ids:
self._logger.trace(__name__, f'User {u.id} joined {after.channel}') self._logger.trace(__name__, f'User {u.id} joined {after.channel}')
self._update_voice_state(True, member.id, after.channel.id, server.server_id) self._update_voice_state(True, member.id, after.channel.id, server.server_id)
# leave # leave
elif before.channel is not None and after.channel is None and before.channel.id not in server_st.afk_channel_ids: elif before.channel is not None and after.channel is None and before.channel.id not in settings.afk_channel_ids:
self._logger.trace(__name__, f'User {u.id} left {before.channel}') self._logger.trace(__name__, f'User {u.id} left {before.channel}')
self._update_voice_state(False, member.id, before.channel.id, server.server_id) self._update_voice_state(False, member.id, before.channel.id, server.server_id)
# channel to channel # channel to channel
elif before.channel is not None and after.channel is not None: elif before.channel is not None and after.channel is not None:
# joined # joined
if before.channel.id in server_st.afk_channel_ids and after.channel.id not in server_st.afk_channel_ids: if before.channel.id in settings.afk_channel_ids and after.channel.id not in settings.afk_channel_ids:
self._logger.trace(__name__, f'User {u.id} joined {after.channel}') self._logger.trace(__name__, f'User {u.id} joined {after.channel}')
self._update_voice_state(True, member.id, after.channel.id, server.server_id) self._update_voice_state(True, member.id, after.channel.id, server.server_id)
# left # left
elif after.channel.id in server_st.afk_channel_ids and before.channel.id not in server_st.afk_channel_ids: elif after.channel.id in settings.afk_channel_ids and before.channel.id not in settings.afk_channel_ids:
self._logger.trace(__name__, f'User {u.id} left {before.channel}') self._logger.trace(__name__, f'User {u.id} left {before.channel}')
self._update_voice_state(False, member.id, before.channel.id, server.server_id) self._update_voice_state(False, member.id, before.channel.id, server.server_id)

View File

@ -0,0 +1,72 @@
import traceback
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
from cpl_core.console import Console
class BaseSettings(ConfigurationModelABC):
def __init__(self):
ConfigurationModelABC.__init__(self)
self._welcome_message: str = ''
self._welcome_message_for_team: str = ''
self._goodbye_message: str = ''
self._max_voice_state_hours: int = 0
self._xp_per_message: int = 0
self._xp_per_ontime_hour: int = 0
self._afk_channel_ids: list[int] = []
self._purge_message: str = ''
self._no_permissions_message: str = ''
@property
def welcome_message(self) -> str:
return self._welcome_message
@property
def welcome_message_for_team(self) -> str:
return self._welcome_message_for_team
@property
def goodbye_message(self) -> str:
return self._goodbye_message
@property
def max_voice_state_hours(self) -> int:
return self._max_voice_state_hours
@property
def xp_per_message(self) -> int:
return self._xp_per_message
@property
def xp_per_ontime_hour(self) -> int:
return self._xp_per_ontime_hour
@property
def afk_channel_ids(self) -> list[int]:
return self._afk_channel_ids
@property
def purge_message(self) -> str:
return self._purge_message
@property
def no_permissions_message(self) -> str:
return self._no_permissions_message
def from_dict(self, settings: dict):
try:
self._welcome_message = settings['WelcomeMessage']
self._welcome_message_for_team = settings['WelcomeMessageForTeam']
self._goodbye_message = settings['GoodbyeMessage']
self._max_voice_state_hours = int(settings['MaxVoiceStateHours'])
self._xp_per_message = int(settings['XpPerMessage'])
self._xp_per_ontime_hour = int(settings['XpPerOntimeHour'])
for id in settings['AFKChannelIds']:
self._afk_channel_ids.append(int(id))
self._purge_message = settings['PurgeMessage']
self._no_permissions_message = settings['NoPermissionsMessage']
except Exception as e:
Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings')
Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')

View File

@ -0,0 +1 @@
# imports

View File

@ -0,0 +1,54 @@
import asyncio
import discord
from discord.ext import commands
from discord.ext.commands import Context
from cpl_core.logging import LoggerABC
from cpl_core.configuration import ConfigurationABC
from gismo_core.abc.command_abc import CommandABC
from gismo_core.abc.message_service_abc import MessageServiceABC
from gismo_core.configuration.server_settings import ServerSettings
from modules.base.base_settings import BaseSettings
from modules.permission.abc.permission_service_abc import PermissionServiceABC
class BaseCommandService(CommandABC):
def __init__(
self,
logger: LoggerABC,
config: ConfigurationABC,
message_service: MessageServiceABC,
permissions: PermissionServiceABC
):
CommandABC.__init__(self)
self._logger = logger
self._config = config
self._message_service = message_service
self._permissions = permissions
self._logger.trace(__name__, f'Loaded command service: {type(self).__name__}')
@commands.command()
async def ping(self, ctx: Context):
self._logger.debug(__name__, f'Received command ping {ctx}')
await self._message_service.send_ctx_msg(ctx, 'Pong')
self._logger.trace(__name__, f'Finished ping command')
@commands.command()
async def purge(self, ctx: Context):
self._logger.debug(__name__, f'Received command purge {ctx}')
settings: BaseSettings = self._config.get_configuration(f'Base_{ctx.guild.id}')
server_settings: ServerSettings = self._config.get_configuration(f'DSERVER_{ctx.guild.id}')
if (not self._permissions.is_member_moderator(ctx.author)):
await self._message_service.send_ctx_msg(ctx, settings.no_permissions_message)
self._logger.trace(__name__, f'Finished purge command')
return
await self._message_service.send_ctx_msg(ctx, settings.purge_message)
await asyncio.sleep(server_settings.message_delete_timer)
await ctx.channel.purge()
self._logger.trace(__name__, f'Finished purge command')

View File

@ -8,8 +8,9 @@ from discord import guild
from gismo_core.abc.bot_service_abc import BotServiceABC from gismo_core.abc.bot_service_abc import BotServiceABC
from gismo_core.abc.message_service_abc import MessageServiceABC from gismo_core.abc.message_service_abc import MessageServiceABC
from gismo_core.configuration.server_settings import ServerSettings from gismo_core.configuration.server_settings import ServerSettings
from modules_core.abc.events.on_ready_abc import OnReadyABC from modules.boot_log.boot_log_settings import BootLogSettings
from modules_core.abc.module_abc import ModuleABC from gismo_core.abc.events.on_ready_abc import OnReadyABC
from gismo_core.abc.module_abc import ModuleABC
class BootLog(ModuleABC, OnReadyABC): class BootLog(ModuleABC, OnReadyABC):
@ -27,9 +28,14 @@ class BootLog(ModuleABC, OnReadyABC):
self._bot = bot self._bot = bot
self._message_service = message_service self._message_service = message_service
ModuleABC.__init__(self) ModuleABC.__init__(
self._priorities[OnReadyABC] = 10 self,
self._logger.trace(__name__, f'Module {type(self)} loaded') {
OnReadyABC: 10
},
BootLogSettings
)
self._logger.info(__name__, f'Module {type(self)} loaded')
async def on_ready(self): async def on_ready(self):
self._logger.debug(__name__, f'Module {type(self)} started') self._logger.debug(__name__, f'Module {type(self)} started')
@ -55,18 +61,24 @@ class BootLog(ModuleABC, OnReadyABC):
g: guild = g g: guild = g
self._logger.debug(__name__, f'Server detected: {g.id}') self._logger.debug(__name__, f'Server detected: {g.id}')
server_settings: ServerSettings = self._config.get_configuration( server_settings: ServerSettings = self._config.get_configuration(f'DSERVER_{g.id}')
f'DSERVER_{g.id}')
if server_settings is None: if server_settings is None:
self._logger.error( self._logger.error(__name__, f'Config for server {g.id} not found!')
__name__, f'Config for server {g.id} not found!') await self._bot.close()
return
module_settings: BootLogSettings = self._config.get_configuration(f'{type(self).__name__}_{g.id}')
if module_settings is None:
self._logger.error(__name__, f'Config {type(self).__name__}_{g.id} not found!')
await self._bot.close() await self._bot.close()
return return
await self._message_service.send_channel_message( await self._message_service.send_channel_message(
self._bot.get_channel( self._bot.get_channel(
server_settings.login_message_channel_id), module_settings.login_message_channel_id
server_settings.login_message.format(init_time) ),
module_settings.login_message.format(init_time)
) )
self._logger.info(__name__, 'Bot is ready')
self._logger.trace(__name__, f'Module {type(self)} stopped') self._logger.trace(__name__, f'Module {type(self)} stopped')

View File

@ -0,0 +1,29 @@
import traceback
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
from cpl_core.console import Console
class BootLogSettings(ConfigurationModelABC):
def __init__(self):
ConfigurationModelABC.__init__(self)
self._login_message_channel_id: int = 0
self._login_message: str = ''
@property
def login_message_channel_id(self) -> int:
return self._login_message_channel_id
@property
def login_message(self) -> str:
return self._login_message
def from_dict(self, settings: dict):
try:
self._login_message_channel_id = int(settings['LoginMessageChannelId'])
self._login_message = settings['LoginMessage']
except Exception as e:
Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {__name__} settings')
Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')

View File

@ -21,8 +21,8 @@ from gismo_data.model.user import User
from gismo_data.model.user_joined_server import UserJoinedServer from gismo_data.model.user_joined_server import UserJoinedServer
from gismo_data.model.user_joined_voice_channel import UserJoinedVoiceChannel from gismo_data.model.user_joined_voice_channel import UserJoinedVoiceChannel
from gismo_data.service.user_repository_service import ServerRepositoryABC from gismo_data.service.user_repository_service import ServerRepositoryABC
from modules_core.abc.events.on_ready_abc import OnReadyABC from gismo_core.abc.events.on_ready_abc import OnReadyABC
from modules_core.abc.module_abc import ModuleABC from gismo_core.abc.module_abc import ModuleABC
class Database(ModuleABC, OnReadyABC): class Database(ModuleABC, OnReadyABC):
@ -52,9 +52,12 @@ class Database(ModuleABC, OnReadyABC):
self._user_joins = user_joins self._user_joins = user_joins
self._user_joins_vc = user_joins_vc self._user_joins_vc = user_joins_vc
ModuleABC.__init__(self) ModuleABC.__init__(
self._priorities[OnReadyABC] = 0 self,
self._logger.trace(__name__, f'Module {type(self)} loaded') { OnReadyABC: 0 },
None
)
self._logger.info(__name__, f'Module {type(self)} loaded')
def _validate_init_time(self): def _validate_init_time(self):
try: try:

View File

@ -0,0 +1 @@
# imports

View File

@ -0,0 +1 @@
# imports

View File

@ -0,0 +1,38 @@
from abc import ABC, abstractmethod
import discord
class PermissionServiceABC(ABC):
@abstractmethod
def __init__(self): pass
@abstractmethod
def on_ready(self): pass
@abstractmethod
def on_member_update(self, before: discord.Member, after: discord.Member): pass
@abstractmethod
def get_admin_role_ids(self, g_id: int) -> list[int]: pass
@abstractmethod
def get_admin_roles(self, g_id: int) -> list[discord.Role]: pass
@abstractmethod
def get_admins(self, g_id: int) -> list[discord.Member]: pass
@abstractmethod
def get_moderator_role_ids(self, g_id: int) -> list[int]: pass
@abstractmethod
def get_moderator_roles(self, g_id: int) -> list[discord.Role]: pass
@abstractmethod
def get_moderators(self, g_id: int) -> list[discord.Member]: pass
@abstractmethod
def is_member_admin(member: discord.Member) -> bool: pass
@abstractmethod
def is_member_moderator(member: discord.Member) -> bool: pass

View File

@ -0,0 +1,32 @@
import traceback
from cpl_core.configuration.configuration_model_abc import ConfigurationModelABC
from cpl_core.console import Console
class PermissionSettings(ConfigurationModelABC):
def __init__(self):
ConfigurationModelABC.__init__(self)
self._admin_roles: list[int] = []
self._moderator_roles: list[int] = []
@property
def admin_roles(self) -> list[int]:
return self._admin_roles
@property
def moderator_roles(self) -> list[int]:
return self._moderator_roles
def from_dict(self, settings: dict):
try:
for id in settings['AdminRoleIds']:
self._admin_roles.append(int(id))
for id in settings['ModeratorRoleIds']:
self._moderator_roles.append(int(id))
except Exception as e:
Console.error(f'[ ERROR ] [ {__name__} ]: Reading error in {self.__name__} settings')
Console.error(f'[ EXCEPTION ] [ {__name__} ]: {e} -> {traceback.format_exc()}')

View File

@ -0,0 +1,43 @@
{
"ProjectSettings": {
"Name": "modules/permission",
"Version": {
"Major": "0",
"Minor": "0",
"Micro": "0"
},
"Author": "",
"AuthorEmail": "",
"Description": "",
"LongDescription": "",
"URL": "",
"CopyrightDate": "",
"CopyrightName": "",
"LicenseName": "",
"LicenseDescription": "",
"Dependencies": [
"sh_cpl-core>=2021.11.0.post1"
],
"PythonVersion": ">=3.9.2",
"PythonPath": {
"linux": ""
},
"Classifiers": []
},
"BuildSettings": {
"ProjectType": "library",
"SourcePath": "",
"OutputPath": "../../dist",
"Main": "modules/permission.main",
"EntryPoint": "modules/permission",
"IncludePackageData": false,
"Included": [],
"Excluded": [
"*/__pycache__",
"*/logs",
"*/tests"
],
"PackageData": {},
"ProjectReferences": []
}
}

View File

@ -0,0 +1,37 @@
import discord
from cpl_core.logging import LoggerABC
from modules.permission.abc.permission_service_abc import PermissionServiceABC
from modules.permission.configuration.permission_settings import \
PermissionSettings
from gismo_core.abc.events.on_member_update_abc import OnMemberUpdateABC
from gismo_core.abc.events.on_ready_abc import OnReadyABC
from gismo_core.abc.module_abc import ModuleABC
class Permission(ModuleABC, OnReadyABC, OnMemberUpdateABC):
def __init__(
self,
logger: LoggerABC,
permission_service: PermissionServiceABC
):
self._logger = logger
self._permission_service = permission_service
ModuleABC.__init__(
self,
{ OnReadyABC: 1, OnMemberUpdateABC: 0 },
PermissionSettings
)
self._logger.info(__name__, f'Module {type(self)} loaded')
async def on_ready(self):
self._logger.debug(__name__, f'Module {type(self)} started')
self._permission_service.on_ready()
async def on_member_update(self, before: discord.Member, after: discord.Member):
self._logger.debug(__name__, f'Module {type(self)} started')
if before.roles != after.roles:
self._permission_service.on_member_update(before, after)

View File

@ -0,0 +1 @@
# imports

View File

@ -0,0 +1,114 @@
import discord
from cpl_core.logging import LoggerABC
from cpl_core.configuration import ConfigurationABC
from gismo_core.abc.bot_service_abc import BotServiceABC
from modules.permission.abc.permission_service_abc import PermissionServiceABC
from modules.permission.configuration.permission_settings import PermissionSettings
class PermissionService(PermissionServiceABC):
def __init__(self, logger: LoggerABC, bot: BotServiceABC, config: ConfigurationABC):
PermissionServiceABC.__init__(self)
self._logger = logger
self._bot = bot
self._config = config
self._admin_role_ids: dict[str, list[int]] = {}
self._admin_roles: dict[list[discord.Role]] = {}
self._admins: dict[list[discord.Member]] = {}
self._moderator_role_ids: dict[list[int]] = {}
self._moderator_roles: dict[list[discord.Role]] = {}
self._moderators: dict[list[discord.Member]] = {}
def on_ready(self):
for guild in self._bot.guilds:
guild: discord.Guild = guild
self._logger.debug(__name__, f'Validate permission settings')
settings: PermissionSettings = self._config.get_configuration(f'Permission_{guild.id}')
if settings is None:
self._logger.error(__name__, 'Permission settings not found')
return
self._admin_role_ids[guild.id] = settings.admin_roles
self._moderator_role_ids[guild.id] = settings.moderator_roles
admin_roles = []
admins = []
mod_roles = []
mods = []
for role in guild.roles:
role: discord.Role = role
if role.id in self._admin_role_ids[guild.id]:
admin_roles.append(role)
self._logger.trace(__name__, f'Added admin role {role}')
for member in role.members:
admins.append(member)
self._logger.trace(__name__, f'Added admin {member}')
if role.id in self._moderator_role_ids[guild.id]:
mod_roles.append(role)
self._logger.trace(__name__, f'Added moderator role {role}')
for member in role.members:
mods.append(member)
self._logger.trace(__name__, f'Added moderator {member}')
self._admin_roles[guild.id] = admin_roles
self._admins[guild.id] = admins
self._moderator_roles[guild.id] = mod_roles
self._moderators[guild.id] = mods
def on_member_update(self, before: discord.Member, after: discord.Member):
g_id = after.guild.id
for admin_role in self._admin_roles[g_id]:
if admin_role in before.roles and admin_role not in after.roles:
self._admins[g_id].remove(after)
self._logger.trace(__name__, f'Removed {after.id} from admins')
elif admin_role in after.roles and admin_role not in before.roles:
self._admins[g_id].append(after)
self._logger.trace(__name__, f'Added {after.id} to admins')
for moderator_role in self._moderator_roles[g_id]:
if moderator_role in before.roles and moderator_role not in after.roles:
self._moderators[g_id].remove(after)
self._logger.trace(__name__, f'Removed {after.id} from moderators')
elif moderator_role in after.roles and moderator_role not in before.roles:
self._moderators[g_id].append(after)
self._logger.trace(__name__, f'Added {after.id} to moderators')
def get_admin_role_ids(self, g_id: int) -> list[int]:
return self._admin_role_ids[g_id]
def get_admin_roles(self, g_id: int) -> list[discord.Role]:
return self._admin_roles[g_id]
def get_admins(self, g_id: int) -> list[discord.Member]:
return self._admins[g_id]
def get_moderator_role_ids(self, g_id: int) -> list[int]:
return self._moderator_role_ids[g_id]
def get_moderator_roles(self, g_id: int) -> list[discord.Role]:
return self._moderator_roles[g_id]
def get_moderators(self, g_id: int) -> list[discord.Member]:
return self._moderators[g_id]
def is_member_admin(self, member: discord.Member) -> bool:
return member in self._admins[member.guild.id]
def is_member_moderator(self, member: discord.Member) -> bool:
return member in self._moderators[member.guild.id] or self.is_member_admin(member)

View File

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
"""
gismo sh-edraft Gismo
~~~~~~~~~~~~~~~~~~~
sh-edraft Dicord bot Gismo
:copyright: (c) 2021 - 2022 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'modules_core'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '0.3.0'
from collections import namedtuple
# imports
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='0', minor='3', micro='0')

View File

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
"""
gismo sh-edraft Gismo
~~~~~~~~~~~~~~~~~~~
sh-edraft Dicord bot Gismo
:copyright: (c) 2021 - 2022 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'modules_core.abc'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '0.3.0'
from collections import namedtuple
# imports
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='0', minor='3', micro='0')

View File

@ -1,6 +0,0 @@
from enum import Enum
class EventsEnum(Enum):
on_ready = 'on_ready'

View File

@ -1,44 +0,0 @@
{
"ProjectSettings": {
"Name": "modules-core",
"Version": {
"Major": "0",
"Minor": "1",
"Micro": "0"
},
"Author": "Sven Heidemann",
"AuthorEmail": "sven.heidemann@sh-edraft.de",
"Description": "sh-edraft Gismo - Modules core",
"LongDescription": "sh-edraft Dicord bot Gismo - Modules core",
"URL": "https://www.sh-edraft.de",
"CopyrightDate": "2021 - 2022",
"CopyrightName": "sh-edraft.de",
"LicenseName": "MIT",
"LicenseDescription": "MIT, see LICENSE for more details.",
"Dependencies": [
"sh_cpl-core>=2021.11.0",
"sh_cpl-query>=2021.11.0"
],
"PythonVersion": ">=3.9.2",
"PythonPath": {
"linux": "../../venv/bin/python"
},
"Classifiers": []
},
"BuildSettings": {
"ProjectType": "library",
"SourcePath": "",
"OutputPath": "../../dist",
"Main": "",
"EntryPoint": "",
"IncludePackageData": false,
"Included": [],
"Excluded": [
"*/__pycache__",
"*/logs",
"*/tests"
],
"PackageData": {},
"ProjectReferences": []
}
}

View File

@ -1,25 +0,0 @@
# -*- coding: utf-8 -*-
"""
gismo sh-edraft Gismo
~~~~~~~~~~~~~~~~~~~
sh-edraft Dicord bot Gismo
:copyright: (c) 2021 - 2022 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = 'modules_core.service'
__author__ = 'Sven Heidemann'
__license__ = 'MIT'
__copyright__ = 'Copyright (c) 2021 - 2022 sh-edraft.de'
__version__ = '0.3.0'
from collections import namedtuple
# imports
VersionInfo = namedtuple('VersionInfo', 'major minor micro')
version_info = VersionInfo(major='0', minor='3', micro='0')