From 56e681d1415677d4c6617b057177b7b4ef6288f5 Mon Sep 17 00:00:00 2001 From: Victor Melnik Date: Wed, 7 Oct 2020 18:42:48 +0000 Subject: [PATCH] Save last update id in order to not reprocess commands --- .dockerignore | 4 +- .gitignore | 1 + .../similarimagesbot/BaseBotHandler.java | 96 +++++++++++++++++++ .../annimon/similarimagesbot/BotHandler.java | 73 ++++---------- 4 files changed, 117 insertions(+), 57 deletions(-) create mode 100644 src/main/java/com/annimon/similarimagesbot/BaseBotHandler.java diff --git a/.dockerignore b/.dockerignore index e10cedb..b8d8d1b 100644 --- a/.dockerignore +++ b/.dockerignore @@ -2,4 +2,6 @@ .build-cache .idea build -README.md \ No newline at end of file +README.md +*.dat +*.db \ No newline at end of file diff --git a/.gitignore b/.gitignore index 15c04f2..d1051e4 100644 --- a/.gitignore +++ b/.gitignore @@ -6,4 +6,5 @@ .settings bin build +*.dat *.db \ No newline at end of file diff --git a/src/main/java/com/annimon/similarimagesbot/BaseBotHandler.java b/src/main/java/com/annimon/similarimagesbot/BaseBotHandler.java new file mode 100644 index 0000000..47033ac --- /dev/null +++ b/src/main/java/com/annimon/similarimagesbot/BaseBotHandler.java @@ -0,0 +1,96 @@ +package com.annimon.similarimagesbot; + +import java.io.IOException; +import java.nio.file.Files; +import java.nio.file.Path; +import java.nio.file.Paths; +import java.util.Arrays; +import java.util.Comparator; +import java.util.List; +import java.util.Objects; +import java.util.stream.Collectors; +import com.pengrad.telegrambot.TelegramBot; +import com.pengrad.telegrambot.UpdatesListener; +import com.pengrad.telegrambot.model.Message; +import com.pengrad.telegrambot.model.PhotoSize; +import com.pengrad.telegrambot.model.Update; +import com.pengrad.telegrambot.request.GetUpdates; + +public abstract class BaseBotHandler { + + private final Comparator photoSizeComparator = Comparator + .comparingInt(ps -> ps.width() * ps.height()); + + private final Path uniqueIdPath = Paths.get("uniqueId.dat"); + + protected final TelegramBot bot; + + public BaseBotHandler(String botToken) { + bot = new TelegramBot.Builder(botToken) + .updateListenerSleep(20_000L) + .build(); + } + + public void run() { + int oldLastUpdateId = readLastUpdateId(); + bot.setUpdatesListener(updates -> { + final var filteredUpdates = updates.stream() + .filter(u -> u.updateId() > oldLastUpdateId) + .collect(Collectors.toList()); + handleUpdates(filteredUpdates); + int newLastUpdateId = getLastUpdateIdFromUpdatesList(updates, oldLastUpdateId); + writeLastUpdateId(newLastUpdateId + 1); + return UpdatesListener.CONFIRMED_UPDATES_ALL; + }); + } + + public void runOnce() { + int oldLastUpdateId = readLastUpdateId(); + final var updates = bot.execute(new GetUpdates().offset(oldLastUpdateId)).updates(); + handleUpdates(updates); + int newLastUpdateId = getLastUpdateIdFromUpdatesList(updates, oldLastUpdateId); + writeLastUpdateId(newLastUpdateId + 1); + } + + protected abstract void handleUpdates(List updates); + + protected List getChannelPostsWithPhotos(List updates) { + return updates.stream() + .map(Update::channelPost) + .filter(Objects::nonNull) + .filter(msg -> msg.photo() != null) + .collect(Collectors.toList()); + } + + protected PhotoSize getSmallestPhoto(PhotoSize[] photoSizes) { + return Arrays.stream(photoSizes) + .min(photoSizeComparator) + .orElse(photoSizes[0]); + } + + protected PhotoSize getBiggestPhoto(PhotoSize[] photoSizes) { + return Arrays.stream(photoSizes) + .max(photoSizeComparator) + .orElse(photoSizes[0]); + } + + private int getLastUpdateIdFromUpdatesList(List updates, int previousUpdateId) { + return updates.stream() + .mapToInt(Update::updateId) + .max() + .orElse(previousUpdateId); + } + + private int readLastUpdateId() { + try { + return Integer.parseInt(Files.readString(uniqueIdPath)); + } catch (IOException ioe) { + return 0; + } + } + + private void writeLastUpdateId(int updateId) { + try { + Files.writeString(uniqueIdPath, Integer.toString(updateId)); + } catch (IOException ignore) {} + }} diff --git a/src/main/java/com/annimon/similarimagesbot/BotHandler.java b/src/main/java/com/annimon/similarimagesbot/BotHandler.java index be3a472..8a20f0c 100644 --- a/src/main/java/com/annimon/similarimagesbot/BotHandler.java +++ b/src/main/java/com/annimon/similarimagesbot/BotHandler.java @@ -1,29 +1,10 @@ package com.annimon.similarimagesbot; -import com.annimon.similarimagesbot.data.ImageResult; -import com.annimon.similarimagesbot.data.Post; -import com.annimon.similarimagesbot.data.SimilarImagesInfo; -import com.pengrad.telegrambot.TelegramBot; -import com.pengrad.telegrambot.UpdatesListener; -import com.pengrad.telegrambot.model.Message; -import com.pengrad.telegrambot.model.PhotoSize; -import com.pengrad.telegrambot.model.Update; -import com.pengrad.telegrambot.model.request.InputMediaPhoto; -import com.pengrad.telegrambot.model.request.ParseMode; -import com.pengrad.telegrambot.request.DeleteMessage; -import com.pengrad.telegrambot.request.ForwardMessage; -import com.pengrad.telegrambot.request.GetFile; -import com.pengrad.telegrambot.request.GetUpdates; -import com.pengrad.telegrambot.request.SendMediaGroup; -import com.pengrad.telegrambot.request.SendMessage; -import com.pengrad.telegrambot.response.SendResponse; import java.awt.image.BufferedImage; import java.io.IOException; import java.net.URL; import java.sql.SQLException; import java.util.ArrayList; -import java.util.Arrays; -import java.util.Comparator; import java.util.List; import java.util.Objects; import java.util.Optional; @@ -33,22 +14,31 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.imageio.ImageIO; +import com.annimon.similarimagesbot.data.ImageResult; +import com.annimon.similarimagesbot.data.Post; +import com.annimon.similarimagesbot.data.SimilarImagesInfo; +import com.pengrad.telegrambot.model.Message; +import com.pengrad.telegrambot.model.PhotoSize; +import com.pengrad.telegrambot.model.Update; +import com.pengrad.telegrambot.model.request.InputMediaPhoto; +import com.pengrad.telegrambot.model.request.ParseMode; +import com.pengrad.telegrambot.request.DeleteMessage; +import com.pengrad.telegrambot.request.ForwardMessage; +import com.pengrad.telegrambot.request.GetFile; +import com.pengrad.telegrambot.request.SendMediaGroup; +import com.pengrad.telegrambot.request.SendMessage; +import com.pengrad.telegrambot.response.SendResponse; -public class BotHandler { +public class BotHandler extends BaseBotHandler { - private final Comparator photoSizeComparator = Comparator - .comparingInt(ps -> ps.width() * ps.height()); private final Pattern delPattern = Pattern.compile("/del(\\d+)m(\\d+)"); private final Pattern comparePattern = Pattern.compile("/compare(\\d+)m(\\d+)x(\\d+)"); - private final TelegramBot bot; private final ImageIndexer indexer; private long adminId; public BotHandler(String botToken, ImageIndexer indexer) { - bot = new TelegramBot.Builder(botToken) - .updateListenerSleep(20_000L) - .build(); + super(botToken); this.indexer = indexer; } @@ -56,16 +46,7 @@ public class BotHandler { this.adminId = adminId; } - public void run() { - bot.setUpdatesListener(updates -> { - final var removedPosts = processAdminCommands(updates); - processUpdates(updates, removedPosts); - return UpdatesListener.CONFIRMED_UPDATES_ALL; - }); - } - - public void runOnce() { - final var updates = bot.execute(new GetUpdates()).updates(); + protected void handleUpdates(List updates) { final var removedPosts = processAdminCommands(updates); processUpdates(updates, removedPosts); } @@ -154,14 +135,6 @@ public class BotHandler { } } - private List getChannelPostsWithPhotos(List updates) { - return updates.stream() - .map(Update::channelPost) - .filter(Objects::nonNull) - .filter(msg -> msg.photo() != null) - .collect(Collectors.toList()); - } - private void sendReport(List infos) { String report = infos.stream().map(info -> { final var post = info.getOriginalPost(); @@ -201,16 +174,4 @@ public class BotHandler { private String linkToMessage(Long chatId, Integer messageId) { return "https://t.me/c/" + chatId.toString().replace("-100", "") + "/" + messageId; } - - private PhotoSize getSmallestPhoto(PhotoSize[] photoSizes) { - return Arrays.stream(photoSizes) - .min(photoSizeComparator) - .orElse(photoSizes[0]); - } - - private PhotoSize getBiggestPhoto(PhotoSize[] photoSizes) { - return Arrays.stream(photoSizes) - .max(photoSizeComparator) - .orElse(photoSizes[0]); - } }