Search in sources :

Example 31 with Torrent

use of com.biglybt.pif.torrent.Torrent in project BiglyBT by BiglySoftware.

the class DDBaseTTTorrent method read.

// server side read
@Override
public DistributedDatabaseValue read(DistributedDatabaseContact contact, DistributedDatabaseTransferType type, DistributedDatabaseKey key) throws DistributedDatabaseException {
    try {
        byte[] search_key = ((DDBaseKeyImpl) key).getBytes();
        Download download = null;
        PluginInterface pi = PluginInitializer.getDefaultInterface();
        String search_sha1 = pi.getUtilities().getFormatters().encodeBytesToString(search_key);
        if (ta_sha1 == null) {
            ta_sha1 = pi.getTorrentManager().getPluginAttribute("DDBaseTTTorrent::sha1");
        }
        // gotta look for the sha1(hash)
        Download[] downloads = pi.getDownloadManager().getDownloads();
        for (int i = 0; i < downloads.length; i++) {
            Download dl = downloads[i];
            if (dl.getTorrent() == null) {
                continue;
            }
            String sha1 = dl.getAttribute(ta_sha1);
            if (sha1 == null) {
                sha1 = pi.getUtilities().getFormatters().encodeBytesToString(new SHA1Simple().calculateHash(dl.getTorrent().getHash()));
                dl.setAttribute(ta_sha1, sha1);
            }
            if (sha1.equals(search_sha1)) {
                download = dl;
                break;
            }
        }
        if (download == null) {
            synchronized (this) {
                if (external_downloads != null) {
                    for (int i = 0; i < external_downloads.size(); i++) {
                        Download dl = (Download) external_downloads.get(i);
                        if (dl.getTorrent() == null) {
                            continue;
                        }
                        String sha1 = dl.getAttribute(ta_sha1);
                        if (sha1 == null) {
                            sha1 = pi.getUtilities().getFormatters().encodeBytesToString(new SHA1Simple().calculateHash(dl.getTorrent().getHash()));
                            dl.setAttribute(ta_sha1, sha1);
                        }
                        if (sha1.equals(search_sha1)) {
                            download = dl;
                            break;
                        }
                    }
                }
            }
        }
        String originator = contact.getName();
        if (download == null) {
            String msg = "TorrentDownload: request from " + originator + " for '" + pi.getUtilities().getFormatters().encodeBytesToString(search_key) + "' not found";
            if (TRACE) {
                System.out.println(msg);
            }
            ddb.log(msg);
            return (null);
        }
        if (!ddb.isTorrentXferEnabled()) {
            ddb.log("TorrentDownload: request from " + originator + "  for '" + download.getName() + "' denied as torrent transfer is disabled");
            return (null);
        }
        Torrent torrent = download.getTorrent();
        if (torrent.isPrivate()) {
            Debug.out("Attempt to download private torrent");
            ddb.log("TorrentDownload: request from " + originator + "  for '" + download.getName() + "' denied as it is private");
            return (null);
        }
        try {
            // apparently there are some trackers using non-private torrents with passkeys. Crazy, however to give users at
            // least the opportunity to prevent .torrent transfer for these torrents we deny this if the DHT peer source has
            // been disabled by the user
            DownloadManager dm = PluginCoreUtils.unwrapIfPossible(download);
            if (dm != null) {
                DownloadManagerState dms = dm.getDownloadState();
                if (!dms.isPeerSourceEnabled(PEPeerSource.PS_DHT)) {
                    ddb.log("TorrentDownload: request from " + originator + "  for '" + download.getName() + "' denied as DHT peer source disabled");
                    return (null);
                }
                if (dms.getFlag(DownloadManagerState.FLAG_METADATA_DOWNLOAD)) {
                    return (null);
                }
            }
        } catch (Throwable e) {
            Debug.out(e);
        }
        String msg = "TorrentDownload: request from " + originator + "  for '" + download.getName() + "' OK";
        if (TRACE) {
            System.out.println(msg);
        }
        ddb.log(msg);
        HashWrapper hw = new HashWrapper(torrent.getHash());
        synchronized (data_cache) {
            Object[] data = (Object[]) data_cache.get(hw);
            if (data != null) {
                data[1] = new Long(SystemTime.getCurrentTime());
                return (ddb.createValue((byte[]) data[0]));
            }
        }
        torrent = torrent.removeAdditionalProperties();
        // when clients get a torrent from the DHT they take on
        // responsibility for tracking it too
        torrent.setDecentralisedBackupRequested(true);
        byte[] data = torrent.writeToBEncodedData();
        data = encrypt(torrent.getHash(), data);
        if (data == null) {
            return (null);
        }
        synchronized (data_cache) {
            if (data_cache.size() == 0) {
                final TimerEventPeriodic[] pe = { null };
                pe[0] = SimpleTimer.addPeriodicEvent("DDBTorrent:timeout", 30 * 1000, new TimerEventPerformer() {

                    @Override
                    public void perform(TimerEvent event) {
                        long now = SystemTime.getCurrentTime();
                        synchronized (data_cache) {
                            Iterator it = data_cache.values().iterator();
                            while (it.hasNext()) {
                                long time = ((Long) ((Object[]) it.next())[1]).longValue();
                                if (now < time || now - time > 120 * 1000) {
                                    it.remove();
                                }
                            }
                            if (data_cache.size() == 0) {
                                pe[0].cancel();
                            }
                        }
                    }
                });
            }
            data_cache.put(hw, new Object[] { data, new Long(SystemTime.getCurrentTime()) });
        }
        return (ddb.createValue(data));
    } catch (Throwable e) {
        throw (new DistributedDatabaseException("Torrent write fails", e));
    }
}
Also used : Torrent(com.biglybt.pif.torrent.Torrent) PluginInterface(com.biglybt.pif.PluginInterface) DownloadManager(com.biglybt.core.download.DownloadManager) DownloadManagerState(com.biglybt.core.download.DownloadManagerState) Download(com.biglybt.pif.download.Download)

