1
0
mirror of https://github.com/mitb-archive/filebot synced 2024-12-22 15:58:52 -05:00

+ added webstart deployment

* added jnlp descriptors
* automated build, code signing and pack200 compression
* some webstart related code adjustments
* added MediaInfo 0.7.19 native libs for various operating systems
* updated jna
* use .properties file for application settings (name, version, apikeys, ...)
This commit is contained in:
Reinhard Pointner 2009-07-27 22:34:42 +00:00
parent 203eedb24e
commit b0ea60dad6
31 changed files with 311 additions and 60 deletions

View File

@ -93,15 +93,15 @@
<zipfileset src="${dir.lib}/js.jar"> <zipfileset src="${dir.lib}/js.jar">
<include name="org/mozilla/**" /> <include name="org/mozilla/**" />
</zipfileset> </zipfileset>
<zipfileset src="${dir.lib}/sublight-ws.jar"> <zipfileset src="${dir.lib}/sublight-ws.jar">
<include name="net/sublight/webservice/**" /> <include name="net/sublight/webservice/**" />
</zipfileset> </zipfileset>
<zipfileset src="${dir.lib}/junrar-custom.jar"> <zipfileset src="${dir.lib}/junrar-custom.jar">
<include name="de/innosystec/unrar/**" /> <include name="de/innosystec/unrar/**" />
</zipfileset> </zipfileset>
<zipfileset src="${dir.lib}/commons-logging.jar"> <zipfileset src="${dir.lib}/commons-logging.jar">
<include name="org/apache/commons/logging/**" /> <include name="org/apache/commons/logging/**" />
</zipfileset> </zipfileset>
@ -109,6 +109,82 @@
</target> </target>
<target name="webstart" depends="jar">
<!-- create dirs -->
<mkdir dir="${dir.dist}/webstart" />
<!-- copy jars -->
<copy todir="${dir.dist}/webstart">
<fileset dir="${dir.dist}" includes="filebot.jar" />
<fileset dir="${dir.lib}" includes="*.jar" excludes="junit.jar, jna.jar" />
</copy>
<!-- copy jna.jar without native libs -->
<jar destfile="${dir.dist}/webstart/jna.jar">
<zipfileset src="${dir.lib}/jna.jar" includes="**/*.class" />
</jar>
<!-- create native lib jars -->
<antcall target="webstart-nativelib">
<param name="arch" value="win32-x86" />
</antcall>
<antcall target="webstart-nativelib">
<param name="arch" value="win32-amd64" />
</antcall>
<antcall target="webstart-nativelib">
<param name="arch" value="linux-i386" />
</antcall>
<antcall target="webstart-nativelib">
<param name="arch" value="linux-amd64" />
</antcall>
<antcall target="webstart-nativelib">
<param name="arch" value="darwin" />
</antcall>
<!-- sign main jar and native lib jars -->
<fileset id="signjar" dir="${dir.dist}/webstart" includes="filebot.jar, native/*.jar" />
<apply executable="pack200">
<arg line="--repack" />
<srcfile />
<fileset refid="signjar" />
</apply>
<signjar alias="filebot" keystore="filebot.keystore" storepass="secret">
<fileset refid="signjar" />
</signjar>
<!-- pack200 all jars -->
<apply executable="pack200" dest="${dir.dist}/webstart">
<targetfile />
<srcfile />
<fileset dir="${dir.dist}/webstart" includes="*.jar" />
<mapper type="glob" from="*.jar" to="*.jar.pack.gz" />
</apply>
</target>
<target name="webstart-nativelib">
<!-- create temp dir -->
<mkdir dir="${dir.dist}/webstart/native/${arch}" />
<!-- copy native libs to temp dir -->
<copy todir="${dir.dist}/webstart/native/${arch}" flatten="true">
<zipfileset src="${dir.lib}/jna.jar" includes="com/sun/jna/${arch}/*" />
<fileset dir="${dir.lib}/native" includes="${arch}/*" />
</copy>
<!-- create native lib jar -->
<jar destfile="${dir.dist}/webstart/native/${arch}.jar" basedir="${dir.dist}/webstart/native/${arch}" />
<!-- delete temp dir -->
<delete dir="${dir.dist}/webstart/native/${arch}" />
</target>
<target name="genkey">
<genkey alias="filebot" keystore="filebot.keystore" storepass="secret" validity="3650" dname="CN=${user.name}" />
</target>
<target name="build"> <target name="build">
<!-- create build dir --> <!-- create build dir -->
<mkdir dir="${dir.build}" /> <mkdir dir="${dir.build}" />
@ -123,7 +199,7 @@
<!-- copy resources --> <!-- copy resources -->
<copy todir="${dir.build}"> <copy todir="${dir.build}">
<fileset dir="${dir.source}"> <fileset dir="${dir.source}">
<exclude name="**/*.java"/> <exclude name="**/*.java" />
</fileset> </fileset>
</copy> </copy>
</target> </target>

