Added discord impl #378

This commit is contained in:
Sven Heidemann 2023-09-28 17:00:30 +02:00
parent 3546d38f75
commit 0cc8d6f2c7
19 changed files with 280 additions and 16 deletions

View File

@ -16,6 +16,7 @@
"level": "src/modules/level/level.json", "level": "src/modules/level/level.json",
"permission": "src/modules/permission/permission.json", "permission": "src/modules/permission/permission.json",
"technician": "src/modules/technician/technician.json", "technician": "src/modules/technician/technician.json",
"short-role-name": "src/modules/_short_role_name/modules/short-role-name.json",
"checks": "tools/checks/checks.json", "checks": "tools/checks/checks.json",
"get-version": "tools/get_version/get-version.json", "get-version": "tools/get_version/get-version.json",
"post-build": "tools/post_build/post-build.json", "post-build": "tools/post_build/post-build.json",

View File

@ -68,6 +68,7 @@
"../modules/database/database.json", "../modules/database/database.json",
"../modules/level/level.json", "../modules/level/level.json",
"../modules/permission/permission.json", "../modules/permission/permission.json",
"../modules/short_role_name/short-role-name.json",
"../modules/technician/technician.json" "../modules/technician/technician.json"
] ]
} }

View File

@ -13,6 +13,7 @@ from modules.config.config_module import ConfigModule
from modules.database.database_module import DatabaseModule from modules.database.database_module import DatabaseModule
from modules.level.level_module import LevelModule from modules.level.level_module import LevelModule
from modules.permission.permission_module import PermissionModule from modules.permission.permission_module import PermissionModule
from modules.short_role_name.short_role_name_module import ShortRoleNameModule
from modules.technician.technician_module import TechnicianModule from modules.technician.technician_module import TechnicianModule
@ -35,6 +36,7 @@ class ModuleList:
ApiModule, ApiModule,
TechnicianModule, TechnicianModule,
AchievementsModule, AchievementsModule,
ShortRoleNameModule,
# has to be last! # has to be last!
BootLogModule, BootLogModule,
CoreExtensionModule, CoreExtensionModule,

View File

@ -23,3 +23,4 @@ class FeatureFlagsEnum(Enum):
version_in_presence = "VersionInPresence" version_in_presence = "VersionInPresence"
game_server = "GameServer" game_server = "GameServer"
sync_xp = "SyncXp" sync_xp = "SyncXp"
short_role_name = "ShortRoleName"

View File

@ -18,13 +18,14 @@ class FeatureFlagsSettings(ConfigurationModelABC):
FeatureFlagsEnum.moderator_module.value: False, # 02.10.2022 #48 FeatureFlagsEnum.moderator_module.value: False, # 02.10.2022 #48
FeatureFlagsEnum.permission_module.value: True, # 02.10.2022 #48 FeatureFlagsEnum.permission_module.value: True, # 02.10.2022 #48
FeatureFlagsEnum.config_module.value: True, # 19.07.2023 #127 FeatureFlagsEnum.config_module.value: True, # 19.07.2023 #127
FeatureFlagsEnum.short_role_name_module.value: False, # 28.09.2023 #378 FeatureFlagsEnum.short_role_name_module.value: True, # 28.09.2023 #378
# features # features
FeatureFlagsEnum.api_only.value: False, # 13.10.2022 #70 FeatureFlagsEnum.api_only.value: False, # 13.10.2022 #70
FeatureFlagsEnum.presence.value: True, # 03.10.2022 #56 FeatureFlagsEnum.presence.value: True, # 03.10.2022 #56
FeatureFlagsEnum.version_in_presence.value: False, # 21.03.2023 #253 FeatureFlagsEnum.version_in_presence.value: False, # 21.03.2023 #253
FeatureFlagsEnum.game_server.value: False, # 25.09.2023 #366 FeatureFlagsEnum.game_server.value: False, # 25.09.2023 #366
FeatureFlagsEnum.sync_xp.value: False, # 25.09.2023 #366 FeatureFlagsEnum.sync_xp.value: False, # 25.09.2023 #366
FeatureFlagsEnum.short_role_name.value: False, # 28.09.2023 #378
} }
def __init__(self, **kwargs: dict): def __init__(self, **kwargs: dict):

View File

