Save last update id in order to not reprocess commands

This commit is contained in:
Victor Melnik 2020-10-07 18:42:48 +00:00 committed by GitHub
parent 8e0aa41cc0
commit 56e681d141
4 changed files with 117 additions and 57 deletions

View File

@ -2,4 +2,6 @@
.build-cache .build-cache
.idea .idea
build build
README.md README.md
*.dat
*.db

1
.gitignore vendored
View File

@ -6,4 +6,5 @@
.settings .settings
bin bin
build build
*.dat
*.db *.db

View File

@ -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<PhotoSize> 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<Update> updates);
protected List<Message> getChannelPostsWithPhotos(List<Update> 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<Update> 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) {}
}}

View File

@ -1,29 +1,10 @@
package com.annimon.similarimagesbot; 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.awt.image.BufferedImage;
import java.io.IOException; import java.io.IOException;
import java.net.URL; import java.net.URL;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import java.util.Optional; import java.util.Optional;
@ -33,22 +14,31 @@ import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import javax.imageio.ImageIO; 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<PhotoSize> photoSizeComparator = Comparator
.comparingInt(ps -> ps.width() * ps.height());
private final Pattern delPattern = Pattern.compile("/del(\\d+)m(\\d+)"); private final Pattern delPattern = Pattern.compile("/del(\\d+)m(\\d+)");
private final Pattern comparePattern = Pattern.compile("/compare(\\d+)m(\\d+)x(\\d+)"); private final Pattern comparePattern = Pattern.compile("/compare(\\d+)m(\\d+)x(\\d+)");
private final TelegramBot bot;
private final ImageIndexer indexer; private final ImageIndexer indexer;
private long adminId; private long adminId;
public BotHandler(String botToken, ImageIndexer indexer) { public BotHandler(String botToken, ImageIndexer indexer) {
bot = new TelegramBot.Builder(botToken) super(botToken);
.updateListenerSleep(20_000L)
.build();
this.indexer = indexer; this.indexer = indexer;
} }
@ -56,16 +46,7 @@ public class BotHandler {
this.adminId = adminId; this.adminId = adminId;
} }
public void run() { protected void handleUpdates(List<Update> updates) {
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();
final var removedPosts = processAdminCommands(updates); final var removedPosts = processAdminCommands(updates);
processUpdates(updates, removedPosts); processUpdates(updates, removedPosts);
} }
@ -154,14 +135,6 @@ public class BotHandler {
} }
} }
private List<Message> getChannelPostsWithPhotos(List<Update> updates) {
return updates.stream()
.map(Update::channelPost)
.filter(Objects::nonNull)
.filter(msg -> msg.photo() != null)
.collect(Collectors.toList());
}
private void sendReport(List<SimilarImagesInfo> infos) { private void sendReport(List<SimilarImagesInfo> infos) {
String report = infos.stream().map(info -> { String report = infos.stream().map(info -> {
final var post = info.getOriginalPost(); final var post = info.getOriginalPost();
@ -201,16 +174,4 @@ public class BotHandler {
private String linkToMessage(Long chatId, Integer messageId) { private String linkToMessage(Long chatId, Integer messageId) {
return "https://t.me/c/" + chatId.toString().replace("-100", "") + "/" + 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]);
}
} }