Search in sources :

Example 26 with DiskManagerFileInfo

use of com.biglybt.core.disk.DiskManagerFileInfo in project BiglyBT by BiglySoftware.

the class SizeItem method refresh.

@Override
public void refresh(TableCell cell) {
    sizeitemsort value;
    Object ds = cell.getDataSource();
    if (ds instanceof DownloadManager) {
        DownloadManager dm = (DownloadManager) ds;
        value = new sizeitemsort(dm.getStats().getSizeExcludingDND(), dm.getStats().getRemainingExcludingDND());
    } else if (ds instanceof DiskManagerFileInfo) {
        DiskManagerFileInfo fileInfo = (DiskManagerFileInfo) ds;
        value = new sizeitemsort(fileInfo.getLength(), fileInfo.getLength() - fileInfo.getDownloaded());
    } else {
        return;
    }
    // I'm afraid something will break.. so use compareTo
    if (value.compareTo(cell.getSortValue()) == 0 && cell.isValid())
        return;
    cell.setSortValue(value);
    String s = DisplayFormatters.formatCustomSize("column.size", value.size);
    if (s == null) {
        s = DisplayFormatters.formatByteCountToKiBEtc(value.size);
    }
    if (DO_MULTILINE && cell.getMaxLines() > 1 && value.remaining > 0) {
        s += "\n" + DisplayFormatters.formatByteCountToKiBEtc(value.remaining, false, false, 0) + " " + MessageText.getString("TableColumn.header.remaining");
    }
    cell.setText(s);
    if (Utils.getUserMode() > 0 && (cell instanceof TableCellSWT)) {
        if (value.size >= 0x40000000l) {
            ((TableCellSWT) cell).setTextAlpha(200 | 0x100);
        } else if (value.size < 0x100000) {
            ((TableCellSWT) cell).setTextAlpha(180);
        } else {
            ((TableCellSWT) cell).setTextAlpha(255);
        }
    }
}
Also used : DiskManagerFileInfo(com.biglybt.core.disk.DiskManagerFileInfo) TableCellSWT(com.biglybt.ui.swt.views.table.TableCellSWT) DownloadManager(com.biglybt.core.download.DownloadManager)

Example 27 with DiskManagerFileInfo

use of com.biglybt.core.disk.DiskManagerFileInfo in project BiglyBT by BiglySoftware.

the class SmoothedETAItem method refresh.

@Override
public void refresh(TableCell cell) {
    Object ds = cell.getDataSource();
    if (ds instanceof DiskManagerFileInfo) {
        DiskManagerFileInfo file = (DiskManagerFileInfo) cell.getDataSource();
        long value = file.getETA();
        if (!cell.setSortValue(value) && cell.isValid()) {
            return;
        }
        cell.setText(ViewUtils.formatETA(value, eta_absolute, cdf.getDateFormat()));
    } else {
        DownloadManager dm = (DownloadManager) cell.getDataSource();
        long value = (dm == null) ? 0 : dm.getStats().getSmoothedETA();
        if (!cell.setSortValue(value) && cell.isValid()) {
            return;
        }
        cell.setText(ViewUtils.formatETA(value, eta_absolute, cdf.getDateFormat()));
    }
}
Also used : DiskManagerFileInfo(com.biglybt.core.disk.DiskManagerFileInfo) DownloadManager(com.biglybt.core.download.DownloadManager)

Example 28 with DiskManagerFileInfo

use of com.biglybt.core.disk.DiskManagerFileInfo in project BiglyBT by BiglySoftware.

the class NameItem method refresh.

@Override
public void refresh(TableCell cell, boolean sortOnlyRefresh) {
    String name = null;
    DownloadManager dm = (DownloadManager) cell.getDataSource();
    if (dm != null)
        name = dm.getDisplayName();
    if (name == null)
        name = "";
    // setText returns true only if the text is updated
    if ((cell.setText(name) || !cell.isValid())) {
        if (dm != null && isShowIcon() && !sortOnlyRefresh && (cell instanceof TableCellSWT)) {
            DiskManagerFileInfo fileInfo = dm.getDownloadState().getPrimaryFile();
            if (fileInfo != null) {
                // Don't ever dispose of PathIcon, it's cached and may be used elsewhere
                TOTorrent torrent = dm.getTorrent();
                Image icon = ImageRepository.getPathIcon(fileInfo.getFile(false).getName(), false, torrent != null && !torrent.isSimpleTorrent());
                ((TableCellSWT) cell).setIcon(icon);
            }
        }
    }
}
Also used : DiskManagerFileInfo(com.biglybt.core.disk.DiskManagerFileInfo) TableCellSWT(com.biglybt.ui.swt.views.table.TableCellSWT) TOTorrent(com.biglybt.core.torrent.TOTorrent) Image(org.eclipse.swt.graphics.Image) DownloadManager(com.biglybt.core.download.DownloadManager)

Example 29 with DiskManagerFileInfo

use of com.biglybt.core.disk.DiskManagerFileInfo in project BiglyBT by BiglySoftware.

the class ManagerUtils method locateFiles.

