package the8472.mldht.cli.commands;
import static the8472.utils.Functional.awaitAll;
import the8472.bt.TorrentUtils;
import the8472.mldht.TorrentFetcher;
import the8472.mldht.TorrentFetcher.FetchState;
import the8472.mldht.TorrentFetcher.FetchTask;
import the8472.mldht.cli.CommandProcessor;
import lbms.plugins.mldht.kad.Key;
import lbms.plugins.mldht.utils.NIOConnectionManager;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.ByteChannel;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.StandardOpenOption;
import java.util.List;
import java.util.Optional;
import java.util.concurrent.CompletionStage;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.stream.Collectors;
public class GetTorrent extends CommandProcessor {
NIOConnectionManager conMan;
ScheduledThreadPoolExecutor timer;
@Override
protected void process() {
TorrentFetcher fetcher = new TorrentFetcher(dhts);
List<CompletionStage<FetchTask>> tasks = arguments.stream().filter(Key.STRING_PATTERN.asPredicate()).map(hash -> {
Key targetKey = new Key(hash);
FetchTask task = fetcher.fetch(targetKey);
CompletionStage<FetchTask> st = task.awaitCompletion();
return st.whenComplete(this::handleCompletion);
}).collect(Collectors.toList());
awaitAll(tasks).handle((results, ex) -> {
if(ex != null) {
handleException(ex);
exit(1);
} else {
int success = (int) results.stream().filter(r -> r.getState() == FetchState.SUCCESS).count();
println(success+ "/" +results.size()+" downloads successful");
exit(0);
}
return null;
});
}
void handleCompletion(FetchTask task, Throwable ex) {
if(ex != null)
return;
if(task.getState() != FetchState.SUCCESS) {
printErr("download "+task.infohash().toString(false)+" failed\n");
return;
}
task.getResult().ifPresent(buf -> {
Path torrentName = currentWorkDir.resolve(task.infohash().toString(false) +".torrent");
try(ByteChannel chan = Files.newByteChannel(torrentName, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.CREATE, StandardOpenOption.WRITE)) {
ByteBuffer torrent = TorrentUtils.wrapBareInfoDictionary(buf);
Optional<String> name = TorrentUtils.getTorrentName(torrent);
chan.write(torrent);
name.ifPresent(str -> {
println("torrent name: "+ str);
});
println("written meta to "+torrentName);
} catch (IOException e) {
handleException(e);
}
});
}
}