@ -24,7 +24,6 @@ from bot_data.model.server_config import ServerConfig
from bot_data.model.user import User from bot_data.model.user import User
from bot_data.model.user_joined_server import UserJoinedServer from bot_data.model.user_joined_server import UserJoinedServer
from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel from bot_data.model.user_joined_voice_channel import UserJoinedVoiceChannel
from bot_data.service.seeder_service import SeederService
from bot_data.service.user_repository_service import ServerRepositoryABC from bot_data.service.user_repository_service import ServerRepositoryABC
from modules.achievements.achievement_service import AchievementService from modules.achievements.achievement_service import AchievementService
@ -34,7 +33,6 @@ class DataIntegrityService:
self, self,
config: ConfigurationABC, config: ConfigurationABC,
logger: DatabaseLogger, logger: DatabaseLogger,
seeder: SeederService,
bot: DiscordBotServiceABC, bot: DiscordBotServiceABC,
db_context: DatabaseContextABC, db_context: DatabaseContextABC,
server_repo: ServerRepositoryABC, server_repo: ServerRepositoryABC,
@ -51,7 +49,6 @@ class DataIntegrityService:
self._config = config self._config = config
self._logger = logger self._logger = logger
self._seeder = seeder
self._bot = bot self._bot = bot
self._db_context = db_context self._db_context = db_context
self._servers = server_repo self._servers = server_repo

View File

@ -1,5 +1,4 @@
from abc import ABC, abstractmethod from abc import ABC, abstractmethod
from typing import Optional
from cpl_query.extension import List from cpl_query.extension import List
@ -20,7 +19,7 @@ class ShortRoleNameRepositoryABC(ABC):
pass pass
@abstractmethod @abstractmethod
def find_short_role_name_by_role_id(self, role_id: int) -> Optional[ShortRoleName]: def find_short_role_names_by_role_id(self, role_id: int) -> List[ShortRoleName]:
pass pass
@abstractmethod @abstractmethod

View File

@ -58,13 +58,15 @@ class ShortRoleNameRepositoryService(ShortRoleNameRepositoryABC):
return self._short_role_name_from_result(result) return self._short_role_name_from_result(result)
def find_short_role_name_by_role_id(self, role_id: int) -> Optional[ShortRoleName]: def find_short_role_names_by_role_id(self, role_id: int) -> List[ShortRoleName]:
short_role_names = List(ShortRoleName)
self._logger.trace(__name__, f"Send SQL command: {ShortRoleName.get_select_by_role_id_string(role_id)}") self._logger.trace(__name__, f"Send SQL command: {ShortRoleName.get_select_by_role_id_string(role_id)}")
result = self._context.select(ShortRoleName.get_select_by_role_id_string(role_id)) results = self._context.select(ShortRoleName.get_select_by_role_id_string(role_id))
if result is None or len(result) == 0: for result in results:
return None self._logger.trace(__name__, f"Get short_role_name with id {result[0]}")
short_role_names.append(self._short_role_name_from_result(result))
return self._short_role_name_from_result(result[0]) return short_role_names
def get_short_role_names_by_server_id(self, server_id: int) -> List[ShortRoleName]: def get_short_role_names_by_server_id(self, server_id: int) -> List[ShortRoleName]:
short_role_names = List(ShortRoleName) short_role_names = List(ShortRoleName)

View File

@ -5,7 +5,6 @@ from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
from bot_core.abc.module_abc import ModuleABC from bot_core.abc.module_abc import ModuleABC
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_data.service.seeder_service import SeederService
from bot_graphql.abc.filter_abc import FilterABC from bot_graphql.abc.filter_abc import FilterABC
from bot_graphql.abc.query_abc import QueryABC from bot_graphql.abc.query_abc import QueryABC
from bot_graphql.filter.achievement_filter import AchievementFilter from bot_graphql.filter.achievement_filter import AchievementFilter
@ -147,5 +146,3 @@ class GraphQLModule(ModuleABC):
services.add_transient(QueryABC, UserJoinedGameServerMutation) services.add_transient(QueryABC, UserJoinedGameServerMutation)
services.add_transient(QueryABC, TechnicianConfigMutation) services.add_transient(QueryABC, TechnicianConfigMutation)
services.add_transient(QueryABC, ServerConfigMutation) services.add_transient(QueryABC, ServerConfigMutation)
services.add_transient(SeederService)

View File