Example 32 with Torrent

use of com.biglybt.pif.torrent.Torrent in project BiglyBT by BiglySoftware.

the class DeviceManagerRSSFeed method generate.

@Override
public boolean generate(TrackerWebPageRequest request, TrackerWebPageResponse response) throws IOException {
    InetSocketAddress local_address = request.getLocalAddress();
    if (local_address == null) {
        return (false);
    }
    URL url = request.getAbsoluteURL();
    String path = url.getPath();
    path = path.substring(PROVIDER.length() + 1);
    DeviceImpl[] devices = manager.getDevices();
    OutputStream os = response.getOutputStream();
    XMLEscapeWriter pw = new XMLEscapeWriter(new PrintWriter(new OutputStreamWriter(os, "UTF-8")));
    pw.setEnabled(false);
    boolean hide_generic = COConfigurationManager.getBooleanParameter(DeviceManager.CONFIG_VIEW_HIDE_REND_GENERIC, true);
    boolean show_only_tagged = COConfigurationManager.getBooleanParameter(DeviceManager.CONFIG_VIEW_SHOW_ONLY_TAGGED, false);
    if (path.length() <= 1) {
        response.setContentType("text/html; charset=UTF-8");
        pw.println("<HTML><HEAD><TITLE>" + Constants.APP_NAME + " Device Feeds</TITLE></HEAD><BODY>");
        for (DeviceImpl d : devices) {
            if (d.getType() != Device.DT_MEDIA_RENDERER || d.isHidden() || !d.isRSSPublishEnabled() || (hide_generic && d.isNonSimple()) || (show_only_tagged && !d.isTagged())) {
                continue;
            }
            String name = d.getName();
            String device_url = PROVIDER + "/" + URLEncoder.encode(name, "UTF-8");
            pw.println("<LI><A href=\"" + device_url + "\">" + name + "</A>&nbsp;&nbsp;-&nbsp;&nbsp;<font size=\"-1\"><a href=\"" + device_url + "?format=html\">html</a></font></LI>");
        }
        pw.println("</BODY></HTML>");
    } else {
        String device_name = URLDecoder.decode(path.substring(1), "UTF-8");
        DeviceImpl device = null;
        for (DeviceImpl d : devices) {
            if (d.getName().equals(device_name) && d.isRSSPublishEnabled()) {
                device = d;
                break;
            }
        }
        if (device == null) {
            response.setReplyStatus(404);
            return (true);
        }
        TranscodeFileImpl[] _files = device.getFiles();
        List<TranscodeFileImpl> files = new ArrayList<>(_files.length);
        files.addAll(Arrays.asList(_files));
        Collections.sort(files, new Comparator<TranscodeFileImpl>() {

            @Override
            public int compare(TranscodeFileImpl f1, TranscodeFileImpl f2) {
                long added1 = f1.getCreationDateMillis() / 1000;
                long added2 = f2.getCreationDateMillis() / 1000;
                return ((int) (added2 - added1));
            }
        });
        URL feed_url = url;
        // absolute url is borked as it doesn't set the host properly. hack
        String host = (String) request.getHeaders().get("host");
        if (host != null) {
            int pos = host.indexOf(':');
            if (pos != -1) {
                host = host.substring(0, pos);
            }
            feed_url = UrlUtils.setHost(url, host);
        }
        if (device instanceof DeviceMediaRendererImpl) {
            ((DeviceMediaRendererImpl) device).browseReceived();
        }
        String channel_title = Constants.APP_NAME + " Device: " + escape(device.getName());
        boolean html = request.getURL().contains("format=html");
        if (html) {
            response.setContentType("text/html; charset=UTF-8");
            pw.println("<HTML><HEAD><TITLE>" + channel_title + "</TITLE></HEAD><BODY>");
            for (TranscodeFileImpl file : files) {
                if (!file.isComplete()) {
                    if (!file.isTemplate()) {
                        continue;
                    }
                }
                URL stream_url = file.getStreamURL(feed_url.getHost());
                if (stream_url != null) {
                    String url_ext = stream_url.toExternalForm();
                    pw.println("<p>");
                    pw.println("<a href=\"" + url_ext + "\">" + escape(file.getName()) + "</a>");
                    url_ext += url_ext.indexOf('?') == -1 ? "?" : "&";
                    url_ext += "action=download";
                    pw.println("&nbsp;&nbsp;-&nbsp;&nbsp;<font size=\"-1\"><a href=\"" + url_ext + "\">save</a></font>");
                }
            }
            pw.println("</BODY></HTML>");
        } else {
            boolean debug = request.getURL().contains("format=debug");
            if (debug) {
                response.setContentType("text/html; charset=UTF-8");
                pw.println("<HTML><HEAD><TITLE>" + channel_title + "</TITLE></HEAD><BODY>");
                pw.println("<pre>");
                pw.setEnabled(true);
            } else {
                response.setContentType("application/xml; charset=UTF-8");
            }
            try {
                pw.println("<?xml version=\"1.0\" encoding=\"utf-8\"?>");
                pw.println("<rss version=\"2.0\" " + "xmlns:vuze=\"http://www.vuze.com\" " + "xmlns:media=\"http://search.yahoo.com/mrss/\" " + "xmlns:atom=\"http://www.w3.org/2005/Atom\" " + "xmlns:itunes=\"http://www.itunes.com/dtds/podcast-1.0.dtd\">");
                pw.println("<channel>");
                pw.println("<title>" + channel_title + "</title>");
                pw.println("<link>http://biglybt.com</link>");
                pw.println("<atom:link href=\"" + feed_url.toExternalForm() + "\" rel=\"self\" type=\"application/rss+xml\" />");
                pw.println("<description>" + Constants.APP_NAME + " RSS Feed for device " + escape(device.getName()) + "</description>");
                pw.println("<itunes:image href=\"http://biglybt.com/img/biglybt128.png\"/>");
                pw.println("<image><url>https://www.biglybt.com/img/biglybt128.png</url><title>" + channel_title + "</title><link>http://biglybt.com</link></image>");
                String feed_date_key = "devices.feed_date." + device.getID();
                long feed_date = COConfigurationManager.getLongParameter(feed_date_key);
                boolean new_date = false;
                for (TranscodeFileImpl file : files) {
                    long file_date = file.getCreationDateMillis();
                    if (file_date > feed_date) {
                        new_date = true;
                        feed_date = file_date;
                    }
                }
                if (new_date) {
                    COConfigurationManager.setParameter(feed_date_key, feed_date);
                }
                pw.println("<pubDate>" + TimeFormatter.getHTTPDate(feed_date) + "</pubDate>");
                for (TranscodeFileImpl file : files) {
                    if (!file.isComplete()) {
                        if (!file.isTemplate()) {
                            continue;
                        }
                    }
                    try {
                        pw.println("<item>");
                        pw.println("<title>" + escape(file.getName()) + "</title>");
                        pw.println("<pubDate>" + TimeFormatter.getHTTPDate(file.getCreationDateMillis()) + "</pubDate>");
                        pw.println("<guid isPermaLink=\"false\">" + escape(file.getKey()) + "</guid>");
                        String[] categories = file.getCategories();
                        for (String category : categories) {
                            pw.println("<category>" + escape(category) + "</category>");
                        }
                        String[] tags = file.getTags(true);
                        for (String tag : tags) {
                            pw.println("<tag>" + escape(tag) + "</tag>");
                        }
                        String mediaContent = "";
                        URL stream_url = file.getStreamURL(feed_url.getHost());
                        if (stream_url != null) {
                            String url_ext = escape(stream_url.toExternalForm());
                            long fileSize = file.getTargetFile().getLength();
                            pw.println("<link>" + url_ext + "</link>");
                            mediaContent = "<media:content medium=\"video\" fileSize=\"" + fileSize + "\" url=\"" + url_ext + "\"";
                            String mime_type = file.getMimeType();
                            if (mime_type != null) {
                                mediaContent += " type=\"" + mime_type + "\"";
                            }
                            pw.println("<enclosure url=\"" + url_ext + "\" length=\"" + fileSize + (mime_type == null ? "" : "\" type=\"" + mime_type) + "\"></enclosure>");
                        }
                        String thumb_url = null;
                        String author = null;
                        String description = null;
                        try {
                            Torrent torrent = file.getSourceFile().getDownload().getTorrent();
                            TOTorrent toTorrent = PluginCoreUtils.unwrap(torrent);
                            long duration_secs = PlatformTorrentUtils.getContentVideoRunningTime(toTorrent);
                            if (mediaContent.length() > 0 && duration_secs > 0) {
                                mediaContent += " duration=\"" + duration_secs + "\"";
                            }
                            thumb_url = PlatformTorrentUtils.getContentThumbnailUrl(toTorrent);
                            author = PlatformTorrentUtils.getContentAuthor(toTorrent);
                            description = PlatformTorrentUtils.getContentDescription(toTorrent);
                            if (description != null) {
                                description = escapeMultiline(description);
                                /*
			  						if ( thumb_url != null ){


			  							pw.println( "<description type=\"text/html\">" +
			  								escape( "<div style=\"text-align: justify;padding: 5px;\"><img style=\"float: left;margin-right: 15px;margin-bottom: 15px;\" src=\"" + thumb_url + "\"/>" ) +
			  								description +
			  								escape( "</div>" ) +
			  								"</description>" );
			  						}else{
			  						*/
                                pw.println("<description>" + description + "</description>");
                            // }
                            }
                        } catch (Throwable e) {
                        }
                        if (mediaContent.length() > 0) {
                            pw.println(mediaContent += "></media:content>");
                        }
                        pw.println("<media:title>" + escape(file.getName()) + "</media:title>");
                        if (description != null) {
                            pw.println("<media:description>" + description + "</media:description>");
                        }
                        if (thumb_url != null) {
                            pw.println("<media:thumbnail url=\"" + thumb_url + "\"/>");
                        }
                        if (thumb_url != null) {
                            pw.println("<itunes:image href=\"" + thumb_url + "\"/>");
                        }
                        if (author != null) {
                            pw.println("<itunes:author>" + escape(author) + "</itunees:author>");
                        }
                        pw.println("<itunes:summary>" + escape(file.getName()) + "</itunes:summary>");
                        pw.println("<itunes:duration>" + TimeFormatter.formatColon(file.getDurationMillis() / 1000) + "</itunes:duration>");
                        pw.println("</item>");
                    } catch (Throwable e) {
                        Debug.out(e);
                    }
                }
                pw.println("</channel>");
                pw.println("</rss>");
            } finally {
                if (debug) {
                    pw.setEnabled(false);
                    pw.println("</pre>");
                    pw.println("</BODY></HTML>");
                }
            }
        }
    }
    pw.flush();
    return (true);
}
Also used : TOTorrent(com.biglybt.core.torrent.TOTorrent) Torrent(com.biglybt.pif.torrent.Torrent) InetSocketAddress(java.net.InetSocketAddress) OutputStream(java.io.OutputStream) XMLEscapeWriter(com.biglybt.core.xml.util.XMLEscapeWriter) URL(java.net.URL) TOTorrent(com.biglybt.core.torrent.TOTorrent) OutputStreamWriter(java.io.OutputStreamWriter) PrintWriter(java.io.PrintWriter)

