From 296d4941c0a025a58152788e8cdd287a5dddcf4b Mon Sep 17 00:00:00 2001 From: mrMigles Date: Fri, 20 Feb 2026 09:49:56 +0500 Subject: [PATCH 1/2] feat: Add BotPlatformApplication run configuration and refactor code for improved logging and error handling * Introduced a new run configuration for BotPlatformApplication. * Changed method visibility from private to public for init methods in BotPlatformApplication and EducationCache. * Updated imports from `org.apache.commons.lang` to `org.apache.commons.lang3` across multiple files. * Enhanced error handling by replacing print stack traces with logger error messages in various processors. * Fixed variable name typos and improved code readability in several classes. --- .../botplatform/BotPlatformApplication.java | 2 +- .../botplatform/config/BotConfiguration.java | 2 +- .../core/CommonMessageHandler.java | 19 ++++++------ .../core/education/EducationCache.java | 8 +++-- .../core/handler/SettingsHandler.java | 2 +- .../scripting/TelegramScriptEntity.java | 8 +++-- .../scripting/entity/AbstractText.java | 4 +-- .../scripting/entity/MessageBuilder.java | 6 +++- .../scripting/entity/TimePredicate.java | 2 +- .../AnonymousChatTokenSecurityFilter.java | 2 +- .../botplatform/telegram/InlineWorker.java | 2 ++ .../botplatform/telegram/TelegramBot.java | 27 +++++----------- .../processor/AllNotifyMessageProseccor.java | 13 ++++---- .../processor/AnonymMessageProcessor.java | 2 +- .../processor/GeneratorMemesProcessor.java | 23 +++++++++----- .../processor/RandomMemeProcessor.java | 11 +++++-- .../ReconnaissanceMessageProcessor.java | 16 +++++----- .../processor/RemoveLastMessageProcessor.java | 10 ++++-- .../processor/ScriptManagerProcessor.java | 9 ++++-- .../processor/SecretMessageProcessor.java | 8 +++-- .../processor/VoteKickMessageProcessor.java | 28 +++++++---------- .../botplatform/web/CommonController.java | 31 +++++++++---------- 22 files changed, 127 insertions(+), 108 deletions(-) diff --git a/src/main/java/ru/holyway/botplatform/BotPlatformApplication.java b/src/main/java/ru/holyway/botplatform/BotPlatformApplication.java index 5d6d1a5..12a5616 100644 --- a/src/main/java/ru/holyway/botplatform/BotPlatformApplication.java +++ b/src/main/java/ru/holyway/botplatform/BotPlatformApplication.java @@ -31,7 +31,7 @@ public static void main(String[] args) { } @PostConstruct - private void init() { + public void init() { bots.init(); } } diff --git a/src/main/java/ru/holyway/botplatform/config/BotConfiguration.java b/src/main/java/ru/holyway/botplatform/config/BotConfiguration.java index e909ef6..6b0577d 100644 --- a/src/main/java/ru/holyway/botplatform/config/BotConfiguration.java +++ b/src/main/java/ru/holyway/botplatform/config/BotConfiguration.java @@ -1,6 +1,6 @@ package ru.holyway.botplatform.config; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.apache.http.conn.ssl.SSLConnectionSocketFactory; import org.apache.http.conn.ssl.TrustStrategy; import org.apache.http.impl.client.CloseableHttpClient; diff --git a/src/main/java/ru/holyway/botplatform/core/CommonMessageHandler.java b/src/main/java/ru/holyway/botplatform/core/CommonMessageHandler.java index 2eeaa9a..5ea5b50 100644 --- a/src/main/java/ru/holyway/botplatform/core/CommonMessageHandler.java +++ b/src/main/java/ru/holyway/botplatform/core/CommonMessageHandler.java @@ -1,10 +1,11 @@ package ru.holyway.botplatform.core; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.beans.factory.annotation.Qualifier; import org.springframework.beans.factory.annotation.Value; -import ru.holyway.botplatform.core.data.DataHelper; import ru.holyway.botplatform.core.handler.MessageHandler; import javax.annotation.PostConstruct; @@ -16,8 +17,7 @@ */ public class CommonMessageHandler implements CommonHandler { - @Autowired - private DataHelper dataHelper; + private static final Logger LOGGER = LoggerFactory.getLogger(CommonMessageHandler.class); @Autowired @Qualifier("orderedMessageHandlers") @@ -29,7 +29,7 @@ public class CommonMessageHandler implements CommonHandler { @Value("${bot.config.silentPeriod}") private String silentPeriodString; - private long srartTime = 0; + private long startTime = 0; private long silentPeriod = TimeUnit.SECONDS.toMillis(60); @@ -39,7 +39,7 @@ public CommonMessageHandler() { @PostConstruct public void postConstruct() { - srartTime = System.currentTimeMillis(); + startTime = System.currentTimeMillis(); if (StringUtils.isNotEmpty(silentPeriodString)) { silentPeriod = TimeUnit.SECONDS.toMillis(Long.parseLong(silentPeriodString)); } @@ -56,7 +56,7 @@ public String generateAnswer(MessageEntity messageEntity) { return message; } } catch (ProcessStopException e) { - System.out.println("Stop because: " + e.getMessage()); + LOGGER.debug("Stop because: {}", e.getMessage()); break; } } @@ -72,15 +72,14 @@ public void handleMessage(MessageEntity messageEntity) { sendMessage(messageEntity, answer); } } catch (Exception e) { - e.printStackTrace(); - System.out.println(e); + LOGGER.error("Error handling message", e); } } private void sendMessage(MessageEntity messageEntity, String text) { long currentTime = System.currentTimeMillis(); - if (currentTime - this.srartTime > silentPeriod) { + if (currentTime - this.startTime > silentPeriod) { sendMessageInternal(messageEntity, text); context.setLastStamp(System.currentTimeMillis()); context.incrementCount(); diff --git a/src/main/java/ru/holyway/botplatform/core/education/EducationCache.java b/src/main/java/ru/holyway/botplatform/core/education/EducationCache.java index 0901128..60caa9b 100644 --- a/src/main/java/ru/holyway/botplatform/core/education/EducationCache.java +++ b/src/main/java/ru/holyway/botplatform/core/education/EducationCache.java @@ -1,5 +1,7 @@ package ru.holyway.botplatform.core.education; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import ru.holyway.botplatform.core.data.DataHelper; @@ -17,6 +19,8 @@ @Component public class EducationCache { + private static final Logger LOGGER = LoggerFactory.getLogger(EducationCache.class); + private ConcurrentMap>> learningTokenizedDictionary = new ConcurrentHashMap<>(); private ConcurrentMap> listCurrentLearning = new ConcurrentHashMap<>(); @@ -35,7 +39,7 @@ public class EducationCache { private DataHelper dataHelper; @PostConstruct - private void postConstruct() { + public void postConstruct() { init(); } @@ -55,7 +59,7 @@ public synchronized void init() { simpleWords = dataHelper.getSimple(); } catch (Exception e) { - e.printStackTrace(); + LOGGER.error("Error loading learning data", e); } for (Map.Entry> line : learnWords.entrySet()) { final List> tokenizedAnswers = new ArrayList<>(); diff --git a/src/main/java/ru/holyway/botplatform/core/handler/SettingsHandler.java b/src/main/java/ru/holyway/botplatform/core/handler/SettingsHandler.java index 3d1743a..4b86ca0 100644 --- a/src/main/java/ru/holyway/botplatform/core/handler/SettingsHandler.java +++ b/src/main/java/ru/holyway/botplatform/core/handler/SettingsHandler.java @@ -1,6 +1,6 @@ package ru.holyway.botplatform.core.handler; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Component; import ru.holyway.botplatform.core.MessageEntity; diff --git a/src/main/java/ru/holyway/botplatform/scripting/TelegramScriptEntity.java b/src/main/java/ru/holyway/botplatform/scripting/TelegramScriptEntity.java index cf35620..4248d3e 100644 --- a/src/main/java/ru/holyway/botplatform/scripting/TelegramScriptEntity.java +++ b/src/main/java/ru/holyway/botplatform/scripting/TelegramScriptEntity.java @@ -1,5 +1,7 @@ package ru.holyway.botplatform.scripting; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.telegram.telegrambots.meta.api.methods.send.SendMessage; import org.telegram.telegrambots.meta.exceptions.TelegramApiException; @@ -8,6 +10,8 @@ public class TelegramScriptEntity { + private static final Logger LOGGER = LoggerFactory.getLogger(TelegramScriptEntity.class); + public TelegramScriptEntity() { } @@ -18,7 +22,7 @@ private Consumer send(String chatId, String text) { s.message.messageEntity.getSender() .execute(SendMessage.builder().text(text).chatId(chatId).build()); } catch (TelegramApiException e) { - e.printStackTrace(); + LOGGER.error("Error sending message to chat {}", chatId, e); } }; } @@ -29,7 +33,7 @@ private Consumer send(Long chatId, String text) { s.message.messageEntity.getSender() .execute(SendMessage.builder().text(text).chatId(String.valueOf(chatId)).build()); } catch (TelegramApiException e) { - e.printStackTrace(); + LOGGER.error("Error sending message to chat {}", chatId, e); } }; } diff --git a/src/main/java/ru/holyway/botplatform/scripting/entity/AbstractText.java b/src/main/java/ru/holyway/botplatform/scripting/entity/AbstractText.java index 1c3e933..5c4223a 100644 --- a/src/main/java/ru/holyway/botplatform/scripting/entity/AbstractText.java +++ b/src/main/java/ru/holyway/botplatform/scripting/entity/AbstractText.java @@ -172,13 +172,13 @@ public AbstractText group(final Integer group) { }); } - public AbstractText split(final String deliniter, final Integer group) { + public AbstractText split(final String delimiter, final Integer group) { return new Text(scriptContext -> { String value = value().apply(scriptContext); if (value == null) { return null; } - String[] splits = value.split(deliniter); + String[] splits = value.split(delimiter); if (group < 0 || group >= splits.length) { return null; } diff --git a/src/main/java/ru/holyway/botplatform/scripting/entity/MessageBuilder.java b/src/main/java/ru/holyway/botplatform/scripting/entity/MessageBuilder.java index dd6fff9..e87a455 100644 --- a/src/main/java/ru/holyway/botplatform/scripting/entity/MessageBuilder.java +++ b/src/main/java/ru/holyway/botplatform/scripting/entity/MessageBuilder.java @@ -1,5 +1,7 @@ package ru.holyway.botplatform.scripting.entity; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.telegram.telegrambots.meta.api.methods.send.SendMessage; import org.telegram.telegrambots.meta.api.objects.replykeyboard.InlineKeyboardMarkup; import org.telegram.telegrambots.meta.api.objects.replykeyboard.buttons.InlineKeyboardButton; @@ -12,6 +14,8 @@ public class MessageBuilder implements Function { + private static final Logger LOGGER = LoggerFactory.getLogger(MessageBuilder.class); + private Function text; private Function chatId; private Map, Function> buttons = new LinkedHashMap<>(); @@ -56,7 +60,7 @@ public Consumer send() { .execute(apply(s)) .getMessageId().toString()); } catch (TelegramApiException e) { - e.printStackTrace(); + LOGGER.error("Error sending message", e); } }; } diff --git a/src/main/java/ru/holyway/botplatform/scripting/entity/TimePredicate.java b/src/main/java/ru/holyway/botplatform/scripting/entity/TimePredicate.java index a3d9b31..906fbca 100644 --- a/src/main/java/ru/holyway/botplatform/scripting/entity/TimePredicate.java +++ b/src/main/java/ru/holyway/botplatform/scripting/entity/TimePredicate.java @@ -1,6 +1,6 @@ package ru.holyway.botplatform.scripting.entity; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.scheduling.support.CronTrigger; import ru.holyway.botplatform.scripting.ScriptContext; diff --git a/src/main/java/ru/holyway/botplatform/security/AnonymousChatTokenSecurityFilter.java b/src/main/java/ru/holyway/botplatform/security/AnonymousChatTokenSecurityFilter.java index 1432045..401a2a0 100644 --- a/src/main/java/ru/holyway/botplatform/security/AnonymousChatTokenSecurityFilter.java +++ b/src/main/java/ru/holyway/botplatform/security/AnonymousChatTokenSecurityFilter.java @@ -1,6 +1,6 @@ package ru.holyway.botplatform.security; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.security.authentication.AnonymousAuthenticationToken; import org.springframework.security.core.Authentication; diff --git a/src/main/java/ru/holyway/botplatform/telegram/InlineWorker.java b/src/main/java/ru/holyway/botplatform/telegram/InlineWorker.java index 00d7e55..8aa49c8 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/InlineWorker.java +++ b/src/main/java/ru/holyway/botplatform/telegram/InlineWorker.java @@ -54,6 +54,8 @@ public void run() { } } catch (InterruptedException e) { LOGGER.error("Interrupt Error occurred during execution main: ", e); + Thread.currentThread().interrupt(); + return; } catch (Exception e) { LOGGER.error("Error occurred during execution main: ", e); } diff --git a/src/main/java/ru/holyway/botplatform/telegram/TelegramBot.java b/src/main/java/ru/holyway/botplatform/telegram/TelegramBot.java index 7c8e73a..b7df9e9 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/TelegramBot.java +++ b/src/main/java/ru/holyway/botplatform/telegram/TelegramBot.java @@ -1,6 +1,6 @@ package ru.holyway.botplatform.telegram; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; @@ -21,9 +21,7 @@ import javax.annotation.PostConstruct; import java.util.ArrayList; -import java.util.HashMap; import java.util.List; -import java.util.Map; import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; @@ -47,10 +45,6 @@ public class TelegramBot extends TelegramLongPollingBot implements Bot { @Autowired private CommonHandler commonMessageHandler; - private Map locations = new HashMap<>(); - - private Map realAddresses = new HashMap<>(); - private final List> queues; private final List consumers; private final Integer threadCount; @@ -111,11 +105,10 @@ public void onUpdateReceived(Update update) { } queues.get(partition).put(update); } catch (InterruptedException e) { - LOGGER.error("Error occurred during execution: ", e); - } catch (Exception e) { - LOGGER.error("Error occurred during execution: ", e); + LOGGER.error("Interrupted while queuing update: ", e); + Thread.currentThread().interrupt(); } catch (Throwable e) { - LOGGER.error("Throwable occurred during execution: ", e); + LOGGER.error("Error occurred during execution: ", e); } } @@ -198,18 +191,14 @@ private void onUpdateReceivedInternal(Update update) { messageProcessor.process(telegramMessageEntity); break; } - } catch (Exception e) { - LOGGER.error("Error occurred during execution: ", e); } catch (Throwable e) { - LOGGER.error("Throwable occurred during execution: ", e); + LOGGER.error("Error occurred during execution: ", e); } } try { commonMessageHandler.handleMessage(telegramMessageEntity); - } catch (Exception e) { - LOGGER.error("Error occurred during execution: ", e); } catch (Throwable e) { - LOGGER.error("Throwable occurred during execution: ", e); + LOGGER.error("Error occurred during execution: ", e); } } else if (update.hasCallbackQuery()) { for (MessageProcessor messageProcessor : messageProcessors) { @@ -219,10 +208,8 @@ private void onUpdateReceivedInternal(Update update) { messageProcessor.processCallBack(callbackQuery, sender); return; } - } catch (Exception e) { - LOGGER.error("Error occurred during execution: ", e); } catch (Throwable e) { - LOGGER.error("Throwable occurred during execution: ", e); + LOGGER.error("Error occurred during execution: ", e); } } } diff --git a/src/main/java/ru/holyway/botplatform/telegram/processor/AllNotifyMessageProseccor.java b/src/main/java/ru/holyway/botplatform/telegram/processor/AllNotifyMessageProseccor.java index e7b3fbd..a2dc885 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/processor/AllNotifyMessageProseccor.java +++ b/src/main/java/ru/holyway/botplatform/telegram/processor/AllNotifyMessageProseccor.java @@ -1,6 +1,8 @@ package ru.holyway.botplatform.telegram.processor; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -20,15 +22,14 @@ @Order(3) public class AllNotifyMessageProseccor implements MessageProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(AllNotifyMessageProseccor.class); + @Autowired DataHelper dataHelper; @Override public boolean isNeedToHandle(TelegramMessageEntity messageEntity) { - if (StringUtils.containsIgnoreCase(messageEntity.getText(), "@all")) { - return true; - } - return false; + return StringUtils.containsIgnoreCase(messageEntity.getText(), "@all"); } @Override @@ -44,7 +45,7 @@ public void process(TelegramMessageEntity messageEntity) throws TelegramApiExcep } users.add("@" + nameOfUser); } catch (TelegramApiException e) { - e.printStackTrace(); + LOGGER.error("Error fetching chat member {}", userId, e); } }); if (!users.isEmpty()) { diff --git a/src/main/java/ru/holyway/botplatform/telegram/processor/AnonymMessageProcessor.java b/src/main/java/ru/holyway/botplatform/telegram/processor/AnonymMessageProcessor.java index bd00350..9c14c8f 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/processor/AnonymMessageProcessor.java +++ b/src/main/java/ru/holyway/botplatform/telegram/processor/AnonymMessageProcessor.java @@ -1,6 +1,6 @@ package ru.holyway.botplatform.telegram.processor; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.telegram.telegrambots.meta.api.methods.send.SendMessage; diff --git a/src/main/java/ru/holyway/botplatform/telegram/processor/GeneratorMemesProcessor.java b/src/main/java/ru/holyway/botplatform/telegram/processor/GeneratorMemesProcessor.java index 0266d1f..f1a7c93 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/processor/GeneratorMemesProcessor.java +++ b/src/main/java/ru/holyway/botplatform/telegram/processor/GeneratorMemesProcessor.java @@ -1,6 +1,8 @@ package ru.holyway.botplatform.telegram.processor; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -19,7 +21,7 @@ import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; -import java.net.URL; +import java.net.URI; import java.util.Map; import java.util.concurrent.ConcurrentHashMap; @@ -27,9 +29,11 @@ @Order(101) public class GeneratorMemesProcessor implements MessageProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(GeneratorMemesProcessor.class); + private Map wordsToChat = new ConcurrentHashMap<>(); - private Map inageToChat = new ConcurrentHashMap<>(); + private Map imageToChat = new ConcurrentHashMap<>(); private Map askWord = new ConcurrentHashMap<>(); @@ -78,8 +82,8 @@ public void process(TelegramMessageEntity messageEntity) throws TelegramApiExcep .get(messageEntity.getMessage().getPhoto().size() - 1).getFileId()).build()) .getFileUrl(token); try { - BufferedImage bufferedImage = ImageIO.read(new URL(url)); - inageToChat.put(messageEntity.getChatId(), bufferedImage); + BufferedImage bufferedImage = ImageIO.read(URI.create(url).toURL()); + imageToChat.put(messageEntity.getChatId(), bufferedImage); messageEntity.getSender().execute( SendMessage.builder().text("Напишите фразу для мема") .chatId(messageEntity.getChatId()).build()); @@ -87,7 +91,7 @@ public void process(TelegramMessageEntity messageEntity) throws TelegramApiExcep askImage.remove(messageEntity.getSenderLogin()); return; } catch (IOException e) { - e.printStackTrace(); + LOGGER.error("Error reading image from URL", e); } } if (StringUtils.isNotEmpty(mes) && askWord.get(messageEntity.getSenderLogin()) != null) { @@ -111,15 +115,18 @@ public void processCallBack(CallbackQuery callbackQuery, AbsSender sender) private void sendMeme(final String chatID, final String text, TelegramMessageEntity telegramMessageEntity) throws TelegramApiException { try { - BufferedImage result = MemeImageOverlay.overlay(inageToChat.get(chatID), "", text); + BufferedImage result = MemeImageOverlay.overlay(imageToChat.get(chatID), "", text); ByteArrayOutputStream os = new ByteArrayOutputStream(); ImageIO.write(result, "jpg", os); InputStream is = new ByteArrayInputStream(os.toByteArray()); telegramMessageEntity.getSender().execute( SendPhoto.builder().photo(new InputFile(is, "new")).chatId(telegramMessageEntity.getChatId()) .caption(text).build()); - } catch (IOException | InterruptedException e) { - e.printStackTrace(); + } catch (IOException e) { + LOGGER.error("Error generating meme for chat {}", chatID, e); + } catch (InterruptedException e) { + LOGGER.error("Meme generation interrupted for chat {}", chatID, e); + Thread.currentThread().interrupt(); } } } diff --git a/src/main/java/ru/holyway/botplatform/telegram/processor/RandomMemeProcessor.java b/src/main/java/ru/holyway/botplatform/telegram/processor/RandomMemeProcessor.java index 1778141..dbee2c0 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/processor/RandomMemeProcessor.java +++ b/src/main/java/ru/holyway/botplatform/telegram/processor/RandomMemeProcessor.java @@ -1,5 +1,7 @@ package ru.holyway.botplatform.telegram.processor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.telegram.telegrambots.meta.api.methods.send.SendPhoto; import org.telegram.telegrambots.meta.api.objects.CallbackQuery; import org.telegram.telegrambots.meta.api.objects.InputFile; @@ -21,6 +23,8 @@ //@Order(50) public class RandomMemeProcessor implements MessageProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(RandomMemeProcessor.class); + private BufferedImage dynoTemplate; private BufferedImage catTemplate; @@ -65,8 +69,11 @@ public void process(TelegramMessageEntity messageEntity) throws TelegramApiExcep messageEntity.getSender().execute( SendPhoto.builder().photo(new InputFile(is, "new")).chatId(messageEntity.getChatId()).build()); } - } catch (IOException | InterruptedException e) { - e.printStackTrace(); + } catch (IOException e) { + LOGGER.error("Error generating random meme", e); + } catch (InterruptedException e) { + LOGGER.error("Random meme generation interrupted", e); + Thread.currentThread().interrupt(); } } } diff --git a/src/main/java/ru/holyway/botplatform/telegram/processor/ReconnaissanceMessageProcessor.java b/src/main/java/ru/holyway/botplatform/telegram/processor/ReconnaissanceMessageProcessor.java index 6ca137d..d9a32da 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/processor/ReconnaissanceMessageProcessor.java +++ b/src/main/java/ru/holyway/botplatform/telegram/processor/ReconnaissanceMessageProcessor.java @@ -1,6 +1,8 @@ package ru.holyway.botplatform.telegram.processor; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.scheduling.TaskScheduler; @@ -32,6 +34,8 @@ @Order(2) public class ReconnaissanceMessageProcessor implements MessageProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(ReconnaissanceMessageProcessor.class); + private Map> currentReconChatMembers = new HashMap<>(); private Map> chatMembers = new HashMap<>(); @@ -118,18 +122,14 @@ private void sendReconMessage(TelegramMessageEntity messageEntity) try { showResult(message.getChatId(), mes.getMessageId(), messageEntity.getSender()); } catch (TelegramApiException e) { - e.printStackTrace(); + LOGGER.error("Error showing recon result for chat {}", message.getChatId(), e); } }, new Date(System.currentTimeMillis() + DELAY_TO_UPDATE)); } @Override public boolean isRegardingCallback(CallbackQuery callbackQuery) { - final String callback = callbackQuery.getData(); - if (StringUtils.containsIgnoreCase(callback, "who:")) { - return true; - } - return false; + return StringUtils.containsIgnoreCase(callbackQuery.getData(), "who:"); } @Override @@ -192,7 +192,7 @@ private void showResult(String chatId, Integer messageId, AbsSender sender) try { sender.execute(UnpinChatMessage.builder().chatId(chatId).build()); } catch (Exception e) { - e.printStackTrace(); + LOGGER.warn("Could not unpin message in chat {}", chatId, e); } if (currentReconChatMembers.get(chatId) != null && !currentReconChatMembers.get(chatId) diff --git a/src/main/java/ru/holyway/botplatform/telegram/processor/RemoveLastMessageProcessor.java b/src/main/java/ru/holyway/botplatform/telegram/processor/RemoveLastMessageProcessor.java index 82a1a04..19f1785 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/processor/RemoveLastMessageProcessor.java +++ b/src/main/java/ru/holyway/botplatform/telegram/processor/RemoveLastMessageProcessor.java @@ -1,6 +1,8 @@ package ru.holyway.botplatform.telegram.processor; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.telegram.telegrambots.meta.api.methods.groupadministration.GetChatAdministrators; @@ -19,6 +21,8 @@ @Order(2) public class RemoveLastMessageProcessor implements MessageProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(RemoveLastMessageProcessor.class); + @Override public boolean isNeedToHandle(TelegramMessageEntity messageEntity) { final String mes = messageEntity.getText(); @@ -41,7 +45,7 @@ public void process(TelegramMessageEntity messageEntity) throws TelegramApiExcep messageEntity.getSender() .execute(DeleteMessage.builder().chatId(messageEntity.getChatId()).messageId(i).build()); } catch (Exception e) { - e.printStackTrace(); + LOGGER.warn("Could not delete message {} in chat {}", i, messageEntity.getChatId(), e); } } } @@ -49,7 +53,7 @@ public void process(TelegramMessageEntity messageEntity) throws TelegramApiExcep } catch (Exception e) { messageEntity.getSender() .execute(SendMessage.builder().chatId(messageEntity.getChatId()).text("Нимагу").build()); - e.printStackTrace(); + LOGGER.error("Error deleting messages in chat {}", messageEntity.getChatId(), e); } } diff --git a/src/main/java/ru/holyway/botplatform/telegram/processor/ScriptManagerProcessor.java b/src/main/java/ru/holyway/botplatform/telegram/processor/ScriptManagerProcessor.java index fa896db..4ce03e6 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/processor/ScriptManagerProcessor.java +++ b/src/main/java/ru/holyway/botplatform/telegram/processor/ScriptManagerProcessor.java @@ -1,6 +1,8 @@ package ru.holyway.botplatform.telegram.processor; import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; @@ -29,6 +31,8 @@ @Order(98) public class ScriptManagerProcessor implements MessageProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(ScriptManagerProcessor.class); + public static final String SECURITY_VALUE_SET_REGEX = "(\\/put)(\\s)(\\\")(.*)(\\\")(\\s)(\\\")(.*)(\\\")"; @Autowired private ScriptMessageProcessor scriptMessageProcessor; @@ -166,7 +170,6 @@ public boolean isRegardingCallback(CallbackQuery callbackQuery) { public void processCallBack(CallbackQuery callbackQuery, AbsSender sender) throws TelegramApiException { if (callbackQuery.getData().startsWith("script:edit:")) { - final String scriptId = StringUtils.substringAfter(callbackQuery.getData(), "script:edit:"); sender .execute(SendMessage.builder().replyMarkup(new ForceReplyKeyboard()) .chatId(String.valueOf(callbackQuery.getMessage().getChatId())) @@ -201,7 +204,7 @@ public void processCallBack(CallbackQuery callbackQuery, AbsSender sender) try { sender.execute(DeleteMessage.builder().chatId(String.valueOf(callbackQuery.getMessage().getChatId())).messageId(i).build()); } catch (Exception e) { - e.printStackTrace(); + LOGGER.warn("Could not delete message {} in chat {}", i, callbackQuery.getMessage().getChatId(), e); } } } else if (callbackQuery.getData().startsWith("script:more:")) { @@ -219,7 +222,7 @@ public void processCallBack(CallbackQuery callbackQuery, AbsSender sender) try { scriptMessageProcessor.sendScriptMenu(messageEntity, script.getStringScript().replaceAll("\\\\\\$", "\\$").replaceAll("\\.owner\\(\\d*\\)", ""), script); } catch (Exception e) { - e.printStackTrace(); + LOGGER.error("Error sending script menu for script at index {}", i, e); } } sendControlButtons(messageEntity, max, firstMessage); diff --git a/src/main/java/ru/holyway/botplatform/telegram/processor/SecretMessageProcessor.java b/src/main/java/ru/holyway/botplatform/telegram/processor/SecretMessageProcessor.java index 44ff7fc..3970534 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/processor/SecretMessageProcessor.java +++ b/src/main/java/ru/holyway/botplatform/telegram/processor/SecretMessageProcessor.java @@ -1,6 +1,8 @@ package ru.holyway.botplatform.telegram.processor; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.stereotype.Component; import org.telegram.telegrambots.meta.api.methods.send.SendMessage; @@ -20,6 +22,8 @@ @Order(1) public class SecretMessageProcessor implements MessageProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(SecretMessageProcessor.class); + private Map> secretMessages = new HashMap<>(); @Override @@ -45,7 +49,7 @@ public void process(TelegramMessageEntity messageEntity) throws TelegramApiExcep messageEntity.getSender().execute( DeleteMessage.builder().chatId(messageEntity.getChatId()).messageId(integer).build()); } catch (Exception e) { - e.printStackTrace(); + LOGGER.warn("Could not delete secret message {} in chat {}", integer, messageEntity.getChatId(), e); } secretMessages.remove(messageEntity.getChatId()); } diff --git a/src/main/java/ru/holyway/botplatform/telegram/processor/VoteKickMessageProcessor.java b/src/main/java/ru/holyway/botplatform/telegram/processor/VoteKickMessageProcessor.java index 710dece..3c52d14 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/processor/VoteKickMessageProcessor.java +++ b/src/main/java/ru/holyway/botplatform/telegram/processor/VoteKickMessageProcessor.java @@ -1,6 +1,8 @@ package ru.holyway.botplatform.telegram.processor; -import org.apache.commons.lang.StringUtils; +import org.apache.commons.lang3.StringUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.core.annotation.Order; import org.springframework.scheduling.TaskScheduler; import org.springframework.scheduling.concurrent.ConcurrentTaskScheduler; @@ -34,6 +36,8 @@ @Order(2) public class VoteKickMessageProcessor implements MessageProcessor { + private static final Logger LOGGER = LoggerFactory.getLogger(VoteKickMessageProcessor.class); + private Map banList = new HashMap<>(); private Integer voteSize = 3; @@ -48,15 +52,10 @@ public class VoteKickMessageProcessor implements MessageProcessor { public boolean isNeedToHandle(TelegramMessageEntity messageEntity) { final String mes = messageEntity.getText(); if (StringUtils.isNotEmpty(mes) && (StringUtils.equalsIgnoreCase(mes, "кик") || StringUtils - .equalsIgnoreCase(mes, "бан"))) { - if (messageEntity.getMessage().getReplyToMessage() != null) { - return true; - } - } - if (StringUtils.containsIgnoreCase(mes, "/votestop")) { + .equalsIgnoreCase(mes, "бан")) && messageEntity.getMessage().getReplyToMessage() != null) { return true; } - return false; + return StringUtils.containsIgnoreCase(mes, "/votestop"); } @Override @@ -137,7 +136,7 @@ public void process(TelegramMessageEntity messageEntity) throws TelegramApiExcep endVote(messageEntity.getChatId(), banList.get(messageEntity.getChatId()).getMessageID(), messageEntity.getSender()); } catch (TelegramApiException e) { - e.printStackTrace(); + LOGGER.error("Error ending vote for chat {}", messageEntity.getChatId(), e); } }, new Date(System.currentTimeMillis() + DELAY_TO_UPDATE)); } @@ -145,11 +144,8 @@ public void process(TelegramMessageEntity messageEntity) throws TelegramApiExcep @Override public boolean isRegardingCallback(CallbackQuery callbackQuery) { final String callback = callbackQuery.getData(); - if (banList.get(String.valueOf(callbackQuery.getMessage().getChatId())) != null && StringUtils - .containsIgnoreCase(callback, "kick:")) { - return true; - } - return false; + return banList.get(String.valueOf(callbackQuery.getMessage().getChatId())) != null + && StringUtils.containsIgnoreCase(callback, "kick:"); } @Override @@ -205,7 +201,7 @@ public void processCallBack(CallbackQuery callbackQuery, AbsSender sender) .userId(banInfo.getUser().getId()).build()); } } catch (TelegramApiException e) { - e.printStackTrace(); + LOGGER.error("Error lifting ban for user in chat {}", chatID, e); } }, new Date(System.currentTimeMillis() + DELAY_TO_UPDATE)); } @@ -227,7 +223,7 @@ private void endVote(final String chatID, final Integer messageID, final AbsSend try { sender.execute(UnpinChatMessage.builder().chatId(chatID).build()); } catch (Exception e) { - e.printStackTrace(); + LOGGER.warn("Could not unpin message in chat {}", chatID, e); } diff --git a/src/main/java/ru/holyway/botplatform/web/CommonController.java b/src/main/java/ru/holyway/botplatform/web/CommonController.java index 32b9e43..6344f7d 100644 --- a/src/main/java/ru/holyway/botplatform/web/CommonController.java +++ b/src/main/java/ru/holyway/botplatform/web/CommonController.java @@ -1,6 +1,8 @@ package ru.holyway.botplatform.web; import org.apache.commons.lang3.StringEscapeUtils; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.HttpStatus; import org.springframework.http.ResponseEntity; @@ -15,7 +17,6 @@ import ru.holyway.botplatform.web.entities.SimpleRequest; import ru.holyway.botplatform.web.entities.SimpleResponse; -import java.io.UnsupportedEncodingException; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -26,6 +27,8 @@ @RestController public class CommonController { + private static final Logger LOGGER = LoggerFactory.getLogger(CommonController.class); + @Autowired List bots; @@ -39,14 +42,13 @@ public class CommonController { @PreAuthorize("permitAll()") @RequestMapping(value = "/", method = RequestMethod.GET) - public ResponseEntity echo() { - return new ResponseEntity(HttpStatus.OK); + public ResponseEntity echo() { + return new ResponseEntity<>(HttpStatus.OK); } @PreAuthorize("permitAll()") @RequestMapping(value = "/command", method = RequestMethod.POST) - public ResponseEntity test(@RequestBody SimpleRequest simpleRequest) - throws UnsupportedEncodingException { + public ResponseEntity test(@RequestBody SimpleRequest simpleRequest) { final String action = simpleRequest.getResult().getAction(); if ("whatis".equals(action)) { @@ -63,7 +65,7 @@ public ResponseEntity test(@RequestBody SimpleRequest simpleRequ result = result.substring(start + 10, end); result = StringEscapeUtils.escapeHtml4(result); result = result.replaceAll("&[^\\s]*;", ""); - if (result.length() > 0) { + if (!result.isEmpty()) { result = "Это " + result; return new ResponseEntity<>(new SimpleResponse(result, result), HttpStatus.OK); } @@ -72,21 +74,16 @@ public ResponseEntity test(@RequestBody SimpleRequest simpleRequ return new ResponseEntity<>(new SimpleResponse("Я многое понимаю, но этого я не понимаю...", "Я многое понимаю, но этого я не понимаю..."), HttpStatus.OK); } - System.out.println("New request: " + simpleRequest.getResult().getAction()); - try { - return new ResponseEntity<>( - new SimpleResponse("Ответ пришёл к тебе для " + simpleRequest.getResult().getParameters(), - "Ответ пришёл к тебе для "), HttpStatus.OK); - } catch (Exception e) { - return new ResponseEntity<>(new SimpleResponse("Плохо, очень плохо!", "Плохо, очень плохо!"), - HttpStatus.INTERNAL_SERVER_ERROR); - } + LOGGER.info("New request: {}", simpleRequest.getResult().getAction()); + return new ResponseEntity<>( + new SimpleResponse("Ответ пришёл к тебе для " + simpleRequest.getResult().getParameters(), + "Ответ пришёл к тебе для "), HttpStatus.OK); } @PreAuthorize("hasAuthority('USER')") @RequestMapping(value = "/send", method = RequestMethod.GET) public ResponseEntity restart(@RequestParam("chatId") String chatId, - @RequestParam("entity") String message) throws UnsupportedEncodingException { + @RequestParam("entity") String message) { for (Bot bot : bots) { bot.sendMessage(message, chatId); } @@ -96,7 +93,7 @@ public ResponseEntity restart(@RequestParam("chatId") String chatId, @PreAuthorize("permitAll()") @RequestMapping(value = "/mes", method = RequestMethod.GET) public ResponseEntity message(@RequestParam("id") String chatId, - @RequestParam("entity") String message) throws UnsupportedEncodingException { + @RequestParam("entity") String message) { MessageEntity messageEntity = new WebMessageEntity(chatId, "web", message); final String answer = commonHandler.generateAnswer(messageEntity); From 0795eb55924573edc8241579f1bb2fac82613e91 Mon Sep 17 00:00:00 2001 From: mrMigles Date: Fri, 20 Feb 2026 11:05:11 +0500 Subject: [PATCH 2/2] feat: Enhance scripting functionality and add comprehensive unit tests * Updated .gitignore to include VS Code and Maven local configurations. * Refactored Portainer deploy workflow to improve error handling and stack management. * Modified ArrayEntity methods to ensure proper context handling during iteration. * Added unit tests for ArrayEntity, ConditionHandler, LoopHandler, and other scripting components to ensure robust functionality. * Implemented various utility classes and predicates for enhanced scripting capabilities. --- .github/workflows/portainer-deploy.yml | 44 +- .gitignore | 10 +- .../scripting/entity/ArrayEntity.java | 4 +- .../processor/ScriptMessageProcessor.java | 5 +- .../scripting/ArrayEntityTest.java | 141 ++++++ .../scripting/ConditionHandlerTest.java | 97 ++++ .../scripting/InTimePredicateTest.java | 67 +++ .../scripting/LoopHandlerTest.java | 151 ++++++ .../scripting/ScriptContextTest.java | 75 +++ .../scripting/TernaryHandlerTest.java | 74 +++ .../botplatform/scripting/TextJoinerTest.java | 91 ++++ .../scripting/TimePredicateTest.java | 72 +++ .../botplatform/scripting/TimeTest.java | 179 +++++++ .../scripting/VariableEntityTest.java | 94 ++++ .../processor/ScriptManagerProcessorTest.java | 185 ++++++++ .../processor/ScriptMessageProcessorTest.java | 446 ++++++++++++++++++ 16 files changed, 1724 insertions(+), 11 deletions(-) create mode 100644 src/test/java/ru/holyway/botplatform/scripting/ArrayEntityTest.java create mode 100644 src/test/java/ru/holyway/botplatform/scripting/ConditionHandlerTest.java create mode 100644 src/test/java/ru/holyway/botplatform/scripting/InTimePredicateTest.java create mode 100644 src/test/java/ru/holyway/botplatform/scripting/LoopHandlerTest.java create mode 100644 src/test/java/ru/holyway/botplatform/scripting/ScriptContextTest.java create mode 100644 src/test/java/ru/holyway/botplatform/scripting/TernaryHandlerTest.java create mode 100644 src/test/java/ru/holyway/botplatform/scripting/TextJoinerTest.java create mode 100644 src/test/java/ru/holyway/botplatform/scripting/TimePredicateTest.java create mode 100644 src/test/java/ru/holyway/botplatform/scripting/TimeTest.java create mode 100644 src/test/java/ru/holyway/botplatform/scripting/VariableEntityTest.java create mode 100644 src/test/java/ru/holyway/botplatform/telegram/processor/ScriptManagerProcessorTest.java create mode 100644 src/test/java/ru/holyway/botplatform/telegram/processor/ScriptMessageProcessorTest.java diff --git a/.github/workflows/portainer-deploy.yml b/.github/workflows/portainer-deploy.yml index 26c09a4..cf08c96 100644 --- a/.github/workflows/portainer-deploy.yml +++ b/.github/workflows/portainer-deploy.yml @@ -94,8 +94,9 @@ jobs: if not all([url, username, password, stack_id]): sys.exit("Portainer secrets are not configured") + base = url.rstrip("/") auth_request = request.Request( - f"{url.rstrip('/')}/api/auth", + f"{base}/api/auth", data=json.dumps({"Username": username, "Password": password}).encode(), headers={"Content-Type": "application/json"}, ) @@ -110,11 +111,42 @@ jobs: if not token: sys.exit("Failed to obtain Portainer JWT token") + headers = {"Authorization": f"Bearer {token}", "Content-Type": "application/json"} + + # Get stack details (includes EndpointId) + inspect_request = request.Request(f"{base}/api/stacks/{stack_id}", headers=headers) + try: + with request.urlopen(inspect_request) as resp: + stack = json.loads(resp.read().decode()) + except error.HTTPError as exc: + exit_with_http_details(exc) + endpoint_id = stack.get("EndpointId") + if endpoint_id is None: + sys.exit("Stack response missing EndpointId") + + # Get current stack file content + file_request = request.Request(f"{base}/api/stacks/{stack_id}/file", headers=headers) + try: + with request.urlopen(file_request) as resp: + file_data = json.loads(resp.read().decode()) + except error.HTTPError as exc: + exit_with_http_details(exc) + stack_file_content = file_data.get("StackFileContent") or file_data.get("stackFileContent", "") + env = file_data.get("Env") or file_data.get("env") or [] + + # Redeploy via PUT (Portainer has no POST .../deploy endpoint) + payload = { + "endpointId": endpoint_id, + "stackFileContent": stack_file_content, + "env": env, + "prune": True, + "pullImage": True, + } deploy_request = request.Request( - f"{url.rstrip('/')}/api/stacks/{stack_id}/deploy", - data=json.dumps({"prune": True, "pullImage": True}).encode(), - headers={"Authorization": f"Bearer {token}", "Content-Type": "application/json"}, - method="POST", + f"{base}/api/stacks/{stack_id}", + data=json.dumps(payload).encode(), + headers=headers, + method="PUT", ) try: with request.urlopen(deploy_request) as resp: @@ -123,5 +155,5 @@ jobs: except error.HTTPError as exc: exit_with_http_details(exc) except error.URLError as exc: - sys.exit(f"Failed to reach Portainer deploy endpoint: {exc.reason}") + sys.exit(f"Failed to reach Portainer stack update endpoint: {exc.reason}") PY diff --git a/.gitignore b/.gitignore index 2af7cef..2d6659c 100644 --- a/.gitignore +++ b/.gitignore @@ -1,5 +1,11 @@ target/ -!.mvn/wrapper/maven-wrapper.jar + +### VS Code ### +.vscode/ + +### Maven (keep wrapper, ignore local config) ### +.mvn/* +!.mvn/wrapper/ ### STS ### .apt_generated @@ -10,7 +16,7 @@ target/ .springBeans ### IntelliJ IDEA ### -.idea +.idea/ *.iws *.iml *.ipr diff --git a/src/main/java/ru/holyway/botplatform/scripting/entity/ArrayEntity.java b/src/main/java/ru/holyway/botplatform/scripting/entity/ArrayEntity.java index 433f573..b093586 100644 --- a/src/main/java/ru/holyway/botplatform/scripting/entity/ArrayEntity.java +++ b/src/main/java/ru/holyway/botplatform/scripting/entity/ArrayEntity.java @@ -17,11 +17,11 @@ public ArrayEntity(Function> array) { } public Consumer forEachFrom(Consumer func, Function startFrom) { - return scriptContext -> forEachFrom(func, Integer.parseInt(startFrom.apply(scriptContext).toString())); + return scriptContext -> forEachFrom(func, Integer.parseInt(startFrom.apply(scriptContext).toString())).accept(scriptContext); } public Consumer forEachLast(Consumer func, Function last) { - return scriptContext -> forEachLast(func, Integer.parseInt(last.apply(scriptContext).toString())); + return scriptContext -> forEachLast(func, Integer.parseInt(last.apply(scriptContext).toString())).accept(scriptContext); } public Consumer forEachFrom(Consumer func, int startFrom) { diff --git a/src/main/java/ru/holyway/botplatform/telegram/processor/ScriptMessageProcessor.java b/src/main/java/ru/holyway/botplatform/telegram/processor/ScriptMessageProcessor.java index 83930c6..e55edc8 100644 --- a/src/main/java/ru/holyway/botplatform/telegram/processor/ScriptMessageProcessor.java +++ b/src/main/java/ru/holyway/botplatform/telegram/processor/ScriptMessageProcessor.java @@ -52,7 +52,10 @@ public ScriptMessageProcessor(ScriptCompiler scriptCompiler, DataHelper dataHelp } catch (Exception e) { LOGGER.error("Error during loading script:", e); } - scripts.get(chatScripts.getKey()).sort(Script::compareTo); + } + List