public static void locateFiles(final DownloadManager[] dms, final DiskManagerFileInfo[][] dm_files, Shell shell) {
    DirectoryDialog dd = new DirectoryDialog(shell);
    dd.setFilterPath(TorrentOpener.getFilterPathData());
    dd.setText(MessageText.getString("MyTorrentsView.menu.locatefiles.dialog"));
    String path = dd.open();
    if (path != null) {
        TorrentOpener.setFilterPathData(path);
        final File dir = new File(path);
        final TextViewerWindow viewer = new TextViewerWindow(MessageText.getString("locatefiles.view.title"), null, "", true, true);
        viewer.setEditable(false);
        viewer.setOKEnabled(true);
        new AEThread2("FileLocator") {

            @Override
            public void run() {
                final int MAX_LINKS = DownloadManagerStateFactory.MAX_FILES_FOR_INCOMPLETE_AND_DND_LINKAGE;
                final String LINK_LIMIT_MSG = "Link limit of " + MAX_LINKS + " exceeded. See Tools->Options->Files to increase this";
                try {
                    Map<Long, Set<File>> file_map = new HashMap<>();
                    final boolean[] quit = { false };
                    viewer.addListener(new TextViewerWindow.TextViewerWindowListener() {

                        @Override
                        public void closed() {
                            synchronized (quit) {
                                quit[0] = true;
                            }
                        }
                    });
                    logLine(viewer, new SimpleDateFormat().format(new Date()) + ": Enumerating files in " + dir);
                    long bfm_start = SystemTime.getMonotonousTime();
                    long[] last_log = { bfm_start };
                    int file_count = buildFileMap(viewer, dir, file_map, last_log, quit);
                    logLine(viewer, (bfm_start == last_log[0] ? "" : "\r\n") + "Found " + file_count + " files with " + file_map.size() + " distinct sizes");
                    Set<String> all_dm_incomplete_files = null;
                    ConcurrentHasher hasher = ConcurrentHasher.getSingleton();
                    int downloads_modified = 0;
                    for (int i = 0; i < dms.length; i++) {
                        DownloadManager dm = dms[i];
                        synchronized (quit) {
                            if (quit[0]) {
                                break;
                            }
                        }
                        if (!dm.isPersistent()) {
                            continue;
                        }
                        TOTorrent torrent = dm.getTorrent();
                        if (torrent == null) {
                            continue;
                        }
                        DiskManagerFileInfo[] selected_files = dm_files == null ? null : dm_files[i];
                        Set<Integer> selected_file_indexes;
                        if (selected_files == null) {
                            selected_file_indexes = null;
                        } else {
                            selected_file_indexes = new HashSet<>();
                            for (DiskManagerFileInfo f : selected_files) {
                                selected_file_indexes.add(f.getIndex());
                            }
                        }
                        TOTorrentFile[] to_files = torrent.getFiles();
                        long piece_size = torrent.getPieceLength();
                        byte[][] pieces = torrent.getPieces();
                        logLine(viewer, "Processing '" + dm.getDisplayName() + "', piece size=" + DisplayFormatters.formatByteCountToKiBEtc(piece_size));
                        int dm_state = dm.getState();
                        if (!(dm_state == DownloadManager.STATE_STOPPED || dm_state == DownloadManager.STATE_ERROR)) {
                            logLine(viewer, "    Download must be stopped");
                            continue;
                        }
                        DiskManagerFileInfo[] files = dm.getDiskManagerFileInfoSet().getFiles();
                        Set<String> dm_files = null;
                        Map<DiskManagerFileInfo, File> links_established = new HashMap<>();
                        Map<DiskManagerFileInfo, Set<String>> unmatched_files = new TreeMap<>(new Comparator<DiskManagerFileInfo>() {

                            @Override
                            public int compare(DiskManagerFileInfo o1, DiskManagerFileInfo o2) {
                                long diff = o2.getLength() - o1.getLength();
                                if (diff < 0) {
                                    return (-1);
                                } else if (diff > 0) {
                                    return (1);
                                } else {
                                    return (0);
                                }
                            }
                        });
                        int no_candidates = 0;
                        int already_complete = 0;
                        int link_count = 0;
                        try {
                            download_loop: for (final DiskManagerFileInfo file : files) {
                                synchronized (quit) {
                                    if (quit[0]) {
                                        break;
                                    }
                                }
                                if (selected_file_indexes != null) {
                                    if (!selected_file_indexes.contains(file.getIndex())) {
                                        continue;
                                    }
                                }
                                long file_length = file.getLength();
                                if (file.getDownloaded() == file_length) {
                                    already_complete++;
                                    continue;
                                }
                                Set<File> candidates = file_map.get(file_length);
                                if (candidates != null) {
                                    if (candidates.size() > 0) {
                                        if (all_dm_incomplete_files == null) {
                                            all_dm_incomplete_files = new HashSet<>();
                                            List<DownloadManager> all_dms = CoreFactory.getSingleton().getGlobalManager().getDownloadManagers();
                                            for (DownloadManager x : all_dms) {
                                                if (!x.isDownloadComplete(false)) {
                                                    DiskManagerFileInfo[] fs = x.getDiskManagerFileInfoSet().getFiles();
                                                    for (DiskManagerFileInfo f : fs) {
                                                        if (f.isSkipped() || f.getDownloaded() != f.getLength()) {
                                                            all_dm_incomplete_files.add(f.getFile(true).getAbsolutePath());
                                                        }
                                                    }
                                                }
                                            }
                                        }
                                        Iterator<File> it = candidates.iterator();
                                        while (it.hasNext()) {
                                            File f = it.next();
                                            if (all_dm_incomplete_files.contains(f.getAbsolutePath())) {
                                                it.remove();
                                            }
                                        }
                                    }
                                    if (candidates.size() > 0) {
                                        // duplicate now as this is download-specific
                                        candidates = new HashSet<>(candidates);
                                        if (dm_files == null) {
                                            dm_files = new HashSet<>();
                                            for (DiskManagerFileInfo f : files) {
                                                dm_files.add(f.getFile(true).getAbsolutePath());
                                            }
                                        }
                                        Iterator<File> it = candidates.iterator();
                                        while (it.hasNext()) {
                                            File f = it.next();
                                            if (dm_files.contains(f.getAbsolutePath())) {
                                                it.remove();
                                            }
                                        }
                                    }
                                    if (candidates.size() > 0) {
                                        boolean matched = false;
                                        Set<String> failed_candidates = new HashSet<>();
                                        TOTorrentFile to_file = file.getTorrentFile();
                                        long offset = 0;
                                        for (TOTorrentFile tf : to_files) {
                                            if (tf == to_file) {
                                                break;
                                            }
                                            offset += tf.getLength();
                                        }
                                        int to_piece_number = to_file.getFirstPieceNumber();
                                        long to_file_offset = offset % piece_size;
                                        if (to_file_offset != 0) {
                                            to_file_offset = piece_size - to_file_offset;
                                            to_piece_number++;
                                        }
                                        long to_stop_at = file_length - piece_size;
                                        if (to_file_offset < to_stop_at) {
                                            logLine(viewer, "    " + candidates.size() + " candidate(s) for " + to_file.getRelativePath() + " (size=" + DisplayFormatters.formatByteCountToKiBEtc(to_file.getLength()) + ")");
                                            byte[] buffer = new byte[(int) piece_size];
                                            for (File candidate : candidates) {
                                                synchronized (quit) {
                                                    if (quit[0]) {
                                                        break;
                                                    }
                                                }
                                                log(viewer, "        Testing " + candidate);
                                                RandomAccessFile raf = null;
                                                boolean error = false;
                                                boolean hash_failed = false;
                                                long last_ok_log = SystemTime.getMonotonousTime();
                                                try {
                                                    raf = new RandomAccessFile(candidate, "r");
                                                    long file_offset = to_file_offset;
                                                    int piece_number = to_piece_number;
                                                    while (file_offset < to_stop_at) {
                                                        synchronized (quit) {
                                                            if (quit[0]) {
                                                                break;
                                                            }
                                                        }
                                                        raf.seek(file_offset);
                                                        raf.read(buffer);
                                                        ConcurrentHasherRequest req = hasher.addRequest(ByteBuffer.wrap(buffer));
                                                        byte[] hash = req.getResult();
                                                        boolean match = Arrays.equals(pieces[piece_number], hash);
                                                        if (match) {
                                                            long now = SystemTime.getMonotonousTime();
                                                            if (now - last_ok_log >= 250) {
                                                                last_ok_log = now;
                                                                log(viewer, ".");
                                                            }
                                                            file_offset += piece_size;
                                                            piece_number++;
                                                        } else {
                                                            hash_failed = true;
                                                            failed_candidates.add(candidate.getAbsolutePath());
                                                            logLine(viewer, "X");
                                                            break;
                                                        }
                                                    }
                                                } catch (Throwable e) {
                                                    logLine(viewer, "X");
                                                    error = true;
                                                } finally {
                                                    if (raf != null) {
                                                        try {
                                                            raf.close();
                                                        } catch (Throwable e) {
                                                        }
                                                    }
                                                }
                                                if (!(error || hash_failed)) {
                                                    logLine(viewer, " Matched");
                                                    try {
                                                        dm.setUserData("set_link_dont_delete_existing", true);
                                                        if (file.setLink(candidate)) {
                                                            logLine(viewer, "        Link successful");
                                                            links_established.put(file, candidate);
                                                            link_count++;
                                                            matched = true;
                                                            if (link_count > MAX_LINKS) {
                                                                logLine(viewer, "    " + LINK_LIMIT_MSG);
                                                                break download_loop;
                                                            }
                                                        } else {
                                                            logLine(viewer, "        Link failed");
                                                        }
                                                    } finally {
                                                        dm.setUserData("set_link_dont_delete_existing", null);
                                                    }
                                                    break;
                                                }
                                            }
                                        }
                                        if (!matched) {
                                            unmatched_files.put(file, failed_candidates);
                                        }
                                    } else {
                                        no_candidates++;
                                    }
                                } else {
                                    no_candidates++;
                                }
                            }
                            logLine(viewer, "    Matched=" + links_established.size() + ", complete=" + already_complete + ", no candidates=" + no_candidates + ", remaining=" + unmatched_files.size() + " (total=" + files.length + ")");
                            if (links_established.size() > 0 && unmatched_files.size() > 0) {
                                logLine(viewer, "    Looking for other potential name-based matches");
                                File overall_root = null;
                                for (Map.Entry<DiskManagerFileInfo, File> entry : links_established.entrySet()) {
                                    DiskManagerFileInfo dm_file = entry.getKey();
                                    File root = entry.getValue();
                                    String rel = dm_file.getTorrentFile().getRelativePath();
                                    int pos = 0;
                                    while (root != null) {
                                        root = root.getParentFile();
                                        pos = rel.indexOf(File.separatorChar, pos);
                                        if (pos >= 0) {
                                            pos = pos + 1;
                                        } else {
                                            break;
                                        }
                                    }
                                    if (root == null) {
                                        logLine(viewer, "        No usable root folder found");
                                        break;
                                    }
                                    if (overall_root == null) {
                                        overall_root = root;
                                    } else {
                                        if (!overall_root.equals(root)) {
                                            overall_root = null;
                                            logLine(viewer, "        Inconsistent root folder found");
                                            break;
                                        }
                                    }
                                }
                                if (overall_root != null) {
                                    logLine(viewer, "        Root folder is " + overall_root.getAbsolutePath());
                                    int links_ok = 0;
                                    for (Map.Entry<DiskManagerFileInfo, Set<String>> entry : unmatched_files.entrySet()) {
                                        synchronized (quit) {
                                            if (quit[0]) {
                                                break;
                                            }
                                        }
                                        DiskManagerFileInfo file = entry.getKey();
                                        if (selected_file_indexes != null) {
                                            if (!selected_file_indexes.contains(file.getIndex())) {
                                                continue;
                                            }
                                        }
                                        File expected_file = new File(overall_root, file.getTorrentFile().getRelativePath());
                                        if (expected_file.exists() && expected_file.length() == file.getLength()) {
                                            if (!entry.getValue().contains(expected_file.getAbsolutePath())) {
                                                try {
                                                    dm.setUserData("set_link_dont_delete_existing", true);
                                                    if (file.setLink(expected_file)) {
                                                        links_ok++;
                                                        link_count++;
                                                        if (link_count > MAX_LINKS) {
                                                            logLine(viewer, "        " + LINK_LIMIT_MSG);
                                                            break;
                                                        }
                                                    }
                                                } finally {
                                                    dm.setUserData("set_link_dont_delete_existing", null);
                                                }
                                            }
                                        }
                                    }
                                    logLine(viewer, "        Linked " + links_ok + " of " + unmatched_files.size());
                                }
                            }
                        } finally {
                            if (link_count > 0) {
                                dm.forceRecheck();
                                downloads_modified++;
                            }
                        }
                    }
                    logLine(viewer, new SimpleDateFormat().format(new Date()) + ": Complete, downloads updated=" + downloads_modified);
                } catch (Throwable e) {
                    log(viewer, "\r\n" + new SimpleDateFormat().format(new Date()) + ": Failed: " + Debug.getNestedExceptionMessage(e) + "\r\n");
                }
            }
        }.start();
        viewer.goModal();
    }
}
Also used : DiskManagerFileInfoSet(com.biglybt.core.disk.DiskManagerFileInfoSet) DownloadManager(com.biglybt.core.download.DownloadManager) TextViewerWindow(com.biglybt.ui.swt.TextViewerWindow) DirectoryDialog(org.eclipse.swt.widgets.DirectoryDialog) DiskManagerFileInfo(com.biglybt.core.disk.DiskManagerFileInfo) TOTorrentFile(com.biglybt.core.torrent.TOTorrentFile) TOTorrent(com.biglybt.core.torrent.TOTorrent) TOTorrentFile(com.biglybt.core.torrent.TOTorrentFile) SimpleDateFormat(java.text.SimpleDateFormat)