Example 33 with Torrent

use of com.biglybt.pif.torrent.Torrent in project BiglyBT by BiglySoftware.

the class ResourceDownloaderTorrentImpl method downloadTorrent.

protected void downloadTorrent() {
    try {
        String name = new String(torrent_holder[0].getName(), Constants.DEFAULT_ENCODING_CHARSET);
        informActivity(getLogIndent() + "Downloading: " + name);
        TOTorrent torrent = torrent_holder[0];
        byte[] torrent_hash = torrent.getHash();
        // see if already there in an error state and delete if so
        Download existing = null;
        try {
            existing = download_manager.getDownload(torrent_hash);
            if (existing != null) {
                int existing_state = existing.getState();
                if (existing_state == Download.ST_ERROR || existing_state == Download.ST_STOPPED) {
                    informActivity(getLogIndent() + "Deleting existing stopped/error state download for " + name);
                    existing.remove(true, true);
                    existing = null;
                }
            }
        } catch (Throwable e) {
            informActivity(getLogIndent() + "Failed to tidy up: " + Debug.getNestedExceptionMessage(e));
        }
        File torrent_file;
        File data_dir;
        if (existing == null) {
            // we *don't* want this temporary file to be deleted automatically as we're
            // going to use it across the client restarts to hold the download data and
            // to seed it afterwards. Therefore we don't use AETemporaryFileHandler.createTempFile!!!!
            torrent_file = AETemporaryFileHandler.createSemiTempFile(name + ".torrent");
            if (download_dir != null && !download_dir.exists()) {
                FileUtil.mkdirs(download_dir);
            }
            data_dir = download_dir == null ? torrent_file.getParentFile() : download_dir;
            TorrentUtils.setFlag(torrent, TorrentUtils.TORRENT_FLAG_LOW_NOISE, true);
            boolean anon = isAnonymous();
            torrent.serialiseToBEncodedFile(torrent_file);
            DownloadWillBeAddedListener dwbal = null;
            try {
                Torrent t = new TorrentImpl(torrent);
                if (anon) {
                    dwbal = new DownloadWillBeAddedListener() {

                        @Override
                        public void initialised(Download download) {
                            try {
                                if (Arrays.equals(download.getTorrentHash(), torrent.getHash())) {
                                    PluginCoreUtils.unwrap(download).getDownloadState().setNetworks(AENetworkClassifier.AT_NON_PUBLIC);
                                }
                            } catch (Throwable e) {
                                Debug.out(e);
                            }
                        }
                    };
                    download_manager.addDownloadWillBeAddedListener(dwbal);
                } else {
                    // if torrent includes i2p url and i2p installed then enable network
                    Set<String> hosts = TorrentUtils.getUniqueTrackerHosts(torrent);
                    boolean has_i2p = false;
                    for (String host : hosts) {
                        if (AENetworkClassifier.categoriseAddress(host) == AENetworkClassifier.AT_I2P) {
                            has_i2p = true;
                        }
                    }
                    if (has_i2p && I2PHelpers.isI2PInstalled()) {
                        dwbal = new DownloadWillBeAddedListener() {

                            @Override
                            public void initialised(Download download) {
                                try {
                                    if (Arrays.equals(download.getTorrentHash(), torrent.getHash())) {
                                        PluginCoreUtils.unwrap(download).getDownloadState().setNetworks(new String[] { AENetworkClassifier.AT_PUBLIC, AENetworkClassifier.AT_I2P });
                                    }
                                } catch (Throwable e) {
                                    Debug.out(e);
                                }
                            }
                        };
                        download_manager.addDownloadWillBeAddedListener(dwbal);
                    }
                }
                if (persistent) {
                    download = download_manager.addDownload(t, torrent_file, data_dir);
                } else {
                    download = download_manager.addNonPersistentDownload(t, torrent_file, data_dir);
                }
            } finally {
                if (dwbal != null) {
                    download_manager.removeDownloadWillBeAddedListener(dwbal);
                }
            }
        } else {
            download = existing;
            torrent_file = FileUtil.newFile(download.getTorrentFileName());
            data_dir = FileUtil.newFile(download.getSavePath()).getParentFile();
        }
        download.moveTo(1);
        download.setForceStart(true);
        // Prevents any move-on-completion or move-on-removal behaviour happening.
        download.setFlag(Download.FLAG_DISABLE_AUTO_FILE_MOVE, true);
        download.setFlag(Download.FLAG_DISABLE_STOP_AFTER_ALLOC, true);
        if (COConfigurationManager.getBooleanParameter("Ip Filter Disable For Updates")) {
            download.setFlag(Download.FLAG_DISABLE_IP_FILTER, true);
        }
        download_manager.addListener(new DownloadManagerListener() {

            @Override
            public void downloadAdded(Download download) {
            }

            @Override
            public void downloadRemoved(Download _download) {
                if (download == _download) {
                    ResourceDownloaderTorrentImpl.this.downloadRemoved(torrent_file, data_dir);
                }
            }
        });
        download.addListener(new DownloadListener() {

            @Override
            public void stateChanged(final Download download, int old_state, int new_state) {
                if (new_state == Download.ST_SEEDING) {
                    download.removeListener(this);
                    PluginInitializer.getDefaultInterface().getUtilities().createThread("resource complete event dispatcher", new Runnable() {

                        @Override
                        public void run() {
                            downloadSucceeded(download, torrent_file, data_dir);
                        }
                    });
                }
            }

            @Override
            public void positionChanged(Download download, int oldPosition, int newPosition) {
            }
        });
        Thread t = new AEThread("RDTorrent percentage checker") {

            @Override
            public void runSupport() {
                int last_percentage = 0;
                while (result == null) {
                    int this_percentage = download.getStats().getDownloadCompleted(false) / 10;
                    long total = torrent.getSize();
                    if (this_percentage != last_percentage) {
                        reportPercentComplete(ResourceDownloaderTorrentImpl.this, this_percentage);
                        last_percentage = this_percentage;
                    }
                    try {
                        Thread.sleep(1000);
                    } catch (Throwable e) {
                        Debug.printStackTrace(e);
                    }
                }
            }
        };
        t.setDaemon(true);
        t.start();
        int state = download.getState();
        if (state == Download.ST_STOPPED) {
            // might have been added-stopped, start if so
            download.start();
        } else if (state == Download.ST_SEEDING) {
            // its possible that the d/l has already occurred and it is seeding!
            downloadSucceeded(download, torrent_file, data_dir);
        }
    } catch (Throwable e) {
        failed(this, new ResourceDownloaderException(this, "Torrent download failed", e));
    }
}
Also used : TOTorrent(com.biglybt.core.torrent.TOTorrent) Torrent(com.biglybt.pif.torrent.Torrent) TorrentImpl(com.biglybt.pifimpl.local.torrent.TorrentImpl) ResourceDownloaderException(com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderException) TOTorrent(com.biglybt.core.torrent.TOTorrent) File(java.io.File)

