/** * Returns true if the code was executed correctly. False if there was an error trying to share * the file. If the file was not supposed to be shared, and was not shared, true would still be * returned. */ private boolean shareTorrentFile(File torrentFile) { if (torrentManager.isDownloadingTorrent(torrentFile)) { return true; } if (!SharingSettings.SHARE_DOWNLOADED_FILES_IN_NON_SHARED_DIRECTORIES.getValue()) { return true; } BTData btData = null; FileInputStream torrentInputStream = null; try { torrentInputStream = new FileInputStream(torrentFile); Map<?, ?> torrentFileMap = (Map<?, ?>) Token.parse(torrentInputStream.getChannel()); btData = new BTDataImpl(torrentFileMap); } catch (IOException e) { LOG.error("Error reading torrent file: " + torrentFile, e); return false; } finally { FileUtils.close(torrentInputStream); } if (btData.isPrivate()) { gnutellaFileList.remove(torrentFile); return true; } File saveDir = SharingSettings.getSaveDirectory(); File torrentParent = torrentFile.getParentFile(); if (torrentParent.equals(saveDir)) { // already in saveDir gnutellaFileList.add(torrentFile); return true; } final File tFile = getSharedTorrentMetaDataFile(btData); if (tFile.equals(torrentFile)) { gnutellaFileList.add(tFile); return true; } gnutellaFileList.remove(tFile); File backup = null; if (tFile.exists()) { backup = new File(tFile.getParent(), tFile.getName().concat(".bak")); FileUtils.forceRename(tFile, backup); } if (FileUtils.copy(torrentFile, tFile)) { gnutellaFileList.add(tFile); } else { if (backup != null) { // restore backup if (FileUtils.forceRename(backup, tFile)) { gnutellaFileList.add(tFile); } } } return true; }
/** * Adds a root to the tree if it's not already in there. * * @return false if dir is already in the tree */ public boolean addRoot(File dir) { // remove from deselected in any case boolean changed = deselected.remove(dir); // check if already included for (File root : roots) { if (FileUtils.isAncestor(root, dir)) { if (root.equals(dir)) { if (changed) { directoryTreeModel.valueForPathChanged(getTreePath(dir), null); } return changed; } // make sure it is included removeFromPath(dir); TreePath path = getTreePath(dir); directoryTree.scrollPathToVisible(path); return changed; } else if (FileUtils.isAncestor(dir, root)) { removeRoot(root); addDirToTree(dir); // expand to root and its parent, since expand has no effect if root // doesn't have subfolders setExpanded(root); // guaranteed to not be null since at least dir is its real ancestor setExpanded(root.getParentFile()); return true; } } addDirToTree(dir); setRootExpanded(); return true; }
void moveToCompleteFolder() { File parent = _incompleteFile.getParentFile(); boolean success = _incompleteFile.renameTo(_completeFile); if (!success) { success = FileUtils.copy(_incompleteFile, _completeFile); if (success) _incompleteFile.delete(); } if (success) FileUtils.deleteRecursive(parent); }
/** * Opens a dialog asking the user to choose a file which is is used for saving to. * * @param parent the parent component the dialog is centered on * @param titleKey the key for the locale-specific string to use for the file dialog title * @param suggestedFile the suggested file for saving * @param the filter to use for what's shown. * @return the file or <code>null</code> when the user cancelled the dialog */ public static File getSaveAsFile( Component parent, String titleKey, File suggestedFile, final FileFilter filter) { if (OSUtils.isAnyMac()) { FileDialog dialog = new FileDialog(GUIMediator.getAppFrame(), I18n.tr(titleKey), FileDialog.SAVE); dialog.setDirectory(suggestedFile.getParent()); dialog.setFile(suggestedFile.getName()); if (filter != null) { FilenameFilter f = new FilenameFilter() { public boolean accept(File dir, String name) { return filter.accept(new File(dir, name)); } }; dialog.setFilenameFilter(f); } dialog.setVisible(true); String dir = dialog.getDirectory(); setLastInputDirectory(new File(dir)); String file = dialog.getFile(); if (dir != null && file != null) { if (suggestedFile != null) { String suggestedFileExtension = FileUtils.getFileExtension(suggestedFile); String newFileExtension = FileUtils.getFileExtension(file); if (newFileExtension == null && suggestedFileExtension != null) { file = file + "." + suggestedFileExtension; } } File f = new File(dir, file); if (filter != null && !filter.accept(f)) return null; else return f; } else { return null; } } else { JFileChooser chooser = getDirectoryChooser(titleKey, null, null, JFileChooser.FILES_ONLY, filter); chooser.setSelectedFile(suggestedFile); int ret = chooser.showSaveDialog(parent); File file = chooser.getSelectedFile(); setLastInputDirectory(file); return ret != JFileChooser.APPROVE_OPTION ? null : file; } }
/** * Deletes incomplete files more than INCOMPLETE_PURGE_TIME days old from disk Then removes * entries in this for which there is no file on disk. * * @param activeFiles which files are currently being downloaded. * @return true iff any entries were purged */ public synchronized boolean initialPurge(Collection<File> activeFiles) { // Remove any files that are old. boolean ret = false; for (Iterator<File> iter = blocks.keySet().iterator(); iter.hasNext(); ) { File file = iter.next(); try { file = FileUtils.getCanonicalFile(file); } catch (IOException iox) { file = file.getAbsoluteFile(); } if (!file.exists() || (isOld(file) && !activeFiles.contains(file))) { ret = true; fileManager.get().getManagedFileList().remove(file); file.delete(); iter.remove(); } } for (Iterator<File> iter = hashes.values().iterator(); iter.hasNext(); ) { File file = iter.next(); if (!file.exists()) { iter.remove(); ret = true; } } return ret; }
private void recursiveButtonSearch(Container container) { for (Component component : container.getComponents()) { if (component instanceof Container) { recursiveButtonSearch((Container) component); } if (component instanceof JButton) { JButton button = (JButton) component; String buttonText = button.getText(); // Using end of button text to determine whether button shouild be disabled // then disable it. This is because JEditorPane does not disable buttons // disabled in the form html if (buttonText.endsWith(":disabled")) { buttonText = buttonText.substring(0, buttonText.lastIndexOf(":disabled")); button.setText(buttonText); button.setEnabled(false); } String extension = FileUtils.getFileExtension(buttonText); if (!extension.isEmpty()) { Icon icon = iconManager.get().getIconForExtension(extension); button.setIcon(icon); } } } }
private void handleCoreDownloader() { File possibleTorrentFile = null; possibleTorrentFile = downloader.getSaveFile(); String fileExtension = FileUtils.getFileExtension(possibleTorrentFile); if ("torrent".equalsIgnoreCase(fileExtension)) { try { shareTorrentFile(possibleTorrentFile); downloadManager.downloadTorrent(possibleTorrentFile, null, false); downloadItems.remove(getDownloadItem(downloader)); } catch (DownloadException e) { final File torrentFile = possibleTorrentFile; activityCallback.handleDownloadException( new DownloadAction() { @Override public void download(File saveDirectory, boolean overwrite) throws DownloadException { downloadManager.downloadTorrent(torrentFile, saveDirectory, overwrite); downloadItems.remove(getDownloadItem(downloader)); } @Override public void downloadCanceled(DownloadException ignored) { // nothing to do } }, e, false); } } }
/** Loads a playlist. */ public void importM3U(Playlist playlist) { File parentFile = FileChooserHandler.getLastInputDirectory(); if (parentFile == null) parentFile = CommonUtils.getCurrentDirectory(); final File selFile = FileChooserHandler.getInputFile( GUIMediator.getAppFrame(), I18nMarker.marktr("Open Playlist (.m3u)"), parentFile, new PlaylistListFileFilter()); // nothing selected? exit. if (selFile == null || !selFile.isFile()) return; String path = selFile.getPath(); try { path = FileUtils.getCanonicalPath(selFile); } catch (IOException ignored) { // LOG.warn("unable to get canonical path for file: " + selFile, ignored); } // create a new thread off of the event queue to process reading the files from // disk loadM3U(playlist, selFile, path); }
private static ThemeSetter loadCurrentTheme() { ThemeSetter currentTheme = DEFAULT_THEME; BufferedReader input = null; try { File skinsFile = ThemeSettings.SKINS_FILE; if (skinsFile.exists()) { input = new BufferedReader(new FileReader(skinsFile)); String name = input.readLine(); for (int i = 0; i < THEMES.size(); i++) { if (THEMES.get(i).getName().equals(name)) { currentTheme = THEMES.get(i); break; } } } } catch (IOException e) { e.printStackTrace(); } finally { FileUtils.close(input); } return currentTheme; }
public boolean accept(File pathname) { if (FileUtils.isAncestor(SharingSettings.TORRENT_DATA_DIR_SETTING.getValue(), pathname)) { return false; } for (File f : LibrarySettings.DIRECTORIES_TO_INCLUDE_FROM_FROSTWIRE4.getValue()) { if (FileUtils.isAncestor(f, pathname)) { return false; } } if (FileUtils.isAncestor(LibrarySettings.USER_MUSIC_FOLDER.getValue(), pathname)) { return false; } return pathname.isDirectory() && !pathname.isHidden(); }
/** Returns true if dir is excluded from sharing or one of its ancestors is. */ private boolean isExcluded(File dir) { for (File file : deselected) { if (FileUtils.isAncestor(file, dir)) { return true; } } return false; }
/** Returns true if dir and all its subfolders are included. */ private boolean isFullyIncluded(File dir) { for (File offspring : deselected) { if (FileUtils.isAncestor(dir, offspring)) { return false; } } return true; }
/** Saves a playlist. */ public void exportM3U(Playlist playlist) { if (playlist == null) { return; } String suggestedName = CommonUtils.convertFileName(playlist.getName()); // get the user to select a new one.... avoid FrostWire installation folder. File suggested; File suggestedDirectory = FileChooserHandler.getLastInputDirectory(); if (suggestedDirectory.equals(CommonUtils.getCurrentDirectory())) { suggestedDirectory = new File(CommonUtils.getUserHomeDir(), "Desktop"); } suggested = new File(suggestedDirectory, suggestedName + ".m3u"); File selFile = FileChooserHandler.getSaveAsFile( GUIMediator.getAppFrame(), I18nMarker.marktr("Save Playlist As"), suggested, new PlaylistListFileFilter()); // didn't select a file? nothing we can do. if (selFile == null) { return; } // if the file already exists and not the one just opened, ask if it should be // overwritten. // TODO: this should be handled in the jfilechooser if (selFile.exists()) { DialogOption choice = GUIMediator.showYesNoMessage( I18n.tr( "Warning: a file with the name {0} already exists in the folder. Overwrite this file?", selFile.getName()), QuestionsHandler.PLAYLIST_OVERWRITE_OK, DialogOption.NO); if (choice != DialogOption.YES) return; } String path = selFile.getPath(); try { path = FileUtils.getCanonicalPath(selFile); } catch (IOException ignored) { // LOG.warn("unable to get canonical path for file: " + selFile, ignored); } // force m3u on the end. if (!path.toLowerCase().endsWith(".m3u")) path += ".m3u"; // create a new thread to handle saving the playlist to disk saveM3U(playlist, path); }
boolean isAlreadyGoingToBeShared(File dir) { if (sharingPanel.getFoldersToExclude().contains(dir)) { return false; } for (File folder : sharingPanel.getRootsToShare()) { if (FileUtils.isAncestor(folder, dir)) { return true; } } return false; }
public static void populateProperties( String fileName, long fileSize, long creationTime, Map<FilePropertyKey, Object> properties, LimeXMLDocument doc) { properties.put(FilePropertyKey.NAME, ""); // Make sure name defaults to empty. set(properties, FilePropertyKey.NAME, FileUtils.getFilenameNoExtension(fileName)); set(properties, FilePropertyKey.DATE_CREATED, creationTime); set(properties, FilePropertyKey.FILE_SIZE, fileSize); String extension = FileUtils.getFileExtension(fileName); Category category = CategoryConverter.categoryForExtension(extension); if (doc != null) { for (FilePropertyKey filePropertyKey : FilePropertyKey.values()) { set(properties, doc, category, filePropertyKey); } Long bitrate, length; Integer quality; switch (category) { case AUDIO: bitrate = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.AUDIO_BITRATE)); length = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.AUDIO_SECONDS)); quality = toAudioQualityScore(extension, fileSize, bitrate, length); set(properties, FilePropertyKey.QUALITY, quality); break; case VIDEO: bitrate = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_BITRATE)); length = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_LENGTH)); Long height = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_HEIGHT)); Long width = CommonUtils.parseLongNoException(doc.getValue(LimeXMLNames.VIDEO_WIDTH)); quality = toVideoQualityScore(extension, fileSize, bitrate, length, height, width); set(properties, FilePropertyKey.QUALITY, quality); break; } } }
private static void saveCurrentTheme(ThemeSetter theme) throws IOException { File skinsFile = ThemeSettings.SKINS_FILE; BufferedWriter output = new BufferedWriter(new FileWriter(skinsFile)); try { output.write(theme.getName()); } finally { FileUtils.close(output); } }
/** * Retains common ancestors and removes subfolders since they will be part of the recursive * sharing. */ static Set<File> retainAncestors(File... roots) { if (roots == null) { return new HashSet<File>(); } for (int i = 0; i < roots.length; i++) { for (int j = i + 1; j < roots.length && roots[i] != null; j++) { if (roots[j] != null) { if (FileUtils.isAncestor(roots[i], roots[j])) { roots[j] = null; } else if (FileUtils.isAncestor(roots[j], roots[i])) { roots[i] = null; } } } } Set<File> retained = new HashSet<File>(roots.length); for (File file : roots) { if (file != null) { retained.add(file); } } return retained; }
/** * replaces tokens in the update command with info about the specific system i.e. <PATH> -> * C:\Documents And Settings.... */ private static void prepareUpdateCommand(UpdateData info) { if (info == null || info.getUpdateCommand() == null) return; File path = LibraryUtils.PREFERENCE_SHARE.getAbsoluteFile(); String name = info.getUpdateFileName(); try { path = FileUtils.getCanonicalFile(path); } catch (IOException bad) { } String command = info.getUpdateCommand(); command = StringUtils.replace(command, "$", path.getPath() + File.separator); command = StringUtils.replace(command, "%", name); info.setUpdateCommand(command); }
private void storeAndUpdate(byte[] data, SimppParser parser, UpdateType updateType) { if (LOG.isTraceEnabled()) LOG.trace("Retrieved new data from: " + updateType + ", storing & updating"); if (parser.getVersion() == IGNORE_ID && updateType == UpdateType.FROM_NETWORK) throw new IllegalStateException("shouldn't be here!"); if (updateType == UpdateType.FROM_NETWORK && httpRequestControl.isRequestPending()) return; _lastId = parser.getVersion(); _lastBytes = data; if (updateType != UpdateType.FROM_DISK) { FileUtils.verySafeSave(CommonUtils.getUserSettingsDir(), FILENAME, data); } for (SimppSettingsManager ssm : simppSettingsManagers) ssm.updateSimppSettings(parser.getPropsData()); for (SimppListener listener : listeners) listener.simppUpdated(_lastId); }
/** * Removes all files from <code>deselected</code> that are ancestors * of <code>file</code or vice versa. */ private void removeFromPath(File file) { // remove all children, file itself is removed here too for (Iterator<File> i = deselected.iterator(); i.hasNext(); ) { File f = i.next(); if (FileUtils.isAncestor(file, f)) { i.remove(); } } while (file != null && !roots.contains(file)) { // mark other children of parent as excluded File parent = file.getParentFile(); if (ancestorIsExcluded(parent)) { deselected.remove(parent); int childCount = directoryTreeModel.getChildCount(parent); for (int j = 0; j < childCount; j++) { File sibling = (File) directoryTreeModel.getChild(parent, j); if (sibling != null && !sibling.equals(file)) { deselected.add(sibling); } } } file = parent; } }
/** * A utility method to close Closeable objects (Readers, Writers, Input- and OutputStreams and * RandomAccessFiles). */ public static void close(Closeable closeable) { FileUtils.close(closeable); }
/** * Returns true if a file with the given name is of this media type, i.e., the suffix of the * filename matches one of this' extensions. */ public boolean matches(String filename) { if (exts == null) return true; return FileUtils.hasExtension(filename, extsArray); }
/** * Stores the given data to disk & posts an update to neighboring connections. Starts the download * of any updates */ private void storeAndUpdate(byte[] data, UpdateCollection uc, UpdateType updateType) { if (LOG.isTraceEnabled()) LOG.trace("Retrieved new data from: " + updateType + ", storing & updating."); if (uc.getId() == IGNORE_ID && updateType == UpdateType.FROM_NETWORK) throw new IllegalStateException("shouldn't be here!"); // If an http max request is pending, don't even bother with this stuff. // We want to get it straight from the source... if (updateType == UpdateType.FROM_NETWORK && httpRequestControl.isRequestPending() && httpRequestControl.getRequestReason() == HttpRequestControl.RequestReason.MAX) return; _lastId = uc.getId(); _lastTimestamp = uc.getTimestamp(); UpdateSettings.LAST_UPDATE_TIMESTAMP.setValue(_lastTimestamp); long delay = UpdateSettings.UPDATE_DOWNLOAD_DELAY.getValue(); long random = Math.abs(RANDOM.nextLong() % delay); _nextDownloadTime = _lastTimestamp + random; _lastBytes = data; if (updateType != UpdateType.FROM_DISK) { // cancel any http and pretend we just updated. if (httpRequestControl.getRequestReason() == HttpRequestControl.RequestReason.TIMEOUT) httpRequestControl.cancelRequest(); UpdateSettings.LAST_HTTP_FAILOVER.setValue(clock.now()); FileUtils.verySafeSave(CommonUtils.getUserSettingsDir(), FILENAME, data); capabilitiesVMFactory.updateCapabilities(); connectionManager.get().sendUpdatedCapabilities(); } Version limeV; try { limeV = new Version(LimeWireUtils.getLimeWireVersion()); } catch (VersionFormatException vfe) { LOG.warn("Invalid LimeWire version", vfe); return; } Version javaV = null; try { javaV = new Version(VersionUtils.getJavaVersion()); } catch (VersionFormatException vfe) { LOG.warn("Invalid java version", vfe); } // don't allow someone to set the style to be above major. int style = Math.min(UpdateStyle.STYLE_MAJOR, UpdateSettings.UPDATE_STYLE.getValue()); UpdateData updateInfo = uc.getUpdateDataFor( limeV, ApplicationSettings.getLanguage(), LimeWireUtils.isPro(), style, javaV); List<DownloadInformation> updatesToDownload = uc.getUpdatesWithDownloadInformation(); _killingObsoleteNecessary = true; // if we have an update for our machine, prepare the command line // and move our update to the front of the list of updates if (updateInfo != null && updateInfo.getUpdateURN() != null) { prepareUpdateCommand(updateInfo); updatesToDownload = new LinkedList<DownloadInformation>(updatesToDownload); updatesToDownload.add(0, updateInfo); } _updateInfo = updateInfo; _updatesToDownload = updatesToDownload; downloadUpdates(updatesToDownload, null); if (updateInfo == null) { LOG.warn("No relevant update info to notify about."); return; } else if (updateInfo.getUpdateURN() == null || isHopeless(updateInfo)) { if (LOG.isDebugEnabled()) LOG.debug( "we have an update, but it doesn't need a download. " + "or all our updates are hopeles. Scheduling URL notification..."); updateInfo.setUpdateCommand(null); backgroundExecutor.schedule( new NotificationFailover(_lastId), delay(clock.now(), uc.getTimestamp()), TimeUnit.MILLISECONDS); } else if (isMyUpdateDownloaded(updateInfo)) { LOG.debug("there is an update for me, but I happen to have it on disk"); fireUpdate(updateInfo); } else LOG.debug("we have an update, it needs a download. Rely on callbacks"); }
/** * Returns the fully-qualified temporary download file for the given file/location pair. If an * incomplete file already exists for this URN, that file is returned. Otherwise, the location of * the file is determined by the "incDir" variable. For example, getFile("test.txt", 1999) may * return "C:\Program Files\LimeWire\Incomplete\T-1999-Test.txt" if "incDir" is "C:\Program * Files\LimeWire\Incomplete". The disk is not modified, except for the file possibly being * created. * * <p>This method gives duplicate files the same temporary file, which is critical for resume and * swarmed downloads. That is, for all rfd_i and rfd_j * * <pre> * similar(rfd_i, rfd_j) <==> getFile(rfd_i).equals(getFile(rfd_j))<p> * </pre> * * It is imperative that the files are compared as in their canonical formats to preserve the * integrity of the filesystem. Otherwise, multiple downloads could be downloading to "FILE A", * and "file a", although only "file a" exists on disk and is being written to by both. * * @throws IOException if there was an IOError while determining the file's name. */ public synchronized File getFile(String name, URN sha1, long size, File incDir) throws IOException { boolean dirsMade = false; File baseFile = null; File canonFile = null; // make sure its created.. (the user might have deleted it) dirsMade = incDir.mkdirs(); String convertedName = CommonUtils.convertFileName(name); try { if (sha1 != null) { File file = hashes.get(sha1); if (file != null) { // File already allocated for hash return file; } else { // Allocate unique file for hash. By "unique" we mean not in // the value set of HASHES. Because we allow risky resumes, // there's no need to look at BLOCKS as well... for (int i = 1; ; i++) { file = new File(incDir, tempName(convertedName, size, i)); baseFile = file; file = canonicalize(file); canonFile = file; if (!hashes.values().contains(file)) break; } // ...and record the hash for later. hashes.put(sha1, file); // ...and make sure the file exists on disk, so that // future File.getCanonicalFile calls will match this // file. This was a problem on OSX, where // File("myfile") and File("MYFILE") aren't equal, // but File("myfile").getCanonicalFile() will only return // a File("MYFILE") if that already existed on disk. // This means that in order for the canonical-checking // within this class to work, the file must exist on disk. FileUtils.touch(file); return file; } } else { // No hash. File f = new File(incDir, tempName(convertedName, size, 0)); baseFile = f; f = canonicalize(f); canonFile = f; return f; } } catch (IOException ioe) { IOException ioe2 = new IOException( "dirsMade: " + dirsMade + "\ndirExist: " + incDir.exists() + "\nbaseFile: " + baseFile + "\ncannFile: " + canonFile); ioe2.initCause(ioe); throw ioe2; } }
/** * A utility method to flush Flushable objects (Readers, Writers, Input- and OutputStreams and * RandomAccessFiles). */ public static void flush(Flushable flushable) { FileUtils.flush(flushable); }
/** * Override the default removal so we can actually stop sharing and delete the file. Deletes the * selected rows in the table. CAUTION: THIS WILL DELETE THE FILE FROM THE DISK. */ public void removeSelection() { int[] rows = TABLE.getSelectedRows(); if (rows.length == 0) return; if (TABLE.isEditing()) { TableCellEditor editor = TABLE.getCellEditor(); editor.cancelCellEditing(); } List<File> files = new ArrayList<File>(rows.length); // sort row indices and go backwards so list indices don't change when // removing the files from the model list Arrays.sort(rows); for (int i = rows.length - 1; i >= 0; i--) { File file = DATA_MODEL.getFile(rows[i]); files.add(file); } CheckBoxListPanel<File> listPanel = new CheckBoxListPanel<File>(files, new FileTextProvider(), true); listPanel.getList().setVisibleRowCount(4); // display list of files that should be deleted Object[] message = new Object[] { new MultiLineLabel( I18n.tr( "Are you sure you want to delete the selected file(s), thus removing it from your computer?"), 400), Box.createVerticalStrut(ButtonRow.BUTTON_SEP), listPanel, Box.createVerticalStrut(ButtonRow.BUTTON_SEP) }; // get platform dependent options which are displayed as buttons in the dialog Object[] removeOptions = createRemoveOptions(); int option = JOptionPane.showOptionDialog( MessageService.getParentComponent(), message, I18n.tr("Message"), JOptionPane.YES_NO_OPTION, JOptionPane.QUESTION_MESSAGE, null, removeOptions, removeOptions[0] /* default option */); if (option == removeOptions.length - 1 /* "cancel" option index */ || option == JOptionPane.CLOSED_OPTION) { return; } // remove still selected files List<File> selected = listPanel.getSelectedElements(); List<String> undeletedFileNames = new ArrayList<String>(); boolean somethingWasRemoved = false; for (File file : selected) { // stop seeding if seeding BittorrentDownload dm = null; if ((dm = TorrentUtil.getDownloadManager(file)) != null) { dm.setDeleteDataWhenRemove(false); dm.setDeleteTorrentWhenRemove(false); BTDownloadMediator.instance().remove(dm); } // close media player if still playing if (MediaPlayer.instance().isThisBeingPlayed(file)) { MediaPlayer.instance().stop(); MPlayerMediator.instance().showPlayerWindow(false); } // removeOptions > 2 => OS offers trash options boolean removed = FileUtils.delete( file, removeOptions.length > 2 && option == 0 /* "move to trash" option index */); if (removed) { somethingWasRemoved = true; DATA_MODEL.remove(DATA_MODEL.getRow(file)); } else { undeletedFileNames.add(getCompleteFileName(file)); } } clearSelection(); if (somethingWasRemoved) { LibraryMediator.instance().getLibraryExplorer().refreshSelection(true); } if (undeletedFileNames.isEmpty()) { return; } // display list of files that could not be deleted message = new Object[] { new MultiLineLabel( I18n.tr( "The following files could not be deleted. They may be in use by another application or are currently being downloaded to."), 400), Box.createVerticalStrut(ButtonRow.BUTTON_SEP), new JScrollPane(createFileList(undeletedFileNames)) }; JOptionPane.showMessageDialog( MessageService.getParentComponent(), message, I18n.tr("Error"), JOptionPane.ERROR_MESSAGE); super.removeSelection(); }
/** * Deletes the incomplete files for this torrent file system. The torrent file system should * handle the possibility of this method being called multiple times. */ public void deleteIncompleteFiles() { File parent = _incompleteFile.getParentFile(); FileUtils.deleteRecursive(parent); }
/** * Constructs the file system using the given BTData & hash information. If any of the information * is malformed, throws a ValueException. * * @param data contains all the data about a .torrent file * @param numHashes number of pieces the torrent was divided into * @param pieceLength size of divided up torrent file * @param infoHash a string of alphanumeric characters in the .torrent file that the client uses * to verify the data that is being transferred * @throws ValueException */ TorrentFileSystem(BTData data, int numHashes, long pieceLength, byte[] infoHash) throws IOException { // name of the torrent, also specifying the directory under which to save the torrents. _name = CommonUtils.convertFileName(data.getName()); // we need to check the name of the torrent, security risk! if (_name.length() == 0) throw new ValueException("bad torrent name"); _incompleteFile = new File( SharingSettings.INCOMPLETE_DIRECTORY.get(), Base32.encode(infoHash) + File.separator + _name); _completeFile = new File(SharingSettings.getSaveDirectory(_name), _name); if (!FileUtils.isReallyParent(SharingSettings.getSaveDirectory(_name), _completeFile)) { throw new SaveLocationException(LocationCode.SECURITY_VIOLATION, _completeFile); } if (data.getFiles() != null) { List<BTData.BTFileData> files = data.getFiles(); List<TorrentFile> torrents = new ArrayList<TorrentFile>(files.size()); long position = 0; for (BTData.BTFileData file : files) { String torrentPath = _name + file.getPath(); TorrentFile f = new TorrentFile( file.getLength(), new File(_completeFile, file.getPath()).getAbsolutePath(), torrentPath); f.setBeginPiece((int) (position / pieceLength)); f.setStartByte(position); position += f.length(); f.setEndPiece((int) (position / pieceLength)); f.setEndByte(position - 1); if (!FileUtils.isReallyInParentPath(_completeFile, f)) throw new SaveLocationException(LocationCode.SECURITY_VIOLATION, f); torrents.add(f); } if (files.size() == 0) throw new ValueException("bad metainfo, no files!"); _files = torrents; // add folders, for easier conflict checking later on for (String folderPath : data.getFolders()) _folders.add(new File(_completeFile, folderPath)); _folders.add(_completeFile); } else { String torrentPath = data.getName(); TorrentFile f = new TorrentFile(data.getLength(), _completeFile.getAbsolutePath(), torrentPath); f.setBeginPiece(0); f.setStartByte(0); f.setEndPiece(numHashes - 1); f.setEndByte(f.length()); _files = new ArrayList<TorrentFile>(1); _files.add(f); } _unmodFiles = Collections.unmodifiableList(_files); _totalSize = calculateTotalSize(_files); if (_totalSize <= 0) throw new ValueException("invalid size " + _totalSize); }