From 2f81307caf04c58dc6aaf556de25297ab52d643e Mon Sep 17 00:00:00 2001 From: Victor Date: Tue, 29 Sep 2020 00:12:43 +0300 Subject: [PATCH] Ability to remove image from index and post from channel --- .../annimon/similarimagesbot/BotHandler.java | 34 +++++++++++++++++-- .../similarimagesbot/ImageIndexer.java | 14 +++++--- .../SimilarImagesH2DatabaseMatcher.java | 22 ++++++++++++ 3 files changed, 64 insertions(+), 6 deletions(-) create mode 100644 src/main/java/com/annimon/similarimagesbot/SimilarImagesH2DatabaseMatcher.java diff --git a/src/main/java/com/annimon/similarimagesbot/BotHandler.java b/src/main/java/com/annimon/similarimagesbot/BotHandler.java index 189c313..33f242e 100644 --- a/src/main/java/com/annimon/similarimagesbot/BotHandler.java +++ b/src/main/java/com/annimon/similarimagesbot/BotHandler.java @@ -8,6 +8,7 @@ import com.pengrad.telegrambot.model.Message; import com.pengrad.telegrambot.model.PhotoSize; import com.pengrad.telegrambot.model.Update; import com.pengrad.telegrambot.model.request.ParseMode; +import com.pengrad.telegrambot.request.DeleteMessage; import com.pengrad.telegrambot.request.GetFile; import com.pengrad.telegrambot.request.GetUpdates; import com.pengrad.telegrambot.request.SendMessage; @@ -20,6 +21,7 @@ import java.util.Arrays; import java.util.Comparator; import java.util.List; import java.util.Objects; +import java.util.regex.Pattern; import java.util.stream.Collectors; import javax.imageio.ImageIO; @@ -42,13 +44,37 @@ public class BotHandler { public void run() { bot.setUpdatesListener(updates -> { + processAdminCommands(updates); processUpdates(updates); return UpdatesListener.CONFIRMED_UPDATES_ALL; }); } public void runOnce() { - processUpdates(bot.execute(new GetUpdates()).updates()); + final var updates = bot.execute(new GetUpdates()).updates(); + processAdminCommands(updates); + processUpdates(updates); + } + + private void processAdminCommands(List updates) { + final var delPattern = Pattern.compile("/del(\\d+)m(\\d+)"); + updates.stream() + .map(Update::message) + .filter(Objects::nonNull) + .filter(msg -> msg.chat().id() == adminId) + .map(Message::text) + .filter(Objects::nonNull) + .forEach(command -> { + final var m = delPattern.matcher(command); + if (m.find()) { + final var channelId = Long.parseLong("-100" + m.group(1)); + final var messageId = Integer.parseInt(m.group(2)); + bot.execute(new DeleteMessage(channelId, messageId)); + try { + indexer.deleteImage(channelId, messageId); + } catch (SQLException ignored) {} + } + }); } private void processUpdates(List updates) { @@ -84,10 +110,14 @@ public class BotHandler { private void sendReport(List infos) { String report = infos.stream().map(info -> { - String text = "For post " + formatPostLink(info.getOriginalPost()) + " found:\n"; + final var post = info.getOriginalPost(); + String text = "For post " + formatPostLink(post) + " found:\n"; text += info.getResults().stream() .map(r -> String.format(" %s, dst: %.2f", formatPostLink(r.getPost()), r.getDistance())) .collect(Collectors.joining("\n")); + text += String.format("%n/del%sm%d", + post.getChannelId().toString().replace("-100", ""), + post.getMessageId()); return text; }).collect(Collectors.joining("\n\n")); diff --git a/src/main/java/com/annimon/similarimagesbot/ImageIndexer.java b/src/main/java/com/annimon/similarimagesbot/ImageIndexer.java index e26fab2..a4318ec 100644 --- a/src/main/java/com/annimon/similarimagesbot/ImageIndexer.java +++ b/src/main/java/com/annimon/similarimagesbot/ImageIndexer.java @@ -5,7 +5,6 @@ import com.annimon.similarimagesbot.data.Post; import com.annimon.similarimagesbot.data.SimilarImagesInfo; import com.github.kilianB.hashAlgorithms.DifferenceHash; import com.github.kilianB.hashAlgorithms.PerceptiveHash; -import com.github.kilianB.matcher.persistent.database.H2DatabaseImageMatcher; import java.awt.image.BufferedImage; import java.sql.DriverManager; import java.sql.SQLException; @@ -17,7 +16,7 @@ import static com.github.kilianB.hashAlgorithms.DifferenceHash.Precision; public class ImageIndexer { - private final Map databases = new HashMap<>(5); + private final Map databases = new HashMap<>(5); private final DifferenceHash differenceHash = new DifferenceHash(32, Precision.Double); private final PerceptiveHash perceptiveHash = new PerceptiveHash(32); @@ -41,14 +40,21 @@ public class ImageIndexer { return new SimilarImagesInfo(originalPost, results); } - private H2DatabaseImageMatcher getDatabaseForChannel(Long channelId) throws SQLException { + + public void deleteImage(Long channelId, Integer messageId) throws SQLException { + final String uniqueId = messageId.toString(); + final var db = getDatabaseForChannel(channelId); + db.removeImage(uniqueId); + } + + private SimilarImagesH2DatabaseMatcher getDatabaseForChannel(Long channelId) throws SQLException { var db = databases.get(channelId); if (db != null) { return db; } var jdbcUrl = "jdbc:h2:./imagesdb_" + channelId; var conn = DriverManager.getConnection(jdbcUrl, "root", ""); - db = new H2DatabaseImageMatcher(conn); + db = new SimilarImagesH2DatabaseMatcher(conn); db.addHashingAlgorithm(differenceHash, 0.4); db.addHashingAlgorithm(perceptiveHash, 0.2); databases.put(channelId, db); diff --git a/src/main/java/com/annimon/similarimagesbot/SimilarImagesH2DatabaseMatcher.java b/src/main/java/com/annimon/similarimagesbot/SimilarImagesH2DatabaseMatcher.java new file mode 100644 index 0000000..53c3ced --- /dev/null +++ b/src/main/java/com/annimon/similarimagesbot/SimilarImagesH2DatabaseMatcher.java @@ -0,0 +1,22 @@ +package com.annimon.similarimagesbot; + +import com.github.kilianB.matcher.persistent.database.H2DatabaseImageMatcher; +import java.sql.Connection; +import java.sql.SQLException; + +public class SimilarImagesH2DatabaseMatcher extends H2DatabaseImageMatcher { + + public SimilarImagesH2DatabaseMatcher(Connection dbConnection) throws SQLException { + super(dbConnection); + } + + public void removeImage(String uniqueId) throws SQLException { + for (var algo : steps.keySet()) { + try (var stmt = conn + .prepareStatement("DELETE FROM " + resolveTableName(algo) + " WHERE URL = ?")) { + stmt.setString(1, uniqueId); + stmt.execute(); + } + } + } +}