Example 30 with DiskManagerFileInfo

use of com.biglybt.core.disk.DiskManagerFileInfo in project BiglyBT by BiglySoftware.

the class ManagerUtils method browse.

public static String browse(final DownloadManager dm, DiskManagerFileInfo _file, final boolean anon, final boolean launch) {
    Properties props = new Properties();
    File save_location = dm.getSaveLocation();
    final String root_dir;
    if (save_location.isFile()) {
        root_dir = save_location.getParentFile().getAbsolutePath();
    } else {
        root_dir = save_location.getAbsolutePath();
    }
    final String url_suffix;
    boolean always_browse = COConfigurationManager.getBooleanParameter("Library.LaunchWebsiteInBrowserDirList");
    if (!always_browse) {
        if (_file == null) {
            _file = getBrowseHomePage(dm);
        }
    }
    final DiskManagerFileInfo file = _file;
    if (file == null) {
        // asked to launch a download (note that the double-click on a download that has an index.html file will by default result in
        // us getting here with the file set, not null)
        url_suffix = "";
    } else {
        String relative_path = file.getTorrentFile().getRelativePath();
        String[] bits = relative_path.replace(File.separatorChar, '/').split("/");
        String _url_suffix = "";
        int bits_to_use = always_browse ? bits.length - 1 : bits.length;
        for (int i = 0; i < bits_to_use; i++) {
            String bit = bits[i];
            if (bit.length() == 0) {
                continue;
            }
            _url_suffix += (_url_suffix == "" ? "" : "/") + UrlUtils.encode(bit);
        }
        url_suffix = _url_suffix;
    }
    synchronized (browse_plugins) {
        WebPlugin plugin = browse_plugins.get(dm);
        if (plugin == null) {
            props.put(WebPlugin.PR_PORT, 0);
            props.put(WebPlugin.PR_BIND_IP, "127.0.0.1");
            props.put(WebPlugin.PR_HOME_PAGE, "");
            props.put(WebPlugin.PR_ROOT_DIR, root_dir);
            props.put(WebPlugin.PR_ACCESS, "local");
            props.put(WebPlugin.PR_HIDE_RESOURCE_CONFIG, true);
            props.put(WebPlugin.PR_ENABLE_KEEP_ALIVE, true);
            props.put(WebPlugin.PR_ENABLE_PAIRING, false);
            props.put(WebPlugin.PR_ENABLE_UPNP, false);
            props.put(WebPlugin.PR_ENABLE_I2P, false);
            props.put(WebPlugin.PR_ENABLE_TOR, false);
            final String plugin_id = "webserver:" + dm.getInternalName();
            final String plugin_name = "Web Server for " + dm.getDisplayName();
            Properties messages = new Properties();
            messages.put("plugins." + plugin_id, plugin_name);
            PluginInitializer.getDefaultInterface().getUtilities().getLocaleUtilities().integrateLocalisedMessageBundle(messages);
            final AESemaphore waiter = new AESemaphore("waiter");
            final String[] url_holder = { null };
            plugin = new UnloadableWebPlugin(props) {

                private Map<String, Object> file_map = new HashMap<>();

                private String protocol;

                private String host;

                private int port;

                @Override
                public void initialize(PluginInterface plugin_interface) throws PluginException {
                    DiskManagerFileInfoSet file_set = dm.getDiskManagerFileInfoSet();
                    DiskManagerFileInfo[] files = file_set.getFiles();
                    Set<Object> root_dir = new HashSet<>();
                    file_map.put("", root_dir);
                    for (DiskManagerFileInfo dm_file : files) {
                        TOTorrentFile file = dm_file.getTorrentFile();
                        String path = file.getRelativePath();
                        file_map.put(path, dm_file);
                        if (path.startsWith(File.separator)) {
                            path = path.substring(1);
                        }
                        Set<Object> dir = root_dir;
                        int pos = 0;
                        while (true) {
                            int next_pos = path.indexOf(File.separatorChar, pos);
                            if (next_pos == -1) {
                                dir.add(dm_file);
                                break;
                            } else {
                                String bit = path.substring(pos, next_pos);
                                dir.add(bit);
                                String sub_path = path.substring(0, next_pos);
                                dir = (Set<Object>) file_map.get(sub_path);
                                if (dir == null) {
                                    dir = new HashSet<>();
                                    file_map.put(sub_path, dir);
                                }
                                pos = next_pos + 1;
                            }
                        }
                    }
                    Properties props = plugin_interface.getPluginProperties();
                    props.put("plugin.name", plugin_name);
                    super.initialize(plugin_interface);
                    InetAddress bind_ip = getServerBindIP();
                    if (bind_ip.isAnyLocalAddress()) {
                        host = "127.0.0.1";
                    } else {
                        host = bind_ip.getHostAddress();
                    }
                    port = getServerPort();
                    log("Assigned port: " + port);
                    protocol = getProtocol();
                    String url = protocol + "://" + host + ":" + port + "/" + url_suffix;
                    if (launch) {
                        Utils.launch(url, false, true, anon);
                    } else {
                        synchronized (url_holder) {
                            url_holder[0] = url;
                        }
                        waiter.release();
                    }
                }

                @Override
                public boolean generate(TrackerWebPageRequest request, TrackerWebPageResponse response) throws IOException {
                    try {
                        boolean res = super.generate(request, response);
                        if (!res) {
                            response.setReplyStatus(404);
                        }
                    } catch (Throwable e) {
                        response.setReplyStatus(404);
                    }
                    return (true);
                }

                @Override
                protected boolean useFile(TrackerWebPageRequest request, final TrackerWebPageResponse response, String root, String relative_url) throws IOException {
                    URL absolute_url = request.getAbsoluteURL();
                    String query = absolute_url.getQuery();
                    if (query != null) {
                        String[] args = query.split("&");
                        String vuze_source = null;
                        int vuze_file_index = -1;
                        String vuze_file_name = null;
                        List<String> networks = new ArrayList<>();
                        for (String arg : args) {
                            String[] bits = arg.split("=");
                            String lhs = bits[0];
                            String rhs = UrlUtils.decode(bits[1]);
                            if (lhs.equals("vuze_source")) {
                                if (rhs.endsWith(".torrent") || rhs.startsWith("magnet")) {
                                    vuze_source = rhs;
                                }
                            } else if (lhs.equals("vuze_file_index")) {
                                vuze_file_index = Integer.parseInt(rhs);
                            } else if (lhs.equals("vuze_file_name")) {
                                vuze_file_name = rhs;
                            } else if (lhs.equals("vuze_network")) {
                                String net = AENetworkClassifier.internalise(rhs);
                                if (net != null) {
                                    networks.add(net);
                                }
                            }
                        }
                        if (vuze_source != null) {
                            String referrer = (String) request.getHeaders().get("referer");
                            if (referrer == null || !referrer.contains("://" + host + ":" + port)) {
                                response.setReplyStatus(403);
                                return (true);
                            }
                            if (vuze_source.endsWith(".torrent")) {
                                Object file_node = file_map.get(vuze_source);
                                if (file_node instanceof DiskManagerFileInfo) {
                                    DiskManagerFileInfo dm_file = (DiskManagerFileInfo) file_node;
                                    long file_size = dm_file.getLength();
                                    File target_file = dm_file.getFile(true);
                                    boolean done = dm_file.getDownloaded() == file_size && target_file.length() == file_size;
                                    if (done) {
                                        return (handleRedirect(dm, target_file, vuze_file_index, vuze_file_name, networks, request, response));
                                    } else {
                                        try {
                                            File torrent_file = AETemporaryFileHandler.createTempFile();
                                            final FileOutputStream fos = new FileOutputStream(torrent_file);
                                            try {
                                                DiskManagerChannel chan = PluginCoreUtils.wrap(dm_file).createChannel();
                                                try {
                                                    final DiskManagerRequest req = chan.createRequest();
                                                    req.setOffset(0);
                                                    req.setLength(file_size);
                                                    req.addListener(new DiskManagerListener() {

                                                        @Override
                                                        public void eventOccurred(DiskManagerEvent event) {
                                                            int type = event.getType();
                                                            if (type == DiskManagerEvent.EVENT_TYPE_BLOCKED) {
                                                                return;
                                                            } else if (type == DiskManagerEvent.EVENT_TYPE_FAILED) {
                                                                throw (new RuntimeException(event.getFailure()));
                                                            }
                                                            PooledByteBuffer buffer = event.getBuffer();
                                                            if (buffer == null) {
                                                                throw (new RuntimeException("eh?"));
                                                            }
                                                            try {
                                                                byte[] data = buffer.toByteArray();
                                                                fos.write(data);
                                                            } catch (IOException e) {
                                                                throw (new RuntimeException("Failed to write to " + file, e));
                                                            } finally {
                                                                buffer.returnToPool();
                                                            }
                                                        }
                                                    });
                                                    req.run();
                                                } finally {
                                                    chan.destroy();
                                                }
                                            } finally {
                                                fos.close();
                                            }
                                            return (handleRedirect(dm, torrent_file, vuze_file_index, vuze_file_name, networks, request, response));
                                        } catch (Throwable e) {
                                            Debug.out(e);
                                            return (false);
                                        }
                                    }
                                } else {
                                    return (false);
                                }
                            } else {
                                URL magnet = new URL(vuze_source);
                                File torrent_file = AETemporaryFileHandler.createTempFile();
                                try {
                                    URLConnection connection = magnet.openConnection();
                                    connection.connect();
                                    FileUtil.copyFile(connection.getInputStream(), torrent_file.getAbsoluteFile());
                                    return (handleRedirect(dm, torrent_file, vuze_file_index, vuze_file_name, networks, request, response));
                                } catch (Throwable e) {
                                    Debug.out(e);
                                }
                            }
                        }
                    }
                    String path = absolute_url.getPath();
                    if (path.equals("/")) {
                        if (COConfigurationManager.getBooleanParameter("Library.LaunchWebsiteInBrowserDirList")) {
                            relative_url = "/";
                        }
                    }
                    String download_name = XUXmlWriter.escapeXML(dm.getDisplayName());
                    String relative_file = relative_url.replace('/', File.separatorChar);
                    String node_key = relative_file.substring(1);
                    Object file_node = file_map.get(node_key);
                    boolean file_node_is_parent = false;
                    if (file_node == null) {
                        int pos = node_key.lastIndexOf(File.separator);
                        if (pos == -1) {
                            node_key = "";
                        } else {
                            node_key = node_key.substring(0, pos);
                        }
                        file_node = file_map.get(node_key);
                        file_node_is_parent = true;
                    }
                    if (file_node == null) {
                        return (false);
                    }
                    if (file_node instanceof Set) {
                        if (relative_url.equals("/favicon.ico")) {
                            try {
                                InputStream stream = getClass().getClassLoader().getResourceAsStream("com/biglybt/ui/icons/favicon.ico");
                                response.useStream("image/x-icon", stream);
                                return (true);
                            } catch (Throwable e) {
                            }
                        }
                        Set<Object> kids = (Set<Object>) file_node;
                        String request_url = request.getURL();
                        if (file_node_is_parent) {
                            int pos = request_url.lastIndexOf("/");
                            if (pos == -1) {
                                request_url = "";
                            } else {
                                request_url = request_url.substring(0, pos);
                            }
                        }
                        response.setContentType("text/html");
                        OutputStream os = response.getOutputStream();
                        String title = XUXmlWriter.escapeXML(UrlUtils.decode(request_url));
                        if (title.length() == 0) {
                            title = "/";
                        }
                        os.write(("<html>" + NL + " <head>" + NL + " <meta charset=\"UTF-8\">" + NL + "  <title>" + download_name + ": Index of " + title + "</title>" + NL + " </head>" + NL + " <body>" + NL + "  <p>" + download_name + "</p>" + NL + "  <h1>Index of " + title + "</h1>" + NL + "  <pre><hr>" + NL).getBytes("UTF-8"));
                        String root_url = request_url;
                        if (!root_url.endsWith("/")) {
                            root_url += "/";
                        }
                        if (request_url.length() > 1) {
                            int pos = request_url.lastIndexOf('/');
                            if (pos == 0) {
                                pos++;
                            }
                            String parent = request_url.substring(0, pos);
                            os.write(("<a href=\"" + parent + "\">..</a>" + NL).getBytes("UTF-8"));
                        }
                        List<String[]> filenames = new ArrayList<>(kids.size());
                        int max_filename = 0;
                        int MAX_LEN = 120;
                        for (Object entry : kids) {
                            DiskManagerFileInfo file;
                            String file_name;
                            if (entry instanceof String) {
                                file = null;
                                file_name = (String) entry;
                            } else {
                                file = (DiskManagerFileInfo) entry;
                                if (file.isSkipped()) {
                                    continue;
                                }
                                file_name = file.getTorrentFile().getRelativePath();
                                int pos = file_name.lastIndexOf(File.separatorChar);
                                if (pos != -1) {
                                    file_name = file_name.substring(pos + 1);
                                }
                            }
                            String url = root_url + UrlUtils.encode(file_name);
                            if (file == null) {
                                file_name += "/";
                            }
                            int len = file_name.length();
                            if (len > MAX_LEN) {
                                file_name = file_name.substring(0, MAX_LEN - 3) + "...";
                                len = file_name.length();
                            }
                            if (len > max_filename) {
                                max_filename = len;
                            }
                            filenames.add(new String[] { url, file_name, file == null ? "" : DisplayFormatters.formatByteCountToKiBEtc(file.getLength()) });
                        }
                        max_filename = ((max_filename + 15) / 8) * 8;
                        char[] padding = new char[max_filename];
                        Arrays.fill(padding, ' ');
                        Collections.sort(filenames, new Comparator<String[]>() {

                            Comparator comp = new FormattersImpl().getAlphanumericComparator(true);

                            @Override
                            public int compare(String[] o1, String[] o2) {
                                return (comp.compare(o1[0], o2[0]));
                            }
                        });
                        for (String[] entry : filenames) {
                            String file_name = entry[1];
                            int len = file_name.length();
                            StringBuilder line = new StringBuilder(max_filename + 64);
                            line.append("<a href=\"").append(entry[0]).append("\">").append(XUXmlWriter.escapeXML(file_name)).append("</a>");
                            line.append(padding, 0, max_filename - len);
                            line.append(entry[2]);
                            line.append(NL);
                            os.write(line.toString().getBytes("UTF-8"));
                        }
                        os.write(("  <hr></pre>" + NL + "  <address>" + Constants.APP_NAME + " Web Server at " + host + " Port " + getServerPort() + "</address>" + NL + " </body>" + NL + "</html>").getBytes("UTF-8"));
                        return (true);
                    } else {
                        DiskManagerFileInfo dm_file = (DiskManagerFileInfo) file_node;
                        long file_size = dm_file.getLength();
                        File target_file = dm_file.getFile(true);
                        boolean done = dm_file.getDownloaded() == file_size && target_file.length() == file_size;
                        String file_type;
                        // Use the original torrent file name when deducing file type to
                        // avoid incomplete suffix issues etc
                        String relative_path = dm_file.getTorrentFile().getRelativePath();
                        int pos = relative_path.lastIndexOf(".");
                        if (pos == -1) {
                            file_type = "";
                        } else {
                            file_type = relative_path.substring(pos + 1);
                        }
                        if (file_size >= 512 * 1024) {
                            String content_type = HTTPUtils.guessContentTypeFromFileType(file_type);
                            if (content_type.startsWith("text/") || content_type.startsWith("image/")) {
                            // don't want to be redirecting here as (for example) .html needs
                            // to remain in the 'correct' place so that relative assets work
                            } else {
                                URL stream_url = getMediaServerContentURL(dm_file);
                                if (stream_url != null) {
                                    OutputStream os = response.getRawOutputStream();
                                    os.write(("HTTP/1.1 302 Found" + NL + "Location: " + stream_url.toExternalForm() + NL + NL).getBytes("UTF-8"));
                                    return (true);
                                }
                            }
                        }
                        if (done) {
                            if (file_size < 512 * 1024) {
                                FileInputStream fis = null;
                                try {
                                    fis = new FileInputStream(target_file);
                                    response.useStream(file_type, fis);
                                    return (true);
                                } finally {
                                    if (fis != null) {
                                        fis.close();
                                    }
                                }
                            } else {
                                OutputStream os = null;
                                InputStream is = null;
                                try {
                                    os = response.getRawOutputStream();
                                    os.write(("HTTP/1.1 200 OK" + NL + "Content-Type:" + HTTPUtils.guessContentTypeFromFileType(file_type) + NL + "Content-Length: " + file_size + NL + "Connection: close" + NL + NL).getBytes("UTF-8"));
                                    byte[] buffer = new byte[128 * 1024];
                                    is = new FileInputStream(target_file);
                                    while (true) {
                                        int len = is.read(buffer);
                                        if (len <= 0) {
                                            break;
                                        }
                                        os.write(buffer, 0, len);
                                    }
                                } catch (Throwable e) {
                                // e.printStackTrace();
                                } finally {
                                    try {
                                        os.close();
                                    } catch (Throwable e) {
                                    }
                                    try {
                                        is.close();
                                    } catch (Throwable e) {
                                    }
                                }
                                return (true);
                            }
                        } else {
                            dm_file.setPriority(10);
                            try {
                                final OutputStream os = response.getRawOutputStream();
                                os.write(("HTTP/1.1 200 OK" + NL + "Content-Type:" + HTTPUtils.guessContentTypeFromFileType(file_type) + NL + "Content-Length: " + file_size + NL + "Connection: close" + NL + "X-Vuze-Hack: X").getBytes("UTF-8"));
                                DiskManagerChannel chan = PluginCoreUtils.wrap(dm_file).createChannel();
                                try {
                                    final DiskManagerRequest req = chan.createRequest();
                                    final boolean[] header_complete = { false };
                                    final long[] last_write = { 0 };
                                    req.setOffset(0);
                                    req.setLength(file_size);
                                    req.addListener(new DiskManagerListener() {

                                        @Override
                                        public void eventOccurred(DiskManagerEvent event) {
                                            int type = event.getType();
                                            if (type == DiskManagerEvent.EVENT_TYPE_BLOCKED) {
                                                return;
                                            } else if (type == DiskManagerEvent.EVENT_TYPE_FAILED) {
                                                throw (new RuntimeException(event.getFailure()));
                                            }
                                            PooledByteBuffer buffer = event.getBuffer();
                                            if (buffer == null) {
                                                throw (new RuntimeException("eh?"));
                                            }
                                            try {
                                                boolean do_header = false;
                                                synchronized (header_complete) {
                                                    if (!header_complete[0]) {
                                                        do_header = true;
                                                        header_complete[0] = true;
                                                    }
                                                    last_write[0] = SystemTime.getMonotonousTime();
                                                }
                                                if (do_header) {
                                                    os.write((NL + NL).getBytes("UTF-8"));
                                                }
                                                byte[] data = buffer.toByteArray();
                                                os.write(data);
                                            } catch (IOException e) {
                                                throw (new RuntimeException("Failed to write to " + file, e));
                                            } finally {
                                                buffer.returnToPool();
                                            }
                                        }
                                    });
                                    final TimerEventPeriodic[] timer_event = { null };
                                    timer_event[0] = SimpleTimer.addPeriodicEvent("KeepAlive", 10 * 1000, new TimerEventPerformer() {

                                        boolean cancel_outstanding = false;

                                        @Override
                                        public void perform(TimerEvent event) {
                                            if (cancel_outstanding) {
                                                req.cancel();
                                            } else {
                                                synchronized (header_complete) {
                                                    if (header_complete[0]) {
                                                        if (SystemTime.getMonotonousTime() - last_write[0] >= 5 * 60 * 1000) {
                                                            req.cancel();
                                                        }
                                                    } else {
                                                        try {
                                                            os.write("X".getBytes("UTF-8"));
                                                            os.flush();
                                                        } catch (Throwable e) {
                                                            req.cancel();
                                                        }
                                                    }
                                                }
                                                if (!response.isActive()) {
                                                    cancel_outstanding = true;
                                                }
                                            }
                                        }
                                    });
                                    try {
                                        req.run();
                                    } finally {
                                        timer_event[0].cancel();
                                    }
                                    return (true);
                                } finally {
                                    chan.destroy();
                                }
                            } catch (Throwable e) {
                                return (false);
                            }
                        }
                    }
                }

                private boolean handleRedirect(DownloadManager dm, File torrent_file, int file_index, String file_name, List<String> networks, TrackerWebPageRequest request, TrackerWebPageResponse response) {
                    try {
                        TOTorrent torrent = TOTorrentFactory.deserialiseFromBEncodedFile(torrent_file);
                        GlobalManager gm = CoreFactory.getSingleton().getGlobalManager();
                        UIFunctions uif = UIFunctionsManager.getUIFunctions();
                        TorrentOpenOptions torrent_options = new TorrentOpenOptions(torrent_file.getAbsolutePath(), torrent, false);
                        torrent_options.setTorrent(torrent);
                        String[] existing_nets;
                        if (networks.size() == 0) {
                            // inherit networks from parent
                            existing_nets = dm.getDownloadState().getNetworks();
                        } else {
                            existing_nets = networks.toArray(new String[networks.size()]);
                        }
                        for (String net : AENetworkClassifier.AT_NETWORKS) {
                            boolean found = false;
                            for (String x : existing_nets) {
                                if (net == x) {
                                    found = true;
                                    break;
                                }
                            }
                            torrent_options.setNetworkEnabled(net, found);
                        }
                        Map<String, Object> add_options = new HashMap<>();
                        add_options.put(UIFunctions.OTO_SILENT, true);
                        if (uif.addTorrentWithOptions(torrent_options, add_options)) {
                            long start = SystemTime.getMonotonousTime();
                            while (true) {
                                DownloadManager o_dm = gm.getDownloadManager(torrent);
                                if (o_dm != null) {
                                    if (!o_dm.getDownloadState().getFlag(DownloadManagerState.FLAG_METADATA_DOWNLOAD)) {
                                        DiskManagerFileInfo[] files = o_dm.getDiskManagerFileInfoSet().getFiles();
                                        DiskManagerFileInfo o_dm_file = null;
                                        if (file_name != null) {
                                            for (DiskManagerFileInfo file : files) {
                                                String path = file.getTorrentFile().getRelativePath();
                                                if (path.equals(file_name)) {
                                                    o_dm_file = file;
                                                    break;
                                                }
                                            }
                                            if (o_dm_file == null) {
                                                o_dm_file = files[0];
                                            }
                                        } else {
                                            if (file_index < 0) {
                                                long largest = -1;
                                                for (DiskManagerFileInfo file : files) {
                                                    if (file.getLength() > largest) {
                                                        o_dm_file = file;
                                                        largest = file.getLength();
                                                    }
                                                }
                                            } else {
                                                o_dm_file = files[file_index];
                                            }
                                        }
                                        String original_path = request.getAbsoluteURL().getPath();
                                        if (original_path.endsWith(".html")) {
                                            String url = browse(o_dm, file_index < 0 ? null : o_dm_file, anon, false);
                                            OutputStream os = response.getRawOutputStream();
                                            os.write(("HTTP/1.1 302 Found" + NL + "Location: " + url + NL + NL).getBytes("UTF-8"));
                                            return (true);
                                        } else {
                                            URL stream_url = getMediaServerContentURL(o_dm_file);
                                            if (stream_url != null) {
                                                OutputStream os = response.getRawOutputStream();
                                                os.write(("HTTP/1.1 302 Found" + NL + "Location: " + stream_url.toExternalForm() + NL + NL).getBytes("UTF-8"));
                                                return (true);
                                            }
                                        }
                                    }
                                }
                                long now = SystemTime.getMonotonousTime();
                                if (now - start > 3 * 60 * 1000) {
                                    Debug.out("Timeout waiting for download to be added");
                                    return (false);
                                }
                                Thread.sleep(1000);
                            }
                        } else {
                            Debug.out("Failed to add download for some reason");
                            return (false);
                        }
                    } catch (Throwable e) {
                        Debug.out(e);
                        return (false);
                    }
                }

                @Override
                public void unload() throws PluginException {
                    synchronized (browse_plugins) {
                        browse_plugins.remove(dm);
                    }
                    super.unload();
                }
            };
            PluginManager.registerPlugin(plugin, plugin_id, plugin_id);
            browse_plugins.put(dm, plugin);
            if (launch) {
                return (null);
            } else {
                waiter.reserve(10 * 1000);
                synchronized (url_holder) {
                    return (url_holder[0]);
                }
            }
        } else {
            String protocol = plugin.getProtocol();
            InetAddress bind_ip = plugin.getServerBindIP();
            String host;
            if (bind_ip.isAnyLocalAddress()) {
                host = "127.0.0.1";
            } else {
                host = bind_ip.getHostAddress();
            }
            String url = protocol + "://" + host + ":" + plugin.getServerPort() + "/" + url_suffix;
            if (launch) {
                Utils.launch(url, false, true, anon);
                return (null);
            } else {
                return (url);
            }
        }
    }
}
Also used : TrackerWebPageRequest(com.biglybt.pif.tracker.web.TrackerWebPageRequest) TrackerWebPageResponse(com.biglybt.pif.tracker.web.TrackerWebPageResponse) DownloadManager(com.biglybt.core.download.DownloadManager) GlobalManager(com.biglybt.core.global.GlobalManager) DiskManagerListener(com.biglybt.pif.disk.DiskManagerListener) UIFunctions(com.biglybt.ui.UIFunctions) DiskManagerChannel(com.biglybt.pif.disk.DiskManagerChannel) PluginException(com.biglybt.pif.PluginException) DiskManagerFileInfoSet(com.biglybt.core.disk.DiskManagerFileInfoSet) TOTorrentFile(com.biglybt.core.torrent.TOTorrentFile) TOTorrentFile(com.biglybt.core.torrent.TOTorrentFile) InetAddress(java.net.InetAddress) DiskManagerFileInfoSet(com.biglybt.core.disk.DiskManagerFileInfoSet) URL(java.net.URL) TorrentOpenOptions(com.biglybt.core.torrent.impl.TorrentOpenOptions) PooledByteBuffer(com.biglybt.pif.utils.PooledByteBuffer) WebPlugin(com.biglybt.ui.webplugin.WebPlugin) DiskManagerFileInfo(com.biglybt.core.disk.DiskManagerFileInfo) DiskManagerRequest(com.biglybt.pif.disk.DiskManagerRequest) PluginInterface(com.biglybt.pif.PluginInterface) FormattersImpl(com.biglybt.pifimpl.local.utils.FormattersImpl) URLConnection(java.net.URLConnection) TOTorrent(com.biglybt.core.torrent.TOTorrent) DiskManagerEvent(com.biglybt.pif.disk.DiskManagerEvent)

