* allow move-rename in CLI
This commit is contained in:
parent
cd8b8aa620
commit
4ca962f297
@ -172,19 +172,20 @@ public class ArgumentProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// map old files to new paths by applying formatting and validating filenames
|
// map old files to new paths by applying formatting and validating filenames
|
||||||
Map<File, String> renameMap = new LinkedHashMap<File, String>();
|
Map<File, File> renameMap = new LinkedHashMap<File, File>();
|
||||||
|
|
||||||
for (Match<File, Episode> match : matches) {
|
for (Match<File, Episode> match : matches) {
|
||||||
File file = match.getValue();
|
File file = match.getValue();
|
||||||
Episode episode = match.getCandidate();
|
Episode episode = match.getCandidate();
|
||||||
String newName = (format != null) ? format.format(new MediaBindingBean(episode, file)) : EpisodeFormat.SeasonEpisode.format(episode);
|
String newName = (format != null) ? format.format(new MediaBindingBean(episode, file)) : EpisodeFormat.SeasonEpisode.format(episode);
|
||||||
|
File newFile = new File(newName + "." + getExtension(file));
|
||||||
|
|
||||||
if (isInvalidFileName(newName)) {
|
if (isInvalidFilePath(newFile)) {
|
||||||
CLILogger.config("Stripping invalid characters from new name: " + newName);
|
CLILogger.config("Stripping invalid characters from new name: " + newName);
|
||||||
newName = validateFileName(newName);
|
newFile = validateFilePath(newFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
renameMap.put(file, newName + "." + getExtension(file));
|
renameMap.put(file, newFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
// rename episodes
|
// rename episodes
|
||||||
@ -209,20 +210,21 @@ public class ArgumentProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// map old files to new paths by applying formatting and validating filenames
|
// map old files to new paths by applying formatting and validating filenames
|
||||||
Map<File, String> renameMap = new LinkedHashMap<File, String>();
|
Map<File, File> renameMap = new LinkedHashMap<File, File>();
|
||||||
|
|
||||||
for (int i = 0; i < movieFiles.length; i++) {
|
for (int i = 0; i < movieFiles.length; i++) {
|
||||||
if (movieDescriptors[i] != null) {
|
if (movieDescriptors[i] != null) {
|
||||||
Movie movie = movieDescriptors[i];
|
Movie movie = movieDescriptors[i];
|
||||||
File file = movieFiles[i];
|
File file = movieFiles[i];
|
||||||
String newName = (format != null) ? format.format(new MediaBindingBean(movie, file)) : movie.toString();
|
String newName = (format != null) ? format.format(new MediaBindingBean(movie, file)) : movie.toString();
|
||||||
|
File newFile = new File(newName + "." + getExtension(file));
|
||||||
|
|
||||||
if (isInvalidFileName(newName)) {
|
if (isInvalidFilePath(newFile)) {
|
||||||
CLILogger.config("Stripping invalid characters from new path: " + newName);
|
CLILogger.config("Stripping invalid characters from new path: " + newName);
|
||||||
newName = validateFileName(newName);
|
newFile = validateFilePath(newFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
renameMap.put(file, newName + "." + getExtension(file));
|
renameMap.put(file, newFile);
|
||||||
} else {
|
} else {
|
||||||
CLILogger.warning("No matching movie: " + movieFiles[i]);
|
CLILogger.warning("No matching movie: " + movieFiles[i]);
|
||||||
}
|
}
|
||||||
@ -237,8 +239,9 @@ public class ArgumentProcessor {
|
|||||||
String movieName = getName(movieFiles[i]);
|
String movieName = getName(movieFiles[i]);
|
||||||
|
|
||||||
if (subtitleName.equalsIgnoreCase(movieName)) {
|
if (subtitleName.equalsIgnoreCase(movieName)) {
|
||||||
String movieDestinationName = renameMap.get(movieFiles[i]);
|
File movieDestination = renameMap.get(movieFiles[i]);
|
||||||
renameMap.put(subtitleFile, getNameWithoutExtension(movieDestinationName) + "." + getExtension(subtitleFile));
|
File subtitleDestination = new File(movieDestination.getParentFile(), getName(movieDestination) + "." + getExtension(subtitleFile));
|
||||||
|
renameMap.put(subtitleFile, subtitleDestination);
|
||||||
|
|
||||||
// movie match found, we're done
|
// movie match found, we're done
|
||||||
break;
|
break;
|
||||||
@ -375,12 +378,12 @@ public class ArgumentProcessor {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Set<File> renameAll(Map<File, String> renameMap) throws Exception {
|
private Set<File> renameAll(Map<File, File> renameMap) throws Exception {
|
||||||
// rename files
|
// rename files
|
||||||
final List<Entry<File, File>> renameLog = new ArrayList<Entry<File, File>>();
|
final List<Entry<File, File>> renameLog = new ArrayList<Entry<File, File>>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (Entry<File, String> it : renameMap.entrySet()) {
|
for (Entry<File, File> it : renameMap.entrySet()) {
|
||||||
try {
|
try {
|
||||||
// rename file, throw exception on failure
|
// rename file, throw exception on failure
|
||||||
File destination = renameFile(it.getKey(), it.getValue());
|
File destination = renameFile(it.getKey(), it.getValue());
|
||||||
|
@ -50,11 +50,11 @@ public final class HistorySpooler {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public synchronized void append(Iterable<Entry<File, String>> elements) {
|
public synchronized void append(Iterable<Entry<File, File>> elements) {
|
||||||
List<Element> sequence = new ArrayList<Element>();
|
List<Element> sequence = new ArrayList<Element>();
|
||||||
|
|
||||||
for (Entry<File, String> element : elements) {
|
for (Entry<File, File> element : elements) {
|
||||||
sequence.add(new Element(element.getKey().getName(), element.getValue(), element.getKey().getParentFile()));
|
sequence.add(new Element(element.getKey().getName(), element.getValue().getPath(), element.getKey().getParentFile()));
|
||||||
}
|
}
|
||||||
|
|
||||||
// append to session history
|
// append to session history
|
||||||
|
@ -16,6 +16,7 @@ import java.util.HashSet;
|
|||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.ListIterator;
|
import java.util.ListIterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
import java.util.AbstractMap.SimpleEntry;
|
||||||
import java.util.Map.Entry;
|
import java.util.Map.Entry;
|
||||||
|
|
||||||
import javax.swing.AbstractAction;
|
import javax.swing.AbstractAction;
|
||||||
@ -39,10 +40,10 @@ class RenameAction extends AbstractAction {
|
|||||||
|
|
||||||
|
|
||||||
public void actionPerformed(ActionEvent evt) {
|
public void actionPerformed(ActionEvent evt) {
|
||||||
List<Entry<File, String>> renameLog = new ArrayList<Entry<File, String>>();
|
List<Entry<File, File>> renameLog = new ArrayList<Entry<File, File>>();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
for (Entry<File, String> mapping : validate(model.getRenameMap(), getWindow(evt.getSource()))) {
|
for (Entry<File, File> mapping : validate(model.getRenameMap(), getWindow(evt.getSource()))) {
|
||||||
// rename file, throw exception on failure
|
// rename file, throw exception on failure
|
||||||
renameFile(mapping.getKey(), mapping.getValue());
|
renameFile(mapping.getKey(), mapping.getValue());
|
||||||
|
|
||||||
@ -59,12 +60,12 @@ class RenameAction extends AbstractAction {
|
|||||||
UILogger.warning(e.getMessage());
|
UILogger.warning(e.getMessage());
|
||||||
|
|
||||||
// revert rename operations in reverse order
|
// revert rename operations in reverse order
|
||||||
for (ListIterator<Entry<File, String>> iterator = renameLog.listIterator(renameLog.size()); iterator.hasPrevious();) {
|
for (ListIterator<Entry<File, File>> iterator = renameLog.listIterator(renameLog.size()); iterator.hasPrevious();) {
|
||||||
Entry<File, String> mapping = iterator.previous();
|
Entry<File, File> mapping = iterator.previous();
|
||||||
|
|
||||||
// revert rename
|
// revert rename
|
||||||
File original = mapping.getKey();
|
File original = mapping.getKey();
|
||||||
File current = new File(original.getParentFile(), mapping.getValue());
|
File current = new File(original.getParentFile(), mapping.getValue().getPath());
|
||||||
|
|
||||||
if (current.renameTo(original)) {
|
if (current.renameTo(original)) {
|
||||||
// remove reverted rename operation from log
|
// remove reverted rename operation from log
|
||||||
@ -100,19 +101,22 @@ class RenameAction extends AbstractAction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
private Iterable<Entry<File, String>> validate(Map<File, String> renameMap, Window parent) {
|
private Iterable<Entry<File, File>> validate(Map<File, String> renameMap, Window parent) {
|
||||||
final List<Entry<File, String>> source = new ArrayList<Entry<File, String>>(renameMap.entrySet());
|
final List<Entry<File, File>> source = new ArrayList<Entry<File, File>>(renameMap.size());
|
||||||
|
for (Entry<File, String> entry : renameMap.entrySet()) {
|
||||||
|
source.add(new SimpleEntry<File, File>(entry.getKey(), new File(entry.getValue())));
|
||||||
|
}
|
||||||
|
|
||||||
List<String> destinationFileNameView = new AbstractList<String>() {
|
List<File> destinationFileNameView = new AbstractList<File>() {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String get(int index) {
|
public File get(int index) {
|
||||||
return source.get(index).getValue();
|
return source.get(index).getValue();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String set(int index, String name) {
|
public File set(int index, File name) {
|
||||||
return source.get(index).setValue(name);
|
return source.get(index).setValue(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,5 +135,4 @@ class RenameAction extends AbstractAction {
|
|||||||
// return empty list if validation was cancelled
|
// return empty list if validation was cancelled
|
||||||
return emptyList();
|
return emptyList();
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -39,15 +39,15 @@ class ValidateDialog extends JDialog {
|
|||||||
|
|
||||||
private final JList list;
|
private final JList list;
|
||||||
|
|
||||||
private String[] model;
|
private File[] model;
|
||||||
|
|
||||||
private boolean cancelled = true;
|
private boolean cancelled = true;
|
||||||
|
|
||||||
|
|
||||||
public ValidateDialog(Window owner, Collection<String> source) {
|
public ValidateDialog(Window owner, Collection<File> source) {
|
||||||
super(owner, "Invalid Names", ModalityType.DOCUMENT_MODAL);
|
super(owner, "Invalid Names", ModalityType.DOCUMENT_MODAL);
|
||||||
|
|
||||||
model = source.toArray(new String[0]);
|
model = source.toArray(new File[0]);
|
||||||
|
|
||||||
list = new JList(model);
|
list = new JList(model);
|
||||||
list.setEnabled(false);
|
list.setEnabled(false);
|
||||||
@ -99,7 +99,7 @@ class ValidateDialog extends JDialog {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public List<String> getModel() {
|
public List<File> getModel() {
|
||||||
return unmodifiableList(Arrays.asList(model));
|
return unmodifiableList(Arrays.asList(model));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -124,7 +124,7 @@ class ValidateDialog extends JDialog {
|
|||||||
// validate names
|
// validate names
|
||||||
for (int i = 0; i < model.length; i++) {
|
for (int i = 0; i < model.length; i++) {
|
||||||
// remove illegal characters
|
// remove illegal characters
|
||||||
model[i] = validateFilePath(new File(model[i])).getPath();
|
model[i] = validateFilePath(model[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
// update view
|
// update view
|
||||||
@ -155,14 +155,12 @@ class ValidateDialog extends JDialog {
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
public static boolean validate(Component parent, List<String> source) {
|
public static boolean validate(Component parent, List<File> source) {
|
||||||
IndexView<String> invalidFilePaths = new IndexView<String>(source);
|
IndexView<File> invalidFilePaths = new IndexView<File>(source);
|
||||||
|
|
||||||
for (int i = 0; i < source.size(); i++) {
|
for (int i = 0; i < source.size(); i++) {
|
||||||
String path = source.get(i);
|
|
||||||
|
|
||||||
// invalid file names are also invalid file paths
|
// invalid file names are also invalid file paths
|
||||||
if (isInvalidFilePath(new File(path))) {
|
if (isInvalidFilePath(source.get(i))) {
|
||||||
invalidFilePaths.addIndex(i);
|
invalidFilePaths.addIndex(i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -182,7 +180,7 @@ class ValidateDialog extends JDialog {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
List<String> validatedFilePaths = dialog.getModel();
|
List<File> validatedFilePaths = dialog.getModel();
|
||||||
|
|
||||||
// validate source list via index view
|
// validate source list via index view
|
||||||
for (int i = 0; i < invalidFilePaths.size(); i++) {
|
for (int i = 0; i < invalidFilePaths.size(); i++) {
|
||||||
|
@ -30,13 +30,11 @@ import com.ibm.icu.text.CharsetMatch;
|
|||||||
|
|
||||||
public final class FileUtilities {
|
public final class FileUtilities {
|
||||||
|
|
||||||
public static File renameFile(File source, String newPath) throws IOException {
|
public static File renameFile(File source, File destination) throws IOException {
|
||||||
File destination = new File(newPath);
|
|
||||||
|
|
||||||
// resolve destination
|
// resolve destination
|
||||||
if (!destination.isAbsolute()) {
|
if (!destination.isAbsolute()) {
|
||||||
// same folder, different name
|
// same folder, different name
|
||||||
destination = new File(source.getParentFile(), newPath);
|
destination = new File(source.getParentFile(), destination.getPath());
|
||||||
}
|
}
|
||||||
|
|
||||||
// make sure we that we can create the destination folder structure
|
// make sure we that we can create the destination folder structure
|
||||||
|
Loading…
Reference in New Issue
Block a user