From f943247e7d04903e90f873700ef2ab8b08847650 Mon Sep 17 00:00:00 2001 From: Sheldan <5037282+Sheldan@users.noreply.github.com> Date: Thu, 10 Jun 2021 01:11:51 +0200 Subject: [PATCH] [OPB-25] implementation of FAQ commands --- README.md | 2 +- application/executable/pom.xml | 6 + application/oneplus-bot-modules/faq/pom.xml | 48 + .../faq/src/main/assembly/liquibase.xml | 18 + .../bot/modules/faq/command/DeleteFAQ.java | 75 + .../bot/modules/faq/command/ExportFAQ.java | 74 + .../oneplus/bot/modules/faq/command/FAQ.java | 115 ++ .../bot/modules/faq/command/FAQUsage.java | 85 + .../bot/modules/faq/command/ImportFAQ.java | 111 ++ .../modules/faq/command/ListFAQCommands.java | 63 + .../modules/faq/config/FAQFeatureConfig.java | 34 + .../faq/config/FAQFeatureDefinition.java | 15 + .../modules/faq/config/FAQFeatureMode.java | 15 + .../faq/config/FAQModuleDefinition.java | 21 + .../bot/modules/faq/config/FAQProperties.java | 10 + .../GlobalChannelGroupDelayActionConfig.java | 24 + ...GlobalChannelGroupDelayedActionConfig.java | 17 + .../GlobalChannelGroupSetupDelayedAction.java | 49 + .../converter/FAQCommandConfigConverter.java | 87 ++ .../ListFAQCommandsModelConverter.java | 58 + ...DuplicatedCommandNameOrAliasException.java | 29 + .../DuplicatedFAQCommandAliasException.java | 28 + .../FAQCommandAliasShadowingException.java | 28 + .../FAQCommandNotFoundException.java | 26 + ...ndResponseDuplicatedPositionException.java | 27 + ...obalFAQCommandConfigMismatchException.java | 26 + .../GlobalFAQCommandResponsesException.java | 28 + .../NoFAQResponseFoundException.java | 20 + .../FAQAsyncChannelGroupCreatedListener.java | 49 + .../FAQChannelGroupDeletedListener.java | 31 + .../command/config/FaqCommandConfig.java | 18 + .../config/FaqCommandResponseConfig.java | 16 + .../FaqCommandResponseEmbedAuthorConfig.java | 14 + .../FaqCommandResponseEmbedColorConfig.java | 18 + .../config/FaqCommandResponseEmbedConfig.java | 16 + .../FaqCommandResponseMessageConfig.java | 15 + .../command/faq/FAQResponseMessageModel.java | 33 + .../models/command/faq/FAQResponseModel.java | 18 + .../faquses/FAQCommandResponseUsage.java | 13 + .../command/faquses/FAQCommandUsage.java | 15 + .../models/command/faquses/FAQUsageModel.java | 14 + ...stFAQCommandsCommandChannelGroupModel.java | 11 + .../list/ListFAQCommandsCommandModel.java | 14 + .../command/list/ListFAQCommandsModel.java | 16 + .../faq/models/database/FAQChannelGroup.java | 34 + .../database/FAQChannelGroupCommand.java | 44 + .../faq/models/database/FAQCommand.java | 52 + .../faq/models/database/FAQCommandAlias.java | 31 + .../models/database/FAQCommandResponse.java | 55 + .../database/embed/ChannelGroupCommandId.java | 21 + .../database/embed/CommandResponseId.java | 23 + .../database/embed/FAQCommandAliasId.java | 21 + .../DuplicatedCommandNameExceptionModel.java | 14 + ...plicatedFAQCommandAliasExceptionModel.java | 14 + ...AQCommandAliasShadowingExceptionModel.java | 13 + .../FAQCommandNotFoundExceptionModel.java | 12 + ...ponseDuplicatedPositionExceptionModel.java | 13 + .../GlobalCommandResponseExceptionModel.java | 14 + ...AQCommandConfigMismatchExceptionModel.java | 13 + .../FAQChannelGroupCommandRepository.java | 16 + .../repository/FAQChannelGroupRepository.java | 13 + .../repository/FAQCommandAliasRepository.java | 14 + .../faq/repository/FAQCommandRepository.java | 17 + .../FAQCommandResponseRepository.java | 10 + .../faq/service/FAQResponseServiceBean.java | 175 +++ .../modules/faq/service/FAQServiceBean.java | 411 +++++ .../faq/service/FAQUsageServiceBean.java | 68 + .../faq/service/FAQValidationServiceBean.java | 41 + ...nnelGroupCommandManagementServiceBean.java | 77 + .../FAQChannelGroupManagementServiceBean.java | 47 + .../FAQCommandAliasManagementService.java | 53 + .../FAQCommandManagementServiceBean.java | 59 + ...QCommandResponseManagementServiceBean.java | 68 + .../faq/src/main/resources/faq.properties | 8 + .../resources/migrations/1.4.4/collection.xml | 11 + .../1.4.4/seedData/channel_group_type.xml | 16 + .../migrations/1.4.4/seedData/command.xml | 43 + .../migrations/1.4.4/seedData/data.xml | 13 + .../migrations/1.4.4/seedData/feature.xml | 14 + .../migrations/1.4.4/seedData/module.xml | 14 + .../1.4.4/tables/faq_channel_group.xml | 36 + .../tables/faq_channel_group_command.xml | 38 + .../migrations/1.4.4/tables/faq_command.xml | 45 + .../1.4.4/tables/faq_command_alias.xml | 39 + .../1.4.4/tables/faq_command_response.xml | 59 + .../migrations/1.4.4/tables/tables.xml | 14 + .../main/resources/migrations/dbchangelog.xsd | 1386 +++++++++++++++++ .../resources/migrations/faq-changeLog.xml | 10 + .../resources/validation/createScheme.json | 189 +++ .../news/{commands => command}/News.java | 2 +- .../{commands => command}/UpdateNews.java | 2 +- application/oneplus-bot-modules/pom.xml | 1 + deployment/image-packaging/pom.xml | 31 + .../deployment/config/artifact_versions.json | 7 +- pom.xml | 4 +- .../faq-templates/pom.xml | 43 + .../src/main/assembly/assembly.xml | 15 + .../FAQUsage_response_embed_en_US.ftl | 14 + .../commands/faq/FAQ_response_embed_en_US.ftl | 21 + ..._response_no_command_found_embed_en_US.ftl | 4 + .../listFAQCommands_response_embed_en_US.ftl | 20 + ...cated_command_or_alias_exception_en_US.ftl | 2 + ...ated_faq_command_alias_exception_en_US.ftl | 4 + ...ommand_alias_shadowing_exception_en_US.ftl | 3 + .../faq_command_not_found_exception_en_US.ftl | 2 + ...se_duplicated_position_exception_en_US.ftl | 3 + ...ommand_config_mismatch_exception_en_US.ftl | 2 + ..._faq_command_responses_exception_en_US.ftl | 2 + .../no_faq_response_found_exception_en_US.ftl | 1 + .../news-templates/pom.xml | 2 +- .../oneplus-bot-modules-templates/pom.xml | 1 + .../translations/faq-translations/pom.xml | 36 + .../src/main/assembly/assembly.xml | 15 + ...found_message_available_commands_en_US.ftl | 1 + ...esponse_no_command_found_message_en_US.ftl | 1 + ...ommand_found_message_no_commands_en_US.ftl | 1 + .../FAQ/help/FAQ_description_en_US.ftl | 1 + .../commands/FAQ/help/FAQ_long_help_en_US.ftl | 3 + .../FAQ/help/FAQ_parameter_channel_en_US.ftl | 1 + .../FAQ/help/FAQ_parameter_command_en_US.ftl | 1 + .../FAQUsage_command_display_en_US.ftl | 1 + .../FAQUsage/FAQUsage_no_usages_en_US.ftl | 1 + .../FAQUsage/FAQUsage_usage_display_en_US.ftl | 1 + .../help/FAQUsage_description_en_US.ftl | 1 + .../help/FAQUsage_long_help_en_US.ftl | 2 + .../FAQUsage_parameter_commandName_en_US.ftl | 1 + .../help/deleteFAQ_description_en_US.ftl | 1 + .../help/deleteFAQ_long_help_en_US.ftl | 2 + .../deleteFAQ_parameter_commandName_en_US.ftl | 1 + .../help/exportFAQ_description_en_US.ftl | 1 + .../help/exportFAQ_long_help_en_US.ftl | 2 + .../exportFAQ_parameter_commandName_en_US.ftl | 1 + .../help/importFAQ_description_en_US.ftl | 1 + .../help/importFAQ_long_help_en_US.ftl | 1 + .../help/importFAQ_parameter_file_en_US.ftl | 1 + .../listFAQCommands_description_en_US.ftl | 1 + .../help/listFAQCommands_long_help_en_US.ftl | 1 + ...ds_channel_group_display_aliases_en_US.ftl | 1 + ...AQCommands_channel_group_display_en_US.ftl | 1 + ...AQCommands_channel_groups_header_en_US.ftl | 1 + .../listFAQCommands_command_display_en_US.ftl | 1 + .../listFAQCommands_command_header_en_US.ftl | 1 + .../listFAQCommands_no_commands_en_US.ftl | 1 + .../channel_group_type_faq_name_en_US.ftl | 1 + .../en_US/config/feature_faq_en_US.ftl | 1 + .../module_faqModule_description_en_US.ftl | 1 + .../setup_global_channel_group_info_en_US.ftl | 1 + ...mmand_or_alias_exception_message_en_US.ftl | 1 + ..._command_alias_exception_message_en_US.ftl | 1 + ...lias_shadowing_exception_message_en_US.ftl | 1 + ...mand_not_found_exception_message_en_US.ftl | 1 + ...cated_position_exception_message_en_US.ftl | 1 + ...onfig_mismatch_exception_message_en_US.ftl | 2 + ...mand_responses_exception_message_en_US.ftl | 1 + ...response_found_exception_message_en_US.ftl | 1 + .../translations/news-translations/pom.xml | 2 +- templates/translations/pom.xml | 1 + 157 files changed, 5106 insertions(+), 10 deletions(-) create mode 100644 application/oneplus-bot-modules/faq/pom.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/assembly/liquibase.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/DeleteFAQ.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ExportFAQ.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/FAQ.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/FAQUsage.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ImportFAQ.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ListFAQCommands.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureConfig.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureDefinition.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureMode.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQModuleDefinition.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQProperties.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupDelayActionConfig.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupDelayedActionConfig.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupSetupDelayedAction.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/converter/FAQCommandConfigConverter.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/converter/ListFAQCommandsModelConverter.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/DuplicatedCommandNameOrAliasException.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/DuplicatedFAQCommandAliasException.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandAliasShadowingException.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandNotFoundException.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandResponseDuplicatedPositionException.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/GlobalFAQCommandConfigMismatchException.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/GlobalFAQCommandResponsesException.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/NoFAQResponseFoundException.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/listener/FAQAsyncChannelGroupCreatedListener.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/listener/FAQChannelGroupDeletedListener.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandConfig.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseConfig.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedAuthorConfig.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedColorConfig.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedConfig.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseMessageConfig.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faq/FAQResponseMessageModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faq/FAQResponseModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQCommandResponseUsage.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQCommandUsage.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQUsageModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsCommandChannelGroupModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsCommandModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQChannelGroup.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQChannelGroupCommand.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommand.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommandAlias.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommandResponse.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/ChannelGroupCommandId.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/CommandResponseId.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/FAQCommandAliasId.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/DuplicatedCommandNameExceptionModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/DuplicatedFAQCommandAliasExceptionModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandAliasShadowingExceptionModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandNotFoundExceptionModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandResponseDuplicatedPositionExceptionModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/GlobalCommandResponseExceptionModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/GlobalFAQCommandConfigMismatchExceptionModel.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQChannelGroupCommandRepository.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQChannelGroupRepository.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandAliasRepository.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandRepository.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandResponseRepository.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQResponseServiceBean.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQServiceBean.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQUsageServiceBean.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQValidationServiceBean.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQChannelGroupCommandManagementServiceBean.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQChannelGroupManagementServiceBean.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandAliasManagementService.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandManagementServiceBean.java create mode 100644 application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandResponseManagementServiceBean.java create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/faq.properties create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/collection.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/channel_group_type.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/command.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/data.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/feature.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/module.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_channel_group.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_channel_group_command.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command_alias.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command_response.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/tables.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/dbchangelog.xsd create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/migrations/faq-changeLog.xml create mode 100644 application/oneplus-bot-modules/faq/src/main/resources/validation/createScheme.json rename application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/{commands => command}/News.java (97%) rename application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/{commands => command}/UpdateNews.java (97%) create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/pom.xml create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/assembly/assembly.xml create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/FAQUsage/FAQUsage_response_embed_en_US.ftl create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/faq/FAQ_response_embed_en_US.ftl create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/faq/FAQ_response_no_command_found_embed_en_US.ftl create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_response_embed_en_US.ftl create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/duplicated_command_or_alias_exception_en_US.ftl create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/duplicated_faq_command_alias_exception_en_US.ftl create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_alias_shadowing_exception_en_US.ftl create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_not_found_exception_en_US.ftl create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_response_duplicated_position_exception_en_US.ftl create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/global_faq_command_config_mismatch_exception_en_US.ftl create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/global_faq_command_responses_exception_en_US.ftl create mode 100644 templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/no_faq_response_found_exception_en_US.ftl create mode 100644 templates/translations/faq-translations/pom.xml create mode 100644 templates/translations/faq-translations/src/main/assembly/assembly.xml create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_available_commands_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_no_commands_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_description_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_long_help_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_parameter_channel_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_parameter_command_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_command_display_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_no_usages_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_usage_display_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_description_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_long_help_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_parameter_commandName_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_description_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_long_help_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_parameter_commandName_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_description_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_long_help_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_parameter_commandName_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_description_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_long_help_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_parameter_file_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/help/listFAQCommands_description_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/help/listFAQCommands_long_help_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_group_display_aliases_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_group_display_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_groups_header_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_command_display_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_command_header_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_no_commands_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/config/channel_group_type_faq_name_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/config/feature_faq_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/config/module_faqModule_description_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/config/setup_global_channel_group_info_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/exception/duplicated_command_or_alias_exception_message_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/exception/duplicated_faq_command_alias_exception_message_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_alias_shadowing_exception_message_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_not_found_exception_message_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_response_duplicated_position_exception_message_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/exception/global_faq_command_config_mismatch_exception_message_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/exception/global_faq_command_responses_exception_message_en_US.ftl create mode 100644 templates/translations/faq-translations/src/main/resources/en_US/exception/no_faq_response_found_exception_message_en_US.ftl diff --git a/README.md b/README.md index 720c580..c18a86b 100644 --- a/README.md +++ b/README.md @@ -6,6 +6,6 @@ and most of them will be in [abstracto](https://github.com/Sheldan/abstracto), b The migration of the existing data from the database is handled via one time migration, and can be found [here](https://github.com/Sheldan/OnePlusBot-migration). Custom features which were ported - - [ ] FAQ + - [x] FAQ - [x] Setup channel handling - [x] Referral link handling diff --git a/application/executable/pom.xml b/application/executable/pom.xml index 8089a56..6df3350 100644 --- a/application/executable/pom.xml +++ b/application/executable/pom.xml @@ -154,6 +154,12 @@ ${project.version} + + dev.sheldan.oneplus.bot.application.modules + faq + ${project.version} + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/pom.xml b/application/oneplus-bot-modules/faq/pom.xml new file mode 100644 index 0000000..5fe6c55 --- /dev/null +++ b/application/oneplus-bot-modules/faq/pom.xml @@ -0,0 +1,48 @@ + + + + oneplus-bot-modules + dev.sheldan.oneplus.bot.application.modules + 1.4.4-SNAPSHOT + + 4.0.0 + + faq + + + 8 + 8 + + + + + + maven-assembly-plugin + + + src/main/assembly/liquibase.xml + + + + + make-assembly + package + + single + + + + + + + + + + com.google.code.gson + gson + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/assembly/liquibase.xml b/application/oneplus-bot-modules/faq/src/main/assembly/liquibase.xml new file mode 100644 index 0000000..8b4774f --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/assembly/liquibase.xml @@ -0,0 +1,18 @@ + + liquibase + + zip + + false + + + . + ${project.basedir}/src/main/resources/migrations + + **/* + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/DeleteFAQ.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/DeleteFAQ.java new file mode 100644 index 0000000..04f6615 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/DeleteFAQ.java @@ -0,0 +1,75 @@ +package dev.sheldan.oneplus.bot.modules.faq.command; + +import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; +import dev.sheldan.abstracto.core.command.config.CommandConfiguration; +import dev.sheldan.abstracto.core.command.config.HelpInfo; +import dev.sheldan.abstracto.core.command.config.Parameter; +import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.execution.CommandResult; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.abstracto.core.service.ChannelService; +import dev.sheldan.abstracto.core.service.JSONValidationService; +import dev.sheldan.abstracto.core.service.management.ServerManagementService; +import dev.sheldan.abstracto.core.utils.FileService; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition; +import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@Component +@Slf4j +public class DeleteFAQ extends AbstractConditionableCommand { + + @Autowired + private FileService fileService; + + @Autowired + private FAQServiceBean faqServiceBean; + + @Autowired + private ChannelService channelService; + + @Autowired + private JSONValidationService jsonValidationService; + + @Autowired + private ServerManagementService serverManagementService; + + @Override + public CompletableFuture executeAsync(CommandContext commandContext) { + List parameter = commandContext.getParameters().getParameters(); + String faqCommandName = (String) parameter.get(0); + AServer server = serverManagementService.loadServer(commandContext.getGuild()); + faqServiceBean.deleteFAQCommand(faqCommandName, server); + return CompletableFuture.completedFuture(CommandResult.fromSuccess()); + } + + @Override + public CommandConfiguration getConfiguration() { + Parameter fileAttachmentParameter = Parameter.builder().name("commandName").type(String.class).templated(true).build(); + List parameters = Arrays.asList(fileAttachmentParameter); + HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); + return CommandConfiguration.builder() + .name("deleteFAQ") + .module(FAQModuleDefinition.FAQ) + .parameters(parameters) + .supportsEmbedException(true) + .help(helpInfo) + .async(true) + .templated(true) + .causesReaction(true) + .build(); + } + + @Override + public FeatureDefinition getFeature() { + return FAQFeatureDefinition.FAQ; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ExportFAQ.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ExportFAQ.java new file mode 100644 index 0000000..300d695 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ExportFAQ.java @@ -0,0 +1,74 @@ +package dev.sheldan.oneplus.bot.modules.faq.command; + +import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; +import dev.sheldan.abstracto.core.command.config.CommandConfiguration; +import dev.sheldan.abstracto.core.command.config.HelpInfo; +import dev.sheldan.abstracto.core.command.config.Parameter; +import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.execution.CommandResult; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.abstracto.core.service.ChannelService; +import dev.sheldan.abstracto.core.service.management.ServerManagementService; +import dev.sheldan.abstracto.core.utils.FutureUtils; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition; +import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@Component +@Slf4j +public class ExportFAQ extends AbstractConditionableCommand { + + @Autowired + private FAQServiceBean faqServiceBean; + + @Autowired + private ServerManagementService serverManagementService; + + @Autowired + private ChannelService channelService; + + @Override + public CompletableFuture executeAsync(CommandContext commandContext) { + List parameters = commandContext.getParameters().getParameters(); + String configString; + AServer server = serverManagementService.loadServer(commandContext.getGuild().getIdLong()); + if(parameters.isEmpty()) { + configString = faqServiceBean.exportFAQConfig(server); + } else { + String commandName = (String) parameters.get(0); + configString = faqServiceBean.exportFAQConfig(commandName, server); + } + return FutureUtils.toSingleFutureGeneric(channelService.sendFileToChannel(configString, "faqConfig.json", commandContext.getChannel())) + .thenApply(unused -> CommandResult.fromSuccess()); + } + + @Override + public CommandConfiguration getConfiguration() { + Parameter commandNameParameter = Parameter.builder().name("commandName").type(String.class).optional(true).templated(true).build(); + List parameters = Arrays.asList(commandNameParameter); + HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); + return CommandConfiguration.builder() + .name("exportFAQ") + .module(FAQModuleDefinition.FAQ) + .parameters(parameters) + .supportsEmbedException(true) + .help(helpInfo) + .async(true) + .templated(true) + .causesReaction(true) + .build(); + } + + @Override + public FeatureDefinition getFeature() { + return FAQFeatureDefinition.FAQ; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/FAQ.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/FAQ.java new file mode 100644 index 0000000..33f4892 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/FAQ.java @@ -0,0 +1,115 @@ +package dev.sheldan.oneplus.bot.modules.faq.command; + +import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; +import dev.sheldan.abstracto.core.command.config.CommandConfiguration; +import dev.sheldan.abstracto.core.command.config.HelpInfo; +import dev.sheldan.abstracto.core.command.config.Parameter; +import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.execution.CommandResult; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.models.database.AChannel; +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.abstracto.core.service.ChannelService; +import dev.sheldan.abstracto.core.service.management.ChannelManagementService; +import dev.sheldan.abstracto.core.service.management.ServerManagementService; +import dev.sheldan.abstracto.core.utils.FutureUtils; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition; +import dev.sheldan.oneplus.bot.modules.faq.models.command.faq.FAQResponseModel; +import dev.sheldan.oneplus.bot.modules.faq.service.FAQResponseServiceBean; +import net.dv8tion.jda.api.entities.TextChannel; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@Component +public class FAQ extends AbstractConditionableCommand { + + @Autowired + private FAQResponseServiceBean faqService; + + @Autowired + private ChannelService channelService; + + @Autowired + private ServerManagementService serverManagementService; + + @Autowired + private ChannelManagementService channelManagementService; + + private static final String FAQ_RESPONSE_TEMPLATE_KEY = "FAQ_response"; + private static final String FAQ_RESPONSE_NO_COMMAND_FOUND_TEMPLATE_KEY = "FAQ_response_no_command_found"; + + @Override + public CompletableFuture executeAsync(CommandContext commandContext) { + List parameters = commandContext.getParameters().getParameters(); + String commandName; + if(!parameters.isEmpty()) { + commandName = (String) parameters.get(0); + TextChannel channel; + if (parameters.size() == 2) { + channel = (TextChannel) parameters.get(1); + } else { + channel = commandContext.getChannel(); + } + return faqService.loadFAQResponse(commandName, channel) + .thenCompose(faqResponseModel -> { + if (!faqResponseModel.getMessages().isEmpty()) { + List> messageFutures = new ArrayList<>(); + faqResponseModel + .getMessages() + .forEach(faqResponseMessageModel -> + messageFutures.add(FutureUtils. + toSingleFutureGeneric(channelService. + sendEmbedTemplateInTextChannelList(FAQ_RESPONSE_TEMPLATE_KEY, + faqResponseMessageModel, commandContext.getChannel())))); + return FutureUtils.toSingleFutureGeneric(messageFutures); + } else { + return FutureUtils + .toSingleFutureGeneric( + channelService. + sendEmbedTemplateInTextChannelList(FAQ_RESPONSE_NO_COMMAND_FOUND_TEMPLATE_KEY, + faqResponseModel, commandContext.getChannel())); + } + }) + .thenApply(unused -> CommandResult.fromSuccess()); + } else { + AServer server = serverManagementService.loadServer(commandContext.getGuild()); + AChannel channel = channelManagementService.loadChannel(commandContext.getChannel()); + FAQResponseModel model = faqService.getNoCommandFoundModel(server, channel); + return FutureUtils + .toSingleFutureGeneric( + channelService. + sendEmbedTemplateInTextChannelList(FAQ_RESPONSE_NO_COMMAND_FOUND_TEMPLATE_KEY, + model, commandContext.getChannel())) + .thenApply(unused -> CommandResult.fromSuccess()); + } + } + + @Override + public CommandConfiguration getConfiguration() { + Parameter commandNameParameter = Parameter.builder().name("command").type(String.class).templated(true).optional(true).build(); + Parameter channelParameter = Parameter.builder().name("channel").type(TextChannel.class).optional(true).templated(true).build(); + List parameters = Arrays.asList(commandNameParameter, channelParameter); + HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); + return CommandConfiguration.builder() + .name("FAQ") + .module(FAQModuleDefinition.FAQ) + .parameters(parameters) + .supportsEmbedException(true) + .help(helpInfo) + .async(true) + .templated(true) + .causesReaction(true) + .build(); + } + + @Override + public FeatureDefinition getFeature() { + return FAQFeatureDefinition.FAQ; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/FAQUsage.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/FAQUsage.java new file mode 100644 index 0000000..11a6c11 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/FAQUsage.java @@ -0,0 +1,85 @@ +package dev.sheldan.oneplus.bot.modules.faq.command; + +import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; +import dev.sheldan.abstracto.core.command.config.CommandConfiguration; +import dev.sheldan.abstracto.core.command.config.HelpInfo; +import dev.sheldan.abstracto.core.command.config.Parameter; +import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.execution.CommandResult; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.config.FeatureMode; +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.abstracto.core.service.ChannelService; +import dev.sheldan.abstracto.core.service.management.ServerManagementService; +import dev.sheldan.abstracto.core.utils.FutureUtils; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureMode; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition; +import dev.sheldan.oneplus.bot.modules.faq.models.command.faquses.FAQUsageModel; +import dev.sheldan.oneplus.bot.modules.faq.service.FAQUsageServiceBean; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; + +@Component +@Slf4j +public class FAQUsage extends AbstractConditionableCommand { + + @Autowired + private FAQUsageServiceBean faqUsageServiceBean; + + @Autowired + private ServerManagementService serverManagementService; + + @Autowired + private ChannelService channelService; + + private static final String FAQ_USAGE_RESPONSE_TEMPLATE_KEY = "FAQUsage_response"; + + @Override + public CompletableFuture executeAsync(CommandContext commandContext) { + List parameters = commandContext.getParameters().getParameters(); + FAQUsageModel model; + AServer server = serverManagementService.loadServer(commandContext.getGuild()); + if(parameters.isEmpty()) { + model = faqUsageServiceBean.getFAQUsageModel(server); + } else { + String commandName = (String) parameters.get(0); + model = faqUsageServiceBean.getFAQUsageModel(server, commandName); + } + + return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(FAQ_USAGE_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel())) + .thenApply(unused -> CommandResult.fromSuccess()); + } + + @Override + public CommandConfiguration getConfiguration() { + Parameter commandNameParameter = Parameter.builder().name("commandName").type(String.class).templated(true).optional(true).build(); + List parameters = Arrays.asList(commandNameParameter); + HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); + return CommandConfiguration.builder() + .name("FAQUsage") + .module(FAQModuleDefinition.FAQ) + .parameters(parameters) + .supportsEmbedException(true) + .help(helpInfo) + .async(true) + .templated(true) + .causesReaction(true) + .build(); + } + + @Override + public FeatureDefinition getFeature() { + return FAQFeatureDefinition.FAQ; + } + + @Override + public List getFeatureModeLimitations() { + return Arrays.asList(FAQFeatureMode.FAQ_USES); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ImportFAQ.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ImportFAQ.java new file mode 100644 index 0000000..71c7398 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ImportFAQ.java @@ -0,0 +1,111 @@ +package dev.sheldan.oneplus.bot.modules.faq.command; + +import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; +import dev.sheldan.abstracto.core.command.config.CommandConfiguration; +import dev.sheldan.abstracto.core.command.config.HelpInfo; +import dev.sheldan.abstracto.core.command.config.Parameter; +import dev.sheldan.abstracto.core.command.exception.AbstractoTemplatedException; +import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.execution.CommandResult; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.models.JSONValidationResult; +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.abstracto.core.service.ChannelService; +import dev.sheldan.abstracto.core.service.JSONValidationService; +import dev.sheldan.abstracto.core.service.management.ServerManagementService; +import dev.sheldan.abstracto.core.utils.FileService; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition; +import dev.sheldan.oneplus.bot.modules.faq.models.command.config.FaqCommandConfig; +import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean; +import dev.sheldan.oneplus.bot.modules.faq.service.FAQValidationServiceBean; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.FileUtils; +import org.everit.json.schema.ValidationException; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.io.File; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.List; +import java.util.concurrent.CompletableFuture; +import java.util.stream.Collectors; + +@Slf4j +@Component +public class ImportFAQ extends AbstractConditionableCommand { + + @Autowired + private FileService fileService; + + @Autowired + private FAQServiceBean faqServiceBean; + + @Autowired + private FAQValidationServiceBean faqValidationServiceBean; + + @Autowired + private ChannelService channelService; + + @Autowired + private JSONValidationService jsonValidationService; + + @Autowired + private ServerManagementService serverManagementService; + + @Override + public CompletableFuture executeAsync(CommandContext commandContext) { + List parameter = commandContext.getParameters().getParameters(); + File jsonConfigFile = (File) parameter.get(0); + try { + String jsonContent = FileUtils.readFileToString(jsonConfigFile, StandardCharsets.UTF_8); + JSONValidationResult result = faqValidationServiceBean.validateJSONForCreation(jsonContent); + if(result.getResult().equals(JSONValidationService.Result.SUCCESSFUL)) { + AServer server = serverManagementService.loadServer(commandContext.getGuild()); + List commands = faqServiceBean.loadFAQCommandsFromJson(jsonContent); + faqServiceBean.createOrUpdateFAQCommands(commands, server); + } else { + + List errors = jsonValidationService.getDetailedException(result.getExceptions()) + .stream() + .map(ValidationException::getMessage) + .collect(Collectors.toList()); + channelService.sendTextToChannel(String.join("\n", errors), commandContext.getChannel()); + } + return CompletableFuture.completedFuture(CommandResult.fromSuccess()); + } catch (IOException e) { + log.error("IO Exception when loading input file.", e); + throw new AbstractoTemplatedException("Failed to load json config.", "failed_to_set_template_exception", e); + } finally { + try { + fileService.safeDelete(jsonConfigFile); + } catch (IOException e) { + log.error("Failed to delete downloaded json file.", e); + } + } + } + + @Override + public CommandConfiguration getConfiguration() { + Parameter fileAttachmentParameter = Parameter.builder().name("file").type(File.class).templated(true).build(); + List parameters = Arrays.asList(fileAttachmentParameter); + HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); + return CommandConfiguration.builder() + .name("importFAQ") + .module(FAQModuleDefinition.FAQ) + .parameters(parameters) + .supportsEmbedException(true) + .help(helpInfo) + .async(true) + .templated(true) + .causesReaction(true) + .build(); + } + + @Override + public FeatureDefinition getFeature() { + return FAQFeatureDefinition.FAQ; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ListFAQCommands.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ListFAQCommands.java new file mode 100644 index 0000000..2207e27 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/command/ListFAQCommands.java @@ -0,0 +1,63 @@ +package dev.sheldan.oneplus.bot.modules.faq.command; + +import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; +import dev.sheldan.abstracto.core.command.config.CommandConfiguration; +import dev.sheldan.abstracto.core.command.config.HelpInfo; +import dev.sheldan.abstracto.core.command.execution.CommandContext; +import dev.sheldan.abstracto.core.command.execution.CommandResult; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.abstracto.core.service.ChannelService; +import dev.sheldan.abstracto.core.service.management.ServerManagementService; +import dev.sheldan.abstracto.core.utils.FutureUtils; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQModuleDefinition; +import dev.sheldan.oneplus.bot.modules.faq.models.command.list.ListFAQCommandsModel; +import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.concurrent.CompletableFuture; + +@Component +@Slf4j +public class ListFAQCommands extends AbstractConditionableCommand { + + @Autowired + private FAQServiceBean faqServiceBean; + + @Autowired + private ChannelService channelService; + + @Autowired + private ServerManagementService serverManagementService; + + private static final String LIST_FAQ_COMMANDS_RESPONSE_TEMPLATE_KEY = "listFAQCommands_response"; + + @Override + public CompletableFuture executeAsync(CommandContext commandContext) { + AServer server = serverManagementService.loadServer(commandContext.getGuild()); + ListFAQCommandsModel model = faqServiceBean.getCommandListingForServer(server); + return FutureUtils.toSingleFutureGeneric(channelService.sendEmbedTemplateInTextChannelList(LIST_FAQ_COMMANDS_RESPONSE_TEMPLATE_KEY, model, commandContext.getChannel())) + .thenApply(unused -> CommandResult.fromSuccess()); + } + + @Override + public CommandConfiguration getConfiguration() { + HelpInfo helpInfo = HelpInfo.builder().templated(true).build(); + return CommandConfiguration.builder() + .name("listFAQCommands") + .module(FAQModuleDefinition.FAQ) + .supportsEmbedException(true) + .help(helpInfo) + .async(true) + .templated(true) + .build(); + } + + @Override + public FeatureDefinition getFeature() { + return FAQFeatureDefinition.FAQ; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureConfig.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureConfig.java new file mode 100644 index 0000000..d88796f --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureConfig.java @@ -0,0 +1,34 @@ +package dev.sheldan.oneplus.bot.modules.faq.config; + +import dev.sheldan.abstracto.core.config.FeatureConfig; +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import dev.sheldan.abstracto.core.config.FeatureMode; +import dev.sheldan.abstracto.core.interactive.AutoDelayedAction; +import dev.sheldan.oneplus.bot.modules.faq.config.setup.GlobalChannelGroupDelayedActionConfig; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; + +@Component +public class FAQFeatureConfig implements FeatureConfig { + + @Autowired + private GlobalChannelGroupDelayedActionConfig globalChannelGroupDelayedActionConfig; + + @Override + public FeatureDefinition getFeature() { + return FAQFeatureDefinition.FAQ; + } + + @Override + public List getAutoSetupSteps() { + return Arrays.asList(globalChannelGroupDelayedActionConfig); + } + + @Override + public List getAvailableModes() { + return Arrays.asList(FAQFeatureMode.FAQ_USES); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureDefinition.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureDefinition.java new file mode 100644 index 0000000..ca49c63 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureDefinition.java @@ -0,0 +1,15 @@ +package dev.sheldan.oneplus.bot.modules.faq.config; + +import dev.sheldan.abstracto.core.config.FeatureDefinition; +import lombok.Getter; + +@Getter +public enum FAQFeatureDefinition implements FeatureDefinition { + FAQ("faq"); + + private String key; + + FAQFeatureDefinition(String key) { + this.key = key; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureMode.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureMode.java new file mode 100644 index 0000000..19677c3 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQFeatureMode.java @@ -0,0 +1,15 @@ +package dev.sheldan.oneplus.bot.modules.faq.config; + +import dev.sheldan.abstracto.core.config.FeatureMode; +import lombok.Getter; + +@Getter +public enum FAQFeatureMode implements FeatureMode { + FAQ_USES("faqUses"); + + private final String key; + + FAQFeatureMode(String key) { + this.key = key; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQModuleDefinition.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQModuleDefinition.java new file mode 100644 index 0000000..66f2d07 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQModuleDefinition.java @@ -0,0 +1,21 @@ +package dev.sheldan.oneplus.bot.modules.faq.config; + +import dev.sheldan.abstracto.core.command.config.ModuleDefinition; +import dev.sheldan.abstracto.core.command.config.ModuleInfo; +import org.springframework.stereotype.Component; + +@Component +public class FAQModuleDefinition implements ModuleDefinition { + + public static final String FAQ = "faqModule"; + + @Override + public ModuleInfo getInfo() { + return ModuleInfo.builder().name(FAQ).templated(true).build(); + } + + @Override + public String getParentModule() { + return "default"; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQProperties.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQProperties.java new file mode 100644 index 0000000..d1e043f --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/FAQProperties.java @@ -0,0 +1,10 @@ +package dev.sheldan.oneplus.bot.modules.faq.config; + +import org.springframework.context.annotation.Configuration; +import org.springframework.context.annotation.PropertySource; + +@Configuration +@PropertySource("classpath:faq.properties") +public class FAQProperties { + +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupDelayActionConfig.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupDelayActionConfig.java new file mode 100644 index 0000000..bc3235b --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupDelayActionConfig.java @@ -0,0 +1,24 @@ +package dev.sheldan.oneplus.bot.modules.faq.config.setup; + +import dev.sheldan.abstracto.core.interactive.DelayedActionConfig; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class GlobalChannelGroupDelayActionConfig implements DelayedActionConfig { + + private Long serverId; + + @Override + public String getTemplateName() { + return "setup_global_channel_group_info"; + } + + @Override + public Object getTemplateModel() { + return new Object(); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupDelayedActionConfig.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupDelayedActionConfig.java new file mode 100644 index 0000000..4a92407 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupDelayedActionConfig.java @@ -0,0 +1,17 @@ +package dev.sheldan.oneplus.bot.modules.faq.config.setup; + +import dev.sheldan.abstracto.core.interactive.AutoDelayedAction; +import dev.sheldan.abstracto.core.interactive.DelayedActionConfig; +import dev.sheldan.abstracto.core.models.AServerChannelUserId; +import org.springframework.stereotype.Component; + +@Component +public class GlobalChannelGroupDelayedActionConfig implements AutoDelayedAction { + @Override + public DelayedActionConfig getDelayedActionConfig(AServerChannelUserId aServerChannelUserId) { + return GlobalChannelGroupDelayActionConfig + .builder() + .serverId(aServerChannelUserId.getGuildId()) + .build(); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupSetupDelayedAction.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupSetupDelayedAction.java new file mode 100644 index 0000000..7902664 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/config/setup/GlobalChannelGroupSetupDelayedAction.java @@ -0,0 +1,49 @@ +package dev.sheldan.oneplus.bot.modules.faq.config.setup; + +import dev.sheldan.abstracto.core.interactive.DelayedAction; +import dev.sheldan.abstracto.core.interactive.DelayedActionConfig; +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.abstracto.core.models.database.ChannelGroupType; +import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService; +import dev.sheldan.abstracto.core.service.management.ChannelGroupTypeManagementService; +import dev.sheldan.abstracto.core.service.management.ServerManagementService; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import static dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean.FAQ_CHANNEL_GROUP_KEY; + +@Component +@Slf4j +public class GlobalChannelGroupSetupDelayedAction implements DelayedAction { + + @Autowired + private ChannelGroupManagementService channelGroupManagementService; + + @Autowired + private ServerManagementService serverManagementService; + + @Autowired + private ChannelGroupTypeManagementService channelGroupTypeManagementService; + + @Value("${abstracto.faq.globalChannelGroupName}") + private String globalChannelGroupName; + + @Override + public void execute(DelayedActionConfig delayedActionConfig) { + GlobalChannelGroupDelayActionConfig config = (GlobalChannelGroupDelayActionConfig) delayedActionConfig; + AServer server = serverManagementService.loadServer(config.getServerId()); + if(!channelGroupManagementService.doesChannelGroupExist(globalChannelGroupName, server)) { + ChannelGroupType faqChannelGroupType = channelGroupTypeManagementService.findChannelGroupTypeByKey(FAQ_CHANNEL_GROUP_KEY); + channelGroupManagementService.createChannelGroup(globalChannelGroupName, server, faqChannelGroupType); + } else { + log.info("Global channel group named {} already exists for server {}.", globalChannelGroupName, config.getServerId()); + } + } + + @Override + public boolean handles(DelayedActionConfig delayedActionConfig) { + return delayedActionConfig instanceof GlobalChannelGroupDelayActionConfig; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/converter/FAQCommandConfigConverter.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/converter/FAQCommandConfigConverter.java new file mode 100644 index 0000000..d8b81e2 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/converter/FAQCommandConfigConverter.java @@ -0,0 +1,87 @@ +package dev.sheldan.oneplus.bot.modules.faq.converter; + +import com.google.gson.Gson; +import dev.sheldan.oneplus.bot.modules.faq.models.command.config.*; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Component +public class FAQCommandConfigConverter { + + @Autowired + private Gson gson; + + public String serializeCommands(List asList) { + List config = asList.stream().map(faqCommand -> { + List commandResponseConfigs = convertGroupCommands(faqCommand.getGroupResponses()); + List aliases; + if(faqCommand.getAliases() != null) { + aliases = faqCommand.getAliases().stream().map(faqCommandAlias -> faqCommandAlias.getId().getAlias()).collect(Collectors.toList()); + } else { + aliases = new ArrayList<>(); + } + return FaqCommandConfig + .builder() + .faqCommandName(faqCommand.getName()) + .global(faqCommand.getGlobal()) + .responses(commandResponseConfigs) + .aliases(aliases) + .build(); + }).collect(Collectors.toList()); + + return gson.toJson(config); + } + + private List convertGroupCommands(List responses) { + return responses.stream().map(faqChannelGroupCommand -> { + List responseConfigs = convertCommandResponses(faqChannelGroupCommand.getResponses()); + return FaqCommandResponseConfig + .builder() + .channelGroupName(faqChannelGroupCommand.getChannelGroup().getChannelGroup().getGroupName()) + .messages(responseConfigs) + .build(); + }).collect(Collectors.toList()); + } + + private List convertCommandResponses(List responses) { + return responses.stream().map(this::convertCommandResponse).collect(Collectors.toList()); + } + + private FaqCommandResponseMessageConfig convertCommandResponse(FAQCommandResponse response) { + FaqCommandResponseEmbedConfig embedConfig = null; + if(response.getDescription() != null) { + FaqCommandResponseEmbedColorConfig colorConfig = FaqCommandResponseEmbedColorConfig + .builder() + .red(response.getRed()) + .green(response.getGreen()) + .blue(response.getBlue()) + .build(); + FaqCommandResponseEmbedAuthorConfig authorConfig = FaqCommandResponseEmbedAuthorConfig + .builder() + .userId(response.getAuthorUserId()) + .useBot(null) + .build(); + embedConfig = FaqCommandResponseEmbedConfig + .builder() + .description(response.getDescription()) + .imageUrl(response.getImageURL()) + .color(colorConfig) + .author(authorConfig) + .build(); + } + return FaqCommandResponseMessageConfig + .builder() + .position(response.getId().getPosition()) + .additionalMessage(response.getAdditionalMessage()) + .embed(embedConfig) + .build(); + } + +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/converter/ListFAQCommandsModelConverter.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/converter/ListFAQCommandsModelConverter.java new file mode 100644 index 0000000..dde82ce --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/converter/ListFAQCommandsModelConverter.java @@ -0,0 +1,58 @@ +package dev.sheldan.oneplus.bot.modules.faq.converter; + +import dev.sheldan.abstracto.core.models.database.AChannelGroup; +import dev.sheldan.oneplus.bot.modules.faq.models.command.list.ListFAQCommandsCommandChannelGroupModel; +import dev.sheldan.oneplus.bot.modules.faq.models.command.list.ListFAQCommandsModel; +import dev.sheldan.oneplus.bot.modules.faq.models.command.list.ListFAQCommandsCommandModel; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand; +import org.springframework.stereotype.Component; + +import java.util.ArrayList; +import java.util.List; +import java.util.stream.Collectors; + +@Component +public class ListFAQCommandsModelConverter { + + public ListFAQCommandsModel fromFAQCommands(List faqCommandList) { + List commands = faqCommandList + .stream() + .map(this::convertCommand) + .collect(Collectors.toList()); + return ListFAQCommandsModel + .builder() + .commands(commands) + .build(); + } + + private ListFAQCommandsCommandModel convertCommand(FAQCommand faqCommand) { + List channelGroups = faqCommand + .getGroupResponses() + .stream() + .map(this::convertGroupCommand) + .collect(Collectors.toList()); + + List aliases; + if(faqCommand.getAliases() != null) { + aliases = faqCommand.getAliases().stream().map(faqCommandAlias -> faqCommandAlias.getId().getAlias()).collect(Collectors.toList()); + } else { + aliases = new ArrayList<>(); + } + return ListFAQCommandsCommandModel + .builder() + .commandName(faqCommand.getName()) + .aliases(aliases) + .channelGroups(channelGroups) + .build(); + } + + private ListFAQCommandsCommandChannelGroupModel convertGroupCommand(FAQChannelGroupCommand faqChannelGroupCommand) { + AChannelGroup channelGroup = faqChannelGroupCommand.getChannelGroup().getChannelGroup(); + return ListFAQCommandsCommandChannelGroupModel + .builder() + .responseCount(faqChannelGroupCommand.getResponses().size()) + .channelGroupName(channelGroup.getGroupName()) + .build(); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/DuplicatedCommandNameOrAliasException.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/DuplicatedCommandNameOrAliasException.java new file mode 100644 index 0000000..2e3c06b --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/DuplicatedCommandNameOrAliasException.java @@ -0,0 +1,29 @@ +package dev.sheldan.oneplus.bot.modules.faq.exception; + +import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException; +import dev.sheldan.oneplus.bot.modules.faq.models.exception.DuplicatedCommandNameExceptionModel; + +import java.util.List; + +public class DuplicatedCommandNameOrAliasException extends AbstractoTemplatableException { + + private final DuplicatedCommandNameExceptionModel model; + + public DuplicatedCommandNameOrAliasException(List commandKeys) { + super("Duplicated command name or alias found."); + this.model = DuplicatedCommandNameExceptionModel + .builder() + .duplicatedCommandKeys(commandKeys) + .build(); + } + + @Override + public String getTemplateName() { + return "duplicated_command_or_alias_exception"; + } + + @Override + public Object getTemplateModel() { + return this.model; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/DuplicatedFAQCommandAliasException.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/DuplicatedFAQCommandAliasException.java new file mode 100644 index 0000000..6fdb68b --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/DuplicatedFAQCommandAliasException.java @@ -0,0 +1,28 @@ +package dev.sheldan.oneplus.bot.modules.faq.exception; + +import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException; +import dev.sheldan.oneplus.bot.modules.faq.models.exception.DuplicatedFAQCommandAliasExceptionModel; + +public class DuplicatedFAQCommandAliasException extends AbstractoTemplatableException { + private final DuplicatedFAQCommandAliasExceptionModel model; + + public DuplicatedFAQCommandAliasException(String commandName, String alias, String usedCommand) { + super("Alias for FAQ command is already used as an alias in another name."); + this.model = DuplicatedFAQCommandAliasExceptionModel + .builder() + .alias(alias) + .commandName(commandName) + .originCommandName(usedCommand) + .build(); + } + + @Override + public String getTemplateName() { + return "duplicated_faq_command_alias_exception"; + } + + @Override + public Object getTemplateModel() { + return this.model; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandAliasShadowingException.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandAliasShadowingException.java new file mode 100644 index 0000000..0675094 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandAliasShadowingException.java @@ -0,0 +1,28 @@ +package dev.sheldan.oneplus.bot.modules.faq.exception; + +import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException; +import dev.sheldan.oneplus.bot.modules.faq.models.exception.FAQCommandAliasShadowingExceptionModel; + +public class FAQCommandAliasShadowingException extends AbstractoTemplatableException { + + private final FAQCommandAliasShadowingExceptionModel model; + + public FAQCommandAliasShadowingException(String commandName, String alias) { + super("Alias shadows another existing command."); + this.model = FAQCommandAliasShadowingExceptionModel + .builder() + .alias(alias) + .commandName(commandName) + .build(); + } + + @Override + public String getTemplateName() { + return "faq_command_alias_shadowing_exception"; + } + + @Override + public Object getTemplateModel() { + return this.model; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandNotFoundException.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandNotFoundException.java new file mode 100644 index 0000000..482d2b6 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandNotFoundException.java @@ -0,0 +1,26 @@ +package dev.sheldan.oneplus.bot.modules.faq.exception; + +import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException; +import dev.sheldan.oneplus.bot.modules.faq.models.exception.FAQCommandNotFoundExceptionModel; + +public class FAQCommandNotFoundException extends AbstractoTemplatableException { + private final FAQCommandNotFoundExceptionModel model; + + public FAQCommandNotFoundException(String commandName) { + super("FAQ command not found."); + this.model = FAQCommandNotFoundExceptionModel + .builder() + .commandName(commandName) + .build(); + } + + @Override + public String getTemplateName() { + return "faq_command_not_found_exception"; + } + + @Override + public Object getTemplateModel() { + return this.model; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandResponseDuplicatedPositionException.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandResponseDuplicatedPositionException.java new file mode 100644 index 0000000..180b689 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/FAQCommandResponseDuplicatedPositionException.java @@ -0,0 +1,27 @@ +package dev.sheldan.oneplus.bot.modules.faq.exception; + +import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException; +import dev.sheldan.oneplus.bot.modules.faq.models.exception.FAQCommandResponseDuplicatedPositionExceptionModel; + +public class FAQCommandResponseDuplicatedPositionException extends AbstractoTemplatableException { + private final FAQCommandResponseDuplicatedPositionExceptionModel model; + + public FAQCommandResponseDuplicatedPositionException(String commandName, String channelGroupName) { + super("Two messages within a FAQ command response have the same position."); + this.model = FAQCommandResponseDuplicatedPositionExceptionModel + .builder() + .channelGroupName(channelGroupName) + .commandName(commandName) + .build(); + } + + @Override + public String getTemplateName() { + return "faq_command_response_duplicated_position_exception"; + } + + @Override + public Object getTemplateModel() { + return this.model; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/GlobalFAQCommandConfigMismatchException.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/GlobalFAQCommandConfigMismatchException.java new file mode 100644 index 0000000..66590ed --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/GlobalFAQCommandConfigMismatchException.java @@ -0,0 +1,26 @@ +package dev.sheldan.oneplus.bot.modules.faq.exception; + +import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException; +import dev.sheldan.oneplus.bot.modules.faq.models.exception.GlobalFAQCommandConfigMismatchExceptionModel; + +public class GlobalFAQCommandConfigMismatchException extends AbstractoTemplatableException { + private final GlobalFAQCommandConfigMismatchExceptionModel model; + + public GlobalFAQCommandConfigMismatchException(String faqCommandName) { + super("The configuration for a global FAQ command does not make sense. It must be a the global FAQ channel group and the command needs to have global enabled."); + this.model = GlobalFAQCommandConfigMismatchExceptionModel + .builder() + .commandName(faqCommandName) + .build(); + } + + @Override + public String getTemplateName() { + return "global_faq_command_config_mismatch_exception"; + } + + @Override + public Object getTemplateModel() { + return this.model; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/GlobalFAQCommandResponsesException.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/GlobalFAQCommandResponsesException.java new file mode 100644 index 0000000..e15ef25 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/GlobalFAQCommandResponsesException.java @@ -0,0 +1,28 @@ +package dev.sheldan.oneplus.bot.modules.faq.exception; + +import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException; +import dev.sheldan.oneplus.bot.modules.faq.models.exception.GlobalCommandResponseExceptionModel; + +import java.util.List; + +public class GlobalFAQCommandResponsesException extends AbstractoTemplatableException { + private final GlobalCommandResponseExceptionModel model; + + public GlobalFAQCommandResponsesException(List commandNames) { + super("A global command can only have one response."); + this.model = GlobalCommandResponseExceptionModel + .builder() + .commandNames(commandNames) + .build(); + } + + @Override + public String getTemplateName() { + return "global_faq_command_responses_exception"; + } + + @Override + public Object getTemplateModel() { + return this.model; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/NoFAQResponseFoundException.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/NoFAQResponseFoundException.java new file mode 100644 index 0000000..858d882 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/exception/NoFAQResponseFoundException.java @@ -0,0 +1,20 @@ +package dev.sheldan.oneplus.bot.modules.faq.exception; + +import dev.sheldan.abstracto.core.exception.AbstractoTemplatableException; + +public class NoFAQResponseFoundException extends AbstractoTemplatableException { + + public NoFAQResponseFoundException() { + super("No FAQ Command response found."); + } + + @Override + public String getTemplateName() { + return "no_faq_response_found_exception"; + } + + @Override + public Object getTemplateModel() { + return new Object(); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/listener/FAQAsyncChannelGroupCreatedListener.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/listener/FAQAsyncChannelGroupCreatedListener.java new file mode 100644 index 0000000..9a15708 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/listener/FAQAsyncChannelGroupCreatedListener.java @@ -0,0 +1,49 @@ +package dev.sheldan.oneplus.bot.modules.faq.listener; + +import dev.sheldan.abstracto.core.listener.DefaultListenerResult; +import dev.sheldan.abstracto.core.listener.sync.entity.AsyncChannelGroupCreatedListener; +import dev.sheldan.abstracto.core.models.database.AChannelGroup; +import dev.sheldan.abstracto.core.models.listener.ChannelGroupCreatedListenerModel; +import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup; +import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean; +import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQChannelGroupManagementServiceBean; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +@Component +@Slf4j +public class FAQAsyncChannelGroupCreatedListener implements AsyncChannelGroupCreatedListener { + + @Autowired + private ChannelGroupManagementService channelGroupManagementService; + + @Autowired + private FAQChannelGroupManagementServiceBean faqChannelGroupManagementServiceBean; + + @Value("${abstracto.faq.globalChannelGroupName}") + private String globalChannelGroupName; + + @Override + public DefaultListenerResult execute(ChannelGroupCreatedListenerModel model) { + AChannelGroup channelGroup = channelGroupManagementService.findChannelGroupById(model.getChannelGroupId()); + if(channelGroup.getChannelGroupType().getGroupTypeKey().equals(FAQServiceBean.FAQ_CHANNEL_GROUP_KEY)) { + FAQChannelGroup createdChannelGroup = faqChannelGroupManagementServiceBean.createFAQChannelGroup(channelGroup); + if(channelGroup.getGroupName().equals(globalChannelGroupName)) { + Optional globalGroup = faqChannelGroupManagementServiceBean.getGlobalChannelGroup(channelGroup.getServer()); + globalGroup.ifPresent(faqChannelGroup -> { + log.info("Setting channel group {} to not be global for server {}.", faqChannelGroup.getId(), channelGroup.getServer().getId()); + faqChannelGroup.setGlobal(false); + }); + log.info("Setting channel group {} to be global for server {}.", channelGroup.getId(), channelGroup.getServer().getId()); + createdChannelGroup.setGlobal(true); + } + return DefaultListenerResult.PROCESSED; + } + return DefaultListenerResult.IGNORED; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/listener/FAQChannelGroupDeletedListener.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/listener/FAQChannelGroupDeletedListener.java new file mode 100644 index 0000000..69a2520 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/listener/FAQChannelGroupDeletedListener.java @@ -0,0 +1,31 @@ +package dev.sheldan.oneplus.bot.modules.faq.listener; + +import dev.sheldan.abstracto.core.listener.DefaultListenerResult; +import dev.sheldan.abstracto.core.listener.sync.entity.ChannelGroupDeletedListener; +import dev.sheldan.abstracto.core.models.database.AChannelGroup; +import dev.sheldan.abstracto.core.models.listener.ChannelGroupDeletedListenerModel; +import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService; +import dev.sheldan.oneplus.bot.modules.faq.service.FAQServiceBean; +import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQChannelGroupManagementServiceBean; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +@Component +public class FAQChannelGroupDeletedListener implements ChannelGroupDeletedListener { + + @Autowired + private FAQChannelGroupManagementServiceBean faqChannelGroupManagementServiceBean; + + @Autowired + private ChannelGroupManagementService channelGroupManagementService; + + @Override + public DefaultListenerResult execute(ChannelGroupDeletedListenerModel model) { + AChannelGroup channelGroup = channelGroupManagementService.findChannelGroupById(model.getChannelGroupId()); + if(channelGroup.getChannelGroupType().getGroupTypeKey().equals(FAQServiceBean.FAQ_CHANNEL_GROUP_KEY)) { + faqChannelGroupManagementServiceBean.deleteFAQChannelGroup(channelGroup); + return DefaultListenerResult.PROCESSED; + } + return DefaultListenerResult.IGNORED; + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandConfig.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandConfig.java new file mode 100644 index 0000000..c3c202d --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandConfig.java @@ -0,0 +1,18 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.config; + +import lombok.*; + +import java.util.List; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class FaqCommandConfig { + private String faqCommandName; + private Boolean global; + private List aliases; + private List responses; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseConfig.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseConfig.java new file mode 100644 index 0000000..fd1812d --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseConfig.java @@ -0,0 +1,16 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.config; + +import lombok.*; + +import java.util.List; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class FaqCommandResponseConfig { + private String channelGroupName; + private List messages; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedAuthorConfig.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedAuthorConfig.java new file mode 100644 index 0000000..dbdd01e --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedAuthorConfig.java @@ -0,0 +1,14 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.config; + +import lombok.*; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class FaqCommandResponseEmbedAuthorConfig { + private Long userId; + private Boolean useBot; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedColorConfig.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedColorConfig.java new file mode 100644 index 0000000..d763556 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedColorConfig.java @@ -0,0 +1,18 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.config; + +import lombok.*; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class FaqCommandResponseEmbedColorConfig { + @Builder.Default + private Integer red = 0; + @Builder.Default + private Integer green = 0; + @Builder.Default + private Integer blue = 0; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedConfig.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedConfig.java new file mode 100644 index 0000000..d8f41ca --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseEmbedConfig.java @@ -0,0 +1,16 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.config; + +import lombok.*; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class FaqCommandResponseEmbedConfig { + private String description; + private String imageUrl; + private FaqCommandResponseEmbedColorConfig color; + private FaqCommandResponseEmbedAuthorConfig author; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseMessageConfig.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseMessageConfig.java new file mode 100644 index 0000000..3905e22 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/config/FaqCommandResponseMessageConfig.java @@ -0,0 +1,15 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.config; + +import lombok.*; + +@Getter +@Setter +@Builder +@NoArgsConstructor +@AllArgsConstructor +@ToString +public class FaqCommandResponseMessageConfig { + private Integer position; + private String additionalMessage; + private FaqCommandResponseEmbedConfig embed; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faq/FAQResponseMessageModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faq/FAQResponseMessageModel.java new file mode 100644 index 0000000..f4218de --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faq/FAQResponseMessageModel.java @@ -0,0 +1,33 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.faq; + +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse; +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; +import net.dv8tion.jda.api.entities.User; + +@Getter +@Setter +@Builder +public class FAQResponseMessageModel { + private User author; + private String additionalMessage; + private String description; + private String imageURL; + private Integer red; + private Integer green; + private Integer blue; + + public static FAQResponseMessageModel fromFAQCommandResponse(FAQCommandResponse response, User user) { + return FAQResponseMessageModel + .builder() + .author(user) + .additionalMessage(response.getAdditionalMessage()) + .description(response.getDescription()) + .blue(response.getBlue()) + .green(response.getGreen()) + .red(response.getRed()) + .imageURL(response.getImageURL()) + .build(); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faq/FAQResponseModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faq/FAQResponseModel.java new file mode 100644 index 0000000..9b9e980 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faq/FAQResponseModel.java @@ -0,0 +1,18 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.faq; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.util.ArrayList; +import java.util.List; + +@Getter +@Setter +@Builder +public class FAQResponseModel { + @Builder.Default + private List messages = new ArrayList<>(); + @Builder.Default + private List availableCommands = new ArrayList<>(); +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQCommandResponseUsage.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQCommandResponseUsage.java new file mode 100644 index 0000000..8209786 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQCommandResponseUsage.java @@ -0,0 +1,13 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.faquses; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class FAQCommandResponseUsage { + private String channelGroupName; + private Integer uses; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQCommandUsage.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQCommandUsage.java new file mode 100644 index 0000000..8fbeac6 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQCommandUsage.java @@ -0,0 +1,15 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.faquses; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@Builder +public class FAQCommandUsage { + private String faqCommandName; + private List faqChannelGroupUsages; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQUsageModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQUsageModel.java new file mode 100644 index 0000000..ab23a3e --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/faquses/FAQUsageModel.java @@ -0,0 +1,14 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.faquses; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@Builder +public class FAQUsageModel { + private List uses; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsCommandChannelGroupModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsCommandChannelGroupModel.java new file mode 100644 index 0000000..7f57d18 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsCommandChannelGroupModel.java @@ -0,0 +1,11 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.list; + +import lombok.Builder; +import lombok.Getter; + +@Getter +@Builder +public class ListFAQCommandsCommandChannelGroupModel { + private String channelGroupName; + private Integer responseCount; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsCommandModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsCommandModel.java new file mode 100644 index 0000000..ba965a2 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsCommandModel.java @@ -0,0 +1,14 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.list; + +import lombok.Builder; +import lombok.Getter; + +import java.util.List; + +@Builder +@Getter +public class ListFAQCommandsCommandModel { + private String commandName; + private List aliases; + private List channelGroups; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsModel.java new file mode 100644 index 0000000..619e1fe --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/command/list/ListFAQCommandsModel.java @@ -0,0 +1,16 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.command.list; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Setter +@Builder +@Getter +public class ListFAQCommandsModel { + private List commands; +} + + diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQChannelGroup.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQChannelGroup.java new file mode 100644 index 0000000..0329785 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQChannelGroup.java @@ -0,0 +1,34 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.database; + +import dev.sheldan.abstracto.core.models.database.AChannelGroup; +import lombok.*; + +import javax.persistence.*; +import java.time.Instant; + +@Builder +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "faq_channel_group") +@Getter +@Setter +@EqualsAndHashCode +public class FAQChannelGroup { + @Id + @Column(name = "id") + private Long id; + + @OneToOne(fetch = FetchType.LAZY, cascade = {CascadeType.PERSIST, CascadeType.MERGE}) + @PrimaryKeyJoinColumn + private AChannelGroup channelGroup; + + @Column(name = "global") + private Boolean global; + + @Column(name = "created", nullable = false, insertable = false, updatable = false) + private Instant created; + + @Column(name = "updated", insertable = false, updatable = false) + private Instant updated; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQChannelGroupCommand.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQChannelGroupCommand.java new file mode 100644 index 0000000..de3c285 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQChannelGroupCommand.java @@ -0,0 +1,44 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.database; + +import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.ChannelGroupCommandId; +import lombok.*; + +import javax.persistence.*; +import java.io.Serializable; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +@Builder +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "faq_channel_group_command") +@EqualsAndHashCode +@Getter +@Setter +public class FAQChannelGroupCommand implements Serializable { + + @EmbeddedId + private ChannelGroupCommandId groupCommandId; + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("channelGroupId") + @JoinColumn(name = "channel_group_id", referencedColumnName = "id", nullable = false) + private FAQChannelGroup channelGroup; + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("commandId") + @JoinColumn(name = "command_id", referencedColumnName = "id", nullable = false) + private FAQCommand command; + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "groupCommand") + @Builder.Default + private List responses = new ArrayList<>(); + + @Column(name = "created", nullable = false, insertable = false, updatable = false) + private Instant created; + + @Column(name = "uses") + private Integer uses; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommand.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommand.java new file mode 100644 index 0000000..c5c3f49 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommand.java @@ -0,0 +1,52 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.database; + +import dev.sheldan.abstracto.core.models.database.AServer; +import lombok.*; + +import javax.persistence.*; +import java.io.Serializable; +import java.time.Instant; +import java.util.ArrayList; +import java.util.List; + +@Builder +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "faq_command") +@Getter +@Setter +@EqualsAndHashCode +public class FAQCommand implements Serializable { + + @Id + @GeneratedValue(strategy = GenerationType.IDENTITY) + @Column(name = "id") + private Long id; + + @Column(name = "name", length = 20) + private String name; + + @Column(name = "global") + private Boolean global; + + @Getter + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumn(name = "server_id", nullable = false) + private AServer server; + + @Column(name = "created", nullable = false, insertable = false, updatable = false) + private Instant created; + + @Column(name = "updated", insertable = false, updatable = false) + private Instant updated; + + @Getter + @OneToMany(fetch = FetchType.LAZY, mappedBy = "command") + @Builder.Default + private List groupResponses = new ArrayList<>(); + + @OneToMany(fetch = FetchType.LAZY, mappedBy = "command") + @Builder.Default + private List aliases = new ArrayList<>(); +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommandAlias.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommandAlias.java new file mode 100644 index 0000000..b169e98 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommandAlias.java @@ -0,0 +1,31 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.database; + +import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.FAQCommandAliasId; +import lombok.*; + +import javax.persistence.*; +import java.io.Serializable; +import java.time.Instant; + +@Builder +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "faq_command_alias") +@Getter +@Setter +@EqualsAndHashCode +public class FAQCommandAlias implements Serializable { + + @EmbeddedId + private FAQCommandAliasId id; + + @ManyToOne(fetch = FetchType.LAZY) + @MapsId("commandId") + @JoinColumn(name = "command_id", referencedColumnName = "id", nullable = false) + private FAQCommand command; + + @Column(name = "created", nullable = false, insertable = false, updatable = false) + private Instant created; + +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommandResponse.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommandResponse.java new file mode 100644 index 0000000..7771258 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/FAQCommandResponse.java @@ -0,0 +1,55 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.database; + +import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.CommandResponseId; +import lombok.*; + +import javax.persistence.*; +import java.time.Instant; + +@Builder +@Entity +@NoArgsConstructor +@AllArgsConstructor +@Table(name = "faq_command_response") +@Getter +@Setter +@EqualsAndHashCode +public class FAQCommandResponse { + @EmbeddedId + private CommandResponseId id; + + @Column(name = "description", length = 2000) + private String description; + + @Column(name = "additional_message", length = 2000) + private String additionalMessage; + + @Column(name = "image_url", length = 2000) + private String imageURL; + + @Column(name = "red") + private Integer red; + + @Column(name = "green") + private Integer green; + + @Column(name = "blue") + private Integer blue; + + @Column(name = "author_user_id") + private Long authorUserId; + + @ManyToOne(fetch = FetchType.LAZY) + @JoinColumns( + { + @JoinColumn(updatable = false, insertable = false, name = "channel_group_id", referencedColumnName = "channel_group_id"), + @JoinColumn(updatable = false, insertable = false, name = "command_id", referencedColumnName = "command_id") + }) + private FAQChannelGroupCommand groupCommand; + + @Column(name = "created", nullable = false, insertable = false, updatable = false) + private Instant created; + + @Column(name = "updated", insertable = false, updatable = false) + private Instant updated; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/ChannelGroupCommandId.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/ChannelGroupCommandId.java new file mode 100644 index 0000000..979251d --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/ChannelGroupCommandId.java @@ -0,0 +1,21 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.database.embed; + +import lombok.*; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.io.Serializable; + +@Embeddable +@Getter +@Setter +@Builder +@AllArgsConstructor +@NoArgsConstructor +@EqualsAndHashCode +public class ChannelGroupCommandId implements Serializable { + @Column(name = "channel_group_id") + private Long channelGroupId; + @Column(name = "command_id") + private Long commandId; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/CommandResponseId.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/CommandResponseId.java new file mode 100644 index 0000000..56ae46b --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/CommandResponseId.java @@ -0,0 +1,23 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.database.embed; + +import lombok.*; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.io.Serializable; + +@Embeddable +@Getter +@Setter +@EqualsAndHashCode +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class CommandResponseId implements Serializable { + @Column(name = "channel_group_id") + private Long channelGroupId; + @Column(name = "command_id") + private Long commandId; + @Column(name = "position") + private Integer position; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/FAQCommandAliasId.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/FAQCommandAliasId.java new file mode 100644 index 0000000..3b37c66 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/database/embed/FAQCommandAliasId.java @@ -0,0 +1,21 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.database.embed; + +import lombok.*; + +import javax.persistence.Column; +import javax.persistence.Embeddable; +import java.io.Serializable; + +@Embeddable +@Getter +@Setter +@EqualsAndHashCode +@Builder +@NoArgsConstructor +@AllArgsConstructor +public class FAQCommandAliasId implements Serializable { + @Column(name = "command_id") + private Long faqCommandId; + @Column(name = "alias", length = 20) + private String alias; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/DuplicatedCommandNameExceptionModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/DuplicatedCommandNameExceptionModel.java new file mode 100644 index 0000000..f5b0b68 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/DuplicatedCommandNameExceptionModel.java @@ -0,0 +1,14 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.exception; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@Builder +public class DuplicatedCommandNameExceptionModel { + private List duplicatedCommandKeys; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/DuplicatedFAQCommandAliasExceptionModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/DuplicatedFAQCommandAliasExceptionModel.java new file mode 100644 index 0000000..6e60ff1 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/DuplicatedFAQCommandAliasExceptionModel.java @@ -0,0 +1,14 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.exception; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class DuplicatedFAQCommandAliasExceptionModel { + private String commandName; + private String alias; + private String originCommandName; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandAliasShadowingExceptionModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandAliasShadowingExceptionModel.java new file mode 100644 index 0000000..1388c3b --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandAliasShadowingExceptionModel.java @@ -0,0 +1,13 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.exception; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class FAQCommandAliasShadowingExceptionModel { + private String commandName; + private String alias; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandNotFoundExceptionModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandNotFoundExceptionModel.java new file mode 100644 index 0000000..58c3639 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandNotFoundExceptionModel.java @@ -0,0 +1,12 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.exception; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class FAQCommandNotFoundExceptionModel { + private String commandName; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandResponseDuplicatedPositionExceptionModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandResponseDuplicatedPositionExceptionModel.java new file mode 100644 index 0000000..30235aa --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/FAQCommandResponseDuplicatedPositionExceptionModel.java @@ -0,0 +1,13 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.exception; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class FAQCommandResponseDuplicatedPositionExceptionModel { + private String commandName; + private String channelGroupName; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/GlobalCommandResponseExceptionModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/GlobalCommandResponseExceptionModel.java new file mode 100644 index 0000000..6b99409 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/GlobalCommandResponseExceptionModel.java @@ -0,0 +1,14 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.exception; + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +import java.util.List; + +@Getter +@Setter +@Builder +public class GlobalCommandResponseExceptionModel { + private List commandNames; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/GlobalFAQCommandConfigMismatchExceptionModel.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/GlobalFAQCommandConfigMismatchExceptionModel.java new file mode 100644 index 0000000..52238db --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/models/exception/GlobalFAQCommandConfigMismatchExceptionModel.java @@ -0,0 +1,13 @@ +package dev.sheldan.oneplus.bot.modules.faq.models.exception; + + +import lombok.Builder; +import lombok.Getter; +import lombok.Setter; + +@Getter +@Setter +@Builder +public class GlobalFAQCommandConfigMismatchExceptionModel { + private String commandName; +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQChannelGroupCommandRepository.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQChannelGroupCommandRepository.java new file mode 100644 index 0000000..6353f02 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQChannelGroupCommandRepository.java @@ -0,0 +1,16 @@ +package dev.sheldan.oneplus.bot.modules.faq.repository; + +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.ChannelGroupCommandId; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; + +@Repository +public interface FAQChannelGroupCommandRepository extends JpaRepository { + List findByChannelGroup(FAQChannelGroup faqChannelGroup); + List findByChannelGroup_IdIn(List channelGroupIds); + List findByChannelGroupIn(List faqChannelGroup); +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQChannelGroupRepository.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQChannelGroupRepository.java new file mode 100644 index 0000000..ed38a92 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQChannelGroupRepository.java @@ -0,0 +1,13 @@ +package dev.sheldan.oneplus.bot.modules.faq.repository; + +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface FAQChannelGroupRepository extends JpaRepository { + Optional findByChannelGroup_ServerAndGlobalTrue(AServer server); +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandAliasRepository.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandAliasRepository.java new file mode 100644 index 0000000..3522762 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandAliasRepository.java @@ -0,0 +1,14 @@ +package dev.sheldan.oneplus.bot.modules.faq.repository; + +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandAlias; +import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.FAQCommandAliasId; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.Optional; + +@Repository +public interface FAQCommandAliasRepository extends JpaRepository { + Optional findById_AliasAndCommand_Server(String alias, AServer server); +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandRepository.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandRepository.java new file mode 100644 index 0000000..1d3696e --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandRepository.java @@ -0,0 +1,17 @@ +package dev.sheldan.oneplus.bot.modules.faq.repository; + +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +import java.util.List; +import java.util.Optional; + +@Repository +public interface FAQCommandRepository extends JpaRepository { + Optional findByNameEqualsIgnoreCaseAndServer(String name, AServer server); + List findByNameInIgnoreCaseAndServer(List names, AServer server); + List findByServer(AServer server); + List findByServerAndGlobalTrue(AServer server); +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandResponseRepository.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandResponseRepository.java new file mode 100644 index 0000000..11b3c83 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/repository/FAQCommandResponseRepository.java @@ -0,0 +1,10 @@ +package dev.sheldan.oneplus.bot.modules.faq.repository; + +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse; +import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.CommandResponseId; +import org.springframework.data.jpa.repository.JpaRepository; +import org.springframework.stereotype.Repository; + +@Repository +public interface FAQCommandResponseRepository extends JpaRepository { +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQResponseServiceBean.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQResponseServiceBean.java new file mode 100644 index 0000000..78ab7ca --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQResponseServiceBean.java @@ -0,0 +1,175 @@ +package dev.sheldan.oneplus.bot.modules.faq.service; + +import dev.sheldan.abstracto.core.models.database.AChannel; +import dev.sheldan.abstracto.core.models.database.AChannelGroup; +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.abstracto.core.service.ChannelGroupService; +import dev.sheldan.abstracto.core.service.FeatureModeService; +import dev.sheldan.abstracto.core.service.UserService; +import dev.sheldan.abstracto.core.service.management.ChannelManagementService; +import dev.sheldan.abstracto.core.service.management.ServerManagementService; +import dev.sheldan.abstracto.core.utils.CompletableFutureList; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureDefinition; +import dev.sheldan.oneplus.bot.modules.faq.config.FAQFeatureMode; +import dev.sheldan.oneplus.bot.modules.faq.exception.NoFAQResponseFoundException; +import dev.sheldan.oneplus.bot.modules.faq.models.command.faq.FAQResponseMessageModel; +import dev.sheldan.oneplus.bot.modules.faq.models.command.faq.FAQResponseModel; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandAlias; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse; +import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQChannelGroupCommandManagementServiceBean; +import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQCommandAliasManagementService; +import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQCommandManagementServiceBean; +import lombok.extern.slf4j.Slf4j; +import net.dv8tion.jda.api.entities.ISnowflake; +import net.dv8tion.jda.api.entities.SelfUser; +import net.dv8tion.jda.api.entities.TextChannel; +import net.dv8tion.jda.api.entities.User; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; +import org.springframework.transaction.annotation.Transactional; + +import java.util.*; +import java.util.concurrent.CompletableFuture; +import java.util.function.Function; +import java.util.stream.Collectors; +import java.util.stream.Stream; + +@Component +@Slf4j +public class FAQResponseServiceBean { + + @Autowired + private ServerManagementService serverManagementService; + + @Autowired + private ChannelGroupService channelGroupService; + + @Autowired + private FAQCommandManagementServiceBean faqCommandManagementServiceBean; + + @Autowired + private FAQChannelGroupCommandManagementServiceBean faqChannelGroupCommandManagementServiceBean; + + @Autowired + private FAQCommandAliasManagementService faqCommandAliasManagementService; + + @Autowired + private ChannelManagementService channelManagementService; + + @Autowired + private UserService userService; + + @Autowired + private FeatureModeService featureModeService; + + @Autowired + private FAQResponseServiceBean self; + + public CompletableFuture loadFAQResponse(String commandName, TextChannel textChannel) { + AServer server = serverManagementService.loadServer(textChannel.getGuild().getIdLong()); + Optional faqCommandOptional = faqCommandManagementServiceBean.findByNameAndServer(commandName, server); + if(!faqCommandOptional.isPresent()) { + log.debug("Did not find the command, trying via command alias."); + Optional faqCommandAlias = faqCommandAliasManagementService.findByNameAndServer(commandName, server); + if(faqCommandAlias.isPresent()) { + faqCommandOptional = Optional.of(faqCommandAlias.get().getCommand()); + } + } + AChannel channel = channelManagementService.loadChannel(textChannel.getIdLong()); + if (!faqCommandOptional.isPresent()) { + log.debug("Did not find a faq response. Returning model with possible command names."); + return CompletableFuture.completedFuture(getNoCommandFoundModel(server, channel)); + } else { + FAQCommand command = faqCommandOptional.get(); + Optional groupCommand; + if(command.getGlobal()) { + groupCommand = command.getGroupResponses().stream().findAny(); + } else { + Stream matchingChannels = command + .getGroupResponses() + .stream() + .filter(faqChannelGroupCommand -> channelGroupService.isChannelInGroup(channel, faqChannelGroupCommand.getChannelGroup().getChannelGroup())); + List allMatchingCommands = matchingChannels.collect(Collectors.toList()); + if(allMatchingCommands.size() > 1) { + log.warn("There are multiple matching channel groups for command {} and channel {}.", command.getId(), channel.getId()); + } + if(!allMatchingCommands.isEmpty()) { + FAQChannelGroupCommand foundCommandChannelGroup = allMatchingCommands.get(0); + log.info("Using response from channel group {} for command {} in server {}.", foundCommandChannelGroup.getChannelGroup().getId(), command.getId(), server.getId()); + groupCommand = Optional.of(foundCommandChannelGroup); + } else { + groupCommand = Optional.empty(); + } + } + if(groupCommand.isPresent()) { + FAQChannelGroupCommand channelGroupCommand = groupCommand.get(); + if(featureModeService.featureModeActive(FAQFeatureDefinition.FAQ, server.getId(), FAQFeatureMode.FAQ_USES)){ + log.debug("Incrementing use counter for channel group {} for command {} in server {}.", channelGroupCommand.getChannelGroup().getId(), command.getId(), server.getId()); + channelGroupCommand.setUses(channelGroupCommand.getUses() + 1); + } + Set userIds = channelGroupCommand + .getResponses() + .stream() + .map(FAQCommandResponse::getAuthorUserId) + .filter(Objects::nonNull) + .collect(Collectors.toSet()); + Long commandId = channelGroupCommand.getGroupCommandId().getCommandId(); + Long channelGroupId = channelGroupCommand.getGroupCommandId().getChannelGroupId(); + CompletableFuture modelFuture = new CompletableFuture<>(); + if(userIds.isEmpty()) { + log.info("No user could not be found for channel group {} for command {} in server {}. Continuing with the bot as user.", channelGroupCommand.getChannelGroup().getId(), command.getId(), server.getId()); + self.createModel(commandId, channelGroupId, null, modelFuture); + } else { + CompletableFutureList userFutures = userService.retrieveUsers(new ArrayList<>(userIds)); + userFutures + .getMainFuture() + .whenComplete((unused, throwable) -> self.createModel(commandId, channelGroupId, userFutures, modelFuture)); + } + return modelFuture; + } else { + throw new NoFAQResponseFoundException(); + } + } + } + + public FAQResponseModel getNoCommandFoundModel(AServer server, AChannel channel) { + List channelGroups = channelGroupService.getChannelGroupsOfChannelWithType(channel, FAQServiceBean.FAQ_CHANNEL_GROUP_KEY); + List possibleCommands = faqChannelGroupCommandManagementServiceBean.getGroupCommandsForBasicChannelGroups(channelGroups); + List globalCommands = faqCommandManagementServiceBean.findGlobalCommandsInServer(server); + Set commandNames = possibleCommands + .stream() + .map(faqChannelGroupCommand -> faqChannelGroupCommand.getCommand().getName()) + .collect(Collectors.toSet()); + commandNames.addAll(globalCommands.stream().map(FAQCommand::getName).collect(Collectors.toSet())); + return FAQResponseModel + .builder() + .availableCommands(new ArrayList<>(commandNames)) + .build(); + } + + @Transactional + public void createModel(Long commandId, Long channelGroupId, CompletableFutureList userFutures, CompletableFuture modelFuture) { + try { + FAQChannelGroupCommand loadedGroupCommand = faqChannelGroupCommandManagementServiceBean.findChannelGroupCommand(commandId, channelGroupId); + FAQResponseModel mainModel = FAQResponseModel.builder().build(); + SelfUser selfUser = userService.getSelfUser(); + if(userFutures != null) { + List users = userFutures.getObjects(); + Map userMap = users.stream().collect(Collectors.toMap(ISnowflake::getIdLong, Function.identity())); + loadedGroupCommand.getResponses().forEach(response -> { + User user = userMap.getOrDefault(response.getAuthorUserId(), selfUser); + mainModel.getMessages().add(FAQResponseMessageModel.fromFAQCommandResponse(response, user)); + }); + } else { + loadedGroupCommand + .getResponses() + .forEach(response -> mainModel.getMessages().add(FAQResponseMessageModel.fromFAQCommandResponse(response, selfUser))); + } + modelFuture.complete(mainModel); + } catch (Exception exception) { + modelFuture.completeExceptionally(exception); + } + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQServiceBean.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQServiceBean.java new file mode 100644 index 0000000..e93adf2 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQServiceBean.java @@ -0,0 +1,411 @@ +package dev.sheldan.oneplus.bot.modules.faq.service; + +import com.google.gson.Gson; +import dev.sheldan.abstracto.core.models.database.AChannelGroup; +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.abstracto.core.service.UserService; +import dev.sheldan.abstracto.core.service.management.ChannelGroupManagementService; +import dev.sheldan.oneplus.bot.modules.faq.converter.FAQCommandConfigConverter; +import dev.sheldan.oneplus.bot.modules.faq.converter.ListFAQCommandsModelConverter; +import dev.sheldan.oneplus.bot.modules.faq.exception.*; +import dev.sheldan.oneplus.bot.modules.faq.models.command.config.*; +import dev.sheldan.oneplus.bot.modules.faq.models.command.list.ListFAQCommandsModel; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse; +import dev.sheldan.oneplus.bot.modules.faq.service.management.*; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.*; +import java.util.function.Function; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class FAQServiceBean { + + public static final String FAQ_CHANNEL_GROUP_KEY = "faq"; + + @Autowired + private ChannelGroupManagementService channelGroupManagementService; + + @Autowired + private Gson gson; + + @Autowired + private FAQCommandManagementServiceBean faqCommandManagementServiceBean; + + @Autowired + private FAQChannelGroupManagementServiceBean faqChannelGroupManagementServiceBean; + + @Autowired + private FAQCommandResponseManagementServiceBean faqCommandResponseManagementServiceBean; + + @Autowired + private FAQChannelGroupCommandManagementServiceBean faqChannelGroupCommandManagementServiceBean; + + @Autowired + private FAQCommandAliasManagementService faqCommandAliasManagementService; + + @Autowired + private UserService userService; + + @Autowired + private FAQCommandConfigConverter configConverter; + + @Autowired + private ListFAQCommandsModelConverter listFAQCommandsModelConverter; + + public void createOrUpdateFAQCommands(List commands, AServer server) { + fillDefaults(commands); + validateCommandConfig(commands, server); + commands.forEach(faqCommandConfig -> handleFAQCommand(faqCommandConfig, server)); + } + + private void validateCommandConfig(List commands, AServer server) { + List incorrectGlobalConfigurations = commands + .stream() + .filter(faqCommandConfig -> faqCommandConfig.getGlobal() && faqCommandConfig.getResponses().size() > 1) + .collect(Collectors.toList()); + if(!incorrectGlobalConfigurations.isEmpty()) { + List commandsWithIllegalConfiguration = incorrectGlobalConfigurations + .stream() + .map(FaqCommandConfig::getFaqCommandName) + .collect(Collectors.toList()); + throw new GlobalFAQCommandResponsesException(commandsWithIllegalConfiguration); + } + + List toBeConfiguredCommandNames = new ArrayList<>(); + commands.forEach(faqCommandConfig -> { + toBeConfiguredCommandNames.add(faqCommandConfig.getFaqCommandName()); + if(faqCommandConfig.getAliases() != null) { + toBeConfiguredCommandNames.addAll(faqCommandConfig.getAliases()); + } + }); + + Set uniqueToBeConfiguredCommandNames = new HashSet<>(toBeConfiguredCommandNames); + if(toBeConfiguredCommandNames.size() != uniqueToBeConfiguredCommandNames.size()) { + List duplicatedKeys = getDuplicatedKeys(toBeConfiguredCommandNames); + throw new DuplicatedCommandNameOrAliasException(duplicatedKeys); + } + List allCommands = faqCommandManagementServiceBean.findAllInServer(server); + Map aliasMappings = getAliasMappings(allCommands); + commands.forEach(faqCommandConfig -> { + if(faqCommandConfig.getAliases() == null) return; + // find a command in which the alias is used as alias + faqCommandConfig.getAliases().forEach(aliasName -> { + if(aliasMappings.containsKey(aliasName)) { + FAQCommand faqCommand = aliasMappings.get(aliasName); + // but the command should be a different one, else we would find ourselves + if(!faqCommand.getName().equals(faqCommandConfig.getFaqCommandName())) { + throw new DuplicatedFAQCommandAliasException(faqCommand.getName(), aliasName, faqCommandConfig.getFaqCommandName()); + } + } + }); + }); + Map commandMappings = getCommandMappings(allCommands); + commands.forEach(faqCommandConfig -> { + if(faqCommandConfig.getAliases() == null) return; + // check if the to be configured aliases clash with an existing command + faqCommandConfig.getAliases().forEach(aliasName -> { + if(commandMappings.containsKey(aliasName)) { + throw new FAQCommandAliasShadowingException(faqCommandConfig.getFaqCommandName(), aliasName); + } + }); + }); + } + + private List getDuplicatedKeys(List toBeConfiguredCommandNames) { + Map collections = toBeConfiguredCommandNames.stream().collect( + Collectors.groupingBy( + Function.identity(), + Collectors.counting())); + List duplicatedKeys = new ArrayList<>(); + collections.forEach((s, aLong) -> { + if(aLong > 1) { + duplicatedKeys.add(s); + } + }); + return duplicatedKeys; + } + + private void handleFAQCommand(FaqCommandConfig faqCommandConfig, AServer server) { + Optional existingFAQCommandOptional = faqCommandManagementServiceBean.findByNameAndServer(faqCommandConfig.getFaqCommandName(), server); + FAQCommand commandInstance; + if(existingFAQCommandOptional.isPresent()) { + commandInstance = existingFAQCommandOptional.get(); + log.debug("Updating command {} in server {}.", commandInstance.getId(), server.getId()); + updateFAQCommand(faqCommandConfig, commandInstance); + } else { + log.debug("Creating new command in server {}.", server.getId()); + commandInstance = createFAQCommand(faqCommandConfig, server); + } + Set existingChannelGroupNames = + commandInstance.getGroupResponses() + .stream() + .map(faqChannelGroupCommand -> faqChannelGroupCommand.getChannelGroup().getChannelGroup().getGroupName()) + .collect(Collectors.toSet()); + Set configuredChannelGroupNames = new HashSet<>(); + faqCommandConfig + .getResponses() + .forEach(faqCommandResponseConfig -> { + handleFAQChannelGroupCommand(faqCommandResponseConfig, commandInstance, server); + configuredChannelGroupNames.add(faqCommandResponseConfig.getChannelGroupName()); + }); + // this deletes any channel group responses which were not reflected in the configuration + existingChannelGroupNames.removeAll(configuredChannelGroupNames); + existingChannelGroupNames.forEach(channelGroupName -> { + AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServerAndType(channelGroupName, server, FAQ_CHANNEL_GROUP_KEY); + FAQChannelGroup faqChannelGroup = faqChannelGroupManagementServiceBean.getFAQChannelGroupById(channelGroup.getId()); + faqChannelGroupCommandManagementServiceBean.deleteFAQChannelGroupCommand(commandInstance, faqChannelGroup); + }); + } + + private void handleFAQChannelGroupCommand(FaqCommandResponseConfig responseConfig, FAQCommand command, AServer server) { + AChannelGroup channelGroup = channelGroupManagementService.findByNameAndServerAndType(responseConfig.getChannelGroupName(), server, FAQ_CHANNEL_GROUP_KEY); + FAQChannelGroup faqChannelGroup = faqChannelGroupManagementServiceBean.getFAQChannelGroupById(channelGroup.getId()); + Optional existingChannelGroupCommandOptional = command.getGroupResponses() + .stream() + .filter(faqChannelGroupCommand -> faqChannelGroupCommand.getChannelGroup().getChannelGroup() + .equals(faqChannelGroup.getChannelGroup())) + .findAny(); + if(command.getGlobal() && !faqChannelGroup.getGlobal()) { + log.warn("Command {} is configured as global, but to be used channel group is not defined as the global channel group.", command.getId()); + throw new GlobalFAQCommandConfigMismatchException(command.getName()); + } + if(faqChannelGroup.getGlobal() && !command.getGlobal()) { + log.warn("Channel group to be used is configured as global, but command {} is not. This is an illegal combination.", command.getId()); + throw new GlobalFAQCommandConfigMismatchException(command.getName()); + } + if(existingChannelGroupCommandOptional.isPresent()) { + FAQChannelGroupCommand existing = existingChannelGroupCommandOptional.get(); + log.debug("Updating faq channel group command {} for channel group {} in server {}.", command.getId(), faqChannelGroup.getId(), server.getId()); + updateFAQChannelGroupCommand(existing, responseConfig); + } else { + log.debug("Creating new faq channel group command for command {} in channel group {} in server {}.", command.getId(), faqChannelGroup.getId(), server.getId()); + createFAQChannelGroupCommand(command, faqChannelGroup, responseConfig); + } + } + + private void createFAQChannelGroupCommand(FAQCommand faqCommand, FAQChannelGroup faqChannelGroup, FaqCommandResponseConfig responseConfig) { + FAQChannelGroupCommand channelGroupCommand = faqChannelGroupCommandManagementServiceBean.createFAQChannelGroupCommand(faqCommand, faqChannelGroup); + log.debug("Creating {} messages.", responseConfig.getMessages().size()); + for (int i = 0; i < responseConfig.getMessages().size(); i++) { + createFAQResponses(channelGroupCommand, responseConfig.getMessages().get(i), i); + } + } + + private void updateFAQChannelGroupCommand(FAQChannelGroupCommand existing, FaqCommandResponseConfig responseConfig) { + Set positions = responseConfig + .getMessages() + .stream() + .map(FaqCommandResponseMessageConfig::getPosition) + .collect(Collectors.toSet()); + + if(positions.size() != responseConfig.getMessages().size()) { + throw new FAQCommandResponseDuplicatedPositionException(existing.getCommand().getName(), responseConfig.getChannelGroupName()); + } + + List existingResponses = existing + .getResponses() + .stream() + .sorted(Comparator.comparing(o -> o.getId().getPosition())) + .collect(Collectors.toList()); + + List configMessages = responseConfig + .getMessages() + .stream() + .sorted(Comparator.comparingInt(FaqCommandResponseMessageConfig::getPosition)) + .collect(Collectors.toList()); + + // re-use the existing entries, and only update if necessary, so have the appropriate update timestamp + int iterations = Math.min(configMessages.size(), existingResponses.size()); + for (int i = 0; i < iterations; i++) { + mergeConfig(existingResponses.get(i), configMessages.get(i)); + } + + // remove all the rest, as they were not specified in the config + for(int i = iterations; i < existingResponses.size(); i++) { + faqCommandResponseManagementServiceBean.deleteCommandResponse(existingResponses.get(i)); + } + + for(int i = iterations; i < configMessages.size(); i++) { + createFAQResponses(existing, configMessages.get(i), i); + } + + } + + private void createFAQResponses(FAQChannelGroupCommand existing, FaqCommandResponseMessageConfig config, int position) { + faqCommandResponseManagementServiceBean.createResponse(config, position, existing); + } + + private void mergeConfig(FAQCommandResponse existingResponse, FaqCommandResponseMessageConfig config) { + if(existingResponse.getAdditionalMessage() == null || !existingResponse.getAdditionalMessage().equals(config.getAdditionalMessage())) { + existingResponse.setAdditionalMessage(config.getAdditionalMessage()); + } + FaqCommandResponseEmbedConfig embed = config.getEmbed(); + if(embed != null) { + if(existingResponse.getDescription() == null || !existingResponse.getDescription().equals(embed.getDescription())) { + existingResponse.setDescription(embed.getDescription()); + } + if(existingResponse.getImageURL() == null || !existingResponse.getImageURL().equals(embed.getImageUrl())) { + existingResponse.setImageURL(embed.getImageUrl()); + } + if(existingResponse.getAuthorUserId() == null || !existingResponse.getAuthorUserId().equals(embed.getAuthor().getUserId())) { + existingResponse.setAuthorUserId(embed.getAuthor().getUserId()); + } + mergeEmbedColor(existingResponse, embed); + } else { + existingResponse.setDescription(null); + existingResponse.setImageURL(null); + existingResponse.setAuthorUserId(null); + } + } + + private void mergeEmbedColor(FAQCommandResponse existingResponse, FaqCommandResponseEmbedConfig embed) { + FaqCommandResponseEmbedColorConfig embedColor = embed.getColor(); + if(existingResponse.getBlue() == null || !existingResponse.getBlue().equals(embedColor.getBlue())) { + existingResponse.setBlue(embedColor.getBlue()); + } + if(existingResponse.getGreen() == null || !existingResponse.getGreen().equals(embedColor.getGreen())){ + existingResponse.setGreen(embedColor.getGreen()); + } + if(existingResponse.getRed() == null || !existingResponse.getRed().equals(embedColor.getRed())) { + existingResponse.setRed(embedColor.getRed()); + } + } + + private void updateFAQCommand(FaqCommandConfig faqCommandConfig, FAQCommand command){ + if(!faqCommandConfig.getGlobal().equals(command.getGlobal())) { + command.setGlobal(faqCommandConfig.getGlobal()); + } + Set existingAlias; + if(command.getAliases() != null) { + existingAlias = command + .getAliases() + .stream() + .map(faqCommandAlias -> faqCommandAlias.getId().getAlias()) + .collect(Collectors.toSet()); + } else { + existingAlias = new HashSet<>(); + } + + Set toBeConfigured; + if(faqCommandConfig.getAliases() != null) { + toBeConfigured = new HashSet<>(faqCommandConfig.getAliases()); + } else { + toBeConfigured = new HashSet<>(); + } + Set aliasNeedingCreation = new HashSet<>(toBeConfigured); + aliasNeedingCreation.removeAll(existingAlias); + log.info("Creating {} aliases for command {}.", aliasNeedingCreation.size(), command.getId()); + createFAQCommandAlias(command, aliasNeedingCreation); + Set aliasToDelete = new HashSet<>(existingAlias); + aliasToDelete.removeAll(toBeConfigured); + log.info("Removing {} aliases for command {}.", aliasToDelete.size(), command.getId()); + deleteFAQCommandAlias(command, aliasToDelete); + } + + private void createFAQCommandAlias(FAQCommand command, Collection aliasNames) { + aliasNames.forEach(s -> faqCommandAliasManagementService.createFAQCommandAlias(command, s)); + } + + private void deleteFAQCommandAlias(FAQCommand command, Collection aliasName) { + aliasName.forEach(s -> faqCommandAliasManagementService.deleteFAQCommandAlias(command, s)); + } + + private FAQCommand createFAQCommand(FaqCommandConfig faqCommandConfig, AServer server) { + FAQCommand faqCommand = faqCommandManagementServiceBean.createFAQCommand(faqCommandConfig, server); + if(faqCommandConfig.getAliases() != null) { + createFAQCommandAlias(faqCommand, faqCommandConfig.getAliases()); + } + return faqCommand; + } + + private void fillDefaults(List commands) { + commands + .forEach(faqCommandConfig -> { + if(faqCommandConfig.getGlobal() == null) { + faqCommandConfig.setGlobal(Boolean.FALSE); + } + faqCommandConfig + .getResponses() + .forEach(faqCommandResponse -> faqCommandResponse + .getMessages().forEach( + faqCommandResponseMessage -> { + FaqCommandResponseEmbedConfig embed = faqCommandResponseMessage.getEmbed(); + if(embed == null) { + return; + } + FaqCommandResponseEmbedColorConfig color = embed.getColor(); + if(color == null) { + color = FaqCommandResponseEmbedColorConfig.builder().build(); + embed.setColor(color); + } + if(color.getBlue() == null || color.getBlue() == 0) { + color.setBlue(0); + } + if(color.getRed() == null || color.getRed() == 0) { + color.setRed(0); + } + if(color.getGreen() == null || color.getGreen() == 0) { + color.setGreen(0); + } + if(embed.getAuthor().getUseBot() != null && embed.getAuthor().getUseBot()) { + log.debug("Setting the BOT as the author."); + embed.getAuthor().setUserId(userService.getSelfUser().getIdLong()); + } + } + )); + }); + } + + private Map getCommandMappings(List commands) { + return commands + .stream() + .collect(Collectors.toMap(FAQCommand::getName, Function.identity())); + } + + private Map getAliasMappings(List commands) { + Map commandMappings = commands + .stream() + .collect(Collectors.toMap(FAQCommand::getName, Function.identity())); + commands + .forEach(faqCommand -> faqCommand + .getAliases() + .forEach(faqCommandAlias -> + commandMappings.put(faqCommandAlias.getId().getAlias(), faqCommand))); + return commandMappings; + } + + public List loadFAQCommandsFromJson(String json) { + FaqCommandConfig[] faqCommandConfigs = gson.fromJson(json, FaqCommandConfig[].class); + return Arrays.asList(faqCommandConfigs); + } + + public void deleteFAQCommand(String commandToDelete, AServer server) { + FAQCommand toDelete = faqCommandManagementServiceBean.findByNameAndServer(commandToDelete, server) + .orElseThrow(() -> new FAQCommandNotFoundException(commandToDelete)); + faqCommandManagementServiceBean.deleteFAQCommand(toDelete); + } + + public String exportFAQConfig(String commandToExport, AServer server) { + FAQCommand toExport = faqCommandManagementServiceBean.findByNameAndServer(commandToExport, server) + .orElseThrow(() -> new FAQCommandNotFoundException(commandToExport)); + return configConverter.serializeCommands(Arrays.asList(toExport)); + } + + public String exportFAQConfig(AServer server) { + List toExport = faqCommandManagementServiceBean.findAllInServer(server); + log.info("Exporting {} FAQ commands for server {}.", toExport.size(), server.getId()); + return configConverter.serializeCommands(toExport); + } + + public ListFAQCommandsModel getCommandListingForServer(AServer server) { + List faqCommands = faqCommandManagementServiceBean.findAllInServer(server); + return listFAQCommandsModelConverter.fromFAQCommands(faqCommands); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQUsageServiceBean.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQUsageServiceBean.java new file mode 100644 index 0000000..5bd64eb --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQUsageServiceBean.java @@ -0,0 +1,68 @@ +package dev.sheldan.oneplus.bot.modules.faq.service; + +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.oneplus.bot.modules.faq.exception.FAQCommandNotFoundException; +import dev.sheldan.oneplus.bot.modules.faq.models.command.faquses.FAQCommandResponseUsage; +import dev.sheldan.oneplus.bot.modules.faq.models.command.faquses.FAQCommandUsage; +import dev.sheldan.oneplus.bot.modules.faq.models.command.faquses.FAQUsageModel; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand; +import dev.sheldan.oneplus.bot.modules.faq.service.management.FAQCommandManagementServiceBean; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class FAQUsageServiceBean { + + @Autowired + private FAQCommandManagementServiceBean faqCommandManagementServiceBean; + + public FAQUsageModel getFAQUsageModel(AServer server, String faqCommandName) { + FAQCommand faqCommand = faqCommandManagementServiceBean.findByNameAndServer(faqCommandName, server) + .orElseThrow(() -> new FAQCommandNotFoundException(faqCommandName)); + List commandUsages = Arrays.asList(getFAQCommandUsage(faqCommand)); + return FAQUsageModel + .builder() + .uses(commandUsages) + .build(); + } + + public FAQUsageModel getFAQUsageModel(AServer server) { + List allCommands = faqCommandManagementServiceBean.findAllInServer(server); + List commandUsages = allCommands + .stream() + .map(this::getFAQCommandUsage) + .collect(Collectors.toList()); + return FAQUsageModel + .builder() + .uses(commandUsages) + .build(); + } + + private FAQCommandUsage getFAQCommandUsage(FAQCommand command) { + List channelGroupUsages = command + .getGroupResponses() + .stream() + .map(this::getFAQCommandResponseUsage) + .collect(Collectors.toList()); + return FAQCommandUsage + .builder() + .faqCommandName(command.getName()) + .faqChannelGroupUsages(channelGroupUsages) + .build(); + } + + private FAQCommandResponseUsage getFAQCommandResponseUsage(FAQChannelGroupCommand groupCommand) { + return FAQCommandResponseUsage + .builder() + .uses(groupCommand.getUses()) + .channelGroupName(groupCommand.getChannelGroup().getChannelGroup().getGroupName()) + .build(); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQValidationServiceBean.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQValidationServiceBean.java new file mode 100644 index 0000000..af19f0d --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/FAQValidationServiceBean.java @@ -0,0 +1,41 @@ +package dev.sheldan.oneplus.bot.modules.faq.service; + +import dev.sheldan.abstracto.core.models.JSONValidationResult; +import dev.sheldan.abstracto.core.service.JSONValidationService; +import lombok.extern.slf4j.Slf4j; +import org.apache.commons.io.IOUtils; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Value; +import org.springframework.core.io.Resource; +import org.springframework.stereotype.Component; + +import javax.annotation.PostConstruct; +import java.io.IOException; +import java.nio.charset.StandardCharsets; + +@Component +@Slf4j +public class FAQValidationServiceBean { + + @Autowired + private JSONValidationService jsonValidationService; + + @Value("classpath:validation/createScheme.json") + private Resource creationValidationResource; + + private String creationValidationSchema; + + public JSONValidationResult validateJSONForCreation(String json) { + log.info("Validating FAQ creation schema."); + return jsonValidationService.validateJSONSchema(creationValidationSchema, json); + } + + @PostConstruct + public void postConstruct() { + try { + this.creationValidationSchema = IOUtils.toString(creationValidationResource.getInputStream(), StandardCharsets.UTF_8); + } catch (IOException e) { + log.error("Failed to load validation schemes.", e); + } + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQChannelGroupCommandManagementServiceBean.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQChannelGroupCommandManagementServiceBean.java new file mode 100644 index 0000000..1063b67 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQChannelGroupCommandManagementServiceBean.java @@ -0,0 +1,77 @@ +package dev.sheldan.oneplus.bot.modules.faq.service.management; + +import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException; +import dev.sheldan.abstracto.core.models.database.AChannelGroup; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.ChannelGroupCommandId; +import dev.sheldan.oneplus.bot.modules.faq.repository.FAQChannelGroupCommandRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.stream.Collectors; + +@Component +@Slf4j +public class FAQChannelGroupCommandManagementServiceBean { + + @Autowired + private FAQChannelGroupCommandRepository repository; + + @Autowired + private FAQCommandResponseManagementServiceBean faqCommandResponseManagementServiceBean; + + public FAQChannelGroupCommand createFAQChannelGroupCommand(FAQCommand command, FAQChannelGroup channelGroup) { + FAQChannelGroupCommand groupCommand = FAQChannelGroupCommand + .builder() + .command(command) + .uses(0) + .channelGroup(channelGroup) + .groupCommandId(new ChannelGroupCommandId(channelGroup.getId(), command.getId())) + .build(); + command.getGroupResponses().add(groupCommand); + log.info("Creating FAQ channel group command for command {} in channel group {}.", command.getId(), channelGroup.getId()); + return repository.save(groupCommand); + } + + public FAQChannelGroupCommand findChannelGroupCommand(Long commandId, Long channelGroupId) { + ChannelGroupCommandId id = ChannelGroupCommandId + .builder() + .commandId(commandId) + .channelGroupId(channelGroupId) + .build(); + return repository.findById(id) + .orElseThrow(() -> new AbstractoRunTimeException("Channel group command not found.")); + } + + public void deleteFAQChannelGroupCommands(List faqChannelGroupCommandList) { + log.info("Deleting {} faq channel group commands.", faqChannelGroupCommandList.size()); + faqChannelGroupCommandList + .forEach(faqChannelGroupCommand -> faqCommandResponseManagementServiceBean.deleteCommandResponses(faqChannelGroupCommand.getResponses())); + repository.deleteAll(faqChannelGroupCommandList); + } + + public void deleteFAQChannelGroupCommand(FAQCommand command, FAQChannelGroup channelGroup) { + FAQChannelGroupCommand channelGroupCommand = findChannelGroupCommand(command.getId(), channelGroup.getId()); + faqCommandResponseManagementServiceBean.deleteCommandResponses(channelGroupCommand.getResponses()); + log.info("Deleting faq channel group command for command {} in channel group {}.", command.getId(), channelGroup.getId()); + repository.delete(channelGroupCommand); + } + + public List getGroupCommandsForBasicChannelGroups(List channelGroups) { + List channelGroupIds = channelGroups + .stream() + .map(AChannelGroup::getId) + .collect(Collectors.toList()); + + return getGroupCommandsForChannelGroupIds(channelGroupIds); + } + + public List getGroupCommandsForChannelGroupIds(List channelGroupIds) { + return repository.findByChannelGroup_IdIn(channelGroupIds); + } + +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQChannelGroupManagementServiceBean.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQChannelGroupManagementServiceBean.java new file mode 100644 index 0000000..ffc49e1 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQChannelGroupManagementServiceBean.java @@ -0,0 +1,47 @@ +package dev.sheldan.oneplus.bot.modules.faq.service.management; + +import dev.sheldan.abstracto.core.exception.AbstractoRunTimeException; +import dev.sheldan.abstracto.core.models.database.AChannelGroup; +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroup; +import dev.sheldan.oneplus.bot.modules.faq.repository.FAQChannelGroupRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +@Component +@Slf4j +public class FAQChannelGroupManagementServiceBean { + @Autowired + private FAQChannelGroupRepository faqChannelGroupRepository; + + public Optional findFAQChannelGroupByIdOptional(Long id) { + return faqChannelGroupRepository.findById(id); + } + + public FAQChannelGroup getFAQChannelGroupById(Long id) { + return findFAQChannelGroupByIdOptional(id).orElseThrow(() -> new AbstractoRunTimeException("FAQ Channel group not found.")); + } + + public FAQChannelGroup createFAQChannelGroup(AChannelGroup channelGroup) { + FAQChannelGroup faqChannelGroup = FAQChannelGroup + .builder() + .channelGroup(channelGroup) + .global(false) + .id(channelGroup.getId()) + .build(); + log.info("Creating FAQ channel group for channel group {} in server {}.", channelGroup.getId(), channelGroup.getServer().getId()); + return faqChannelGroupRepository.save(faqChannelGroup); + } + + public Optional getGlobalChannelGroup(AServer server) { + return faqChannelGroupRepository.findByChannelGroup_ServerAndGlobalTrue(server); + } + + public void deleteFAQChannelGroup(AChannelGroup channelGroup) { + log.info("Deleting FAQ channel group {} in server {}.", channelGroup.getId(), channelGroup.getServer().getId()); + faqChannelGroupRepository.delete(getFAQChannelGroupById(channelGroup.getId())); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandAliasManagementService.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandAliasManagementService.java new file mode 100644 index 0000000..7620c65 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandAliasManagementService.java @@ -0,0 +1,53 @@ +package dev.sheldan.oneplus.bot.modules.faq.service.management; + +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandAlias; +import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.FAQCommandAliasId; +import dev.sheldan.oneplus.bot.modules.faq.repository.FAQCommandAliasRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.Optional; + +@Component +@Slf4j +public class FAQCommandAliasManagementService { + + @Autowired + private FAQCommandAliasRepository commandAliasRepository; + + public FAQCommandAlias createFAQCommandAlias(FAQCommand command, String aliasName) { + FAQCommandAlias alias = FAQCommandAlias + .builder() + .command(command) + .id(FAQCommandAliasId + .builder() + .faqCommandId(command.getId()) + .alias(aliasName) + .build()) + .build(); + log.info("Creating faq command alias for command {}.", command.getId()); + return commandAliasRepository.save(alias); + } + + public void deleteFAQCommandAlias(FAQCommand command, String aliasName) { + FAQCommandAliasId aliasId = FAQCommandAliasId + .builder() + .faqCommandId(command.getId()) + .alias(aliasName) + .build(); + log.info("Deleting faq command alias for command {}.", command.getId()); + commandAliasRepository.deleteById(aliasId); + } + + public void deleteFAQCommandAliases(FAQCommand faqCommand){ + log.info("deleting all FAQ command aliases for command {}.", faqCommand.getId()); + commandAliasRepository.deleteAll(faqCommand.getAliases()); + } + + public Optional findByNameAndServer(String name, AServer server) { + return commandAliasRepository.findById_AliasAndCommand_Server(name, server); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandManagementServiceBean.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandManagementServiceBean.java new file mode 100644 index 0000000..de6ae9e --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandManagementServiceBean.java @@ -0,0 +1,59 @@ +package dev.sheldan.oneplus.bot.modules.faq.service.management; + +import dev.sheldan.abstracto.core.models.database.AServer; +import dev.sheldan.oneplus.bot.modules.faq.models.command.config.FaqCommandConfig; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommand; +import dev.sheldan.oneplus.bot.modules.faq.repository.FAQCommandRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; +import java.util.Optional; + +@Component +@Slf4j +public class FAQCommandManagementServiceBean { + @Autowired + private FAQCommandRepository repository; + + @Autowired + private FAQCommandAliasManagementService faqCommandAliasManagementService; + + @Autowired + private FAQChannelGroupCommandManagementServiceBean faqChannelGroupCommandManagementServiceBean; + + public Optional findByNameAndServer(String name, AServer server) { + return repository.findByNameEqualsIgnoreCaseAndServer(name, server); + } + + public List findAllInServer(AServer server) { + return repository.findByServer(server); + } + + public FAQCommand createFAQCommand(String name, Boolean global, AServer server) { + FAQCommand command = FAQCommand + .builder() + .name(name) + .server(server) + .global(global) + .build(); + log.info("Creating FAQ Command in server {}.", server.getId()); + return repository.save(command); + } + + public FAQCommand createFAQCommand(FaqCommandConfig faqCommandConfig, AServer server) { + return createFAQCommand(faqCommandConfig.getFaqCommandName(), faqCommandConfig.getGlobal(), server); + } + + public void deleteFAQCommand(FAQCommand faqCommand) { + faqChannelGroupCommandManagementServiceBean.deleteFAQChannelGroupCommands(faqCommand.getGroupResponses()); + faqCommandAliasManagementService.deleteFAQCommandAliases(faqCommand); + log.info("Deleting FAQ command {}.", faqCommand.getId()); + repository.delete(faqCommand); + } + + public List findGlobalCommandsInServer(AServer server) { + return repository.findByServerAndGlobalTrue(server); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandResponseManagementServiceBean.java b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandResponseManagementServiceBean.java new file mode 100644 index 0000000..797ce14 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/java/dev/sheldan/oneplus/bot/modules/faq/service/management/FAQCommandResponseManagementServiceBean.java @@ -0,0 +1,68 @@ +package dev.sheldan.oneplus.bot.modules.faq.service.management; + +import dev.sheldan.oneplus.bot.modules.faq.models.command.config.FaqCommandResponseEmbedColorConfig; +import dev.sheldan.oneplus.bot.modules.faq.models.command.config.FaqCommandResponseEmbedConfig; +import dev.sheldan.oneplus.bot.modules.faq.models.command.config.FaqCommandResponseMessageConfig; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQChannelGroupCommand; +import dev.sheldan.oneplus.bot.modules.faq.models.database.FAQCommandResponse; +import dev.sheldan.oneplus.bot.modules.faq.models.database.embed.CommandResponseId; +import dev.sheldan.oneplus.bot.modules.faq.repository.FAQCommandResponseRepository; +import lombok.extern.slf4j.Slf4j; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.stereotype.Component; + +import java.util.List; + +@Component +@Slf4j +public class FAQCommandResponseManagementServiceBean { + + @Autowired + private FAQCommandResponseRepository responseRepository; + + public FAQCommandResponse createResponse(FaqCommandResponseMessageConfig config, int position, FAQChannelGroupCommand groupCommand) { + CommandResponseId id = CommandResponseId + .builder() + .commandId(groupCommand.getCommand().getId()) + .channelGroupId(groupCommand.getChannelGroup().getId()) + .position(position) + .build(); + FAQCommandResponse.FAQCommandResponseBuilder builder = FAQCommandResponse + .builder() + .additionalMessage(config.getAdditionalMessage()) + .id(id); + + FaqCommandResponseEmbedConfig embedConfig = config.getEmbed(); + if(embedConfig != null) { + log.debug("The response to create in command {} has an embed.", groupCommand.getCommand().getId()); + FaqCommandResponseEmbedColorConfig colorConfig = embedConfig.getColor(); + if(colorConfig != null) { + builder = builder.blue(colorConfig.getBlue()) + .red(colorConfig.getRed()) + .green(colorConfig.getGreen()); + } + if(embedConfig.getAuthor() != null) { + builder = builder.authorUserId(embedConfig.getAuthor().getUserId()); + } + builder = builder.description(embedConfig.getDescription()) + .imageURL(embedConfig.getImageUrl()); + } + log.info("Creating faq command response for command {} in server {}. There area already {} responses.", + groupCommand.getCommand().getId(), groupCommand.getCommand().getServer().getId(), groupCommand.getResponses().size()); + FAQCommandResponse builtCommand = builder.build(); + builtCommand.setGroupCommand(groupCommand); + groupCommand.getResponses().add(builtCommand); + return responseRepository.save(builtCommand); + } + + public void deleteCommandResponse(FAQCommandResponse response) { + log.info("Deleting fq command response for command {} in channel group {}.", + response.getGroupCommand().getCommand().getId(), response.getGroupCommand().getChannelGroup().getId()); + responseRepository.delete(response); + } + + public void deleteCommandResponses(List responseList) { + log.info("Deleting {} responses.", responseList.size()); + responseRepository.deleteAll(responseList); + } +} diff --git a/application/oneplus-bot-modules/faq/src/main/resources/faq.properties b/application/oneplus-bot-modules/faq/src/main/resources/faq.properties new file mode 100644 index 0000000..0ef8ca5 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/faq.properties @@ -0,0 +1,8 @@ +abstracto.featureFlags.faq.featureName=faq +abstracto.featureFlags.faq.enabled=false + +abstracto.faq.globalChannelGroupName=global + +abstracto.featureModes.faqUses.featureName=faq +abstracto.featureModes.faqUses.mode=faqUses +abstracto.featureModes.faqUses.enabled=false \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/collection.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/collection.xml new file mode 100644 index 0000000..4cd75ec --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/collection.xml @@ -0,0 +1,11 @@ + + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/channel_group_type.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/channel_group_type.xml new file mode 100644 index 0000000..72cea59 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/channel_group_type.xml @@ -0,0 +1,16 @@ + + + + + + + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/command.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/command.xml new file mode 100644 index 0000000..fee7a4b --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/command.xml @@ -0,0 +1,43 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/data.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/data.xml new file mode 100644 index 0000000..f30ea04 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/data.xml @@ -0,0 +1,13 @@ + + + + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/feature.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/feature.xml new file mode 100644 index 0000000..268f23b --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/feature.xml @@ -0,0 +1,14 @@ + + + + + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/module.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/module.xml new file mode 100644 index 0000000..fc070ca --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/seedData/module.xml @@ -0,0 +1,14 @@ + + + + + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_channel_group.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_channel_group.xml new file mode 100644 index 0000000..9e9d95d --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_channel_group.xml @@ -0,0 +1,36 @@ + + + + + + + + + + + + + + + + + + + DROP TRIGGER IF EXISTS faq_channel_group_update_trigger ON faq_channel_group; + CREATE TRIGGER faq_channel_group_update_trigger BEFORE UPDATE ON faq_channel_group FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure(); + + + DROP TRIGGER IF EXISTS faq_channel_group_insert_trigger ON faq_channel_group; + CREATE TRIGGER faq_channel_group_insert_trigger BEFORE INSERT ON faq_channel_group FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure(); + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_channel_group_command.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_channel_group_command.xml new file mode 100644 index 0000000..0f1aa16 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_channel_group_command.xml @@ -0,0 +1,38 @@ + + + + + + + + + + + + + + + + + + + + + + + DROP TRIGGER IF EXISTS faq_channel_group_command_insert_trigger ON faq_channel_group_command; + CREATE TRIGGER faq_channel_group_command_insert_trigger BEFORE INSERT ON faq_channel_group_command FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure(); + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command.xml new file mode 100644 index 0000000..02aa914 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command.xml @@ -0,0 +1,45 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + DROP TRIGGER IF EXISTS faq_command_update_trigger ON faq_command; + CREATE TRIGGER faq_command_update_trigger BEFORE UPDATE ON faq_command FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure(); + + + DROP TRIGGER IF EXISTS faq_command_insert_trigger ON faq_command; + CREATE TRIGGER faq_command_insert_trigger BEFORE INSERT ON faq_command FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure(); + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command_alias.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command_alias.xml new file mode 100644 index 0000000..cdad9bb --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command_alias.xml @@ -0,0 +1,39 @@ + + + + + + + + + + + + + + + + + + + + + + DROP TRIGGER IF EXISTS faq_command_update_trigger ON faq_command; + CREATE TRIGGER faq_command_update_trigger BEFORE UPDATE ON faq_command FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure(); + + + DROP TRIGGER IF EXISTS faq_command_alias_insert_trigger ON faq_command_alias; + CREATE TRIGGER faq_command_alias_insert_trigger BEFORE INSERT ON faq_command_alias FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure(); + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command_response.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command_response.xml new file mode 100644 index 0000000..6dd2f59 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/faq_command_response.xml @@ -0,0 +1,59 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + DROP TRIGGER IF EXISTS faq_command_response_update_trigger ON faq_command_response; + CREATE TRIGGER faq_command_response_update_trigger BEFORE UPDATE ON faq_command_response FOR EACH ROW EXECUTE PROCEDURE update_trigger_procedure(); + + + DROP TRIGGER IF EXISTS faq_command_response_insert_trigger ON faq_command_response; + CREATE TRIGGER faq_command_response_insert_trigger BEFORE INSERT ON faq_command_response FOR EACH ROW EXECUTE PROCEDURE insert_trigger_procedure(); + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/tables.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/tables.xml new file mode 100644 index 0000000..ba4be62 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/1.4.4/tables/tables.xml @@ -0,0 +1,14 @@ + + + + + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/dbchangelog.xsd b/application/oneplus-bot-modules/faq/src/main/resources/migrations/dbchangelog.xsd new file mode 100644 index 0000000..83483a5 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/dbchangelog.xsd @@ -0,0 +1,1386 @@ + + + + + + + + + + + + + + Extension to standard XSD boolean type to allow ${} parameters + + + + + + + + + + + + + + + + Extension to standard XSD integer type to allow ${} parameters + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + onChangeLogPreconditionOnSqlOutput determines what should + happen when evaluating this precondition in updateSQL mode. TEST: Run + precondition, FAIL: Fail precondition, IGNORE: Skip precondition check + [DEFAULT] + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Used with valueClobFile to specify file encoding explicitly. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true for a cycling sequence, false for a non-cycling sequence. + Default is false. + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/migrations/faq-changeLog.xml b/application/oneplus-bot-modules/faq/src/main/resources/migrations/faq-changeLog.xml new file mode 100644 index 0000000..91736e1 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/migrations/faq-changeLog.xml @@ -0,0 +1,10 @@ + + + + \ No newline at end of file diff --git a/application/oneplus-bot-modules/faq/src/main/resources/validation/createScheme.json b/application/oneplus-bot-modules/faq/src/main/resources/validation/createScheme.json new file mode 100644 index 0000000..797fb48 --- /dev/null +++ b/application/oneplus-bot-modules/faq/src/main/resources/validation/createScheme.json @@ -0,0 +1,189 @@ +{ + "$schema": "http://json-schema.org/draft-07/schema#", + "type": "array", + "minItems": 1, + "maxItems": 30, + "items": [ + { + "type": "object", + "properties": { + "faqCommandName": { + "type": "string", + "minLength": 1, + "maxLength": 30, + "pattern": "\\w*" + }, + "global": { + "default": false, + "type": "boolean" + }, + "aliases": { + "type": "array", + "minItems": 1, + "maxItems": 20, + "items": { + "type": "string", + "minLength": 1, + "maxLength": 30, + "pattern": "\\w*" + } + }, + "responses": { + "type": "array", + "minItems": 1, + "maxItems": 255, + "items": { + "type": "object", + "properties": { + "channelGroupName": { + "type": "string", + "minLength": 1, + "maxLength": 20, + "pattern": "\\w*" + }, + "messages": { + "type": "array", + "minItems": 1, + "maxItems": 3, + "items": [ + { + "type": "object", + "properties": { + "position": { + "type": "number", + "minimum": 0, + "maximum": 2 + }, + "additionalMessage": { + "type": "string", + "minLength": 1, + "maxLength": 2000 + }, + "embed": { + "type": "object", + "properties": { + "description": { + "type": "string", + "minLength": 1, + "maxLength": 2000 + }, + "imageUrl": { + "type": "string", + "minLength": 1, + "maxLength": 2000, + "pattern": "\\s*https?:\/\/\\S+" + }, + "color": { + "type": "object", + "properties": { + "red": { + "type": "integer", + "minimum": 0, + "default": 0, + "maximum": 255 + }, + "green": { + "type": "integer", + "minimum": 0, + "default": 0, + "maximum": 255 + }, + "blue": { + "type": "integer", + "minimum": 0, + "default": 0, + "maximum": 255 + } + }, + "required": [ + "red", + "green", + "blue" + ] + }, + "author": { + "type": "object", + "properties": { + "userId": { + "minimum": 1, + "maximum": 18446744073709551615, + "type": "integer" + }, + "useBot": { + "type": "boolean" + } + }, + "additionalProperties": false, + "anyOf": [ + { + "required": [ + "userId" + ] + }, + { + "required": [ + "useBot" + ] + } + ] + } + }, + "additionalProperties": false, + "anyOf": [ + { + "required": [ + "description", + "author" + ] + }, + { + "required": [ + "imageUrl", + "author" + ] + } + ] + } + }, + "additionalProperties": false, + "anyOf": [ + { + "required": [ + "additionalMessage", + "position" + ] + }, + { + "required": [ + "embed", + "position" + ] + }, + { + "required": [ + "additionalMessage", + "embed", + "position" + ] + } + ] + } + ] + } + }, + "additionalProperties": false, + "required": [ + "channelGroupName", + "messages" + ] + } + } + }, + "additionalProperties": false, + "required": [ + "faqCommandName", + "responses" + ] + } + ] +} \ No newline at end of file diff --git a/application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/commands/News.java b/application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/command/News.java similarity index 97% rename from application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/commands/News.java rename to application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/command/News.java index 264ec52..43dbf00 100644 --- a/application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/commands/News.java +++ b/application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/command/News.java @@ -1,4 +1,4 @@ -package dev.sheldan.oneplus.bot.modules.news.commands; +package dev.sheldan.oneplus.bot.modules.news.command; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.config.CommandConfiguration; diff --git a/application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/commands/UpdateNews.java b/application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/command/UpdateNews.java similarity index 97% rename from application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/commands/UpdateNews.java rename to application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/command/UpdateNews.java index 7b4cefb..89e2a8a 100644 --- a/application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/commands/UpdateNews.java +++ b/application/oneplus-bot-modules/news/src/main/java/dev/sheldan/oneplus/bot/modules/news/command/UpdateNews.java @@ -1,4 +1,4 @@ -package dev.sheldan.oneplus.bot.modules.news.commands; +package dev.sheldan.oneplus.bot.modules.news.command; import dev.sheldan.abstracto.core.command.condition.AbstractConditionableCommand; import dev.sheldan.abstracto.core.command.config.CommandConfiguration; diff --git a/application/oneplus-bot-modules/pom.xml b/application/oneplus-bot-modules/pom.xml index f05d4b4..838cc59 100644 --- a/application/oneplus-bot-modules/pom.xml +++ b/application/oneplus-bot-modules/pom.xml @@ -14,6 +14,7 @@ news setup referral + faq diff --git a/deployment/image-packaging/pom.xml b/deployment/image-packaging/pom.xml index 5db0dc2..8103888 100644 --- a/deployment/image-packaging/pom.xml +++ b/deployment/image-packaging/pom.xml @@ -210,6 +210,16 @@ referral.zip + + dev.sheldan.oneplus.bot.templates.modules + faq-templates + ${project.version} + zip + true + ${file.basedir}/deployment/template-artifacts/ + faq.zip + + @@ -398,6 +408,16 @@ referral.zip + + dev.sheldan.oneplus.bot.templates.translations + faq-translations + ${project.version} + zip + true + ${file.basedir}/deployment/translation-artifacts/ + faq.zip + + dev.sheldan.abstracto.scheduling @@ -621,6 +641,17 @@ referral.zip + + dev.sheldan.oneplus.bot.application.modules + faq + ${project.version} + liquibase + zip + true + ${file.basedir}/deployment/liquibase-artifacts/ + faq.zip + + diff --git a/deployment/image-packaging/src/main/docker/deployment/config/artifact_versions.json b/deployment/image-packaging/src/main/docker/deployment/config/artifact_versions.json index f673d2f..c16453a 100644 --- a/deployment/image-packaging/src/main/docker/deployment/config/artifact_versions.json +++ b/deployment/image-packaging/src/main/docker/deployment/config/artifact_versions.json @@ -3,11 +3,11 @@ "suggestion", "invite-filter", "profanity-filter", "statistic", "experience-tracking", "moderation", "starboard-custom", "overrides-templates-webservices", "overrides-templates-core", "overrides-templates-logging", "overrides-templates-statistic", - "news", "referral"], + "news", "referral", "faq"], "translation_artifacts": ["utility", "core", "entertainment", "starboard", "link-embed", "webservices", "suggestion", "remind", "logging", "invite-filter", "profanity-filter", "statistic", "experience-tracking", "moderation", "starboard-custom", - "news", "setup", "referral"], + "news", "setup", "referral", "faq"], "liquibase_artifacts": [ { "zip": "scheduling", "file": "scheduling-changeLog.xml" }, { "zip": "core", "file": "core-changeLog.xml" }, @@ -27,7 +27,8 @@ { "zip": "setup", "file": "setup-changeLog.xml"}, { "zip": "referral", "file": "referral-changeLog.xml"}, { "zip": "starboard-custom", "file": "starboard-custom-changeLog.xml"}, - { "zip": "news", "file": "news-changeLog.xml"} + { "zip": "news", "file": "news-changeLog.xml"}, + { "zip": "faq", "file": "faq-changeLog.xml"} ] } diff --git a/pom.xml b/pom.xml index 33c5ec5..5a03765 100644 --- a/pom.xml +++ b/pom.xml @@ -19,8 +19,8 @@ 1.8 - 1.2.16 - 1.2.12 + 1.2.17-SNAPSHOT + 1.2.13-SNAPSHOT diff --git a/templates/oneplus-bot-modules-templates/faq-templates/pom.xml b/templates/oneplus-bot-modules-templates/faq-templates/pom.xml new file mode 100644 index 0000000..976992e --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/pom.xml @@ -0,0 +1,43 @@ + + + + oneplus-bot-modules-templates + dev.sheldan.oneplus.bot.templates.modules + 1.4.4-SNAPSHOT + + 4.0.0 + + faq-templates + + + 8 + 8 + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + faq-templates-${project.version} + false + + src/main/assembly/assembly.xml + + + + + + + + + \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/assembly/assembly.xml b/templates/oneplus-bot-modules-templates/faq-templates/src/main/assembly/assembly.xml new file mode 100644 index 0000000..aca1e51 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/assembly/assembly.xml @@ -0,0 +1,15 @@ + + zip + false + + zip + + + + . + ${project.basedir}/src/main/resources + + + \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/FAQUsage/FAQUsage_response_embed_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/FAQUsage/FAQUsage_response_embed_en_US.ftl new file mode 100644 index 0000000..67b38ee --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/FAQUsage/FAQUsage_response_embed_en_US.ftl @@ -0,0 +1,14 @@ +{ + <#include "abstracto_color">, + "description": " +<#list uses as usage> +<#assign usage=usage> +<#assign commandName=usage.faqCommandName><@safe_include "FAQUsage_command_display"/>: +<#list usage.faqChannelGroupUsages as channelGroupUsage> +<#assign channelGroupUsage=channelGroupUsage> +<#assign channelGroupName=channelGroupUsage.channelGroupName> +<#assign uses=channelGroupUsage.uses> +<@safe_include "FAQUsage_usage_display"/><#sep>, +<#else> +<@safe_include "FAQUsage_no_usages"/>" +} \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/faq/FAQ_response_embed_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/faq/FAQ_response_embed_en_US.ftl new file mode 100644 index 0000000..4998752 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/faq/FAQ_response_embed_en_US.ftl @@ -0,0 +1,21 @@ +{ + <#if additionalMessage??> + "additionalMessage": "${additionalMessage?json_string}" + + <#if description?? || imageURL??> + <#include "user_author"> + <#if additionalMessage??>, + <@user_author user=author/> + <#if description??> + ,"description": "${description?json_string}" + + ,"color" : { + "r": "${red}", + "g": "${green}", + "b": "${blue}" + } + <#if imageURL??> + ,"imageUrl": "${imageURL}" + + +} \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/faq/FAQ_response_no_command_found_embed_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/faq/FAQ_response_no_command_found_embed_en_US.ftl new file mode 100644 index 0000000..5a55f93 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/faq/FAQ_response_no_command_found_embed_en_US.ftl @@ -0,0 +1,4 @@ +{ + "additionalMessage": "<@safe_include "FAQ_response_no_command_found_message"/> +<#if availableCommands?size gt 0><#assign commandNames>`${availableCommands?join('`, `')}`<@safe_include "FAQ_response_no_command_found_message_available_commands"/><#else><@safe_include "FAQ_response_no_command_found_message_no_commands"/>" +} \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_response_embed_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_response_embed_en_US.ftl new file mode 100644 index 0000000..087f164 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_response_embed_en_US.ftl @@ -0,0 +1,20 @@ +{ + <#include "abstracto_color">, + "description": " + <@safe_include "listFAQCommands_command_header"/> + +<#list commands as command> +<#assign command=command> +<#assign aliases>${command.aliases?join(', ')} +<#assign commandName=command.commandName><@safe_include "listFAQCommands_command_display"/> +<#if command.aliases?size gt 0> <@safe_include "listFAQCommands_channel_group_display_aliases"/> +<@safe_include "listFAQCommands_channel_groups_header"/> +<#list command.channelGroups as channelGroup> +<#assign channelGroup=channelGroup> +<#assign channelGroupName=channelGroup.channelGroupName> +<#assign responseCount=channelGroup.responseCount> +<@safe_include "listFAQCommands_channel_group_display"/><#sep>, + +<#else> +<@safe_include "listFAQCommands_no_commands"/>" +} \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/duplicated_command_or_alias_exception_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/duplicated_command_or_alias_exception_en_US.ftl new file mode 100644 index 0000000..4aa7268 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/duplicated_command_or_alias_exception_en_US.ftl @@ -0,0 +1,2 @@ +<#assign commandKeys>${model.duplicatedCommandKeys?join(', ')} +<#include "duplicated_command_or_alias_exception_message"> \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/duplicated_faq_command_alias_exception_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/duplicated_faq_command_alias_exception_en_US.ftl new file mode 100644 index 0000000..01dbd63 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/duplicated_faq_command_alias_exception_en_US.ftl @@ -0,0 +1,4 @@ +<#assign commandName=model.commandName> +<#assign aliasName=model.alias> +<#assign originalCommandName=model.originCommandName> +<#include "duplicated_faq_command_alias_exception_message"> \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_alias_shadowing_exception_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_alias_shadowing_exception_en_US.ftl new file mode 100644 index 0000000..e0b0973 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_alias_shadowing_exception_en_US.ftl @@ -0,0 +1,3 @@ +<#assign commandName=model.commandName> +<#assign aliasName=model.alias> +<#include "faq_command_alias_shadowing_exception_message"> \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_not_found_exception_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_not_found_exception_en_US.ftl new file mode 100644 index 0000000..6843e57 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_not_found_exception_en_US.ftl @@ -0,0 +1,2 @@ +<#assign commandName=model.commandName> +<#include "faq_command_not_found_exception_message"> \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_response_duplicated_position_exception_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_response_duplicated_position_exception_en_US.ftl new file mode 100644 index 0000000..735a0d5 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/faq_command_response_duplicated_position_exception_en_US.ftl @@ -0,0 +1,3 @@ +<#assign commandName=model.commandName> +<#assign channelGroupName=model.channelGroupName> +<#include "faq_command_response_duplicated_position_exception_message"> \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/global_faq_command_config_mismatch_exception_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/global_faq_command_config_mismatch_exception_en_US.ftl new file mode 100644 index 0000000..578c6b8 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/global_faq_command_config_mismatch_exception_en_US.ftl @@ -0,0 +1,2 @@ +<#assign commandName=model.commandName> +<#include "global_faq_command_config_mismatch_exception_message"> \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/global_faq_command_responses_exception_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/global_faq_command_responses_exception_en_US.ftl new file mode 100644 index 0000000..7c377b5 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/global_faq_command_responses_exception_en_US.ftl @@ -0,0 +1,2 @@ +<#assign commandNames>${model.commandNames?join(', ')} +<#include "global_faq_command_responses_exception_message"> \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/no_faq_response_found_exception_en_US.ftl b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/no_faq_response_found_exception_en_US.ftl new file mode 100644 index 0000000..cdc6ab9 --- /dev/null +++ b/templates/oneplus-bot-modules-templates/faq-templates/src/main/resources/en_US/exceptions/no_faq_response_found_exception_en_US.ftl @@ -0,0 +1 @@ +<#include "no_faq_response_found_exception_message"> \ No newline at end of file diff --git a/templates/oneplus-bot-modules-templates/news-templates/pom.xml b/templates/oneplus-bot-modules-templates/news-templates/pom.xml index d2cebfc..23267ba 100644 --- a/templates/oneplus-bot-modules-templates/news-templates/pom.xml +++ b/templates/oneplus-bot-modules-templates/news-templates/pom.xml @@ -22,7 +22,7 @@ single - starboard-custom-templates-${project.version} + news-templates-${project.version} false src/main/assembly/assembly.xml diff --git a/templates/oneplus-bot-modules-templates/pom.xml b/templates/oneplus-bot-modules-templates/pom.xml index 18d0df7..43eeb5d 100644 --- a/templates/oneplus-bot-modules-templates/pom.xml +++ b/templates/oneplus-bot-modules-templates/pom.xml @@ -15,6 +15,7 @@ starboard-custom-templates news-templates referral-templates + faq-templates diff --git a/templates/translations/faq-translations/pom.xml b/templates/translations/faq-translations/pom.xml new file mode 100644 index 0000000..79520d6 --- /dev/null +++ b/templates/translations/faq-translations/pom.xml @@ -0,0 +1,36 @@ + + + + translations + dev.sheldan.oneplus.bot.templates.translations + 1.4.4-SNAPSHOT + + 4.0.0 + + faq-translations + + + + org.apache.maven.plugins + maven-assembly-plugin + + + package + + single + + + faq-translations-${project.version} + false + + src/main/assembly/assembly.xml + + + + + + + + \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/assembly/assembly.xml b/templates/translations/faq-translations/src/main/assembly/assembly.xml new file mode 100644 index 0000000..aca1e51 --- /dev/null +++ b/templates/translations/faq-translations/src/main/assembly/assembly.xml @@ -0,0 +1,15 @@ + + zip + false + + zip + + + + . + ${project.basedir}/src/main/resources + + + \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_available_commands_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_available_commands_en_US.ftl new file mode 100644 index 0000000..d8eb8b8 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_available_commands_en_US.ftl @@ -0,0 +1 @@ +The following commands are available in the given channel: ${commandNames}. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_en_US.ftl new file mode 100644 index 0000000..78f60b1 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_en_US.ftl @@ -0,0 +1 @@ +No response found. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_no_commands_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_no_commands_en_US.ftl new file mode 100644 index 0000000..796ad49 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/FAQ_response_no_command_found_message_no_commands_en_US.ftl @@ -0,0 +1 @@ +No commands available in the given channel. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_description_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_description_en_US.ftl new file mode 100644 index 0000000..1c7c299 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_description_en_US.ftl @@ -0,0 +1 @@ +Shows pre configured responses for different commands in different channels \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_long_help_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_long_help_en_US.ftl new file mode 100644 index 0000000..057f65e --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_long_help_en_US.ftl @@ -0,0 +1,3 @@ +This command can be used to show frequently asked questions in different channels. +The response depends on the channels it is executed in, if the command is not available in the channel, the available commands are shown. +It is possible to define a channel to get the response for, if the channel is not provided the current channel is used. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_parameter_channel_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_parameter_channel_en_US.ftl new file mode 100644 index 0000000..98f4597 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_parameter_channel_en_US.ftl @@ -0,0 +1 @@ +The channel to get the FAQ response in \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_parameter_command_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_parameter_command_en_US.ftl new file mode 100644 index 0000000..77c47ee --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQ/help/FAQ_parameter_command_en_US.ftl @@ -0,0 +1 @@ +The name of the FAQ command to show \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_command_display_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_command_display_en_US.ftl new file mode 100644 index 0000000..1407054 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_command_display_en_US.ftl @@ -0,0 +1 @@ +**${commandName}** \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_no_usages_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_no_usages_en_US.ftl new file mode 100644 index 0000000..b62f1f3 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_no_usages_en_US.ftl @@ -0,0 +1 @@ +No usages \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_usage_display_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_usage_display_en_US.ftl new file mode 100644 index 0000000..7bc6284 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/FAQUsage_usage_display_en_US.ftl @@ -0,0 +1 @@ +`${channelGroupName}`x${uses} \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_description_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_description_en_US.ftl new file mode 100644 index 0000000..67b1b1e --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_description_en_US.ftl @@ -0,0 +1 @@ +Shows the amount of times faq commands have been used \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_long_help_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_long_help_en_US.ftl new file mode 100644 index 0000000..35ebd4c --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_long_help_en_US.ftl @@ -0,0 +1,2 @@ +This command can be used to show the amount of times each FAQ command response was shown to users. +The tracking only works for the current FAQ commands, and if the response is deleted the usage is also deleted. diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_parameter_commandName_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_parameter_commandName_en_US.ftl new file mode 100644 index 0000000..f4fb821 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/FAQUsage/help/FAQUsage_parameter_commandName_en_US.ftl @@ -0,0 +1 @@ +The FAQ command to show the usages for. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_description_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_description_en_US.ftl new file mode 100644 index 0000000..f627e6e --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_description_en_US.ftl @@ -0,0 +1 @@ +Deletes a complete FAQ command \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_long_help_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_long_help_en_US.ftl new file mode 100644 index 0000000..038cce1 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_long_help_en_US.ftl @@ -0,0 +1,2 @@ +This command can be used to delete a complete FAQ command and all of its responses. +This is a destructive action to use with care. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_parameter_commandName_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_parameter_commandName_en_US.ftl new file mode 100644 index 0000000..50e80a2 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/deleteFAQ/help/deleteFAQ_parameter_commandName_en_US.ftl @@ -0,0 +1 @@ +The name of the FAQ command to delete \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_description_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_description_en_US.ftl new file mode 100644 index 0000000..df7ac1a --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_description_en_US.ftl @@ -0,0 +1 @@ +Exports the FAQ configuration into JSON format \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_long_help_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_long_help_en_US.ftl new file mode 100644 index 0000000..26c6f94 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_long_help_en_US.ftl @@ -0,0 +1,2 @@ +This command can be used to export the current FAQ configuration into the JSON format required for importing it. +There is an optional parameter to only export the FAQ configuration of one specific command. Without this parameter, all commands are exported. diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_parameter_commandName_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_parameter_commandName_en_US.ftl new file mode 100644 index 0000000..9286352 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/exportFAQ/help/exportFAQ_parameter_commandName_en_US.ftl @@ -0,0 +1 @@ +The FAQ command to export the configuration for \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_description_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_description_en_US.ftl new file mode 100644 index 0000000..01adf6f --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_description_en_US.ftl @@ -0,0 +1 @@ +Updates the current FAQ configuration for this server \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_long_help_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_long_help_en_US.ftl new file mode 100644 index 0000000..a50b321 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_long_help_en_US.ftl @@ -0,0 +1 @@ +This command is used to update the current FAQ configuration. It uses a file, containing the configuration as a parameter. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_parameter_file_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_parameter_file_en_US.ftl new file mode 100644 index 0000000..b1dabb0 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/importFAQ/help/importFAQ_parameter_file_en_US.ftl @@ -0,0 +1 @@ +The JSON file containing the FAQ configuration as attachment \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/help/listFAQCommands_description_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/help/listFAQCommands_description_en_US.ftl new file mode 100644 index 0000000..22e429e --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/help/listFAQCommands_description_en_US.ftl @@ -0,0 +1 @@ +Shows the currently configured FAQ commands \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/help/listFAQCommands_long_help_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/help/listFAQCommands_long_help_en_US.ftl new file mode 100644 index 0000000..654be50 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/help/listFAQCommands_long_help_en_US.ftl @@ -0,0 +1 @@ +This command can be used to show the currently configured FAQ commands, the channel groups they have responses in and how many responses there are. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_group_display_aliases_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_group_display_aliases_en_US.ftl new file mode 100644 index 0000000..96bd569 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_group_display_aliases_en_US.ftl @@ -0,0 +1 @@ +Aliases: ${aliases} \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_group_display_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_group_display_en_US.ftl new file mode 100644 index 0000000..5939efd --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_group_display_en_US.ftl @@ -0,0 +1 @@ +`${channelGroupName}` \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_groups_header_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_groups_header_en_US.ftl new file mode 100644 index 0000000..f0aa334 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_channel_groups_header_en_US.ftl @@ -0,0 +1 @@ +Groups: \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_command_display_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_command_display_en_US.ftl new file mode 100644 index 0000000..1407054 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_command_display_en_US.ftl @@ -0,0 +1 @@ +**${commandName}** \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_command_header_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_command_header_en_US.ftl new file mode 100644 index 0000000..8958cf1 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_command_header_en_US.ftl @@ -0,0 +1 @@ +The following commands are configured: \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_no_commands_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_no_commands_en_US.ftl new file mode 100644 index 0000000..dab0388 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/commands/listFAQCommands/listFAQCommands_no_commands_en_US.ftl @@ -0,0 +1 @@ +No FAQ commands. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/config/channel_group_type_faq_name_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/config/channel_group_type_faq_name_en_US.ftl new file mode 100644 index 0000000..32914fe --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/config/channel_group_type_faq_name_en_US.ftl @@ -0,0 +1 @@ +FAQ \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/config/feature_faq_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/config/feature_faq_en_US.ftl new file mode 100644 index 0000000..32914fe --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/config/feature_faq_en_US.ftl @@ -0,0 +1 @@ +FAQ \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/config/module_faqModule_description_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/config/module_faqModule_description_en_US.ftl new file mode 100644 index 0000000..2feaae6 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/config/module_faqModule_description_en_US.ftl @@ -0,0 +1 @@ +Module containing FAQ related commands \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/config/setup_global_channel_group_info_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/config/setup_global_channel_group_info_en_US.ftl new file mode 100644 index 0000000..b949ef7 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/config/setup_global_channel_group_info_en_US.ftl @@ -0,0 +1 @@ +Global channel group will be created for the purpose of global faq commands. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/exception/duplicated_command_or_alias_exception_message_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/exception/duplicated_command_or_alias_exception_message_en_US.ftl new file mode 100644 index 0000000..3ee95ec --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/exception/duplicated_command_or_alias_exception_message_en_US.ftl @@ -0,0 +1 @@ +The commands ${commandKeys} have duplicates names for command or aliases. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/exception/duplicated_faq_command_alias_exception_message_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/exception/duplicated_faq_command_alias_exception_message_en_US.ftl new file mode 100644 index 0000000..0c53c1f --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/exception/duplicated_faq_command_alias_exception_message_en_US.ftl @@ -0,0 +1 @@ +The alias ${aliasName} in command ${commandName} is duplicated in command ${originalCommandName}. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_alias_shadowing_exception_message_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_alias_shadowing_exception_message_en_US.ftl new file mode 100644 index 0000000..ce1f267 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_alias_shadowing_exception_message_en_US.ftl @@ -0,0 +1 @@ +Alias ${aliasName} in command ${commandName} shadows another command. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_not_found_exception_message_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_not_found_exception_message_en_US.ftl new file mode 100644 index 0000000..621796e --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_not_found_exception_message_en_US.ftl @@ -0,0 +1 @@ +FAQ command ${commandName} was not found. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_response_duplicated_position_exception_message_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_response_duplicated_position_exception_message_en_US.ftl new file mode 100644 index 0000000..d7e2f65 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/exception/faq_command_response_duplicated_position_exception_message_en_US.ftl @@ -0,0 +1 @@ +A position in channel group ${channelGroupName} of FAQ command ${commandName} is duplicated. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/exception/global_faq_command_config_mismatch_exception_message_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/exception/global_faq_command_config_mismatch_exception_message_en_US.ftl new file mode 100644 index 0000000..1d3f28a --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/exception/global_faq_command_config_mismatch_exception_message_en_US.ftl @@ -0,0 +1,2 @@ +The configuration for global command ${commandName} is mismatched. +It needs to be configured as `"global": true` and the only response needs to be a channel group with name `global`. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/exception/global_faq_command_responses_exception_message_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/exception/global_faq_command_responses_exception_message_en_US.ftl new file mode 100644 index 0000000..76c7b2a --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/exception/global_faq_command_responses_exception_message_en_US.ftl @@ -0,0 +1 @@ +The FAQ commands ${commandNames} are configured as global, but they do have more than one response configured. \ No newline at end of file diff --git a/templates/translations/faq-translations/src/main/resources/en_US/exception/no_faq_response_found_exception_message_en_US.ftl b/templates/translations/faq-translations/src/main/resources/en_US/exception/no_faq_response_found_exception_message_en_US.ftl new file mode 100644 index 0000000..e3f39b3 --- /dev/null +++ b/templates/translations/faq-translations/src/main/resources/en_US/exception/no_faq_response_found_exception_message_en_US.ftl @@ -0,0 +1 @@ +No FAQ response found. \ No newline at end of file diff --git a/templates/translations/news-translations/pom.xml b/templates/translations/news-translations/pom.xml index 50616f1..64c000b 100644 --- a/templates/translations/news-translations/pom.xml +++ b/templates/translations/news-translations/pom.xml @@ -21,7 +21,7 @@ single - news-templates-${project.version} + news-translations-${project.version} false src/main/assembly/assembly.xml diff --git a/templates/translations/pom.xml b/templates/translations/pom.xml index a4f9704..ed1f477 100644 --- a/templates/translations/pom.xml +++ b/templates/translations/pom.xml @@ -15,5 +15,6 @@ news-translations setup-translations referral-translations + faq-translations \ No newline at end of file