From 66a6278611f2af939b4bf5c5fc2cb1698102834e Mon Sep 17 00:00:00 2001 From: Reinhard Pointner Date: Wed, 22 Jan 2014 07:52:25 +0000 Subject: [PATCH] * Extract API changes to include FileSize --- .../sourceforge/filebot/archive/Archive.java | 78 +++++----- .../filebot/cli/CmdlineOperations.java | 5 +- .../filebot/cli/ConflictAction.java | 14 +- .../filebot/media/MediaDetection.java | 5 +- .../filebot/ui/analyze/ExtractTool.java | 143 ++++++++---------- 5 files changed, 109 insertions(+), 136 deletions(-) diff --git a/source/net/sourceforge/filebot/archive/Archive.java b/source/net/sourceforge/filebot/archive/Archive.java index d9b3ac1f..53b45b37 100644 --- a/source/net/sourceforge/filebot/archive/Archive.java +++ b/source/net/sourceforge/filebot/archive/Archive.java @@ -1,7 +1,5 @@ - package net.sourceforge.filebot.archive; - import java.io.Closeable; import java.io.File; import java.io.FileFilter; @@ -23,21 +21,21 @@ import net.sf.sevenzipjbinding.ISevenZipInArchive; import net.sf.sevenzipjbinding.PropID; import net.sf.sevenzipjbinding.SevenZipException; import net.sourceforge.filebot.MediaTypes; +import net.sourceforge.filebot.vfs.FileInfo; +import net.sourceforge.filebot.vfs.SimpleFileInfo; import net.sourceforge.tuned.FileUtilities.ExtensionFileFilter; - public class Archive implements Closeable { - + private ISevenZipInArchive inArchive; private ArchiveOpenVolumeCallback openVolume; - - + public Archive(File file) throws Exception { // initialize 7-Zip-JBinding if (!file.exists()) { throw new FileNotFoundException(file.getAbsolutePath()); } - + try { openVolume = new ArchiveOpenVolumeCallback(); if (!hasMultiPartIndex(file)) { @@ -51,52 +49,48 @@ public class Archive implements Closeable { throw (Exception) e.getTargetException(); } } - - + public int itemCount() throws SevenZipException { return inArchive.getNumberOfItems(); } - - + public Map getItem(int index) throws SevenZipException { Map item = new EnumMap(PropID.class); - + for (PropID prop : PropID.values()) { Object value = inArchive.getProperty(index, prop); if (value != null) { item.put(prop, value); } } - + return item; } - - - public List listFiles() throws SevenZipException { - List paths = new ArrayList(); - + + public List listFiles() throws SevenZipException { + List paths = new ArrayList(); + for (int i = 0; i < inArchive.getNumberOfItems(); i++) { boolean isFolder = (Boolean) inArchive.getProperty(i, PropID.IS_FOLDER); if (!isFolder) { String path = (String) inArchive.getProperty(i, PropID.PATH); + Long length = (Long) inArchive.getProperty(i, PropID.SIZE); if (path != null) { - paths.add(new File(path)); + paths.add(new SimpleFileInfo(path, length != null ? length : -1)); } } } - + return paths; } - - + public void extract(ExtractOutProvider outputMapper) throws SevenZipException { inArchive.extract(null, false, new ExtractCallback(inArchive, outputMapper)); } - - + public void extract(ExtractOutProvider outputMapper, FileFilter filter) throws SevenZipException { List selection = new ArrayList(); - + for (int i = 0; i < inArchive.getNumberOfItems(); i++) { boolean isFolder = (Boolean) inArchive.getProperty(i, PropID.IS_FOLDER); if (!isFolder) { @@ -106,15 +100,14 @@ public class Archive implements Closeable { } } } - + int[] indices = new int[selection.size()]; for (int i = 0; i < indices.length; i++) { indices[i] = selection.get(i); } inArchive.extract(indices, false, new ExtractCallback(inArchive, outputMapper)); } - - + @Override public void close() throws IOException { try { @@ -125,41 +118,38 @@ public class Archive implements Closeable { openVolume.close(); } } - - + public static Set getArchiveTypes() { Set extensions = new TreeSet(String.CASE_INSENSITIVE_ORDER); - + // application data extensions.addAll(MediaTypes.getDefault().getExtensionList("archive")); - + // formats provided by the library for (ArchiveFormat it : ArchiveFormat.values()) { extensions.add(it.getMethodName()); } - + return extensions; } - + private static final Pattern multiPartIndex = Pattern.compile("[.][0-9]{3}+$"); - - + public static boolean hasMultiPartIndex(File file) { return multiPartIndex.matcher(file.getName()).find(); } - + public static final FileFilter VOLUME_ONE_FILTER = new FileFilter() { - + private Pattern volume = Pattern.compile("[.]r[0-9]+$|[.]part[0-9]+|[.][0-9]+$", Pattern.CASE_INSENSITIVE); private FileFilter archives = new ExtensionFileFilter(getArchiveTypes()); - - + @Override public boolean accept(File path) { if (!archives.accept(path) && !hasMultiPartIndex(path)) { return false; } - + Matcher matcher = volume.matcher(path.getName()); if (matcher.find()) { Scanner scanner = new Scanner(matcher.group()).useDelimiter("\\D+"); @@ -167,10 +157,10 @@ public class Archive implements Closeable { return false; } } - + return true; } - + }; - + } diff --git a/source/net/sourceforge/filebot/cli/CmdlineOperations.java b/source/net/sourceforge/filebot/cli/CmdlineOperations.java index a96ce442..5c40fb0c 100644 --- a/source/net/sourceforge/filebot/cli/CmdlineOperations.java +++ b/source/net/sourceforge/filebot/cli/CmdlineOperations.java @@ -58,6 +58,7 @@ import net.sourceforge.filebot.similarity.SimilarityComparator; import net.sourceforge.filebot.similarity.SimilarityMetric; import net.sourceforge.filebot.subtitle.SubtitleFormat; import net.sourceforge.filebot.subtitle.SubtitleNaming; +import net.sourceforge.filebot.vfs.FileInfo; import net.sourceforge.filebot.vfs.MemoryFile; import net.sourceforge.filebot.web.AudioTrack; import net.sourceforge.filebot.web.Episode; @@ -1085,8 +1086,8 @@ public class CmdlineOperations implements CmdlineInterface { final FileMapper outputMapper = new FileMapper(outputFolder, false); final List outputMapping = new ArrayList(); - for (File entry : archive.listFiles()) { - outputMapping.add(outputMapper.getOutputFile(entry)); + for (FileInfo entry : archive.listFiles()) { + outputMapping.add(outputMapper.getOutputFile(new File(entry.getPath()))); } final Set selection = new TreeSet(); diff --git a/source/net/sourceforge/filebot/cli/ConflictAction.java b/source/net/sourceforge/filebot/cli/ConflictAction.java index 59d1ca89..f9ea09d7 100644 --- a/source/net/sourceforge/filebot/cli/ConflictAction.java +++ b/source/net/sourceforge/filebot/cli/ConflictAction.java @@ -1,20 +1,16 @@ - package net.sourceforge.filebot.cli; - public enum ConflictAction { - - OVERRIDE, - SKIP, - FAIL; - + + SKIP, OVERRIDE, FAIL, AUTO; + public static ConflictAction forName(String action) { for (ConflictAction it : values()) { if (it.name().equalsIgnoreCase(action)) return it; } - + throw new IllegalArgumentException("Illegal conflict action: " + action); } - + } diff --git a/source/net/sourceforge/filebot/media/MediaDetection.java b/source/net/sourceforge/filebot/media/MediaDetection.java index b57feda2..ab109a9e 100644 --- a/source/net/sourceforge/filebot/media/MediaDetection.java +++ b/source/net/sourceforge/filebot/media/MediaDetection.java @@ -53,6 +53,7 @@ import net.sourceforge.filebot.similarity.SequenceMatchSimilarity; import net.sourceforge.filebot.similarity.SeriesNameMatcher; import net.sourceforge.filebot.similarity.SimilarityComparator; import net.sourceforge.filebot.similarity.SimilarityMetric; +import net.sourceforge.filebot.vfs.FileInfo; import net.sourceforge.filebot.web.Date; import net.sourceforge.filebot.web.Episode; import net.sourceforge.filebot.web.Movie; @@ -95,8 +96,8 @@ public class MediaDetection { FileFilter diskFolderEntryFilter = releaseInfo.getDiskFolderEntryFilter(); Archive iso = new Archive(file); try { - for (File path : iso.listFiles()) { - for (File entry : listPath(path)) { + for (FileInfo it : iso.listFiles()) { + for (File entry : listPath(new File(it.getPath()))) { if (diskFolderEntryFilter.accept(entry)) { return true; } diff --git a/source/net/sourceforge/filebot/ui/analyze/ExtractTool.java b/source/net/sourceforge/filebot/ui/analyze/ExtractTool.java index 595fc712..7be8b423 100644 --- a/source/net/sourceforge/filebot/ui/analyze/ExtractTool.java +++ b/source/net/sourceforge/filebot/ui/analyze/ExtractTool.java @@ -1,7 +1,5 @@ - package net.sourceforge.filebot.ui.analyze; - import static net.sourceforge.filebot.ui.NotificationLogging.*; import static net.sourceforge.tuned.ExceptionUtilities.*; import static net.sourceforge.tuned.FileUtilities.*; @@ -38,6 +36,8 @@ import net.sourceforge.filebot.ResourceManager; import net.sourceforge.filebot.archive.Archive; import net.sourceforge.filebot.archive.FileMapper; import net.sourceforge.filebot.ui.analyze.FileTree.FolderNode; +import net.sourceforge.filebot.vfs.FileInfo; +import net.sourceforge.tuned.FileUtilities; import net.sourceforge.tuned.ui.GradientStyle; import net.sourceforge.tuned.ui.LoadingOverlayPane; import net.sourceforge.tuned.ui.ProgressDialog; @@ -45,57 +45,53 @@ import net.sourceforge.tuned.ui.ProgressDialog.Cancellable; import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter; import net.sourceforge.tuned.ui.notification.SeparatorBorder; - class ExtractTool extends Tool { - + private JTable table = new JTable(new ArchiveEntryModel()); - - + public ExtractTool() { super("Archives"); - + table.setFillsViewportHeight(true); table.setAutoCreateRowSorter(true); table.setAutoCreateColumnsFromModel(true); table.setAutoResizeMode(JTable.AUTO_RESIZE_SUBSEQUENT_COLUMNS); table.setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION); table.setRowHeight(20); - + JScrollPane tableScrollPane = new JScrollPane(table); tableScrollPane.setBorder(new SeparatorBorder(2, new Color(0, 0, 0, 90), GradientStyle.TOP_TO_BOTTOM, SeparatorBorder.Position.BOTTOM)); - + setLayout(new MigLayout("insets 0, nogrid, fill", "align center", "[fill][pref!]")); add(new LoadingOverlayPane(tableScrollPane, this, "20px", "30px"), "grow, wrap"); add(new JButton(extractAction), "gap top rel, gap bottom unrel"); } - - + @Override protected void setModel(TableModel model) { table.setModel(model); } - - + @Override protected TableModel createModelInBackground(FolderNode sourceModel) throws InterruptedException { List entries = new ArrayList(); - + try { for (Iterator iterator = sourceModel.fileIterator(); iterator.hasNext();) { File file = iterator.next(); - + // ignore non-archives files and trailing multi-volume parts if (Archive.VOLUME_ONE_FILTER.accept(file)) { Archive archive = new Archive(file); try { - for (File it : archive.listFiles()) { + for (FileInfo it : archive.listFiles()) { entries.add(new ArchiveEntry(file, it)); } } finally { archive.close(); } } - + // unwind thread, if we have been cancelled if (Thread.interrupted()) { throw new InterruptedException(); @@ -108,20 +104,19 @@ class ExtractTool extends Tool { } UILogger.log(Level.WARNING, e.getMessage(), e); } - + return new ArchiveEntryModel(entries); } - - + private Action extractAction = new AbstractAction("Extract All", ResourceManager.getIcon("package.extract")) { - + @Override public void actionPerformed(ActionEvent evt) { final List archives = ((ArchiveEntryModel) table.getModel()).getArchiveList(); if (archives.isEmpty()) { return; } - + Window window = getWindow(evt.getSource()); JFileChooser chooser = new JFileChooser(archives.get(0).getParentFile()); chooser.setFileSelectionMode(JFileChooser.DIRECTORIES_ONLY); @@ -129,18 +124,18 @@ class ExtractTool extends Tool { if (chooser.showSaveDialog(window) != JFileChooser.APPROVE_OPTION) { return; } - + final ExtractJob job = new ExtractJob(archives, chooser.getSelectedFile()); - + final ProgressDialog dialog = new ProgressDialog(window, job); dialog.setLocation(getOffsetLocation(dialog.getOwner())); dialog.setTitle("Extracting files..."); dialog.setIcon((Icon) getValue(SMALL_ICON)); dialog.setIndeterminate(true); - + // close progress dialog when worker is finished job.addPropertyChangeListener(new SwingWorkerPropertyChangeAdapter() { - + @Override protected void event(String name, Object oldValue, Object newValue) { if (name.equals("currentFile")) { @@ -149,48 +144,41 @@ class ExtractTool extends Tool { dialog.setWindowTitle(note); } } - - + @Override protected void done(PropertyChangeEvent evt) { dialog.close(); } }); - + job.execute(); dialog.setVisible(true); } }; - - + private static class ArchiveEntry { - + public final File archive; - public final File entry; - - - public ArchiveEntry(File archive, File entry) { + public final FileInfo entry; + + public ArchiveEntry(File archive, FileInfo entry) { this.archive = archive; this.entry = entry; } } - - + private static class ArchiveEntryModel extends AbstractTableModel { - + private final ArchiveEntry[] data; - - + public ArchiveEntryModel() { this.data = new ArchiveEntry[0]; } - - + public ArchiveEntryModel(Collection data) { this.data = data.toArray(new ArchiveEntry[data.size()]); } - - + public List getArchiveList() { Set archives = new LinkedHashSet(); for (ArchiveEntry it : data) { @@ -198,68 +186,66 @@ class ExtractTool extends Tool { } return new ArrayList(archives); } - - + @Override public int getRowCount() { return data.length; } - - + @Override public int getColumnCount() { - return 2; + return 3; } - - + @Override public String getColumnName(int column) { switch (column) { - case 0: - return "File"; - case 1: - return "Path"; + case 0: + return "File"; + case 1: + return "Path"; + case 2: + return "Size"; } return null; } - - + @Override public Object getValueAt(int row, int column) { switch (column) { - case 0: - return data[row].entry.getName(); - case 1: - File root = new File(data[row].archive.getName()); - File prefix = data[row].entry.getParentFile(); - File path = (prefix == null) ? root : new File(root, prefix.getPath()); - return normalizePathSeparators(path.getPath()); + case 0: + return data[row].entry.getName(); + case 1: + File root = new File(data[row].archive.getName()); + File prefix = new File(data[row].entry.getPath()).getParentFile(); + File path = (prefix == null) ? root : new File(root, prefix.getPath()); + return normalizePathSeparators(path.getPath()); + case 2: + return FileUtilities.formatSize(data[row].entry.getLength()); } + return null; } - + } - - + protected static class ExtractJob extends SwingWorker implements Cancellable { - + private final File[] archives; private final File outputRoot; - - + public ExtractJob(Collection archives, File outputRoot) { this.archives = archives.toArray(new File[archives.size()]); this.outputRoot = outputRoot; } - - + @Override protected Void doInBackground() throws Exception { for (File it : archives) { try { // update progress dialog firePropertyChange("currentFile", null, it); - + Archive archive = new Archive(it); try { File outputFolder = (outputRoot != null) ? outputRoot : new File(it.getParentFile(), getNameWithoutExtension(it.getName())); @@ -271,20 +257,19 @@ class ExtractTool extends Tool { } catch (Exception e) { UILogger.log(Level.WARNING, "Failed to extract archive: " + it.getName(), e); } - + if (isCancelled()) { throw new CancellationException(); } } return null; } - - + @Override public boolean cancel() { return cancel(true); } - + } - + }