BIN
installer/icons/icon16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 854 B

BIN
installer/icons/icon32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

BIN
installer/icons/icon48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 184 B

BIN
installer/icons/sfv.ico Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
installer/icons/sfv16.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 702 B

BIN
installer/icons/sfv32.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

BIN
installer/icons/sfv48.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

BIN
installer/icons/splash.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 15 KiB

View File

@ -0,0 +1,54 @@
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://filebot.sourceforge.net/webstart/" href="filebot.jnlp">
<information>
<title>FileBot</title>
<vendor>rednoah</vendor>
<homepage href="http://sourceforge.net/projects/filebot/" />
<description>A cross-platform tool for tv renaming, subtitle download and file verification</description>
<icon href="nosplash.png" kind="splash" />
<icon href="icon48.png" width="48" height="48" />
<icon href="icon32.png" width="32" height="32" />
<icon href="icon16.png" width="16" height="16" />
<icon href="shortcut.ico" kind="shortcut" />
<shortcut>
<desktop />
<menu />
</shortcut>
<offline-allowed />
</information>
<update check="timeout" policy="always" />
<security>
<all-permissions />
</security>
<resources>
<property name="jnlp.packEnabled" value="true" />
<java version="1.6+" />
<jar href="filebot.jar" main="true" />
<extension name="lib" href="filebot.lib.jnlp" />
</resources>
<resources os="Windows" arch="x86">
<nativelib href="native/win32-x86.jar" />
</resources>
<resources os="Windows" arch="amd64">
<nativelib href="native/win32-amd64.jar" />
</resources>
<resources os="Linux" arch="i386">
<nativelib href="native/linux-i386.jar" />
</resources>
<resources os="Linux" arch="amd64">
<nativelib href="native/linux-amd64.jar" />
</resources>
<resources os="Mac">
<nativelib href="native/darwin.jar" />
</resources>
<application-desc main-class="net.sourceforge.filebot.Main" />
</jnlp>

View File

@ -0,0 +1,32 @@
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://filebot.sourceforge.net/webstart/" href="filebot.lib.jnlp">
<information>
<title>Unsigned libs for FileBot</title>
<vendor>rednoah</vendor>
<offline-allowed />
</information>
<update check="timeout" policy="always" />
<resources>
<property name="jnlp.packEnabled" value="true" />
<jar href="miglayout.jar" />
<jar href="glazedlists.jar" />
<jar href="nekohtml.jar" />
<jar href="xercesImpl.jar" />
<jar href="ehcache.jar" />
<jar href="simmetrics.jar" />
<jar href="args4j.jar" />
<jar href="jna.jar" />
<jar href="js-engine.jar" />
<jar href="js.jar" />
<jar href="junrar-custom.jar" />
<jar href="sublight-ws.jar" />
<jar href="xmlrpc-client.jar" />
<jar href="commons-logging.jar" />
</resources>
<component-desc />
</jnlp>

View File

