package com.frostwire.jlibtorrent; import com.frostwire.jlibtorrent.alerts.Alert; import com.frostwire.jlibtorrent.alerts.AlertType; import com.frostwire.jlibtorrent.alerts.MetadataReceivedAlert; import com.frostwire.jlibtorrent.alerts.TorrentPrioritizeAlert; import com.frostwire.jlibtorrent.swig.*; import java.io.File; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; /** * This class provides a lens only functionality. * * @author gubatron * @author aldenml */ public final class Downloader { private static final int[] LISTENER_TYPES = new int[] { AlertType.METADATA_RECEIVED.getSwig() }; private final Session s; public Downloader(Session s) { this.s = s; } public TorrentHandle find(Sha1Hash infoHash) { return s.findTorrent(infoHash); } public TorrentHandle find(String infoHash) { return s.findTorrent(new Sha1Hash(infoHash)); } public void download(TorrentInfo ti, File saveDir, Priority[] priorities, File resumeFile) { TorrentHandle th = s.findTorrent(ti.getInfoHash()); if (th != null) { // found a download with the same hash, just adjust the priorities if needed if (priorities != null) { if (ti.getNumFiles() != priorities.length) { throw new IllegalArgumentException("The priorities length should be equals to the number of files"); } th.prioritizeFiles(priorities); s.fireAlert(new TorrentPrioritizeAlert(th)); } } else { // new download s.asyncAddTorrent(ti, saveDir, priorities, resumeFile); } } public void download(TorrentInfo ti, File saveDir) { download(ti, saveDir, null, null); } /** * This method is not thread safe. * * @param uri * @param timeout in milliseconds * @return */ public byte[] fetchMagnet(String uri, long timeout) { add_torrent_params p = add_torrent_params.create_instance_no_storage(); error_code ec = new error_code(); libtorrent.parse_magnet_uri(uri, p, ec); if (ec.value() != 0) { throw new IllegalArgumentException(ec.message()); } final sha1_hash info_hash = p.getInfo_hash(); torrent_handle th = s.getSwig().find_torrent(info_hash); boolean add = true; if (th != null && th.is_valid()) { // we have a download with the same info-hash, let's see if we have the torrent info torrent_info ti = th.torrent_file(); if (ti != null && ti.is_valid()) { // ok. we have it, ready to return the data return new TorrentInfo(th.torrent_file()).bencode(); } else { add = false; } } final CountDownLatch signal = new CountDownLatch(1); AlertListener l = new AlertListener() { @Override public int[] types() { return LISTENER_TYPES; } @Override public void alert(Alert<?> alert) { if (!(alert instanceof MetadataReceivedAlert)) { return; } MetadataReceivedAlert mr = (MetadataReceivedAlert) alert; if (mr.getSwig().getHandle().info_hash().op_eq(info_hash)) { signal.countDown(); } } }; s.addListener(l); if (add) { p.setName("fetchMagnet - " + uri); long flags = p.getFlags(); flags &= ~add_torrent_params.flags_t.flag_auto_managed.swigValue(); p.setFlags(flags); th = s.getSwig().add_torrent(p); th.resume(); } try { signal.await(timeout, TimeUnit.MILLISECONDS); } catch (InterruptedException e) { } s.removeListener(l); try { th = s.getSwig().find_torrent(info_hash); if (th != null && th.is_valid()) { // we have a download with the same info-hash, let's see if we have the torrent info torrent_info ti = th.torrent_file(); if (ti != null && ti.is_valid()) { // ok. we have it, ready to return the data return new TorrentInfo(th.torrent_file()).bencode(); } } } finally { s.getSwig().remove_torrent(th); } return null; } }