@ -41,7 +41,7 @@ class ShortRoleNameMutation(QueryABC):
server, server,
) )
result = self._short_role_names.find_short_role_name_by_role_id(short_role_name.role_id) result = self._short_role_names.find_short_role_names_by_role_id(short_role_name.role_id)
if result is not None: if result is not None:
raise ValueError("Short name for role already exists") raise ValueError("Short name for role already exists")

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
"""
bot Keksdose bot
~~~~~~~~~~~~~~~~~~~
Discord bot for the Keksdose discord Server
:copyright: (c) 2022 - 2023 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = "modules.short_role_name"
__author__ = "Sven Heidemann"
__license__ = "MIT"
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
__version__ = "1.1.7"
from collections import namedtuple
# imports
VersionInfo = namedtuple("VersionInfo", "major minor micro")
version_info = VersionInfo(major="1", minor="1", micro="7")

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
"""
bot Keksdose bot
~~~~~~~~~~~~~~~~~~~
Discord bot for the Keksdose discord Server
:copyright: (c) 2022 - 2023 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = "modules.short_role_name.events"
__author__ = "Sven Heidemann"
__license__ = "MIT"
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
__version__ = "1.1.7"
from collections import namedtuple
# imports
VersionInfo = namedtuple("VersionInfo", "major minor micro")
version_info = VersionInfo(major="1", minor="1", micro="7")

View File

@ -0,0 +1,14 @@
import discord
from cpl_discord.events import OnMemberUpdateABC
from modules.short_role_name.service.short_role_name_service import ShortRoleNameService
class ShortRoleNameOnMemberUpdateEvent(OnMemberUpdateABC):
def __init__(self, service: ShortRoleNameService):
OnMemberUpdateABC.__init__(self)
self._service = service
async def on_member_update(self, before: discord.member.Member, after: discord.member.Member):
if before.roles != after.roles or before.name != after.name:
await self._service.check_short_role_names(after)

View File

@ -0,0 +1,26 @@
# -*- coding: utf-8 -*-
"""
bot Keksdose bot
~~~~~~~~~~~~~~~~~~~
Discord bot for the Keksdose discord Server
:copyright: (c) 2022 - 2023 sh-edraft.de
:license: MIT, see LICENSE for more details.
"""
__title__ = "modules.short_role_name.service"
__author__ = "Sven Heidemann"
__license__ = "MIT"
__copyright__ = "Copyright (c) 2022 - 2023 sh-edraft.de"
__version__ = "1.1.7"
from collections import namedtuple
# imports
VersionInfo = namedtuple("VersionInfo", "major minor micro")
version_info = VersionInfo(major="1", minor="1", micro="7")

View File

@ -0,0 +1,76 @@
import discord
from cpl_core.configuration import ConfigurationABC
from cpl_core.logging import LoggerABC
from cpl_discord.service import DiscordBotServiceABC
from cpl_query.extension import List
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_core.configuration.feature_flags_settings import FeatureFlagsSettings
from bot_data.abc.server_repository_abc import ServerRepositoryABC
from bot_data.abc.short_role_name_repository_abc import ShortRoleNameRepositoryABC
from bot_data.model.server_config import ServerConfig
from bot_data.model.short_role_name import ShortRoleName
from bot_data.model.short_role_name_position_enum import ShortRoleNamePositionEnum
class ShortRoleNameService:
def __init__(
self,
config: ConfigurationABC,
logger: LoggerABC,
bot: DiscordBotServiceABC,
server: ServerRepositoryABC,
short_role_names: ShortRoleNameRepositoryABC,
):
self._config = config
self._logger = logger
self._bot = bot
self._server = server
self._short_role_names = short_role_names
async def check_short_role_names(self, member: discord.Member):
self._logger.debug(__name__, f"Started short role name check for {member.id}")
settings: ServerConfig = self._config.get_configuration(f"ServerConfig_{member.guild.id}")
if not FeatureFlagsSettings.get_flag_from_dict(settings.feature_flags, FeatureFlagsEnum.short_role_name):
self._logger.debug(__name__, f"Feature not active")
return
if member == member.guild.owner:
return
before = ""
after = ""
new_nick = member.nick if member.nick is not None else member.name
role_ids = List(discord.Role, member.roles).select(lambda x: x.id)
server = self._server.get_server_by_discord_id(member.guild.id)
for short_role_name in self._short_role_names.get_short_role_names_by_server_id(server.id):
short_role_name: ShortRoleName = short_role_name
new_nick = new_nick.replace(f" [{short_role_name.short_name}]", "")
new_nick = new_nick.replace(f"[{short_role_name.short_name}] ", "")
new_nick = new_nick.replace(f"[{short_role_name.short_name}]", "")
if short_role_name.role_id not in role_ids:
continue
if short_role_name.position == ShortRoleNamePositionEnum.before:
before += f"[{short_role_name.short_name}] "
elif short_role_name.position == ShortRoleNamePositionEnum.after:
after += f" [{short_role_name.short_name}]"
if before != "":
new_nick = before + new_nick
if after != "":
new_nick = new_nick + after
if member.nick is None or member.nick == new_nick:
return
try:
self._logger.debug(__name__, f"Update member {member.id}")
await member.edit(nick=new_nick)
self._logger.debug(__name__, f"Updated member {member.id} {member.name}")
except Exception as e:
self._logger.error(__name__, f"Renaming member {member.name} failed", e)