Example 34 with Torrent

use of com.biglybt.pif.torrent.Torrent in project BiglyBT by BiglySoftware.

the class PeerManagerImpl method checkIfPrivate.

protected void checkIfPrivate() {
    Download dl;
    try {
        dl = getDownload();
    } catch (Throwable e) {
        return;
    }
    Torrent t = dl.getTorrent();
    if (t != null) {
        if (TorrentUtils.isReallyPrivate(PluginCoreUtils.unwrap(t))) {
            throw (new RuntimeException("Torrent is private, peer addition not permitted"));
        }
    }
}
Also used : Torrent(com.biglybt.pif.torrent.Torrent) Download(com.biglybt.pif.download.Download)

Example 35 with Torrent

use of com.biglybt.pif.torrent.Torrent in project BiglyBT by BiglySoftware.

the class SubscriptionSchedulerImpl method download.

@Override
public void download(final Subscription subs, final SubscriptionResult original_result) {
    String download_link = original_result.getDownloadLink();
    if (download_link == null) {
        log(subs.getName() + ": can't download " + original_result.getID() + " as no direct download link available");
        return;
    }
    final String key = subs.getID() + ":" + original_result.getID();
    final String dl = download_link;
    synchronized (active_result_downloaders) {
        if (active_result_downloaders.contains(key)) {
            return;
        }
        log(subs.getName() + ": queued result for download - " + original_result.getID() + "/" + download_link);
        active_result_downloaders.add(key);
        result_downloader.run(new AERunnable() {

            @Override
            public void runSupport() {
                boolean success = false;
                SubscriptionResult result = null;
                // need to fix up to the latest history due to the lazy nature of things :(
                try {
                    result = subs.getHistory().getResult(original_result.getID());
                    if (result == null) {
                        log(subs.getName() + ": result has been deleted - " + original_result.getID());
                        success = true;
                    } else if (result.getRead()) {
                        log(subs.getName() + ": result already marked as read, skipping - " + result.getID());
                        success = true;
                    } else {
                        boolean retry = true;
                        boolean use_ref = subs.getHistory().getDownloadWithReferer();
                        boolean tried_ref_switch = false;
                        while (retry) {
                            retry = false;
                            try {
                                TorrentUtils.setTLSDescription("Subscription: " + subs.getName());
                                URL original_url = new URL(dl);
                                PluginProxy plugin_proxy = null;
                                if (dl.startsWith("tor:")) {
                                    String target_resource = dl.substring(4);
                                    original_url = new URL(target_resource);
                                    Map<String, Object> options = new HashMap<>();
                                    options.put(AEProxyFactory.PO_PEER_NETWORKS, new String[] { AENetworkClassifier.AT_TOR });
                                    plugin_proxy = AEProxyFactory.getPluginProxy("Subscription result download of '" + target_resource + "'", original_url, options, true);
                                    if (plugin_proxy == null) {
                                        throw (new Exception("No Tor plugin proxy available for '" + dl + "'"));
                                    }
                                }
                                URL current_url = plugin_proxy == null ? original_url : plugin_proxy.getURL();
                                Torrent torrent = null;
                                try {
                                    while (true) {
                                        try {
                                            ResourceDownloaderFactory rdf = StaticUtilities.getResourceDownloaderFactory();
                                            ResourceDownloader url_rd = rdf.create(current_url, plugin_proxy == null ? null : plugin_proxy.getProxy());
                                            if (plugin_proxy != null) {
                                                url_rd.setProperty("URL_HOST", plugin_proxy.getURLHostRewrite() + (current_url.getPort() == -1 ? "" : (":" + current_url.getPort())));
                                            }
                                            String referer = use_ref ? subs.getReferer() : null;
                                            UrlUtils.setBrowserHeaders(url_rd, referer);
                                            Engine engine = subs.getEngine();
                                            if (engine instanceof WebEngine) {
                                                WebEngine we = (WebEngine) engine;
                                                if (we.isNeedsAuth()) {
                                                    String cookies = we.getCookies();
                                                    if (cookies != null && cookies.length() > 0) {
                                                        url_rd.setProperty("URL_Cookie", cookies);
                                                    }
                                                }
                                            }
                                            ResourceDownloader mr_rd = rdf.getMetaRefreshDownloader(url_rd);
                                            InputStream is = mr_rd.download();
                                            torrent = new TorrentImpl(TOTorrentFactory.deserialiseFromBEncodedInputStream(is));
                                            break;
                                        } catch (Throwable e) {
                                            if (plugin_proxy == null) {
                                                plugin_proxy = AEProxyFactory.getPluginProxy("Subscription result download", original_url);
                                                if (plugin_proxy != null) {
                                                    current_url = plugin_proxy.getURL();
                                                    continue;
                                                }
                                            }
                                            throw (e);
                                        }
                                    }
                                } finally {
                                    if (plugin_proxy != null) {
                                        plugin_proxy.setOK(torrent != null);
                                    }
                                }
                                byte[] hash = torrent.getHash();
                                // PlatformTorrentUtils.setContentTitle(torrent, torr );
                                DownloadManager dm = PluginInitializer.getDefaultInterface().getDownloadManager();
                                Download download;
                                // if we're assigning a tag/networks then we need to add it stopped in case the tag has any pre-start actions (e.g. set initial save location)
                                // this is because the assignments are done in SubscriptionManagerImpl on the download(willbe)added event
                                boolean stop_override = subs.getTagID() >= 0 || subs.getHistory().getDownloadNetworks() != null;
                                boolean auto_start = manager.shouldAutoStart(torrent);
                                manager.addPrepareTrigger(hash, new Subscription[] { subs }, new SubscriptionResult[] { result });
                                try {
                                    File data_location = null;
                                    File torrent_location = null;
                                    if (manager.getAddHashDirs()) {
                                        String torrent_name = FileUtil.convertOSSpecificChars(torrent.getName(), false);
                                        String hash_str = ByteFormatter.encodeString(hash).substring(0, 8);
                                        String data_dir = COConfigurationManager.getStringParameter("Default save path");
                                        if (data_dir != null && !data_dir.isEmpty()) {
                                            data_location = FileUtil.newFile(data_dir, torrent_name + "_" + hash_str);
                                        }
                                        if (COConfigurationManager.getBooleanParameter("Save Torrent Files")) {
                                            String torrent_dir = COConfigurationManager.getDirectoryParameter("General_sDefaultTorrent_Directory");
                                            if (torrent_dir != null && !torrent_dir.isEmpty()) {
                                                torrent_location = FileUtil.newFile(torrent_dir, torrent_name + "_" + hash_str + ".torrent");
                                                try {
                                                    torrent.writeToFile(torrent_location);
                                                } catch (Throwable e) {
                                                    Debug.out(e);
                                                    torrent_location = null;
                                                }
                                            }
                                        }
                                    }
                                    if (auto_start && !stop_override) {
                                        download = dm.addDownload(torrent, torrent_location, data_location);
                                    } else {
                                        download = dm.addDownloadStopped(torrent, torrent_location, data_location);
                                    }
                                } finally {
                                    manager.removePrepareTrigger(hash);
                                }
                                log(subs.getName() + ": added download " + download.getName() + ": auto-start=" + auto_start);
                                // maybe remove this as should be actioned in the trigger?
                                manager.prepareDownload(download, new Subscription[] { subs }, new SubscriptionResult[] { result });
                                subs.addAssociation(hash);
                                if (auto_start && stop_override) {
                                    download.restart();
                                }
                                result.setRead(true);
                                success = true;
                                if (tried_ref_switch) {
                                    subs.getHistory().setDownloadWithReferer(use_ref);
                                }
                            } catch (Throwable e) {
                                log(subs.getName() + ": Failed to download result " + dl, e);
                                if (e instanceof TOTorrentException && !tried_ref_switch) {
                                    use_ref = !use_ref;
                                    tried_ref_switch = true;
                                    retry = true;
                                    log(subs.getName() + ": Retrying " + (use_ref ? "with referer" : "without referer"));
                                }
                            } finally {
                                TorrentUtils.setTLSDescription(null);
                            }
                        }
                    }
                } finally {
                    try {
                        if (result != null && !success) {
                            if (dl.startsWith("azplug:") || dl.startsWith("chat:")) {
                                // whatever the outcome these have been handled async
                                result.setRead(true);
                            } else {
                                int rad = manager.getAutoDownloadMarkReadAfterDays();
                                if (rad > 0) {
                                    long rad_millis = rad * 24 * 60 * 60 * 1000L;
                                    long time_found = result.getTimeFound();
                                    if (time_found > 0 && time_found + rad_millis < SystemTime.getCurrentTime()) {
                                        log(subs.getName() + ": result expired, marking as read - " + result.getID());
                                        result.setRead(true);
                                    }
                                }
                            }
                        }
                    } catch (Throwable e) {
                        Debug.out(e);
                    } finally {
                        synchronized (active_result_downloaders) {
                            active_result_downloaders.remove(key);
                        }
                        calculateSchedule();
                    }
                }
            }
        });
    }
}
Also used : Torrent(com.biglybt.pif.torrent.Torrent) TorrentImpl(com.biglybt.pifimpl.local.torrent.TorrentImpl) InputStream(java.io.InputStream) PluginProxy(com.biglybt.core.proxy.AEProxyFactory.PluginProxy) ResourceDownloader(com.biglybt.pif.utils.resourcedownloader.ResourceDownloader) DownloadManager(com.biglybt.pif.download.DownloadManager) URL(java.net.URL) TOTorrentException(com.biglybt.core.torrent.TOTorrentException) WebEngine(com.biglybt.core.metasearch.impl.web.WebEngine) TOTorrentException(com.biglybt.core.torrent.TOTorrentException) ResourceDownloaderFactory(com.biglybt.pif.utils.resourcedownloader.ResourceDownloaderFactory) Download(com.biglybt.pif.download.Download) File(java.io.File) WebEngine(com.biglybt.core.metasearch.impl.web.WebEngine) Engine(com.biglybt.core.metasearch.Engine)

Aggregations

Torrent (com.biglybt.pif.torrent.Torrent)41 Download (com.biglybt.pif.download.Download)16 TOTorrent (com.biglybt.core.torrent.TOTorrent)13 URL (java.net.URL)12 PluginInterface (com.biglybt.pif.PluginInterface)7 DownloadManager (com.biglybt.core.download.DownloadManager)6 TorrentAttribute (com.biglybt.pif.torrent.TorrentAttribute)5 File (java.io.File)5 Tag (com.biglybt.core.tag.Tag)4 InetSocketAddress (java.net.InetSocketAddress)4 DownloadManagerState (com.biglybt.core.download.DownloadManagerState)3 PEPeerManager (com.biglybt.core.peer.PEPeerManager)3 TrackerTorrent (com.biglybt.pif.tracker.TrackerTorrent)3 TorrentImpl (com.biglybt.pifimpl.local.torrent.TorrentImpl)3 RPException (com.biglybt.pifimpl.remote.RPException)3 RPReply (com.biglybt.pifimpl.remote.RPReply)3 ArrayList (java.util.ArrayList)3 List (java.util.List)3 ParameterListener (com.biglybt.core.config.ParameterListener)2 PEPeer (com.biglybt.core.peer.PEPeer)2