@ -0,0 +1,47 @@
<?xml version="1.0" encoding="UTF-8"?>
<jnlp spec="1.0+" codebase="http://filebot.sourceforge.net/webstart/" href="filebot.sfv.jnlp">
<information>
<title>Simple File Verification</title>
<vendor>rednoah</vendor>
<homepage href="http://sourceforge.net/projects/filebot/" />
<icon href="nosplash.png" kind="splash" />
<icon href="sfv48.png" width="48" height="48" />
<icon href="sfv32.png" width="32" height="32" />
<icon href="sfv16.png" width="16" height="16" />
<icon href="sfv.ico" kind="shortcut" />
<association extensions="sfv" mime-type="text/x-extension-sfv">
<description>sfv file</description>
<icon href="sfv.ico" />
</association>
<association extensions="md5" mime-type="text/x-extension-md5">
<description>md5sum file</description>
<icon href="sfv.ico" />
</association>
<association extensions="sha" mime-type="text/x-extension-sha">
<description>sha1sum file</description>
<icon href="sfv.ico" />
</association>
<offline-allowed />
</information>
<update check="background" policy="always" />
<security>
<all-permissions />
</security>
<resources>
<property name="jnlp.packEnabled" value="true" />
<java version="1.6+" />
<jar href="filebot.jar" main="true" />
<extension name="lib" href="filebot.lib.jnlp" />
</resources>
<application-desc main-class="net.sourceforge.filebot.Main">
<argument>--sfv</argument>
</application-desc>
</jnlp>

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -5,31 +5,36 @@ package net.sourceforge.filebot;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.logging.Level; import java.util.logging.Level;
import java.util.logging.Logger; import java.util.logging.Logger;
import net.sourceforge.filebot.ui.transfer.FileTransferable;
import org.kohsuke.args4j.Argument; import org.kohsuke.args4j.Argument;
import org.kohsuke.args4j.Option; import org.kohsuke.args4j.Option;
import net.sourceforge.filebot.ui.transfer.FileTransferable;
import net.sourceforge.tuned.FileUtilities;
public class ArgumentBean { public class ArgumentBean {
@Option(name = "-help", usage = "Print this help message") @Option(name = "-help", usage = "Print this help message")
private boolean help = false; private boolean help = false;
@Option(name = "-clear", usage = "Clear history and settings") @Option(name = "-clear", usage = "Clear application settings")
private boolean clear = false; private boolean clear = false;
@Option(name = "--sfv", usage = "Open file in 'SFV' panel", metaVar = "<file>") @Option(name = "-open", usage = "Open file", metaVar = "<file>")
private boolean sfv; private boolean open = false;
@Option(name = "--sfv", usage = "Open SFV panel", metaVar = "<file>")
private boolean sfv = false;
@Argument @Argument
private List<File> arguments; private List<File> arguments = new LinkedList<File>();
public boolean help() { public boolean help() {
return help; return help;
} }
@ -40,8 +45,13 @@ public class ArgumentBean {
} }
public boolean open() {
return open;
}
public boolean sfv() { public boolean sfv() {
return sfv; return sfv || (open && FileUtilities.containsOnly(arguments, MediaTypes.getFilter("verification")));
} }

View File

@ -18,10 +18,8 @@ import javax.swing.JFrame;
import javax.swing.SwingUtilities; import javax.swing.SwingUtilities;
import javax.swing.UIManager; import javax.swing.UIManager;
import org.kohsuke.args4j.CmdLineException;
import org.kohsuke.args4j.CmdLineParser; import org.kohsuke.args4j.CmdLineParser;
import net.sf.ehcache.CacheManager;
import net.sourceforge.filebot.format.ExpressionFormat; import net.sourceforge.filebot.format.ExpressionFormat;
import net.sourceforge.filebot.ui.MainFrame; import net.sourceforge.filebot.ui.MainFrame;
import net.sourceforge.filebot.ui.NotificationLoggingHandler; import net.sourceforge.filebot.ui.NotificationLoggingHandler;
@ -35,7 +33,11 @@ public class Main {
* @param args * @param args
*/ */
public static void main(String... args) throws Exception { public static void main(String... args) throws Exception {
// initialize this stuff before anything else
initializeLogging();
initializeSecurityManager();
// parse arguments
final ArgumentBean argumentBean = initializeArgumentBean(args); final ArgumentBean argumentBean = initializeArgumentBean(args);
if (argumentBean.help()) { if (argumentBean.help()) {
@ -50,16 +52,11 @@ public class Main {
Settings.userRoot().clear(); Settings.userRoot().clear();
} }
initializeLogging();
initializeSettings();
initializeCache();
initializeSecurityManager();
try { try {
// use native laf an all platforms // use native laf an all platforms
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName()); UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
} catch (Exception e) { } catch (Exception e) {
Logger.getLogger(Main.class.getName()).log(Level.WARNING, e.toString(), e); Logger.getLogger(Main.class.getName()).log(Level.WARNING, e.getMessage(), e);
} }
SwingUtilities.invokeLater(new Runnable() { SwingUtilities.invokeLater(new Runnable() {
@ -69,7 +66,7 @@ public class Main {
JFrame frame; JFrame frame;
if (argumentBean.sfv()) { if (argumentBean.sfv()) {
// sfv frame // single panel frame
frame = new SinglePanelFrame(new SfvPanelBuilder()).publish(argumentBean.transferable()); frame = new SinglePanelFrame(new SfvPanelBuilder()).publish(argumentBean.transferable());
} else { } else {
// default frame // default frame
@ -103,30 +100,6 @@ public class Main {
} }
/**
* Preset the default thetvdb.apikey.
*/
private static void initializeSettings() {
Settings.userRoot().putDefault("thetvdb.apikey", "58B4AA94C59AD656");
Settings.userRoot().putDefault("sublight.apikey", "afa9ecb2-a3ee-42b1-9225-000b4038bc85");
}
/**
* Shutdown {@link CacheManager} in case there are any persistent caches that need to be stored.
*/
private static void initializeCache() {
// shutdown CacheManager
Runtime.getRuntime().addShutdownHook(new Thread(new Runnable() {
@Override
public void run() {
CacheManager.getInstance().shutdown();
}
}));
}
/** /**
* Initialize default SecurityManager and grant all permissions via security policy. * Initialize default SecurityManager and grant all permissions via security policy.
* Initialization is required in order to run {@link ExpressionFormat} in a secure sandbox. * Initialization is required in order to run {@link ExpressionFormat} in a secure sandbox.
@ -164,10 +137,15 @@ public class Main {
/** /**
* Parse command line arguments. * Parse command line arguments.
*/ */
private static ArgumentBean initializeArgumentBean(String... args) throws CmdLineException { private static ArgumentBean initializeArgumentBean(String... args) {
ArgumentBean argumentBean = new ArgumentBean(); ArgumentBean argumentBean = new ArgumentBean();
new CmdLineParser(argumentBean).parseArgument(args); try {
CmdLineParser parser = new CmdLineParser(argumentBean);
parser.parseArgument(args);
} catch (Exception e) {
Logger.getLogger(Main.class.getName()).log(Level.WARNING, e.getMessage(), e);
}
return argumentBean; return argumentBean;
} }
@ -179,7 +157,8 @@ public class Main {
private static void printUsage(ArgumentBean argumentBean) { private static void printUsage(ArgumentBean argumentBean) {
System.out.println("Options:"); System.out.println("Options:");
new CmdLineParser(argumentBean).printUsage(System.out); CmdLineParser parser = new CmdLineParser(argumentBean);
parser.printUsage(System.out);
} }
} }

View File

@ -2,6 +2,9 @@
package net.sourceforge.filebot; package net.sourceforge.filebot;
import java.io.File;
import java.util.Locale;
import java.util.ResourceBundle;
import java.util.prefs.BackingStoreException; import java.util.prefs.BackingStoreException;
import java.util.prefs.Preferences; import java.util.prefs.Preferences;
@ -16,15 +19,39 @@ import net.sourceforge.tuned.PreferencesMap.StringAdapter;
public final class Settings { public final class Settings {
public static String getApplicationName() { public static String getApplicationName() {
return "FileBot"; return getApplicationProperty("application.name");
}; };
public static String getApplicationVersion() { public static String getApplicationVersion() {
return "1.9"; return getApplicationProperty("application.version");
}; };
public static String getApplicationProperty(String key) {
return ResourceBundle.getBundle(Settings.class.getName(), Locale.ROOT).getString(key);
}
public static File getApplicationFolder() {
// special handling for web start
if (System.getProperty("javawebstart.version") != null) {
// can't use working directory for web start applications
File folder = new File(System.getProperty("user.home"), ".filebot");
// create folder if necessary
if (!folder.exists()) {
folder.mkdir();
}
return folder;
}
// use working directory
return new File(System.getProperty("user.dir"));
}
private static final Settings userRoot = new Settings(Preferences.userNodeForPackage(Settings.class)); private static final Settings userRoot = new Settings(Preferences.userNodeForPackage(Settings.class));

View File

@ -0,0 +1,6 @@
# application settings
application.name: FileBot
application.version: 0.0
thetvdb.apikey: 58B4AA94C59AD656
sublight.apikey: afa9ecb2-a3ee-42b1-9225-000b4038bc85

View File

@ -9,16 +9,32 @@ import java.util.EnumMap;
import java.util.LinkedHashMap; import java.util.LinkedHashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.logging.Logger;
import com.sun.jna.NativeLibrary;
import com.sun.jna.Platform;
import com.sun.jna.Pointer; import com.sun.jna.Pointer;
import com.sun.jna.WString; import com.sun.jna.WString;
public class MediaInfo implements Closeable { public class MediaInfo implements Closeable {
static {
// libmediainfo for linux depends on libzen
if (Platform.isLinux()) {
try {
// We need to load dependencies first, because we know where our native libs are (e.g. Java Web Start Cache).
// If we do not, the system will look for dependencies, but only in the library path.
NativeLibrary.getInstance("zen");
} catch (Exception e) {
Logger.getLogger(MediaInfo.class.getName()).warning("Failed to preload libzen");
}
}
}
private Pointer handle; private Pointer handle;
public MediaInfo() { public MediaInfo() {
handle = MediaInfoLibrary.INSTANCE.New(); handle = MediaInfoLibrary.INSTANCE.New();
} }
@ -137,7 +153,7 @@ public class MediaInfo implements Closeable {
} }
} }
public enum StreamKind { public enum StreamKind {
General, General,
Video, Video,
@ -194,7 +210,7 @@ public class MediaInfo implements Closeable {
Domain; Domain;
} }
public static String version() { public static String version() {
return staticOption("Info_Version"); return staticOption("Info_Version");
} }

View File

@ -2,6 +2,7 @@
package net.sourceforge.filebot.ui.panel.episodelist; package net.sourceforge.filebot.ui.panel.episodelist;
import static net.sourceforge.filebot.Settings.*;
import static net.sourceforge.filebot.ui.panel.episodelist.SeasonSpinnerModel.*; import static net.sourceforge.filebot.ui.panel.episodelist.SeasonSpinnerModel.*;
import java.awt.event.ActionEvent; import java.awt.event.ActionEvent;
@ -43,7 +44,7 @@ public class EpisodeListPanel extends AbstractSearchPanel<EpisodeListProvider, E
private SeasonSpinnerModel seasonSpinnerModel = new SeasonSpinnerModel(); private SeasonSpinnerModel seasonSpinnerModel = new SeasonSpinnerModel();
public EpisodeListPanel() { public EpisodeListPanel() {
historyPanel.setColumnHeader(0, "Show"); historyPanel.setColumnHeader(0, "Show");
historyPanel.setColumnHeader(1, "Number of Episodes"); historyPanel.setColumnHeader(1, "Number of Episodes");
@ -74,7 +75,7 @@ public class EpisodeListPanel extends AbstractSearchPanel<EpisodeListProvider, E
new AnidbClient(), new AnidbClient(),
new TVDotComClient(), new TVDotComClient(),
new IMDbClient(), new IMDbClient(),
new TheTVDBClient(Settings.userRoot().get("thetvdb.apikey")) new TheTVDBClient(getApplicationProperty("thetvdb.apikey"))
}; };
} }
@ -100,6 +101,7 @@ public class EpisodeListPanel extends AbstractSearchPanel<EpisodeListProvider, E
return new EpisodeListRequestProcessor(new EpisodeListRequest(provider, text, season)); return new EpisodeListRequestProcessor(new EpisodeListRequest(provider, text, season));
}; };
private final PropertyChangeListener selectButtonListener = new PropertyChangeListener() { private final PropertyChangeListener selectButtonListener = new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) { public void propertyChange(PropertyChangeEvent evt) {
@ -114,7 +116,7 @@ public class EpisodeListPanel extends AbstractSearchPanel<EpisodeListProvider, E
} }
}; };
private class SpinSeasonAction extends AbstractAction { private class SpinSeasonAction extends AbstractAction {
public SpinSeasonAction(int spin) { public SpinSeasonAction(int spin) {
@ -176,7 +178,7 @@ public class EpisodeListPanel extends AbstractSearchPanel<EpisodeListProvider, E
private final EpisodeListProvider provider; private final EpisodeListProvider provider;
private final int season; private final int season;
public EpisodeListRequest(EpisodeListProvider provider, String searchText, int season) { public EpisodeListRequest(EpisodeListProvider provider, String searchText, int season) {
super(searchText); super(searchText);
this.provider = provider; this.provider = provider;

View File

@ -2,6 +2,7 @@
package net.sourceforge.filebot.ui.panel.rename; package net.sourceforge.filebot.ui.panel.rename;
import static net.sourceforge.filebot.Settings.*;
import static net.sourceforge.filebot.ui.panel.rename.History.*; import static net.sourceforge.filebot.ui.panel.rename.History.*;
import java.io.File; import java.io.File;
@ -25,7 +26,7 @@ final class HistorySpooler {
} }
private final File file = new File("history.xml"); private final File file = new File(getApplicationFolder(), "history.xml");
private final History sessionHistory = new History(); private final History sessionHistory = new History();

View File

@ -2,6 +2,7 @@
package net.sourceforge.filebot.ui.panel.rename; package net.sourceforge.filebot.ui.panel.rename;
import static net.sourceforge.filebot.Settings.*;
import static net.sourceforge.tuned.ui.LoadingOverlayPane.*; import static net.sourceforge.tuned.ui.LoadingOverlayPane.*;
import static net.sourceforge.tuned.ui.TunedUtilities.*; import static net.sourceforge.tuned.ui.TunedUtilities.*;
@ -143,7 +144,7 @@ public class RenamePanel extends JComponent {
actionPopup.add(new AutoFetchEpisodeListAction(new AnidbClient())); actionPopup.add(new AutoFetchEpisodeListAction(new AnidbClient()));
actionPopup.add(new AutoFetchEpisodeListAction(new TVDotComClient())); actionPopup.add(new AutoFetchEpisodeListAction(new TVDotComClient()));
actionPopup.add(new AutoFetchEpisodeListAction(new IMDbClient())); actionPopup.add(new AutoFetchEpisodeListAction(new IMDbClient()));
actionPopup.add(new AutoFetchEpisodeListAction(new TheTVDBClient(Settings.userRoot().get("thetvdb.apikey")))); actionPopup.add(new AutoFetchEpisodeListAction(new TheTVDBClient(getApplicationProperty("thetvdb.apikey"))));
actionPopup.addSeparator(); actionPopup.addSeparator();
actionPopup.addDescription(new JLabel("Options:")); actionPopup.addDescription(new JLabel("Options:"));

View File

@ -81,7 +81,7 @@ public class SubtitlePanel extends AbstractSearchPanel<SubtitleProvider, Subtitl
return new SubtitleProvider[] { return new SubtitleProvider[] {
new OpenSubtitlesClient(String.format("%s %s", getApplicationName(), getApplicationVersion())), new OpenSubtitlesClient(String.format("%s %s", getApplicationName(), getApplicationVersion())),
new SubsceneSubtitleClient(), new SubsceneSubtitleClient(),
new SublightSubtitleClient(getApplicationName(), Settings.userRoot().get("sublight.apikey")), new SublightSubtitleClient(getApplicationName(), getApplicationProperty("sublight.apikey")),
new SubtitleSourceClient() new SubtitleSourceClient()
}; };
} }