View File

@ -0,0 +1,46 @@
{
"ProjectSettings": {
"Name": "short-role-name",
"Version": {
"Major": "0",
"Minor": "0",
"Micro": "0"
},
"Author": "",
"AuthorEmail": "",
"Description": "",
"LongDescription": "",
"URL": "",
"CopyrightDate": "",
"CopyrightName": "",
"LicenseName": "",
"LicenseDescription": "",
"Dependencies": [
"cpl-core>=2023.4.0.post5"
],
"DevDependencies": [
"cpl-cli>=2023.4.0.post3"
],
"PythonVersion": ">=3.10.4",
"PythonPath": {
"linux": ""
},
"Classifiers": []
},
"BuildSettings": {
"ProjectType": "library",
"SourcePath": "",
"OutputPath": "../../dist",
"Main": "short_role_name.main",
"EntryPoint": "short-role-name",
"IncludePackageData": false,
"Included": [],
"Excluded": [
"*/__pycache__",
"*/logs",
"*/tests"
],
"PackageData": {},
"ProjectReferences": []
}
}

View File

@ -0,0 +1,28 @@
from cpl_core.configuration import ConfigurationABC
from cpl_core.dependency_injection import ServiceCollectionABC
from cpl_core.environment import ApplicationEnvironmentABC
from cpl_discord.discord_event_types_enum import DiscordEventTypesEnum
from cpl_discord.service.discord_collection_abc import DiscordCollectionABC
from bot_core.abc.module_abc import ModuleABC
from bot_core.configuration.feature_flags_enum import FeatureFlagsEnum
from bot_data.abc.data_seeder_abc import DataSeederABC
from modules.short_role_name.events.short_role_name_on_member_update_event import ShortRoleNameOnMemberUpdateEvent
from modules.short_role_name.service.short_role_name_service import ShortRoleNameService
from modules.short_role_name.short_role_name_seeder import ShortRoleNameSeeder
class ShortRoleNameModule(ModuleABC):
def __init__(self, dc: DiscordCollectionABC):
ModuleABC.__init__(self, dc, FeatureFlagsEnum.short_role_name_module)
def configure_configuration(self, config: ConfigurationABC, env: ApplicationEnvironmentABC):
pass
def configure_services(self, services: ServiceCollectionABC, env: ApplicationEnvironmentABC):
services.add_transient(DataSeederABC, ShortRoleNameSeeder)
services.add_transient(ShortRoleNameService)
# commands
# events
self._dc.add_event(DiscordEventTypesEnum.on_member_update.value, ShortRoleNameOnMemberUpdateEvent)

View File

@ -0,0 +1,21 @@
from cpl_discord.service import DiscordBotServiceABC
from bot_data.abc.data_seeder_abc import DataSeederABC
from modules.short_role_name.service.short_role_name_service import ShortRoleNameService
class ShortRoleNameSeeder(DataSeederABC):
def __init__(
self,
bot: DiscordBotServiceABC,
short_role_name_service: ShortRoleNameService,
):
DataSeederABC.__init__(self)
self._bot = bot
self._short_role_name_service = short_role_name_service
async def seed(self):
for guild in self._bot.guilds:
for member in guild.members:
await self._short_role_name_service.check_short_role_names(member)

View File

@ -204,7 +204,7 @@ export class SidebarService {
this.serverAutoRoles.visible = this.hasFeature("AutoRoleModule") ? !!user?.isModerator : false; this.serverAutoRoles.visible = this.hasFeature("AutoRoleModule") ? !!user?.isModerator : false;
this.serverLevels.visible = this.hasFeature("LevelModule") ? !!user?.isModerator : false; this.serverLevels.visible = this.hasFeature("LevelModule") ? !!user?.isModerator : false;
this.serverAchievements.visible = this.hasFeature("AchievementsModule") ? !!user?.isModerator : false; this.serverAchievements.visible = this.hasFeature("AchievementsModule") ? !!user?.isModerator : false;
this.serverShortRoleNames.visible = this.hasFeature("ShortRoleNameModule") ? !!user?.isAdmin : false; this.serverShortRoleNames.visible = this.hasFeature("ShortRoleName") ? !!user?.isAdmin : false;
this.serverConfig.visible = !!user?.isAdmin || isTechnician.length > 0; this.serverConfig.visible = !!user?.isAdmin || isTechnician.length > 0;
} else { } else {