Aggregations

DiskManagerFileInfo (com.biglybt.core.disk.DiskManagerFileInfo)107 DownloadManager (com.biglybt.core.download.DownloadManager)54 File (java.io.File)16 TOTorrent (com.biglybt.core.torrent.TOTorrent)15 PEPeerManager (com.biglybt.core.peer.PEPeerManager)9 DiskManagerFileInfoSet (com.biglybt.core.disk.DiskManagerFileInfoSet)8 TableRowCore (com.biglybt.ui.common.table.TableRowCore)8 DiskManager (com.biglybt.core.disk.DiskManager)7 IOException (java.io.IOException)7 Point (org.eclipse.swt.graphics.Point)7 DownloadManagerState (com.biglybt.core.download.DownloadManagerState)6 MessageBoxShell (com.biglybt.ui.swt.shells.MessageBoxShell)6 FilesView (com.biglybt.ui.swt.views.FilesView)6 List (java.util.List)6 Image (org.eclipse.swt.graphics.Image)6 DiskManagerPiece (com.biglybt.core.disk.DiskManagerPiece)5 PEPeer (com.biglybt.core.peer.PEPeer)5 TOTorrentException (com.biglybt.core.torrent.TOTorrentException)5 UIFunctions (com.biglybt.ui.UIFunctions)5 ISelectedContent (com.biglybt.ui.selectedcontent.ISelectedContent)5