* created SubtitleDescriptor/Client class hierarchy
* refactoring
This commit is contained in:
parent
aa7a236b6b
commit
b9906b6a0d
Binary file not shown.
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 22 KiB |
|
@ -18,6 +18,9 @@ public class Settings {
|
|||
|
||||
private static Settings settings = new Settings();
|
||||
|
||||
public static final String NAME = "FileBot";
|
||||
public static final String VERSION = "2.0";
|
||||
|
||||
public static final String ROOT = "filebot";
|
||||
|
||||
public static final String SELECTED_PANEL = "panel";
|
||||
|
|
Binary file not shown.
Before Width: | Height: | Size: 643 B |
|
@ -1,5 +1,5 @@
|
|||
|
||||
package net.sourceforge.filebot.ui.panel.search;
|
||||
package net.sourceforge.filebot.ui;
|
||||
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
|
@ -19,16 +19,23 @@ import javax.swing.SwingUtilities;
|
|||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
|
||||
|
||||
class TabComponentWithClose extends JPanel {
|
||||
public class FileBotTabComponent extends JPanel {
|
||||
|
||||
private JLabel label;
|
||||
private final JLabel label;
|
||||
|
||||
|
||||
public TabComponentWithClose() {
|
||||
public FileBotTabComponent() {
|
||||
this("", null);
|
||||
}
|
||||
|
||||
|
||||
public FileBotTabComponent(String title, Icon icon) {
|
||||
super(new BorderLayout(0, 0));
|
||||
setOpaque(false);
|
||||
|
||||
label = new JLabel("", SwingConstants.LEFT);
|
||||
label = new JLabel(title, SwingConstants.LEFT);
|
||||
label.setIcon(icon);
|
||||
|
||||
label.setBorder(BorderFactory.createEmptyBorder(0, 0, 0, 2));
|
||||
|
||||
add(label, BorderLayout.CENTER);
|
||||
|
@ -52,8 +59,8 @@ class TabComponentWithClose extends JPanel {
|
|||
|
||||
|
||||
public void close() {
|
||||
JTabbedPane tabs = (JTabbedPane) SwingUtilities.getAncestorOfClass(JTabbedPane.class, TabComponentWithClose.this);
|
||||
tabs.removeTabAt(tabs.indexOfTabComponent(TabComponentWithClose.this));
|
||||
JTabbedPane tabs = (JTabbedPane) SwingUtilities.getAncestorOfClass(JTabbedPane.class, FileBotTabComponent.this);
|
||||
tabs.removeTabAt(tabs.indexOfTabComponent(FileBotTabComponent.this));
|
||||
}
|
||||
|
||||
private final AbstractAction tabCloseAction = new AbstractAction(null, null) {
|
|
@ -40,7 +40,7 @@ public class FileBotWindow extends JFrame implements ListSelectionListener {
|
|||
|
||||
|
||||
public FileBotWindow() {
|
||||
super("FileBot");
|
||||
super(Settings.NAME);
|
||||
setLocationByPlatform(true);
|
||||
setDefaultCloseOperation(EXIT_ON_CLOSE);
|
||||
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
|
||||
package net.sourceforge.filebot.ui;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridLayout;
|
||||
import java.net.URL;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.Border;
|
||||
|
||||
import net.sourceforge.tuned.ui.HyperlinkLabel;
|
||||
|
||||
|
||||
public class HistoryPanel extends JPanel {
|
||||
|
||||
private JPanel grid = new JPanel(new GridLayout(0, 3, 15, 10));
|
||||
|
||||
|
||||
public HistoryPanel(String titleHeader, String infoHeader) {
|
||||
setLayout(new FlowLayout(FlowLayout.CENTER));
|
||||
|
||||
JScrollPane scrollPane = new JScrollPane(grid, ScrollPaneConstants.VERTICAL_SCROLLBAR_AS_NEEDED, ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
scrollPane.setBorder(BorderFactory.createEmptyBorder());
|
||||
|
||||
add(grid);
|
||||
|
||||
setBackground(Color.WHITE);
|
||||
setOpaque(true);
|
||||
grid.setOpaque(false);
|
||||
|
||||
JLabel titleLabel = new JLabel(titleHeader);
|
||||
JLabel infoLabel = new JLabel(infoHeader);
|
||||
JLabel durationLabel = new JLabel("Duration");
|
||||
|
||||
Font font = titleLabel.getFont().deriveFont(Font.BOLD);
|
||||
|
||||
titleLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
infoLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
durationLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
|
||||
titleLabel.setFont(font);
|
||||
infoLabel.setFont(font);
|
||||
durationLabel.setFont(font);
|
||||
|
||||
grid.add(titleLabel);
|
||||
grid.add(infoLabel);
|
||||
grid.add(durationLabel);
|
||||
}
|
||||
|
||||
private final Border infoBorder = BorderFactory.createEmptyBorder(0, 0, 0, 10);
|
||||
|
||||
|
||||
public void add(String title, URL url, String info, long duration, Icon icon) {
|
||||
|
||||
String durationString = NumberFormat.getInstance().format(duration) + " ms";
|
||||
|
||||
JLabel titleLabel = (url != null) ? new HyperlinkLabel(title, url) : new JLabel(title);
|
||||
JLabel infoLabel = new JLabel(info);
|
||||
JLabel durationLabel = new JLabel(durationString);
|
||||
|
||||
infoLabel.setBorder(infoBorder);
|
||||
|
||||
titleLabel.setHorizontalAlignment(SwingConstants.LEFT);
|
||||
infoLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
durationLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
|
||||
titleLabel.setIcon(icon);
|
||||
titleLabel.setIconTextGap(7);
|
||||
|
||||
grid.add(titleLabel);
|
||||
grid.add(infoLabel);
|
||||
grid.add(durationLabel);
|
||||
}
|
||||
|
||||
}
|
|
@ -6,11 +6,12 @@ import javax.swing.ImageIcon;
|
|||
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.ui.FileBotList;
|
||||
import net.sourceforge.filebot.ui.FileBotTabComponent;
|
||||
|
||||
|
||||
class EpisodeListPanel extends FileBotList {
|
||||
public class EpisodeListPanel extends FileBotList {
|
||||
|
||||
private final TabComponentWithClose tabComponent = new TabComponentWithClose();
|
||||
private final FileBotTabComponent tabComponent = new FileBotTabComponent();
|
||||
|
||||
private ImageIcon icon;
|
||||
|
||||
|
@ -22,7 +23,7 @@ class EpisodeListPanel extends FileBotList {
|
|||
}
|
||||
|
||||
|
||||
public TabComponentWithClose getTabComponent() {
|
||||
public FileBotTabComponent getTabComponent() {
|
||||
return tabComponent;
|
||||
}
|
||||
|
||||
|
|
|
@ -1,86 +0,0 @@
|
|||
|
||||
package net.sourceforge.filebot.ui.panel.search;
|
||||
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.FlowLayout;
|
||||
import java.awt.Font;
|
||||
import java.awt.GridLayout;
|
||||
import java.net.URL;
|
||||
import java.text.NumberFormat;
|
||||
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Icon;
|
||||
import javax.swing.JLabel;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.border.Border;
|
||||
|
||||
import net.sourceforge.tuned.ui.HyperlinkLabel;
|
||||
|
||||
|
||||
class HistoryPanel extends JPanel {
|
||||
|
||||
private JPanel grid = new JPanel(new GridLayout(0, 3, 15, 10));
|
||||
|
||||
|
||||
public HistoryPanel() {
|
||||
setLayout(new FlowLayout(FlowLayout.CENTER));
|
||||
|
||||
add(grid);
|
||||
|
||||
setBackground(Color.WHITE);
|
||||
setOpaque(true);
|
||||
grid.setOpaque(false);
|
||||
|
||||
JLabel linkLabel = new JLabel("Show");
|
||||
JLabel numberLabel = new JLabel("Number of Episodes");
|
||||
JLabel durationLabel = new JLabel("Duration");
|
||||
|
||||
Font font = linkLabel.getFont().deriveFont(Font.BOLD);
|
||||
|
||||
linkLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
numberLabel.setHorizontalAlignment(SwingConstants.CENTER);
|
||||
durationLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
|
||||
linkLabel.setFont(font);
|
||||
numberLabel.setFont(font);
|
||||
durationLabel.setFont(font);
|
||||
|
||||
grid.add(linkLabel);
|
||||
grid.add(numberLabel);
|
||||
grid.add(durationLabel);
|
||||
}
|
||||
|
||||
private Border numberBorder = BorderFactory.createEmptyBorder(0, 0, 0, 10);
|
||||
|
||||
|
||||
public void add(String show, URL url, int number, long duration, Icon searchEngineIcon) {
|
||||
String numberString = null;
|
||||
|
||||
if (number > 0)
|
||||
numberString = Integer.toString(number) + " episodes";
|
||||
else
|
||||
numberString = "No episodes found";
|
||||
|
||||
String durationString = NumberFormat.getInstance().format(duration) + " ms";
|
||||
|
||||
JLabel linkLabel = new HyperlinkLabel(show, url);
|
||||
JLabel numberLabel = new JLabel(numberString);
|
||||
JLabel durationLabel = new JLabel(durationString);
|
||||
|
||||
numberLabel.setBorder(numberBorder);
|
||||
|
||||
linkLabel.setHorizontalAlignment(SwingConstants.LEFT);
|
||||
numberLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
durationLabel.setHorizontalAlignment(SwingConstants.RIGHT);
|
||||
|
||||
linkLabel.setIcon(searchEngineIcon);
|
||||
linkLabel.setIconTextGap(7);
|
||||
|
||||
grid.add(linkLabel);
|
||||
grid.add(numberLabel);
|
||||
grid.add(durationLabel);
|
||||
}
|
||||
|
||||
}
|
|
@ -21,11 +21,9 @@ import javax.swing.BorderFactory;
|
|||
import javax.swing.Box;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JScrollPane;
|
||||
import javax.swing.JSpinner;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.ScrollPaneConstants;
|
||||
import javax.swing.SpinnerNumberModel;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
|
@ -36,6 +34,7 @@ import net.sourceforge.filebot.FileBotUtil;
|
|||
import net.sourceforge.filebot.Settings;
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.ui.FileBotPanel;
|
||||
import net.sourceforge.filebot.ui.HistoryPanel;
|
||||
import net.sourceforge.filebot.ui.MessageManager;
|
||||
import net.sourceforge.filebot.ui.SelectDialog;
|
||||
import net.sourceforge.filebot.ui.transfer.SaveAction;
|
||||
|
@ -52,7 +51,7 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
private JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
|
||||
|
||||
private HistoryPanel history = new HistoryPanel();
|
||||
private HistoryPanel historyPanel = new HistoryPanel("Show", "Number of Episodes");
|
||||
|
||||
private SpinnerNumberModel seasonSpinnerModel = new SpinnerNumberModel(SeasonSpinnerEditor.ALL_SEASONS, SeasonSpinnerEditor.ALL_SEASONS, Integer.MAX_VALUE, 1);
|
||||
|
||||
|
@ -60,8 +59,6 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
private TextCompletion searchFieldCompletion;
|
||||
|
||||
private JSpinner seasonSpinner;
|
||||
|
||||
|
||||
public SearchPanel() {
|
||||
super("Search", ResourceManager.getIcon("panel.search"));
|
||||
|
@ -85,7 +82,7 @@ public class SearchPanel extends FileBotPanel {
|
|||
Box searchBox = Box.createHorizontalBox();
|
||||
searchBox.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
|
||||
seasonSpinner = new JSpinner(seasonSpinnerModel);
|
||||
JSpinner seasonSpinner = new JSpinner(seasonSpinnerModel);
|
||||
seasonSpinner.setEditor(new SeasonSpinnerEditor(seasonSpinner));
|
||||
searchField.setMaximumSize(searchField.getPreferredSize());
|
||||
seasonSpinner.setMaximumSize(seasonSpinner.getPreferredSize());
|
||||
|
@ -110,11 +107,7 @@ public class SearchPanel extends FileBotPanel {
|
|||
centerPanel.add(tabbedPane, BorderLayout.CENTER);
|
||||
centerPanel.add(buttonBox, BorderLayout.SOUTH);
|
||||
|
||||
JScrollPane sp = new JScrollPane(history);
|
||||
sp.setBorder(BorderFactory.createEmptyBorder());
|
||||
sp.setHorizontalScrollBarPolicy(ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER);
|
||||
|
||||
tabbedPane.addTab("History", ResourceManager.getIcon("tab.history"), sp);
|
||||
tabbedPane.addTab("History", ResourceManager.getIcon("tab.history"), historyPanel);
|
||||
|
||||
mainPanel.add(searchBox, BorderLayout.NORTH);
|
||||
mainPanel.add(centerPanel, BorderLayout.CENTER);
|
||||
|
@ -124,8 +117,8 @@ public class SearchPanel extends FileBotPanel {
|
|||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("ENTER"), searchAction);
|
||||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("UP"), upAction);
|
||||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("DOWN"), downAction);
|
||||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("shift UP"), new SpinSearchEngineAction(-1));
|
||||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("shift DOWN"), new SpinSearchEngineAction(1));
|
||||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("shift UP"), new SpinClientAction(-1));
|
||||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("shift DOWN"), new SpinClientAction(1));
|
||||
}
|
||||
|
||||
|
||||
|
@ -213,13 +206,12 @@ public class SearchPanel extends FileBotPanel {
|
|||
};
|
||||
|
||||
|
||||
private class SpinSearchEngineAction extends AbstractAction {
|
||||
private class SpinClientAction extends AbstractAction {
|
||||
|
||||
private int spin;
|
||||
|
||||
|
||||
public SpinSearchEngineAction(int spin) {
|
||||
super("Spin Search Engine");
|
||||
public SpinClientAction(int spin) {
|
||||
this.spin = spin;
|
||||
}
|
||||
|
||||
|
@ -232,36 +224,21 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
private class SearchTask extends SwingWorker<List<String>, Object> {
|
||||
|
||||
private String searchTerm;
|
||||
private EpisodeListClient searchEngine;
|
||||
private String query;
|
||||
private EpisodeListClient client;
|
||||
private int numberOfSeason;
|
||||
|
||||
|
||||
public SearchTask(EpisodeListClient searchEngine, String searchterm, int numberOfSeason) {
|
||||
searchTerm = searchterm;
|
||||
this.searchEngine = searchEngine;
|
||||
public SearchTask(EpisodeListClient client, String query, int numberOfSeason) {
|
||||
this.query = query;
|
||||
this.client = client;
|
||||
this.numberOfSeason = numberOfSeason;
|
||||
}
|
||||
|
||||
|
||||
public String getSearchTerm() {
|
||||
return searchTerm;
|
||||
}
|
||||
|
||||
|
||||
public int getNumberOfSeason() {
|
||||
return numberOfSeason;
|
||||
}
|
||||
|
||||
|
||||
public EpisodeListClient getSearchEngine() {
|
||||
return searchEngine;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected List<String> doInBackground() throws Exception {
|
||||
return searchEngine.search(searchTerm);
|
||||
return client.search(query);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -278,14 +255,14 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
episodeList = new EpisodeListPanel();
|
||||
|
||||
String title = task.getSearchTerm();
|
||||
String title = task.query;
|
||||
|
||||
if (task.getNumberOfSeason() != SeasonSpinnerEditor.ALL_SEASONS) {
|
||||
title += String.format(" - Season %d", task.getNumberOfSeason());
|
||||
if (task.numberOfSeason != SeasonSpinnerEditor.ALL_SEASONS) {
|
||||
title += String.format(" - Season %d", task.numberOfSeason);
|
||||
}
|
||||
|
||||
episodeList.setTitle(title);
|
||||
episodeList.setIcon(task.getSearchEngine().getIcon());
|
||||
episodeList.setIcon(task.client.getIcon());
|
||||
|
||||
tabbedPane.addTab(title, episodeList);
|
||||
tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(episodeList), episodeList.getTabComponent());
|
||||
|
@ -319,9 +296,9 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
String showname = null;
|
||||
|
||||
if (task.getSearchEngine().getFoundName(task.getSearchTerm()) != null) {
|
||||
if (task.client.getFoundName(task.query) != null) {
|
||||
// a show matching the search term exactly has already been found
|
||||
showname = task.getSearchEngine().getFoundName(task.getSearchTerm());
|
||||
showname = task.client.getFoundName(task.query);
|
||||
} else if (shows.size() == 1) {
|
||||
// only one show found, select this one
|
||||
showname = shows.get(0);
|
||||
|
@ -337,7 +314,7 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
showname = select.getSelectedValue();
|
||||
} else {
|
||||
MessageManager.showWarning("\"" + task.getSearchTerm() + "\" has not been found.");
|
||||
MessageManager.showWarning("\"" + task.query + "\" has not been found.");
|
||||
}
|
||||
|
||||
if (showname == null) {
|
||||
|
@ -350,13 +327,13 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
String title = showname;
|
||||
|
||||
if (task.getNumberOfSeason() != SeasonSpinnerEditor.ALL_SEASONS) {
|
||||
title += String.format(" - Season %d", task.getNumberOfSeason());
|
||||
if (task.numberOfSeason != SeasonSpinnerEditor.ALL_SEASONS) {
|
||||
title += String.format(" - Season %d", task.numberOfSeason);
|
||||
}
|
||||
|
||||
episodeList.setTitle(title);
|
||||
|
||||
FetchEpisodeListTask getEpisodesTask = new FetchEpisodeListTask(task.getSearchEngine(), showname, task.getNumberOfSeason());
|
||||
FetchEpisodeListTask getEpisodesTask = new FetchEpisodeListTask(task.client, showname, task.numberOfSeason);
|
||||
getEpisodesTask.addPropertyChangeListener(new FetchEpisodeListTaskListener(episodeList));
|
||||
|
||||
getEpisodesTask.execute();
|
||||
|
@ -387,13 +364,14 @@ public class SearchPanel extends FileBotPanel {
|
|||
|
||||
Collection<Episode> episodes = task.get();
|
||||
|
||||
history.add(episodeList.getTitle(), url, episodes.size(), task.getDuration(), episodeList.getIcon());
|
||||
String info = (episodes.size() > 0) ? String.format("%d episodes", episodes.size()) : "No episodes found";
|
||||
|
||||
historyPanel.add(episodeList.getTitle(), url, info, task.getDuration(), episodeList.getIcon());
|
||||
|
||||
if (episodes.size() <= 0)
|
||||
tabbedPane.remove(episodeList);
|
||||
else {
|
||||
episodeList.setLoading(false);
|
||||
|
||||
episodeList.getModel().addAll(episodes);
|
||||
}
|
||||
} catch (Exception e) {
|
||||
|
@ -403,7 +381,6 @@ public class SearchPanel extends FileBotPanel {
|
|||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,121 +0,0 @@
|
|||
|
||||
package net.sourceforge.filebot.ui.panel.subtitle;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Node;
|
||||
import org.w3c.dom.NodeList;
|
||||
|
||||
|
||||
public class Language {
|
||||
|
||||
public static List<Language> languages = null;
|
||||
|
||||
|
||||
public static synchronized List<Language> getLanguages() {
|
||||
if (languages == null) {
|
||||
languages = parseLanguages();
|
||||
}
|
||||
|
||||
return Collections.unmodifiableList(languages);
|
||||
}
|
||||
|
||||
|
||||
public static Language forName(String name) {
|
||||
for (Language language : getLanguages()) {
|
||||
for (String languageName : language.getNames()) {
|
||||
if (name.equalsIgnoreCase(languageName))
|
||||
return language;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
public static Language forCountryCode(String countryCode) {
|
||||
for (Language language : getLanguages()) {
|
||||
if (countryCode.equalsIgnoreCase(language.getCountryCode()))
|
||||
return language;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private static List<Language> parseLanguages() {
|
||||
List<Language> languages = new ArrayList<Language>();
|
||||
|
||||
try {
|
||||
Document dom = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(Language.class.getResourceAsStream("languages.xml"));
|
||||
|
||||
NodeList languageNodes = dom.getDocumentElement().getChildNodes();
|
||||
|
||||
for (int i = 0; i < languageNodes.getLength(); i++) {
|
||||
Node languageNode = languageNodes.item(i);
|
||||
|
||||
if (!languageNode.getNodeName().equals("language"))
|
||||
continue;
|
||||
|
||||
String countryCode = null;
|
||||
ArrayList<String> names = new ArrayList<String>();
|
||||
|
||||
NodeList nodes = languageNode.getChildNodes();
|
||||
|
||||
for (int j = 0; j < nodes.getLength(); j++) {
|
||||
Node node = nodes.item(j);
|
||||
|
||||
if ((countryCode == null) && node.getNodeName().equals("code"))
|
||||
countryCode = node.getTextContent();
|
||||
else if (node.getNodeName().equals("name"))
|
||||
names.add(node.getTextContent());
|
||||
}
|
||||
|
||||
languages.add(new Language(countryCode, names));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
|
||||
return languages;
|
||||
}
|
||||
|
||||
private List<String> names;
|
||||
private String countryCode;
|
||||
|
||||
|
||||
public Language(String countryCode, Collection<String> names) {
|
||||
if (names.isEmpty())
|
||||
throw new IllegalArgumentException("List must not be empty");
|
||||
|
||||
this.countryCode = countryCode;
|
||||
|
||||
this.names = new ArrayList<String>(names);
|
||||
}
|
||||
|
||||
|
||||
public String getCountryCode() {
|
||||
return countryCode;
|
||||
}
|
||||
|
||||
|
||||
public Iterable<String> getNames() {
|
||||
return names;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("[%s] %s", countryCode, names.get(0));
|
||||
}
|
||||
|
||||
}
|
|
@ -2,15 +2,318 @@
|
|||
package net.sourceforge.filebot.ui.panel.subtitle;
|
||||
|
||||
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Window;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.beans.PropertyChangeEvent;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import javax.swing.AbstractAction;
|
||||
import javax.swing.BorderFactory;
|
||||
import javax.swing.Box;
|
||||
import javax.swing.JButton;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.JTabbedPane;
|
||||
import javax.swing.KeyStroke;
|
||||
import javax.swing.SwingConstants;
|
||||
import javax.swing.SwingUtilities;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.border.EmptyBorder;
|
||||
|
||||
import net.sourceforge.filebot.FileBotUtil;
|
||||
import net.sourceforge.filebot.Settings;
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.filebot.ui.FileBotPanel;
|
||||
import net.sourceforge.filebot.ui.FileBotTabComponent;
|
||||
import net.sourceforge.filebot.ui.HistoryPanel;
|
||||
import net.sourceforge.filebot.ui.MessageManager;
|
||||
import net.sourceforge.filebot.ui.SelectDialog;
|
||||
import net.sourceforge.filebot.web.MovieDescriptor;
|
||||
import net.sourceforge.filebot.web.SubtitleClient;
|
||||
import net.sourceforge.filebot.web.SubtitleDescriptor;
|
||||
import net.sourceforge.tuned.ui.SelectButton;
|
||||
import net.sourceforge.tuned.ui.SwingWorkerPropertyChangeAdapter;
|
||||
import net.sourceforge.tuned.ui.TextCompletion;
|
||||
import net.sourceforge.tuned.ui.TextFieldWithSelect;
|
||||
|
||||
|
||||
public class SubtitlePanel extends FileBotPanel {
|
||||
|
||||
private JTabbedPane tabbedPane = new JTabbedPane(SwingConstants.TOP, JTabbedPane.SCROLL_TAB_LAYOUT);
|
||||
|
||||
private HistoryPanel historyPanel = new HistoryPanel("Show / Movie", "Number of Subtitles");
|
||||
|
||||
private TextFieldWithSelect<SubtitleClient> searchField;
|
||||
|
||||
private TextCompletion searchFieldCompletion;
|
||||
|
||||
|
||||
public SubtitlePanel() {
|
||||
super("Subtitle", ResourceManager.getIcon("panel.subtitle"));
|
||||
|
||||
List<SelectButton.Entry<SubtitleClient>> clients = new ArrayList<SelectButton.Entry<SubtitleClient>>();
|
||||
|
||||
for (SubtitleClient client : SubtitleClient.getAvailableSubtitleClients()) {
|
||||
clients.add(new SelectButton.Entry<SubtitleClient>(client, client.getIcon()));
|
||||
}
|
||||
|
||||
searchField = new TextFieldWithSelect<SubtitleClient>(clients);
|
||||
searchField.getTextField().setColumns(25);
|
||||
|
||||
searchFieldCompletion = new TextCompletion(searchField.getTextField());
|
||||
searchFieldCompletion.addTerms(Settings.getSettings().getStringList(Settings.SUBTITLE_HISTORY));
|
||||
searchFieldCompletion.hook();
|
||||
|
||||
JPanel mainPanel = new JPanel(new BorderLayout(5, 5));
|
||||
|
||||
Box searchBox = Box.createHorizontalBox();
|
||||
searchBox.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
|
||||
searchField.setMaximumSize(searchField.getPreferredSize());
|
||||
|
||||
searchBox.add(Box.createHorizontalGlue());
|
||||
searchBox.add(searchField);
|
||||
searchBox.add(Box.createHorizontalStrut(15));
|
||||
searchBox.add(new JButton(searchAction));
|
||||
searchBox.add(Box.createHorizontalGlue());
|
||||
|
||||
JPanel centerPanel = new JPanel(new BorderLayout());
|
||||
centerPanel.setBorder(BorderFactory.createTitledBorder("Search Results"));
|
||||
|
||||
Box buttonBox = Box.createHorizontalBox();
|
||||
buttonBox.setBorder(new EmptyBorder(5, 5, 5, 5));
|
||||
buttonBox.add(Box.createHorizontalGlue());
|
||||
buttonBox.add(new JButton(saveAction));
|
||||
buttonBox.add(Box.createHorizontalGlue());
|
||||
|
||||
centerPanel.add(tabbedPane, BorderLayout.CENTER);
|
||||
centerPanel.add(buttonBox, BorderLayout.SOUTH);
|
||||
|
||||
tabbedPane.addTab("History", ResourceManager.getIcon("tab.history"), historyPanel);
|
||||
|
||||
mainPanel.add(searchBox, BorderLayout.NORTH);
|
||||
mainPanel.add(centerPanel, BorderLayout.CENTER);
|
||||
|
||||
this.add(mainPanel, BorderLayout.CENTER);
|
||||
|
||||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("ENTER"), searchAction);
|
||||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("shift UP"), new SpinClientAction(-1));
|
||||
FileBotUtil.registerActionForKeystroke(this, KeyStroke.getKeyStroke("shift DOWN"), new SpinClientAction(1));
|
||||
}
|
||||
|
||||
|
||||
private class SpinClientAction extends AbstractAction {
|
||||
|
||||
private int spin;
|
||||
|
||||
|
||||
public SpinClientAction(int spin) {
|
||||
this.spin = spin;
|
||||
}
|
||||
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
searchField.getSelectButton().spinValue(spin);
|
||||
}
|
||||
}
|
||||
|
||||
private final AbstractAction searchAction = new AbstractAction("Find", ResourceManager.getIcon("action.find")) {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
searchField.clearTextSelection();
|
||||
|
||||
SearchTask searchTask = new SearchTask(searchField.getSelectedValue(), searchField.getTextField().getText());
|
||||
searchTask.addPropertyChangeListener(new SearchTaskListener());
|
||||
|
||||
searchTask.execute();
|
||||
}
|
||||
};
|
||||
|
||||
private final AbstractAction saveAction = new AbstractAction("Down") {
|
||||
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
//TODO save action
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
private class SearchTask extends SwingWorker<List<MovieDescriptor>, Object> {
|
||||
|
||||
private final String query;
|
||||
private final SubtitleClient client;
|
||||
|
||||
|
||||
public SearchTask(SubtitleClient client, String query) {
|
||||
this.client = client;
|
||||
this.query = query;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected List<MovieDescriptor> doInBackground() throws Exception {
|
||||
return client.search(query);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private class SearchTaskListener extends SwingWorkerPropertyChangeAdapter {
|
||||
|
||||
private SubtitleListPanel subtitleSearchResultPanel;
|
||||
private FileBotTabComponent tabComponent;
|
||||
|
||||
|
||||
@Override
|
||||
public void started(PropertyChangeEvent evt) {
|
||||
SearchTask task = (SearchTask) evt.getSource();
|
||||
|
||||
subtitleSearchResultPanel = new SubtitleListPanel();
|
||||
tabComponent = new FileBotTabComponent(task.query, ResourceManager.getIcon("tab.loading"));
|
||||
|
||||
tabbedPane.addTab(task.query, subtitleSearchResultPanel);
|
||||
tabbedPane.setTabComponentAt(tabbedPane.indexOfComponent(subtitleSearchResultPanel), tabComponent);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void done(PropertyChangeEvent evt) {
|
||||
// tab might have been closed
|
||||
if (tabbedPane.indexOfComponent(subtitleSearchResultPanel) < 0)
|
||||
return;
|
||||
|
||||
SearchTask searchTask = (SearchTask) evt.getSource();
|
||||
|
||||
try {
|
||||
List<MovieDescriptor> desriptors = searchTask.get();
|
||||
|
||||
MovieDescriptor descriptor = selectDescriptor(desriptors, searchTask.client);
|
||||
|
||||
if (descriptor == null) {
|
||||
if (desriptors.isEmpty()) {
|
||||
MessageManager.showWarning(String.format("\"%s\" has not been found.", searchTask.query));
|
||||
}
|
||||
|
||||
tabbedPane.remove(subtitleSearchResultPanel);
|
||||
return;
|
||||
}
|
||||
|
||||
fetchSubtitles(descriptor, searchTask.client);
|
||||
|
||||
} catch (Exception e) {
|
||||
tabbedPane.remove(subtitleSearchResultPanel);
|
||||
|
||||
Throwable cause = FileBotUtil.getRootCause(e);
|
||||
|
||||
MessageManager.showWarning(cause.getMessage());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.WARNING, cause.toString());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
private MovieDescriptor selectDescriptor(List<MovieDescriptor> descriptors, SubtitleClient client) {
|
||||
switch (descriptors.size()) {
|
||||
case 0:
|
||||
return null;
|
||||
case 1:
|
||||
return descriptors.get(0);
|
||||
}
|
||||
|
||||
// multiple shows found, let user selected one
|
||||
Window window = SwingUtilities.getWindowAncestor(SubtitlePanel.this);
|
||||
|
||||
SelectDialog<MovieDescriptor> selectDialog = new SelectDialog<MovieDescriptor>(window, descriptors);
|
||||
|
||||
selectDialog.setText("Select a Show / Movie:");
|
||||
selectDialog.setIconImage(client.getIcon().getImage());
|
||||
selectDialog.setVisible(true);
|
||||
|
||||
// selected value or null if cancelled by the user
|
||||
return selectDialog.getSelectedValue();
|
||||
}
|
||||
|
||||
|
||||
private void fetchSubtitles(MovieDescriptor descriptor, SubtitleClient client) {
|
||||
|
||||
Settings.getSettings().putStringList(Settings.SUBTITLE_HISTORY, searchFieldCompletion.getTerms());
|
||||
searchFieldCompletion.addTerm(descriptor.getTitle());
|
||||
|
||||
tabComponent.setText(descriptor.getTitle());
|
||||
|
||||
FetchSubtitleListTask fetchListTask = new FetchSubtitleListTask(descriptor, client);
|
||||
fetchListTask.addPropertyChangeListener(new FetchSubtitleListTaskListener(subtitleSearchResultPanel, tabComponent));
|
||||
|
||||
fetchListTask.execute();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class FetchSubtitleListTask extends SwingWorker<List<? extends SubtitleDescriptor>, Object> {
|
||||
|
||||
private final SubtitleClient client;
|
||||
private final MovieDescriptor descriptor;
|
||||
|
||||
|
||||
public FetchSubtitleListTask(MovieDescriptor descriptor, SubtitleClient client) {
|
||||
this.descriptor = descriptor;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
protected List<? extends SubtitleDescriptor> doInBackground() throws Exception {
|
||||
return client.getSubtitleList(descriptor);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class FetchSubtitleListTaskListener extends SwingWorkerPropertyChangeAdapter {
|
||||
|
||||
private final SubtitleListPanel subtitleSearchResultPanel;
|
||||
private final FileBotTabComponent tabComponent;
|
||||
|
||||
|
||||
public FetchSubtitleListTaskListener(SubtitleListPanel subtitleSearchResultPanel, FileBotTabComponent tabComponent) {
|
||||
this.subtitleSearchResultPanel = subtitleSearchResultPanel;
|
||||
this.tabComponent = tabComponent;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void done(PropertyChangeEvent evt) {
|
||||
// tab might have been closed
|
||||
if (tabbedPane.indexOfComponent(subtitleSearchResultPanel) < 0)
|
||||
return;
|
||||
|
||||
FetchSubtitleListTask task = (FetchSubtitleListTask) evt.getSource();
|
||||
|
||||
try {
|
||||
List<? extends SubtitleDescriptor> subtitleDescriptors = task.get();
|
||||
|
||||
String info = (subtitleDescriptors.size() > 0) ? String.format("%d subtitles", subtitleDescriptors.size()) : "No subtitles found";
|
||||
|
||||
historyPanel.add(task.descriptor.toString(), null, info, 0, task.client.getIcon());
|
||||
|
||||
if (subtitleDescriptors.isEmpty()) {
|
||||
tabbedPane.remove(subtitleSearchResultPanel);
|
||||
return;
|
||||
}
|
||||
|
||||
tabComponent.setIcon(task.client.getIcon());
|
||||
|
||||
//TODO icon view
|
||||
//TODO sysout
|
||||
System.out.println(subtitleDescriptors);
|
||||
} catch (Exception e) {
|
||||
tabbedPane.remove(subtitleSearchResultPanel);
|
||||
|
||||
MessageManager.showWarning(FileBotUtil.getRootCause(e).getMessage());
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.SEVERE, e.toString(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,777 +0,0 @@
|
|||
<?xml version="1.0" encoding="UTF-8" ?>
|
||||
<languages>
|
||||
<language>
|
||||
<code>aa</code>
|
||||
<name>Afar</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ab</code>
|
||||
<name>Abkhazian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>af</code>
|
||||
<name>Afrikaans</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ak</code>
|
||||
<name>Akan</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sq</code>
|
||||
<name>Albanian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>am</code>
|
||||
<name>Amharic</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ar</code>
|
||||
<name>Arabic</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>an</code>
|
||||
<name>Aragonese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>hy</code>
|
||||
<name>Armenian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>as</code>
|
||||
<name>Assamese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>av</code>
|
||||
<name>Avaric</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ae</code>
|
||||
<name>Avestan</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ay</code>
|
||||
<name>Aymara</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>az</code>
|
||||
<name>Azerbaijani</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ba</code>
|
||||
<name>Bashkir</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>bm</code>
|
||||
<name>Bambara</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>eu</code>
|
||||
<name>Basque</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>be</code>
|
||||
<name>Belarusian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>bn</code>
|
||||
<name>Bengali</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>bh</code>
|
||||
<name>Bihari</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>bi</code>
|
||||
<name>Bislama</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>bs</code>
|
||||
<name>Bosnian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>br</code>
|
||||
<name>Breton</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>bg</code>
|
||||
<name>Bulgarian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>my</code>
|
||||
<name>Burmese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ca</code>
|
||||
<name>Catalan</name>
|
||||
<name>Valencian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ch</code>
|
||||
<name>Chamorro</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ce</code>
|
||||
<name>Chechen</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>zh</code>
|
||||
<name>Chinese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>cu</code>
|
||||
<name>Church Slavic</name>
|
||||
<name>Old Slavonic</name>
|
||||
<name>Church Slavonic</name>
|
||||
<name>Old Bulgarian</name>
|
||||
<name>Old Church Slavonic</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>cv</code>
|
||||
<name>Chuvash</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>kw</code>
|
||||
<name>Cornish</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>co</code>
|
||||
<name>Corsican</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>cr</code>
|
||||
<name>Cree</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>cs</code>
|
||||
<name>Czech</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>da</code>
|
||||
<name>Danish</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>dv</code>
|
||||
<name>Divehi</name>
|
||||
<name>Dhivehi</name>
|
||||
<name>Maldivian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>nl</code>
|
||||
<name>Dutch</name>
|
||||
<name>Flemish</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>dz</code>
|
||||
<name>Dzongkha</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>en</code>
|
||||
<name>English</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>eo</code>
|
||||
<name>Esperanto</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>et</code>
|
||||
<name>Estonian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ee</code>
|
||||
<name>Ewe</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>fo</code>
|
||||
<name>Faroese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>fj</code>
|
||||
<name>Fijian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>fi</code>
|
||||
<name>Finnish</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>fr</code>
|
||||
<name>French</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>fy</code>
|
||||
<name>Western Frisian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ff</code>
|
||||
<name>Fulah</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ka</code>
|
||||
<name>Georgian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>de</code>
|
||||
<name>German</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>gd</code>
|
||||
<name>Gaelic</name>
|
||||
<name>Scottish Gaelic</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ga</code>
|
||||
<name>Irish</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>gl</code>
|
||||
<name>Galician</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>gv</code>
|
||||
<name>Manx</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>el</code>
|
||||
<name>Greek</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>gn</code>
|
||||
<name>Guarani</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>gu</code>
|
||||
<name>Gujarati</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ht</code>
|
||||
<name>Haitian</name>
|
||||
<name>Haitian Creole</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ha</code>
|
||||
<name>Hausa</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>he</code>
|
||||
<name>Hebrew</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>hz</code>
|
||||
<name>Herero</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>hi</code>
|
||||
<name>Hindi</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ho</code>
|
||||
<name>Hiri Motu</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>hu</code>
|
||||
<name>Hungarian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ig</code>
|
||||
<name>Igbo</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>is</code>
|
||||
<name>Icelandic</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>io</code>
|
||||
<name>Ido</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ii</code>
|
||||
<name>Sichuan Yi</name>
|
||||
<name>Nuosu</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>iu</code>
|
||||
<name>Inuktitut</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ie</code>
|
||||
<name>Interlingue</name>
|
||||
<name>Occidental</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ia</code>
|
||||
<name>Interlingua</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>id</code>
|
||||
<name>Indonesian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ik</code>
|
||||
<name>Inupiaq</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>it</code>
|
||||
<name>Italian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>jv</code>
|
||||
<name>Javanese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ja</code>
|
||||
<name>Japanese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>kl</code>
|
||||
<name>Kalaallisut</name>
|
||||
<name>Greenlandic</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>kn</code>
|
||||
<name>Kannada</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ks</code>
|
||||
<name>Kashmiri</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>kr</code>
|
||||
<name>Kanuri</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>kk</code>
|
||||
<name>Kazakh</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>km</code>
|
||||
<name>Central Khmer</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ki</code>
|
||||
<name>Kikuyu</name>
|
||||
<name>Gikuyu</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>rw</code>
|
||||
<name>Kinyarwanda</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ky</code>
|
||||
<name>Kirghiz</name>
|
||||
<name>Kyrgyz</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>kv</code>
|
||||
<name>Komi</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>kg</code>
|
||||
<name>Kongo</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ko</code>
|
||||
<name>Korean</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>kj</code>
|
||||
<name>Kuanyama</name>
|
||||
<name>Kwanyama</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ku</code>
|
||||
<name>Kurdish</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>lo</code>
|
||||
<name>Lao</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>la</code>
|
||||
<name>Latin</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>lv</code>
|
||||
<name>Latvian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>li</code>
|
||||
<name>Limburgan</name>
|
||||
<name>Limburger</name>
|
||||
<name>Limburgish</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ln</code>
|
||||
<name>Lingala</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>lt</code>
|
||||
<name>Lithuanian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>lb</code>
|
||||
<name>Luxembourgish</name>
|
||||
<name>Letzeburgesch</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>lu</code>
|
||||
<name>Luba-Katanga</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>lg</code>
|
||||
<name>Ganda</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>mk</code>
|
||||
<name>Macedonian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>mh</code>
|
||||
<name>Marshallese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ml</code>
|
||||
<name>Malayalam</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>mi</code>
|
||||
<name>Maori</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>mr</code>
|
||||
<name>Marathi</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ms</code>
|
||||
<name>Malay</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>mg</code>
|
||||
<name>Malagasy</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>mt</code>
|
||||
<name>Maltese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>mo</code>
|
||||
<name>Moldavian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>mn</code>
|
||||
<name>Mongolian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>na</code>
|
||||
<name>Nauru</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>nv</code>
|
||||
<name>Navajo</name>
|
||||
<name>Navaho</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>nr</code>
|
||||
<name>Ndebele, South</name>
|
||||
<name>South Ndebele</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>nd</code>
|
||||
<name>Ndebele, North</name>
|
||||
<name>North Ndebele</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ng</code>
|
||||
<name>Ndonga</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ne</code>
|
||||
<name>Nepali</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>nn</code>
|
||||
<name>Norwegian Nynorsk</name>
|
||||
<name>Nynorsk, Norwegian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>nb</code>
|
||||
<name>Bokmål, Norwegian</name>
|
||||
<name>Norwegian Bokmål</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>no</code>
|
||||
<name>Norwegian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ny</code>
|
||||
<name>Chichewa</name>
|
||||
<name>Chewa</name>
|
||||
<name>Nyanja</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>oc</code>
|
||||
<name>Occitan</name>
|
||||
<name>Provençal</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>oj</code>
|
||||
<name>Ojibwa</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>or</code>
|
||||
<name>Oriya</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>om</code>
|
||||
<name>Oromo</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>os</code>
|
||||
<name>Ossetian</name>
|
||||
<name>Ossetic</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>pa</code>
|
||||
<name>Panjabi</name>
|
||||
<name>Punjabi</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>fa</code>
|
||||
<name>Persian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>pi</code>
|
||||
<name>Pali</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>pl</code>
|
||||
<name>Polish</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>pt</code>
|
||||
<name>Portuguese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ps</code>
|
||||
<name>Pushto</name>
|
||||
<name>Pashto</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>qu</code>
|
||||
<name>Quechua</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>rm</code>
|
||||
<name>Romansh</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ro</code>
|
||||
<name>Romanian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>rn</code>
|
||||
<name>Rundi</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ru</code>
|
||||
<name>Russian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sg</code>
|
||||
<name>Sango</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sa</code>
|
||||
<name>Sanskrit</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sr</code>
|
||||
<name>Serbian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>hr</code>
|
||||
<name>Croatian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>si</code>
|
||||
<name>Sinhala</name>
|
||||
<name>Sinhalese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sk</code>
|
||||
<name>Slovak</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sl</code>
|
||||
<name>Slovenian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>se</code>
|
||||
<name>Northern Sami</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sm</code>
|
||||
<name>Samoan</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sn</code>
|
||||
<name>Shona</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sd</code>
|
||||
<name>Sindhi</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>so</code>
|
||||
<name>Somali</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>st</code>
|
||||
<name>Sotho, Southern</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>es</code>
|
||||
<name>Spanish</name>
|
||||
<name>Castilian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sc</code>
|
||||
<name>Sardinian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ss</code>
|
||||
<name>Swati</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>su</code>
|
||||
<name>Sundanese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sw</code>
|
||||
<name>Swahili</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>sv</code>
|
||||
<name>Swedish</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ty</code>
|
||||
<name>Tahitian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ta</code>
|
||||
<name>Tamil</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>tt</code>
|
||||
<name>Tatar</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>te</code>
|
||||
<name>Telugu</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>tg</code>
|
||||
<name>Tajik</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>tl</code>
|
||||
<name>Tagalog</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>th</code>
|
||||
<name>Thai</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>bo</code>
|
||||
<name>Tibetan</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ti</code>
|
||||
<name>Tigrinya</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>to</code>
|
||||
<name>Tonga</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>tn</code>
|
||||
<name>Tswana</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ts</code>
|
||||
<name>Tsonga</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>tk</code>
|
||||
<name>Turkmen</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>tr</code>
|
||||
<name>Turkish</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>tw</code>
|
||||
<name>Twi</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ug</code>
|
||||
<name>Uighur</name>
|
||||
<name>Uyghur</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>uk</code>
|
||||
<name>Ukrainian</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ur</code>
|
||||
<name>Urdu</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>uz</code>
|
||||
<name>Uzbek</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>ve</code>
|
||||
<name>Venda</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>vi</code>
|
||||
<name>Vietnamese</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>vo</code>
|
||||
<name>Volapük</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>cy</code>
|
||||
<name>Welsh</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>wa</code>
|
||||
<name>Walloon</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>wo</code>
|
||||
<name>Wolof</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>xh</code>
|
||||
<name>Xhosa</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>yi</code>
|
||||
<name>Yiddish</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>yo</code>
|
||||
<name>Yoruba</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>za</code>
|
||||
<name>Zhuang</name>
|
||||
<name>Chuang</name>
|
||||
</language>
|
||||
<language>
|
||||
<code>zu</code>
|
||||
<name>Zulu</name>
|
||||
</language>
|
||||
</languages>
|
|
@ -78,7 +78,7 @@ public class ImdbSearchEngine {
|
|||
|
||||
URL imdbUrl = new URL("http", host, href);
|
||||
|
||||
return new MovieDescriptor(title, year, imdbId, imdbUrl);
|
||||
return new MovieDescriptor(title, imdbId, year, imdbUrl);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -7,13 +7,18 @@ import java.net.URL;
|
|||
|
||||
public class MovieDescriptor {
|
||||
|
||||
private String title;
|
||||
private Integer imdbId;
|
||||
private final String title;
|
||||
private final Integer imdbId;
|
||||
|
||||
private Integer year;
|
||||
private URL imdbUrl;
|
||||
private final Integer year;
|
||||
private final URL imdbUrl;
|
||||
|
||||
|
||||
public MovieDescriptor(String description) {
|
||||
this(description, null);
|
||||
}
|
||||
|
||||
|
||||
public MovieDescriptor(String description, Integer imdbId) {
|
||||
this(description, imdbId, null, null);
|
||||
}
|
||||
|
|
|
@ -8,15 +8,17 @@ import java.util.Map;
|
|||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
|
||||
import net.sourceforge.tuned.DownloadTask;
|
||||
|
||||
|
||||
/**
|
||||
* Describes a subtitle on OpenSubtitles.
|
||||
*
|
||||
* @see OpenSubtitlesClient
|
||||
*/
|
||||
public class OpenSubtitleDescriptor {
|
||||
public class OpenSubtitleDescriptor implements SubtitleDescriptor {
|
||||
|
||||
private Map<String, String> properties;
|
||||
private final Map<String, String> properties;
|
||||
|
||||
|
||||
public static enum Properties {
|
||||
|
@ -60,13 +62,19 @@ public class OpenSubtitleDescriptor {
|
|||
}
|
||||
|
||||
|
||||
public Map<String, String> getPropertyMap() {
|
||||
return properties;
|
||||
public String getProperty(Properties property) {
|
||||
return properties.get(property.name());
|
||||
}
|
||||
|
||||
|
||||
public String getProperty(Properties property) {
|
||||
return properties.get(property.name());
|
||||
@Override
|
||||
public String getName() {
|
||||
return getProperty(Properties.SubFileName);
|
||||
}
|
||||
|
||||
|
||||
public String getLanguageName() {
|
||||
return getProperty(Properties.LanguageName);
|
||||
}
|
||||
|
||||
|
||||
|
@ -76,7 +84,7 @@ public class OpenSubtitleDescriptor {
|
|||
|
||||
|
||||
public URL getDownloadLink() {
|
||||
String link = getProperty(Properties.SubDownloadLink);
|
||||
String link = getProperty(Properties.ZipDownloadLink);
|
||||
|
||||
try {
|
||||
return new URL(link);
|
||||
|
@ -87,9 +95,21 @@ public class OpenSubtitleDescriptor {
|
|||
}
|
||||
|
||||
|
||||
@Override
|
||||
public DownloadTask createDownloadTask() {
|
||||
return new DownloadTask(getDownloadLink());
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String getArchiveType() {
|
||||
return "zip";
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return String.format("%s [%s]", getProperty(Properties.SubFileName), getProperty(Properties.LanguageName));
|
||||
return String.format("%s [%s]", getName(), getLanguageName());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -14,6 +14,8 @@ import java.util.logging.Logger;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.sourceforge.filebot.Settings;
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import redstone.xmlrpc.XmlRpcClient;
|
||||
import redstone.xmlrpc.XmlRpcException;
|
||||
import redstone.xmlrpc.XmlRpcFault;
|
||||
|
@ -23,7 +25,18 @@ import redstone.xmlrpc.XmlRpcFault;
|
|||
* Client for the OpenSubtitles XML-RPC API.
|
||||
*
|
||||
*/
|
||||
public class OpenSubtitlesClient {
|
||||
public class OpenSubtitlesClient extends SubtitleClient {
|
||||
|
||||
@Override
|
||||
public List<MovieDescriptor> search(String query) throws Exception {
|
||||
return searchMoviesOnIMDB(query);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<OpenSubtitleDescriptor> getSubtitleList(MovieDescriptor descriptor) throws Exception {
|
||||
return searchSubtitles(descriptor.getImdbId());
|
||||
}
|
||||
|
||||
/**
|
||||
* <table>
|
||||
|
@ -39,11 +52,11 @@ public class OpenSubtitlesClient {
|
|||
*/
|
||||
private String url = "http://www.opensubtitles.org/xml-rpc";
|
||||
|
||||
private String username;
|
||||
private String password;
|
||||
private String language;
|
||||
private String username = "";
|
||||
private String password = "";
|
||||
private String language = "en";
|
||||
|
||||
private String useragent;
|
||||
private String useragent = String.format("%s v%s", Settings.NAME, Settings.VERSION);
|
||||
|
||||
private String token = null;
|
||||
|
||||
|
@ -55,56 +68,8 @@ public class OpenSubtitlesClient {
|
|||
private static final int KEEP_ALIVE_INTERVAL = 12 * 60 * 1000; // 12 minutes
|
||||
|
||||
|
||||
public OpenSubtitlesClient(String useragent) {
|
||||
this.useragent = useragent;
|
||||
}
|
||||
|
||||
|
||||
public boolean isLoggedOn() {
|
||||
return username != null;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* login as anonymous user
|
||||
*/
|
||||
public synchronized void login() throws XmlRpcFault {
|
||||
this.login("", "", "en");
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* This will login user. This method should be called always when starting talking with
|
||||
* server.
|
||||
*
|
||||
* @param username blank for anonymous user.
|
||||
* @param password blank for anonymous user.
|
||||
* @param language <a href="http://en.wikipedia.org/wiki/List_of_ISO_639-2_codes">ISO639</a>
|
||||
* 2 letter codes as language and later communication will be done in this
|
||||
* language if applicable (error codes and so on).
|
||||
*/
|
||||
public synchronized void login(String username, String password, String language) throws XmlRpcFault {
|
||||
if (isLoggedOn())
|
||||
throw new IllegalStateException("User is already logged on");
|
||||
|
||||
if ((username == null) || (password == null) || (language == null))
|
||||
throw new IllegalArgumentException("Username, password and language must not be null");
|
||||
|
||||
this.username = username;
|
||||
this.password = password;
|
||||
this.language = language;
|
||||
}
|
||||
|
||||
|
||||
public synchronized void logout() {
|
||||
if (!isLoggedOn())
|
||||
throw new IllegalStateException("User is not logged on");
|
||||
|
||||
deactivate();
|
||||
|
||||
username = null;
|
||||
password = null;
|
||||
language = null;
|
||||
public OpenSubtitlesClient() {
|
||||
super("OpenSubtitles", ResourceManager.getIcon("search.opensubtitles"));
|
||||
}
|
||||
|
||||
|
||||
|
@ -113,9 +78,6 @@ public class OpenSubtitlesClient {
|
|||
if (isActive())
|
||||
return;
|
||||
|
||||
if (!isLoggedOn())
|
||||
throw new IllegalStateException("User is not logged on");
|
||||
|
||||
Map<String, String> response = (Map<String, String>) invoke("LogIn", username, password, language, useragent);
|
||||
checkStatus(response.get("status"));
|
||||
|
||||
|
@ -262,13 +224,11 @@ public class OpenSubtitlesClient {
|
|||
|
||||
@Override
|
||||
public void run() {
|
||||
Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
|
||||
|
||||
if (!noOperation()) {
|
||||
logger.log(Level.INFO, "Connection lost");
|
||||
deactivate();
|
||||
if (noOperation()) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.INFO, "Connection is OK");
|
||||
} else {
|
||||
logger.log(Level.INFO, "Connection is OK");
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.INFO, "Connection lost");
|
||||
deactivate();
|
||||
}
|
||||
};
|
||||
};
|
||||
|
|
|
@ -17,6 +17,7 @@ import java.util.logging.Logger;
|
|||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import net.sourceforge.filebot.resources.ResourceManager;
|
||||
import net.sourceforge.tuned.XPathUtil;
|
||||
|
||||
import org.w3c.dom.Document;
|
||||
|
@ -24,20 +25,26 @@ import org.w3c.dom.Node;
|
|||
import org.xml.sax.SAXException;
|
||||
|
||||
|
||||
public class SubsceneClient {
|
||||
public class SubsceneClient extends SubtitleClient {
|
||||
|
||||
private Map<String, URL> cache = Collections.synchronizedMap(new HashMap<String, URL>());
|
||||
private final Map<MovieDescriptor, URL> cache = Collections.synchronizedMap(new HashMap<MovieDescriptor, URL>());
|
||||
|
||||
private String host = "subscene.com";
|
||||
private final String host = "subscene.com";
|
||||
|
||||
|
||||
public List<String> search(String searchterm) throws IOException, SAXException {
|
||||
public SubsceneClient() {
|
||||
super("Subscene", ResourceManager.getIcon("search.subscene"));
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public List<MovieDescriptor> search(String searchterm) throws IOException, SAXException {
|
||||
|
||||
Document dom = HtmlUtil.getHtmlDocument(getSearchUrl(searchterm));
|
||||
|
||||
List<Node> nodes = XPathUtil.selectNodes("id('filmSearch')/A", dom);
|
||||
|
||||
ArrayList<String> titles = new ArrayList<String>();
|
||||
ArrayList<MovieDescriptor> results = new ArrayList<MovieDescriptor>(nodes.size());
|
||||
|
||||
for (Node node : nodes) {
|
||||
String title = XPathUtil.selectString("text()", node);
|
||||
|
@ -46,22 +53,21 @@ public class SubsceneClient {
|
|||
try {
|
||||
URL url = new URL("http", host, href);
|
||||
|
||||
cache.put(title, url);
|
||||
titles.add(title);
|
||||
MovieDescriptor descriptor = new MovieDescriptor(title);
|
||||
cache.put(descriptor, url);
|
||||
results.add(descriptor);
|
||||
} catch (MalformedURLException e) {
|
||||
Logger.getLogger(Logger.GLOBAL_LOGGER_NAME).log(Level.WARNING, "Invalid href: " + href, e);
|
||||
}
|
||||
}
|
||||
|
||||
return titles;
|
||||
return results;
|
||||
}
|
||||
|
||||
|
||||
public List<SubsceneSubtitleDescriptor> getSubtitleList(String title) throws IOException, SAXException {
|
||||
URL url = cache.get(title);
|
||||
|
||||
if (url == null)
|
||||
throw new IllegalArgumentException("Unknown title: " + title);
|
||||
@Override
|
||||
public List<SubsceneSubtitleDescriptor> getSubtitleList(MovieDescriptor descriptor) throws IOException, SAXException {
|
||||
URL url = cache.get(descriptor);
|
||||
|
||||
Document dom = HtmlUtil.getHtmlDocument(url);
|
||||
|
||||
|
|
|
@ -8,15 +8,15 @@ import java.util.Map;
|
|||
import net.sourceforge.tuned.DownloadTask;
|
||||
|
||||
|
||||
public class SubsceneSubtitleDescriptor {
|
||||
public class SubsceneSubtitleDescriptor implements SubtitleDescriptor {
|
||||
|
||||
private String title;
|
||||
private String language;
|
||||
private int numberOfCDs;
|
||||
private String author;
|
||||
private final String title;
|
||||
private final String language;
|
||||
private final int numberOfCDs;
|
||||
private final String author;
|
||||
|
||||
private Map<String, String> downloadParameters;
|
||||
private URL downloadUrl;
|
||||
private final Map<String, String> downloadParameters;
|
||||
private final URL downloadUrl;
|
||||
|
||||
|
||||
public SubsceneSubtitleDescriptor(String title, String language, int numberOfCDs, String author, URL downloadUrl, Map<String, String> downloadParameters) {
|
||||
|
@ -30,12 +30,12 @@ public class SubsceneSubtitleDescriptor {
|
|||
}
|
||||
|
||||
|
||||
public String getTitle() {
|
||||
public String getName() {
|
||||
return title;
|
||||
}
|
||||
|
||||
|
||||
public String getLanguage() {
|
||||
public String getLanguageName() {
|
||||
return language;
|
||||
}
|
||||
|
||||
|
@ -50,13 +50,13 @@ public class SubsceneSubtitleDescriptor {
|
|||
}
|
||||
|
||||
|
||||
public String getArchiveType() {
|
||||
return downloadParameters.get("typeId");
|
||||
public DownloadTask createDownloadTask() {
|
||||
return new DownloadTask(downloadUrl, downloadParameters);
|
||||
}
|
||||
|
||||
|
||||
public DownloadTask createDownloadTask() {
|
||||
return new DownloadTask(downloadUrl, downloadParameters);
|
||||
public String getArchiveType() {
|
||||
return downloadParameters.get("typeId");
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import javax.swing.ImageIcon;
|
||||
|
||||
|
||||
public abstract class SubtitleClient {
|
||||
|
||||
private static final List<SubtitleClient> registry = new ArrayList<SubtitleClient>();
|
||||
|
||||
static {
|
||||
registry.add(new OpenSubtitlesClient());
|
||||
registry.add(new SubsceneClient());
|
||||
}
|
||||
|
||||
|
||||
public static List<SubtitleClient> getAvailableSubtitleClients() {
|
||||
return Collections.unmodifiableList(registry);
|
||||
}
|
||||
|
||||
private String name;
|
||||
private ImageIcon icon;
|
||||
|
||||
|
||||
public SubtitleClient(String name, ImageIcon icon) {
|
||||
this.name = name;
|
||||
this.icon = icon;
|
||||
}
|
||||
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
|
||||
public ImageIcon getIcon() {
|
||||
return icon;
|
||||
}
|
||||
|
||||
|
||||
public abstract List<MovieDescriptor> search(String query) throws Exception;
|
||||
|
||||
|
||||
public abstract List<? extends SubtitleDescriptor> getSubtitleList(MovieDescriptor descriptor) throws Exception;
|
||||
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
package net.sourceforge.filebot.web;
|
||||
|
||||
|
||||
import net.sourceforge.tuned.DownloadTask;
|
||||
|
||||
|
||||
public interface SubtitleDescriptor {
|
||||
|
||||
public String getName();
|
||||
|
||||
|
||||
public String getLanguageName();
|
||||
|
||||
|
||||
public String getArchiveType();
|
||||
|
||||
|
||||
public DownloadTask createDownloadTask();
|
||||
|
||||
}
|
|
@ -57,8 +57,6 @@ public abstract class AbstractFancyListCellRenderer extends JComponent implement
|
|||
public AbstractFancyListCellRenderer(Insets padding, Insets margin, Color borderColor) {
|
||||
this.setLayout(new BorderLayout());
|
||||
|
||||
this.margin = margin;
|
||||
|
||||
Border border = null;
|
||||
|
||||
if (padding != null)
|
||||
|
@ -67,8 +65,12 @@ public abstract class AbstractFancyListCellRenderer extends JComponent implement
|
|||
if (borderColor != null)
|
||||
border = new CompoundBorder(new LineBorder(borderColor, 1), border);
|
||||
|
||||
if (margin != null)
|
||||
if (margin != null) {
|
||||
this.margin = margin;
|
||||
border = new CompoundBorder(new EmptyBorder(margin), border);
|
||||
} else {
|
||||
this.margin = new Insets(0, 0, 0, 0);
|
||||
}
|
||||
|
||||
setBorder(border);
|
||||
setOpaque(false);
|
||||
|
|
Loading…
Reference in New Issue