forked from I2P_Developers/i2p.i2p
* Plugins:
- Hook up update/delete/check/save buttons - Implement delete - Hide unless router.enablePlugins=true
This commit is contained in:
@ -35,6 +35,10 @@ public class ConfigClientsHandler extends FormHandler {
|
||||
saveWebAppChanges();
|
||||
return;
|
||||
}
|
||||
if (_action.equals(_("Save Plugin Configuration"))) {
|
||||
savePluginChanges();
|
||||
return;
|
||||
}
|
||||
if (_action.equals(_("Install Plugin"))) {
|
||||
installPlugin();
|
||||
return;
|
||||
@ -60,10 +64,42 @@ public class ConfigClientsHandler extends FormHandler {
|
||||
try {
|
||||
appnum = Integer.parseInt(app);
|
||||
} catch (NumberFormatException nfe) {}
|
||||
if (appnum >= 0)
|
||||
if (appnum >= 0) {
|
||||
deleteClient(appnum);
|
||||
} else {
|
||||
try {
|
||||
PluginStarter.stopPlugin(_context, app);
|
||||
} catch (Exception e) {}
|
||||
PluginStarter.deletePlugin(_context, app);
|
||||
addFormNotice(_("Deleted plugin {0}", app));
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// value
|
||||
if (_action.startsWith("Stop ")) {
|
||||
String app = _action.substring(5);
|
||||
try {
|
||||
PluginStarter.stopPlugin(_context, app);
|
||||
} catch (Exception e) {}
|
||||
addFormNotice(_("Stopped plugin {0}", app));
|
||||
return;
|
||||
}
|
||||
|
||||
// value
|
||||
if (_action.startsWith("Update ")) {
|
||||
String app = _action.substring(7);
|
||||
updatePlugin(app);
|
||||
return;
|
||||
}
|
||||
|
||||
// value
|
||||
if (_action.startsWith("Check ")) {
|
||||
String app = _action.substring(6);
|
||||
checkPlugin(app);
|
||||
return;
|
||||
}
|
||||
|
||||
// label (IE)
|
||||
String xStart = _("Start");
|
||||
if (_action.toLowerCase().startsWith(xStart + "<span class=hide> ") &&
|
||||
@ -81,6 +117,7 @@ public class ConfigClientsHandler extends FormHandler {
|
||||
} else {
|
||||
addFormError(_("Unsupported") + ' ' + _action + '.');
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void setSettings(Map settings) { _settings = new HashMap(settings); }
|
||||
@ -175,7 +212,23 @@ public class ConfigClientsHandler extends FormHandler {
|
||||
props.setProperty(name, "" + (val != null));
|
||||
}
|
||||
RouterConsoleRunner.storeWebAppProperties(props);
|
||||
addFormNotice(_("WebApp configuration saved successfully - restart required to take effect."));
|
||||
addFormNotice(_("WebApp configuration saved."));
|
||||
}
|
||||
|
||||
private void savePluginChanges() {
|
||||
Properties props = PluginStarter.pluginProperties();
|
||||
Set keys = props.keySet();
|
||||
int cur = 0;
|
||||
for (Iterator iter = keys.iterator(); iter.hasNext(); ) {
|
||||
String name = (String)iter.next();
|
||||
if (! (name.startsWith(PluginStarter.PREFIX) && name.endsWith(PluginStarter.ENABLED)))
|
||||
continue;
|
||||
String app = name.substring(PluginStarter.PREFIX.length(), name.lastIndexOf(PluginStarter.ENABLED));
|
||||
Object val = _settings.get(app + ".enabled");
|
||||
props.setProperty(name, "" + (val != null));
|
||||
}
|
||||
PluginStarter.storePluginProperties(props);
|
||||
addFormNotice(_("Plugin configuration saved."));
|
||||
}
|
||||
|
||||
/**
|
||||
@ -205,6 +258,20 @@ public class ConfigClientsHandler extends FormHandler {
|
||||
addFormError(_("No plugin URL specified."));
|
||||
return;
|
||||
}
|
||||
installPlugin(url);
|
||||
}
|
||||
|
||||
private void updatePlugin(String app) {
|
||||
Properties props = PluginStarter.pluginProperties(_context, app);
|
||||
String url = props.getProperty("updateURL");
|
||||
if (url == null) {
|
||||
addFormError(_("No update URL specified for {0}",app));
|
||||
return;
|
||||
}
|
||||
installPlugin(url);
|
||||
}
|
||||
|
||||
private void installPlugin(String url) {
|
||||
if ("true".equals(System.getProperty(UpdateHandler.PROP_UPDATE_IN_PROGRESS))) {
|
||||
addFormError(_("Plugin or update download already in progress."));
|
||||
return;
|
||||
@ -221,4 +288,23 @@ public class ConfigClientsHandler extends FormHandler {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
|
||||
private void checkPlugin(String app) {
|
||||
if ("true".equals(System.getProperty(UpdateHandler.PROP_UPDATE_IN_PROGRESS))) {
|
||||
addFormError(_("Plugin or update download already in progress."));
|
||||
return;
|
||||
}
|
||||
PluginUpdateChecker puc = PluginUpdateChecker.getInstance(_context);
|
||||
if (puc.isRunning()) {
|
||||
addFormError(_("Plugin or update download already in progress."));
|
||||
return;
|
||||
}
|
||||
puc.update(app);
|
||||
addFormNotice(_("Checking plugin {0} for updates", app));
|
||||
// So that update() will post a status to the summary bar before we reload
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
} catch (InterruptedException ie) {}
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -70,6 +70,10 @@ public class ConfigClientsHelper extends HelperBase {
|
||||
return buf.toString();
|
||||
}
|
||||
|
||||
public boolean showPlugins() {
|
||||
return PluginStarter.pluginsEnabled(_context);
|
||||
}
|
||||
|
||||
public String getForm3() {
|
||||
StringBuilder buf = new StringBuilder(1024);
|
||||
buf.append("<table>\n");
|
||||
@ -170,7 +174,7 @@ public class ConfigClientsHelper extends HelperBase {
|
||||
if (ro)
|
||||
buf.append("disabled=\"true\" ");
|
||||
}
|
||||
buf.append("/></td><td align=\"center\" width=\"15%\">");
|
||||
buf.append("></td><td align=\"center\" width=\"15%\">");
|
||||
if ((!enabled) && !edit) {
|
||||
buf.append("<button type=\"submit\" name=\"action\" value=\"Start ").append(index).append("\" >" + _("Start") + "<span class=hide> ").append(index).append("</span></button>");
|
||||
}
|
||||
|
@ -19,6 +19,7 @@ import net.i2p.data.DataHelper;
|
||||
import net.i2p.router.RouterContext;
|
||||
import net.i2p.router.startup.ClientAppConfig;
|
||||
import net.i2p.router.startup.LoadClientAppsJob;
|
||||
import net.i2p.util.FileUtil;
|
||||
import net.i2p.util.Log;
|
||||
import net.i2p.util.Translate;
|
||||
|
||||
@ -41,6 +42,10 @@ public class PluginStarter implements Runnable {
|
||||
_context = ctx;
|
||||
}
|
||||
|
||||
static boolean pluginsEnabled(I2PAppContext ctx) {
|
||||
return Boolean.valueOf(ctx.getProperty("router.enablePlugins")).booleanValue();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
startPlugins(_context);
|
||||
}
|
||||
@ -50,9 +55,9 @@ public class PluginStarter implements Runnable {
|
||||
Properties props = pluginProperties();
|
||||
for (Iterator iter = props.keySet().iterator(); iter.hasNext(); ) {
|
||||
String name = (String)iter.next();
|
||||
if (name.startsWith(PluginStarter.PREFIX) && name.endsWith(PluginStarter.ENABLED)) {
|
||||
if (name.startsWith(PREFIX) && name.endsWith(ENABLED)) {
|
||||
if (Boolean.valueOf(props.getProperty(name)).booleanValue()) {
|
||||
String app = name.substring(PluginStarter.PREFIX.length(), name.lastIndexOf(PluginStarter.ENABLED));
|
||||
String app = name.substring(PREFIX.length(), name.lastIndexOf(ENABLED));
|
||||
try {
|
||||
if (!startPlugin(ctx, app))
|
||||
log.error("Failed to start plugin: " + app);
|
||||
@ -188,7 +193,6 @@ public class PluginStarter implements Runnable {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// remove summary bar link
|
||||
Properties props = pluginProperties(ctx, appName);
|
||||
String name = ConfigClientsHelper.stripHTML(props, "consoleLinkName_" + Messages.getLanguage(ctx));
|
||||
@ -200,6 +204,25 @@ public class PluginStarter implements Runnable {
|
||||
return true;
|
||||
}
|
||||
|
||||
/** @return true on success - call stopPlugin() first */
|
||||
static boolean deletePlugin(RouterContext ctx, String appName) {
|
||||
Log log = ctx.logManager().getLog(PluginStarter.class);
|
||||
File pluginDir = new File(ctx.getAppDir(), PluginUpdateHandler.PLUGIN_DIR + '/' + appName);
|
||||
if ((!pluginDir.exists()) || (!pluginDir.isDirectory())) {
|
||||
log.error("Cannot stop nonexistent plugin: " + appName);
|
||||
return false;
|
||||
}
|
||||
FileUtil.rmdir(pluginDir, false);
|
||||
Properties props = pluginProperties();
|
||||
for (Iterator iter = props.keySet().iterator(); iter.hasNext(); ) {
|
||||
String name = (String)iter.next();
|
||||
if (name.startsWith(PREFIX + appName))
|
||||
iter.remove();
|
||||
}
|
||||
storePluginProperties(props);
|
||||
return true;
|
||||
}
|
||||
|
||||
/** plugin.config */
|
||||
public static Properties pluginProperties(I2PAppContext ctx, String appName) {
|
||||
File cfgFile = new File(ctx.getAppDir(), PluginUpdateHandler.PLUGIN_DIR + '/' + appName + '/' + "plugin.config");
|
||||
|
@ -62,14 +62,15 @@ public class PluginUpdateChecker extends UpdateHandler {
|
||||
String oldVersion = props.getProperty("version");
|
||||
String xpi2pURL = props.getProperty("updateURL");
|
||||
if (oldVersion == null || xpi2pURL == null) {
|
||||
updateStatus("<b>" + _("Cannot update, plugin {0} is not installed", appName) + "</b>");
|
||||
updateStatus("<b>" + _("Cannot check, plugin {0} is not installed", appName) + "</b>");
|
||||
return;
|
||||
}
|
||||
|
||||
if (_pluginUpdateCheckerRunner == null)
|
||||
_pluginUpdateCheckerRunner = new PluginUpdateCheckerRunner(xpi2pURL);
|
||||
_pluginUpdateCheckerRunner = new PluginUpdateCheckerRunner();
|
||||
if (_pluginUpdateCheckerRunner.isRunning())
|
||||
return;
|
||||
_xpi2pURL = xpi2pURL;
|
||||
_appName = appName;
|
||||
_oldVersion = oldVersion;
|
||||
System.setProperty(PROP_UPDATE_IN_PROGRESS, "true");
|
||||
@ -89,18 +90,16 @@ public class PluginUpdateChecker extends UpdateHandler {
|
||||
}
|
||||
|
||||
public class PluginUpdateCheckerRunner extends UpdateRunner implements Runnable, EepGet.StatusListener {
|
||||
String _updateURL;
|
||||
ByteArrayOutputStream _baos;
|
||||
|
||||
public PluginUpdateCheckerRunner(String url) {
|
||||
public PluginUpdateCheckerRunner() {
|
||||
super();
|
||||
_updateURL = url;
|
||||
_baos = new ByteArrayOutputStream(TrustedUpdate.HEADER_BYTES);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void update() {
|
||||
updateStatus("<b>" + _("Checking plugin {0} for updates", _appName) + "</b>");
|
||||
updateStatus("<b>" + _("Checking for update of plugin {0}", _appName) + "</b>");
|
||||
// use the same settings as for updater
|
||||
boolean shouldProxy = Boolean.valueOf(_context.getProperty(ConfigUpdateHandler.PROP_SHOULD_PROXY, ConfigUpdateHandler.DEFAULT_SHOULD_PROXY)).booleanValue();
|
||||
String proxyHost = _context.getProperty(ConfigUpdateHandler.PROP_PROXY_HOST, ConfigUpdateHandler.DEFAULT_PROXY_HOST);
|
||||
|
@ -90,11 +90,9 @@ public class PluginUpdateHandler extends UpdateHandler {
|
||||
}
|
||||
|
||||
public class PluginUpdateRunner extends UpdateRunner implements Runnable, EepGet.StatusListener {
|
||||
String _updateURL;
|
||||
|
||||
public PluginUpdateRunner(String url) {
|
||||
super();
|
||||
_updateURL = url;
|
||||
}
|
||||
|
||||
@Override
|
||||
@ -287,7 +285,7 @@ public class PluginUpdateHandler extends UpdateHandler {
|
||||
if (oldVersion == null ||
|
||||
(new VersionComparator()).compare(oldVersion, version) >= 0) {
|
||||
to.delete();
|
||||
updateStatus("<b>" + _("New plugin version {0} is not newer than installed plugin", version) + "</b>");
|
||||
updateStatus("<b>" + _("Downloaded plugin version {0} is not newer than installed plugin", version) + "</b>");
|
||||
return;
|
||||
}
|
||||
minVersion = ConfigClientsHelper.stripHTML(props, "min-installed-version");
|
||||
|
@ -189,8 +189,10 @@ public class RouterConsoleRunner {
|
||||
|
||||
List<RouterContext> contexts = RouterContext.listContexts();
|
||||
if (contexts != null) {
|
||||
t = new I2PAppThread(new PluginStarter(contexts.get(0)), "PluginStarter", true);
|
||||
t.start();
|
||||
if (PluginStarter.pluginsEnabled(contexts.get(0))) {
|
||||
t = new I2PAppThread(new PluginStarter(contexts.get(0)), "PluginStarter", true);
|
||||
t.start();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
Reference in New Issue
Block a user