mirror of
https://github.com/mitb-archive/filebot
synced 2024-12-24 00:38:52 -05:00
+ support update notifications
This commit is contained in:
parent
fe74476232
commit
ace3e7a96c
@ -3,27 +3,43 @@ package net.sourceforge.filebot;
|
|||||||
|
|
||||||
|
|
||||||
import static java.awt.GraphicsEnvironment.*;
|
import static java.awt.GraphicsEnvironment.*;
|
||||||
|
import static java.util.concurrent.TimeUnit.*;
|
||||||
import static javax.swing.JFrame.*;
|
import static javax.swing.JFrame.*;
|
||||||
import static net.sourceforge.filebot.Settings.*;
|
import static net.sourceforge.filebot.Settings.*;
|
||||||
import static net.sourceforge.tuned.ui.TunedUtilities.*;
|
import static net.sourceforge.tuned.ui.TunedUtilities.*;
|
||||||
|
|
||||||
|
import java.awt.Desktop;
|
||||||
|
import java.awt.Dialog.ModalityType;
|
||||||
|
import java.awt.event.ActionEvent;
|
||||||
import java.awt.event.WindowAdapter;
|
import java.awt.event.WindowAdapter;
|
||||||
import java.awt.event.WindowEvent;
|
import java.awt.event.WindowEvent;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.net.URI;
|
||||||
|
import java.nio.ByteBuffer;
|
||||||
import java.security.CodeSource;
|
import java.security.CodeSource;
|
||||||
import java.security.Permission;
|
import java.security.Permission;
|
||||||
import java.security.PermissionCollection;
|
import java.security.PermissionCollection;
|
||||||
import java.security.Permissions;
|
import java.security.Permissions;
|
||||||
import java.security.Policy;
|
import java.security.Policy;
|
||||||
import java.security.ProtectionDomain;
|
import java.security.ProtectionDomain;
|
||||||
|
import java.util.Properties;
|
||||||
import java.util.logging.Level;
|
import java.util.logging.Level;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
|
import javax.swing.AbstractAction;
|
||||||
|
import javax.swing.JButton;
|
||||||
|
import javax.swing.JDialog;
|
||||||
import javax.swing.JFrame;
|
import javax.swing.JFrame;
|
||||||
|
import javax.swing.JLabel;
|
||||||
|
import javax.swing.JPanel;
|
||||||
import javax.swing.SwingUtilities;
|
import javax.swing.SwingUtilities;
|
||||||
import javax.swing.UIManager;
|
import javax.swing.UIManager;
|
||||||
|
import javax.xml.parsers.DocumentBuilderFactory;
|
||||||
|
|
||||||
import org.kohsuke.args4j.CmdLineException;
|
import org.kohsuke.args4j.CmdLineException;
|
||||||
|
import org.w3c.dom.NodeList;
|
||||||
|
|
||||||
|
import net.miginfocom.swing.MigLayout;
|
||||||
import net.sf.ehcache.CacheManager;
|
import net.sf.ehcache.CacheManager;
|
||||||
import net.sourceforge.filebot.cli.ArgumentBean;
|
import net.sourceforge.filebot.cli.ArgumentBean;
|
||||||
import net.sourceforge.filebot.cli.ArgumentProcessor;
|
import net.sourceforge.filebot.cli.ArgumentProcessor;
|
||||||
@ -33,6 +49,9 @@ import net.sourceforge.filebot.ui.MainFrame;
|
|||||||
import net.sourceforge.filebot.ui.SinglePanelFrame;
|
import net.sourceforge.filebot.ui.SinglePanelFrame;
|
||||||
import net.sourceforge.filebot.ui.sfv.SfvPanelBuilder;
|
import net.sourceforge.filebot.ui.sfv.SfvPanelBuilder;
|
||||||
import net.sourceforge.filebot.ui.transfer.FileTransferable;
|
import net.sourceforge.filebot.ui.transfer.FileTransferable;
|
||||||
|
import net.sourceforge.filebot.web.CachedResource;
|
||||||
|
import net.sourceforge.tuned.ByteBufferInputStream;
|
||||||
|
import net.sourceforge.tuned.PreferencesMap.PreferencesEntry;
|
||||||
|
|
||||||
|
|
||||||
public class Main {
|
public class Main {
|
||||||
@ -78,23 +97,32 @@ public class Main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// GUI mode => start user interface
|
// GUI mode => start user interface
|
||||||
SwingUtilities.invokeLater(new Runnable() {
|
try {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
@Override
|
|
||||||
public void run() {
|
|
||||||
try {
|
|
||||||
// use native laf an all platforms
|
|
||||||
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
|
||||||
} catch (Exception e) {
|
|
||||||
Logger.getLogger(Main.class.getName()).log(Level.WARNING, e.getMessage(), e);
|
|
||||||
}
|
|
||||||
|
|
||||||
startUserInterface(args);
|
@Override
|
||||||
|
public void run() {
|
||||||
|
try {
|
||||||
|
// use native laf an all platforms
|
||||||
|
UIManager.setLookAndFeel(UIManager.getSystemLookAndFeelClassName());
|
||||||
|
} catch (Exception e) {
|
||||||
|
Logger.getLogger(Main.class.getName()).log(Level.WARNING, e.getMessage(), e);
|
||||||
|
}
|
||||||
|
|
||||||
|
startUserInterface(args);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
// pre-load media.types (when loaded during DnD it will freeze the UI for a few hundred milliseconds)
|
||||||
|
MediaTypes.getDefault();
|
||||||
|
|
||||||
|
// check for application updates (only when installed, i.e. not running via fatjar or webstart)
|
||||||
|
if (System.getProperty("application.deployment") != null) {
|
||||||
|
checkUpdate();
|
||||||
}
|
}
|
||||||
});
|
} catch (Exception e) {
|
||||||
|
Logger.getLogger(Main.class.getName()).log(Level.SEVERE, e.getMessage(), e);
|
||||||
// pre-load media.types (when loaded during DnD it will freeze the UI for a few hundred milliseconds)
|
}
|
||||||
MediaTypes.getDefault();
|
|
||||||
} catch (CmdLineException e) {
|
} catch (CmdLineException e) {
|
||||||
// illegal arguments => just print CLI error message and stop
|
// illegal arguments => just print CLI error message and stop
|
||||||
System.err.println(e.getMessage());
|
System.err.println(e.getMessage());
|
||||||
@ -130,6 +158,85 @@ public class Main {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Show update notifications if updates are available
|
||||||
|
*/
|
||||||
|
private static void checkUpdate() throws Exception {
|
||||||
|
final PreferencesEntry<String> updateIgnoreRevision = Settings.forPackage(Main.class).entry("update.ignore");
|
||||||
|
final Properties updateProperties = new CachedResource<Properties>(getApplicationProperty("update.url"), Properties.class, DAYS.toMillis(1)) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public Properties process(ByteBuffer data) {
|
||||||
|
try {
|
||||||
|
Properties properties = new Properties();
|
||||||
|
NodeList fields = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(new ByteBufferInputStream(data)).getFirstChild().getChildNodes();
|
||||||
|
for (int i = 0; i < fields.getLength(); i++) {
|
||||||
|
properties.setProperty(fields.item(i).getNodeName(), fields.item(i).getTextContent());
|
||||||
|
}
|
||||||
|
return properties;
|
||||||
|
} catch (Exception e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}.get();
|
||||||
|
|
||||||
|
// check if update is required
|
||||||
|
int latestRev = Integer.parseInt(updateProperties.getProperty("revision"));
|
||||||
|
int latestIgnoreRev = Math.max(getApplicationRevisionNumber(), updateIgnoreRevision.getValue() == null ? 0 : Integer.parseInt(updateIgnoreRevision.getValue()));
|
||||||
|
|
||||||
|
if (latestRev > latestIgnoreRev) {
|
||||||
|
SwingUtilities.invokeLater(new Runnable() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void run() {
|
||||||
|
final JDialog dialog = new JDialog(JFrame.getFrames()[0], updateProperties.getProperty("title"), ModalityType.APPLICATION_MODAL);
|
||||||
|
final JPanel pane = new JPanel(new MigLayout("fill, nogrid, insets dialog"));
|
||||||
|
dialog.setContentPane(pane);
|
||||||
|
|
||||||
|
pane.add(new JLabel(ResourceManager.getIcon("window.icon.big")), "aligny top");
|
||||||
|
pane.add(new JLabel(updateProperties.getProperty("message")), "gap 10, wrap paragraph:push");
|
||||||
|
pane.add(new JButton(new AbstractAction("Download", ResourceManager.getIcon("dialog.continue")) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent evt) {
|
||||||
|
try {
|
||||||
|
Desktop.getDesktop().browse(URI.create(updateProperties.getProperty("download")));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
dialog.setVisible(false);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}), "tag ok");
|
||||||
|
pane.add(new JButton(new AbstractAction("Details", ResourceManager.getIcon("action.report")) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent evt) {
|
||||||
|
try {
|
||||||
|
Desktop.getDesktop().browse(URI.create(updateProperties.getProperty("discussion")));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RuntimeException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}), "tag help2");
|
||||||
|
pane.add(new JButton(new AbstractAction("Ignore", ResourceManager.getIcon("dialog.cancel")) {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void actionPerformed(ActionEvent evt) {
|
||||||
|
updateIgnoreRevision.setValue(updateProperties.getProperty("revision"));
|
||||||
|
dialog.setVisible(false);
|
||||||
|
}
|
||||||
|
}), "tag cancel");
|
||||||
|
|
||||||
|
dialog.pack();
|
||||||
|
dialog.setLocation(getOffsetLocation(dialog.getOwner()));
|
||||||
|
dialog.setVisible(true);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
private static void restoreWindowBounds(final JFrame window, final Settings settings) {
|
private static void restoreWindowBounds(final JFrame window, final Settings settings) {
|
||||||
// store bounds on close
|
// store bounds on close
|
||||||
window.addWindowListener(new WindowAdapter() {
|
window.addWindowListener(new WindowAdapter() {
|
||||||
|
@ -25,12 +25,12 @@ public final class Settings {
|
|||||||
|
|
||||||
public static String getApplicationName() {
|
public static String getApplicationName() {
|
||||||
return getApplicationProperty("application.name");
|
return getApplicationProperty("application.name");
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getApplicationVersion() {
|
public static String getApplicationVersion() {
|
||||||
return getApplicationProperty("application.version");
|
return getApplicationProperty("application.version");
|
||||||
};
|
}
|
||||||
|
|
||||||
|
|
||||||
public static String getApplicationProperty(String key) {
|
public static String getApplicationProperty(String key) {
|
||||||
|
@ -2,6 +2,9 @@
|
|||||||
application.name: FileBot
|
application.name: FileBot
|
||||||
application.version: 2.3
|
application.version: 2.3
|
||||||
|
|
||||||
|
# application update
|
||||||
|
update.url = http://filebot.sourceforge.net/update.xml
|
||||||
|
|
||||||
# google analytics
|
# google analytics
|
||||||
analytics.WebPropertyID: UA-25379256-3
|
analytics.WebPropertyID: UA-25379256-3
|
||||||
|
|
||||||
|
@ -110,7 +110,7 @@ public class ReleaseInfo {
|
|||||||
|
|
||||||
|
|
||||||
// fetch release group names online and try to update the data every other day
|
// fetch release group names online and try to update the data every other day
|
||||||
protected final CachedResource<String[]> releaseGroupResource = new CachedResource<String[]>(getBundle(getClass().getName()).getString("url.release-groups"), String[].class, DAYS.toMillis(2)) {
|
protected final CachedResource<String[]> releaseGroupResource = new CachedResource<String[]>(getBundle(getClass().getName()).getString("url.release-groups"), String[].class, DAYS.toMillis(1)) {
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String[] process(ByteBuffer data) {
|
public String[] process(ByteBuffer data) {
|
||||||
|
14
website/update.xml
Normal file
14
website/update.xml
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
<?xml version="1.0" encoding="UTF-8" ?>
|
||||||
|
<update>
|
||||||
|
<revision>777</revision>
|
||||||
|
<title>New updates available</title>
|
||||||
|
<message><![CDATA[<html>
|
||||||
|
<b>FileBot 2.3 (r777) is out!</b><br>
|
||||||
|
This release features:<br>
|
||||||
|
+ New Feature 1<br>
|
||||||
|
+ New Feature 2<br>
|
||||||
|
+ New Feature 3<br>
|
||||||
|
<html>]]></message>
|
||||||
|
<discussion><![CDATA[http://filebot.sourceforge.net/forums/viewtopic.php?f=7&t=24#p43]]></discussion>
|
||||||
|
<download><![CDATA[http://filebot.sourceforge.net/#download]]></download>
|
||||||
|
</update>
|
Loading…
Reference in New Issue
Block a user