Improve download logic in case of mismatching filenames
authorDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 27 Oct 2021 10:06:03 +0000 (12:06 +0200)
committerDavid ‘Bombe’ Roden <bombe@pterodactylus.net>
Wed, 27 Oct 2021 10:06:35 +0000 (12:06 +0200)
Because sometimes, the filenames announced by the bot and the name of
the file actually offered by the bot are different, e.g. when the
filesystem and the DCC protocol differ on whether letters outside of
7-bit ASCII do actually exist. I still want those files!

src/main/java/net/pterodactylus/xdcc/core/Core.java

index 649db75..01460c4 100644 (file)
@@ -18,6 +18,7 @@
 package net.pterodactylus.xdcc.core;
 
 import static java.lang.String.format;
+import static java.util.stream.Collectors.toSet;
 import static net.pterodactylus.irc.event.ChannelNotJoined.Reason.banned;
 import static net.pterodactylus.irc.event.ChannelNotJoined.Reason.inviteOnly;
 import static net.pterodactylus.irc.event.ChannelNotJoined.Reason.registeredNicknamesOnly;
@@ -411,7 +412,7 @@ public class Core extends AbstractExecutionThreadService {
                                        .map(Channel::network)
                                        .distinct()
                                        .filter((network) -> !networkConnections.containsKey(network))
-                                       .collect(Collectors.toSet());
+                                       .collect(toSet());
 
                        if (missingNetworks.isEmpty()) {
                                if (!missingChannels.isEmpty()) {
@@ -663,7 +664,7 @@ public class Core extends AbstractExecutionThreadService {
                                .values().stream()
                                .filter(bot -> bot.channel()
                                                .equalsIgnoreCase(channel.get().name()))
-                               .collect(Collectors.toSet());
+                               .collect(toSet());
                botsToRemove.stream()
                                .forEach(bot -> networkBots.row(network.get())
                                                .remove(bot.name()));
@@ -891,34 +892,28 @@ public class Core extends AbstractExecutionThreadService {
                        return;
                }
 
-               Collection<Download> packDownloads = downloads.get(dccSendReceived.filename());
-               if (packDownloads.isEmpty()) {
-                       /* unknown download, ignore. */
-                       return;
-               }
+               Set<Download> openDownloads = downloads.values().stream()
+                               .filter(download -> download.bot().name().equalsIgnoreCase(dccSendReceived.source().nick().orNull()))
+                               .filter(download -> download.dccReceiver() == null)
+                               .collect(toSet());
 
-               /* check if it’s already downloading. */
-               Collection<Download> runningDownloads = FluentIterable.from(packDownloads).filter(FILTER_RUNNING).toSet();
-               if (!runningDownloads.isEmpty()) {
-                       eventBus.post(new GenericMessage(String.format("Ignoring offer for %s, it’s already being downloaded.", dccSendReceived.filename())));
+               if (openDownloads.isEmpty()) {
+                       /* I don't think we requested this. */
+                       eventBus.post(new GenericMessage(format("Ignoring offer for %s, no open download from %s.", dccSendReceived.filename(), dccSendReceived.source())));
                        return;
                }
 
-               /* locate the correct download. */
-               Collection<Download> requestedDownload = FluentIterable.from(packDownloads).filter(new Predicate<Download>() {
-
-                       @Override
-                       public boolean apply(Download download) {
-                               return download.bot().network().equals(network.get()) && download.bot().name().equalsIgnoreCase(dccSendReceived.source().nick().get());
-                       }
-               }).toSet();
-
-               /* we did not request this download. */
-               if (requestedDownload.isEmpty()) {
+               /* check if it’s already downloading. */
+               if (downloads.values().stream().anyMatch(download -> download.filename().equals(dccSendReceived.filename()) && download.dccReceiver() != null)) {
+                       eventBus.post(new GenericMessage(format("Ignoring offer for %s, it’s already being downloaded.", dccSendReceived.filename())));
                        return;
                }
 
-               Download download = requestedDownload.iterator().next();
+               Download download = openDownloads.stream()
+                               .filter(it -> it.filename().equals(dccSendReceived.filename()))
+                               .findFirst()
+                               .orElse(openDownloads.iterator().next());
+               eventBus.post(new GenericMessage(format("Found no offer for %s, using other download from %s, %s.", dccSendReceived.filename(), dccSendReceived.source(), download.filename())));
 
                /* check if the file already exists. */
                File outputFile = new File(temporaryDirectory, dccSendReceived.filename());