1
0
mirror of https://github.com/mitb-archive/filebot synced 2025-03-10 14:31:04 -04:00

* support simple File regex/replace renaming in GUI

* support loading of metadata from xattr (instead of online sources)
This commit is contained in:
Reinhard Pointner 2014-06-28 06:09:11 +00:00
parent 07568068c5
commit 7799f25a3a
4 changed files with 75 additions and 23 deletions

View File

@ -83,6 +83,8 @@ public class MediaBindingBean {
return getMovie().getName(); return getMovie().getName();
if (infoObject instanceof AudioTrack) if (infoObject instanceof AudioTrack)
return getAlbumArtist() != null ? getAlbumArtist() : getArtist(); return getAlbumArtist() != null ? getAlbumArtist() : getArtist();
if (infoObject instanceof File)
return FileUtilities.getName((File) infoObject);
return null; return null;
} }

View File

@ -58,7 +58,6 @@ import javax.swing.event.PopupMenuListener;
import javax.swing.text.AttributeSet; import javax.swing.text.AttributeSet;
import javax.swing.text.BadLocationException; import javax.swing.text.BadLocationException;
import net.miginfocom.swing.MigLayout;
import net.filebot.ResourceManager; import net.filebot.ResourceManager;
import net.filebot.Settings; import net.filebot.Settings;
import net.filebot.format.BindingException; import net.filebot.format.BindingException;
@ -78,6 +77,7 @@ import net.filebot.util.ui.notification.SeparatorBorder.Position;
import net.filebot.web.AudioTrackFormat; import net.filebot.web.AudioTrackFormat;
import net.filebot.web.EpisodeFormat; import net.filebot.web.EpisodeFormat;
import net.filebot.web.MovieFormat; import net.filebot.web.MovieFormat;
import net.miginfocom.swing.MigLayout;
import org.fife.ui.rsyntaxtextarea.RSyntaxDocument; import org.fife.ui.rsyntaxtextarea.RSyntaxDocument;
import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea; import org.fife.ui.rsyntaxtextarea.RSyntaxTextArea;
@ -111,13 +111,18 @@ public class FormatDialog extends JDialog {
private static final PreferencesEntry<String> persistentSampleFile = Settings.forPackage(FormatDialog.class).entry("format.sample.file"); private static final PreferencesEntry<String> persistentSampleFile = Settings.forPackage(FormatDialog.class).entry("format.sample.file");
public enum Mode { public enum Mode {
Episode, Movie, Music; Episode, Movie, Music, File;
public Mode next() { public Mode next() {
if (ordinal() < values().length - 1) // cycle through Episode -> Movie -> Music (but ignore generic File mode)
return values()[ordinal() + 1]; switch (this) {
case Episode:
return values()[0]; return Movie;
case Movie:
return Music;
default:
return Episode;
}
} }
public String key() { public String key() {
@ -130,8 +135,10 @@ public class FormatDialog extends JDialog {
return new EpisodeFormat(true, true); return new EpisodeFormat(true, true);
case Movie: // case Movie case Movie: // case Movie
return new MovieFormat(true, true, false); return new MovieFormat(true, true, false);
default: case Music:
return new AudioTrackFormat(); return new AudioTrackFormat();
default:
return new FileFormat();
} }
} }

View File

@ -3,6 +3,8 @@ help.url = http://www.filebot.net/naming.html
episode.syntax: <html><b>{</b> <b>}</b> \u2026 expression, <b>n</b> \u2026 name, <b>s</b> \u2026 season, <b>e</b> \u2026 episode, <b>t</b> \u2026 title</html> episode.syntax: <html><b>{</b> <b>}</b> \u2026 expression, <b>n</b> \u2026 name, <b>s</b> \u2026 season, <b>e</b> \u2026 episode, <b>t</b> \u2026 title</html>
movie.syntax: <html><b>{</b> <b>}</b> \u2026 expression, <b>n</b> \u2026 name, <b>y</b> \u2026 year</html> movie.syntax: <html><b>{</b> <b>}</b> \u2026 expression, <b>n</b> \u2026 name, <b>y</b> \u2026 year</html>
music.syntax: <html><b>{</b> <b>}</b> \u2026 expression, <b>n</b> \u2026 album artist, <b>t</b> \u2026 title, <b>album</b> \u2026 album, <b>pi</b> \u2026 track</html> music.syntax: <html><b>{</b> <b>}</b> \u2026 expression, <b>n</b> \u2026 album artist, <b>t</b> \u2026 title, <b>album</b> \u2026 album, <b>pi</b> \u2026 track</html>
file.syntax: <html><b>{</b> <b>}</b> \u2026 expression, <b>n</b> \u2026 name</html>
episode.sample: {"@type":"net.filebot.web.Episode","seriesName":"Firefly","seriesStartDate":{"year":2002,"month":9,"day":20},"season":1,"episode":1,"title":"Serenity","absolute":1,"special":null,"airdate":{"year":2002,"month":12,"day":20},"series":{"@type":"net.filebot.web.TheTVDBSearchResult","seriesId":78874,"name":"Firefly","aliasNames":[]}} episode.sample: {"@type":"net.filebot.web.Episode","seriesName":"Firefly","seriesStartDate":{"year":2002,"month":9,"day":20},"season":1,"episode":1,"title":"Serenity","absolute":1,"special":null,"airdate":{"year":2002,"month":12,"day":20},"series":{"@type":"net.filebot.web.TheTVDBSearchResult","seriesId":78874,"name":"Firefly","aliasNames":[]}}
movie.sample: {"@type":"net.filebot.web.MoviePart","partIndex":1,"partCount":2,"year":2009,"imdbId":-1,"tmdbId":19995,"name":"Avatar","aliasNames":[]} movie.sample: {"@type":"net.filebot.web.MoviePart","partIndex":1,"partCount":2,"year":2009,"imdbId":-1,"tmdbId":19995,"name":"Avatar","aliasNames":[]}
@ -40,3 +42,12 @@ music.example[2]: {n} - {t} {[audio.SamplingRateString]}
music.example[3]: {pi.pad(2)} {n} - {t} {[af, audio.BitRate]} music.example[3]: {pi.pad(2)} {n} - {t} {[af, audio.BitRate]}
# organize folder structure # organize folder structure
music.example[4]: {n}/{"$album/"}{"${pi.pad(2)}. "} {t} music.example[4]: {n}/{"$album/"}{"${pi.pad(2)}. "} {t}
# simple filename without extension
file.example[0]: {n}
# simple filename regex-replace
file.example[1]: {n.replaceAll(/\\d+/, '')}
# simple filename regex-replace
file.example[2]: {n.replaceAll(/\\p{Punct}+/, ' ')}
# simple filter
file.example[3]: {n.after('-')}

View File

@ -46,7 +46,6 @@ import javax.swing.SwingWorker;
import javax.swing.border.CompoundBorder; import javax.swing.border.CompoundBorder;
import javax.swing.border.TitledBorder; import javax.swing.border.TitledBorder;
import net.miginfocom.swing.MigLayout;
import net.filebot.History; import net.filebot.History;
import net.filebot.HistorySpooler; import net.filebot.HistorySpooler;
import net.filebot.Language; import net.filebot.Language;
@ -55,6 +54,7 @@ import net.filebot.Settings;
import net.filebot.StandardRenameAction; import net.filebot.StandardRenameAction;
import net.filebot.WebServices; import net.filebot.WebServices;
import net.filebot.format.MediaBindingBean; import net.filebot.format.MediaBindingBean;
import net.filebot.media.MediaDetection;
import net.filebot.similarity.Match; import net.filebot.similarity.Match;
import net.filebot.ui.rename.FormatDialog.Mode; import net.filebot.ui.rename.FormatDialog.Mode;
import net.filebot.ui.rename.RenameModel.FormattedFuture; import net.filebot.ui.rename.RenameModel.FormattedFuture;
@ -71,6 +71,7 @@ import net.filebot.web.MovieFormat;
import net.filebot.web.MovieIdentificationService; import net.filebot.web.MovieIdentificationService;
import net.filebot.web.MusicIdentificationService; import net.filebot.web.MusicIdentificationService;
import net.filebot.web.SortOrder; import net.filebot.web.SortOrder;
import net.miginfocom.swing.MigLayout;
import ca.odell.glazedlists.EventList; import ca.odell.glazedlists.EventList;
import ca.odell.glazedlists.ListSelection; import ca.odell.glazedlists.ListSelection;
import ca.odell.glazedlists.swing.EventSelectionModel; import ca.odell.glazedlists.swing.EventSelectionModel;
@ -90,6 +91,7 @@ public class RenamePanel extends JComponent {
private static final PreferencesEntry<String> persistentEpisodeFormat = Settings.forPackage(RenamePanel.class).entry("rename.format.episode"); private static final PreferencesEntry<String> persistentEpisodeFormat = Settings.forPackage(RenamePanel.class).entry("rename.format.episode");
private static final PreferencesEntry<String> persistentMovieFormat = Settings.forPackage(RenamePanel.class).entry("rename.format.movie"); private static final PreferencesEntry<String> persistentMovieFormat = Settings.forPackage(RenamePanel.class).entry("rename.format.movie");
private static final PreferencesEntry<String> persistentMusicFormat = Settings.forPackage(RenamePanel.class).entry("rename.format.music"); private static final PreferencesEntry<String> persistentMusicFormat = Settings.forPackage(RenamePanel.class).entry("rename.format.music");
private static final PreferencesEntry<String> persistentFileFormat = Settings.forPackage(RenamePanel.class).entry("rename.format.file");
private static final PreferencesEntry<String> persistentLastFormatState = Settings.forPackage(RenamePanel.class).entry("rename.last.format.state"); private static final PreferencesEntry<String> persistentLastFormatState = Settings.forPackage(RenamePanel.class).entry("rename.last.format.state");
private static final PreferencesEntry<String> persistentPreferredLanguage = Settings.forPackage(RenamePanel.class).entry("rename.language").defaultValue("en"); private static final PreferencesEntry<String> persistentPreferredLanguage = Settings.forPackage(RenamePanel.class).entry("rename.language").defaultValue("en");
@ -102,24 +104,34 @@ public class RenamePanel extends JComponent {
filesList.setTitle("Original Files"); filesList.setTitle("Original Files");
filesList.setTransferablePolicy(new FilesListTransferablePolicy(renameModel.files())); filesList.setTransferablePolicy(new FilesListTransferablePolicy(renameModel.files()));
// filename formatter
renameModel.useFormatter(File.class, new FileNameFormatter(renameModel.preserveExtension()));
// movie formatter
renameModel.useFormatter(Movie.class, new MovieFormatter());
try { try {
// restore custom episode formatter // restore custom episode formatter
renameModel.useFormatter(Episode.class, new ExpressionFormatter(persistentEpisodeFormat.getValue(), EpisodeFormat.SeasonEpisode, Episode.class)); renameModel.useFormatter(Episode.class, new ExpressionFormatter(persistentEpisodeFormat.getValue(), EpisodeFormat.SeasonEpisode, Episode.class));
} catch (Exception e) { } catch (Exception e) {
// illegal format, ignore // use default formatter
} }
try { try {
// restore custom movie formatter // restore custom movie formatter
renameModel.useFormatter(Movie.class, new ExpressionFormatter(persistentMovieFormat.getValue(), MovieFormat.NameYear, Movie.class)); renameModel.useFormatter(Movie.class, new ExpressionFormatter(persistentMovieFormat.getValue(), MovieFormat.NameYear, Movie.class));
} catch (Exception e) { } catch (Exception e) {
// illegal format, ignore // use default movie formatter
renameModel.useFormatter(Movie.class, new MovieFormatter());
}
try {
// restore custom music formatter
renameModel.useFormatter(AudioTrack.class, new ExpressionFormatter(persistentMusicFormat.getValue(), new AudioTrackFormat(), AudioTrack.class));
} catch (Exception e) {
// use default formatter
}
try {
// restore custom music formatter
renameModel.useFormatter(File.class, new ExpressionFormatter(persistentFileFormat.getValue(), new FileFormat(), File.class));
} catch (Exception e) {
// use default filename formatter
renameModel.useFormatter(File.class, new FileNameFormatter(renameModel.preserveExtension()));
} }
RenameListCellRenderer cellrenderer = new RenameListCellRenderer(renameModel); RenameListCellRenderer cellrenderer = new RenameListCellRenderer(renameModel);
@ -292,13 +304,26 @@ public class RenamePanel extends JComponent {
@Override @Override
public void actionPerformed(ActionEvent evt) { public void actionPerformed(ActionEvent evt) {
try { try {
int index = namesList.getListComponent().getSelectedIndex(); if (namesList.getModel().isEmpty()) {
File file = (File) filesList.getListComponent().getModel().getElementAt(index); ArrayList<File> files = new ArrayList<File>(renameModel.files());
String generatedName = namesList.getListComponent().getModel().getElementAt(index).toString(); ArrayList<Object> objects = new ArrayList<Object>(files.size());
String forcedName = showInputDialog("Enter Name:", generatedName, "Enter Name", RenamePanel.this); for (File file : files) {
if (forcedName != null && forcedName.length() > 0) { Object metaObject = MediaDetection.readMetaInfo(file);
renameModel.matches().set(index, new Match<Object, File>(forcedName, file)); objects.add(metaObject != null ? metaObject : file);
}
renameModel.clear();
renameModel.addAll(objects, files);
} else {
int index = namesList.getListComponent().getSelectedIndex();
File file = (File) filesList.getListComponent().getModel().getElementAt(index);
String generatedName = namesList.getListComponent().getModel().getElementAt(index).toString();
String forcedName = showInputDialog("Enter Name:", generatedName, "Enter Name", RenamePanel.this);
if (forcedName != null && forcedName.length() > 0) {
renameModel.matches().set(index, new Match<Object, File>(forcedName, file));
}
} }
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(RenamePanel.class.getName()).log(Level.WARNING, e.getMessage()); Logger.getLogger(RenamePanel.class.getName()).log(Level.WARNING, e.getMessage());
@ -427,8 +452,10 @@ public class RenamePanel extends JComponent {
initMode = Mode.Movie; initMode = Mode.Movie;
} else if (lockOnBinding.getInfoObject() instanceof AudioTrack) { } else if (lockOnBinding.getInfoObject() instanceof AudioTrack) {
initMode = Mode.Music; initMode = Mode.Music;
} else if (lockOnBinding.getInfoObject() instanceof File) {
initMode = Mode.File;
} else { } else {
// illegal info object => ignore // ignore objects that cannot be formatted
return; return;
} }
} else { } else {
@ -458,7 +485,12 @@ public class RenamePanel extends JComponent {
renameModel.useFormatter(AudioTrack.class, new ExpressionFormatter(dialog.getFormat().getExpression(), new AudioTrackFormat(), AudioTrack.class)); renameModel.useFormatter(AudioTrack.class, new ExpressionFormatter(dialog.getFormat().getExpression(), new AudioTrackFormat(), AudioTrack.class));
persistentMusicFormat.setValue(dialog.getFormat().getExpression()); persistentMusicFormat.setValue(dialog.getFormat().getExpression());
break; break;
case File:
renameModel.useFormatter(File.class, new ExpressionFormatter(dialog.getFormat().getExpression(), new FileFormat(), File.class));
persistentFileFormat.setValue(dialog.getFormat().getExpression());
break;
} }
if (lockOnBinding == null) { if (lockOnBinding == null) {
persistentLastFormatState.setValue(dialog.getMode().name()); persistentLastFormatState.setValue(dialog.getMode().name());
} }