I2P Address: [http://git.idk.i2p]

Skip to content
Snippets Groups Projects
Commit b4911a2b authored by zzz's avatar zzz
Browse files

support plugin themes

parent 7b70210c
No related branches found
No related tags found
No related merge requests found
package net.i2p.router.web;
import java.io.File;
import java.util.Iterator;
import java.util.TreeSet;
import java.util.Set;
......@@ -19,6 +20,8 @@ public class ConfigUIHelper extends HelperBase {
return buf.toString();
}
static final String PROP_THEME_PFX = "routerconsole.theme.";
/** @return standard and user-installed themes, sorted (untranslated) */
private Set<String> themeSet() {
Set<String> rv = new TreeSet();
......@@ -33,6 +36,13 @@ public class ConfigUIHelper extends HelperBase {
if (files[i].isDirectory() && ! name.equals("images"))
rv.add(name);
}
// user themes
Set props = _context.getPropertyNames();
for (Iterator iter = props.iterator(); iter.hasNext(); ) {
String prop = (String) iter.next();
if (prop.startsWith(PROP_THEME_PFX) && prop.length() > PROP_THEME_PFX.length())
rv.add(prop.substring(PROP_THEME_PFX.length()));
}
return rv;
}
......
......@@ -6,6 +6,7 @@ import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
......@@ -26,7 +27,9 @@ import org.mortbay.jetty.Server;
/**
* Start plugins that are already installed
* Start/stop/delete plugins that are already installed
* Get properties of installed plugins
* Get or change settings in plugins.config
*
* @since 0.7.12
* @author zzz
......@@ -35,6 +38,10 @@ public class PluginStarter implements Runnable {
private RouterContext _context;
static final String PREFIX = "plugin.";
static final String ENABLED = ".startOnLoad";
private static final String[] STANDARD_WEBAPPS = { "i2psnark", "i2ptunnel", "susidns",
"susimail", "addressbook", "routerconsole" };
private static final String[] STANDARD_THEMES = { "images", "light", "dark", "classic",
"midnight" };
public PluginStarter(RouterContext ctx) {
_context = ctx;
......@@ -81,6 +88,18 @@ public class PluginStarter implements Runnable {
}
//log.error("Starting plugin: " + appName);
// register themes
File dir = new File(pluginDir, "console/themes");
File[] tfiles = dir.listFiles();
if (tfiles != null) {
for (int i = 0; i < tfiles.length; i++) {
String name = tfiles[i].getName();
if (tfiles[i].isDirectory() && (!Arrays.asList(STANDARD_THEMES).contains(tfiles[i])))
ctx.router().setConfigSetting(ConfigUIHelper.PROP_THEME_PFX + name, tfiles[i].getAbsolutePath());
// we don't need to save
}
}
// load and start things in clients.config
File clientConfig = new File(pluginDir, "clients.config");
if (clientConfig.exists()) {
......@@ -103,9 +122,7 @@ public class PluginStarter implements Runnable {
String warName = fileNames[i].substring(0, fileNames[i].lastIndexOf(".war"));
//log.error("Found webapp: " + warName);
// check for duplicates in $I2P
// easy way for now...
if (warName.equals("i2psnark") || warName.equals("susidns") || warName.equals("i2ptunnel") ||
warName.equals("susimail") || warName.equals("addressbook")) {
if (Arrays.asList(STANDARD_WEBAPPS).contains(warName)) {
log.error("Skipping duplicate webapp " + warName + " in plugin " + appName);
continue;
}
......@@ -147,8 +164,6 @@ public class PluginStarter implements Runnable {
}
}
// add themes in console/themes
// add summary bar link
Properties props = pluginProperties(ctx, appName);
String name = ConfigClientsHelper.stripHTML(props, "consoleLinkName_" + Messages.getLanguage(ctx));
......@@ -192,8 +207,7 @@ public class PluginStarter implements Runnable {
if (fileNames != null) {
for (int i = 0; i < fileNames.length; i++) {
String warName = fileNames[i].substring(0, fileNames[i].lastIndexOf(".war"));
if (warName.equals("i2psnark") || warName.equals("susidns") || warName.equals("i2ptunnel") ||
warName.equals("susimail") || warName.equals("addressbook")) {
if (Arrays.asList(STANDARD_WEBAPPS).contains(warName)) {
continue;
}
WebAppStarter.stopWebApp(server, warName);
......@@ -213,12 +227,12 @@ public class PluginStarter implements Runnable {
return true;
}
/** @return true on success - call stopPlugin() first */
/** @return true on success - caller should call stopPlugin() first */
static boolean deletePlugin(RouterContext ctx, String appName) throws IOException {
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);
log.error("Cannot delete nonexistent plugin: " + appName);
return false;
}
// uninstall things in clients.config
......@@ -229,6 +243,24 @@ public class PluginStarter implements Runnable {
List<ClientAppConfig> clients = ClientAppConfig.getClientApps(clientConfig);
runClientApps(ctx, pluginDir, clients, "uninstall");
}
// unregister themes, and switch to default if we are unregistering the current theme
File dir = new File(pluginDir, "console/themes");
File[] tfiles = dir.listFiles();
if (tfiles != null) {
String current = ctx.getProperty(CSSHelper.PROP_THEME_NAME);
for (int i = 0; i < tfiles.length; i++) {
String name = tfiles[i].getName();
if (tfiles[i].isDirectory() && (!name.equals("images")) && (!name.equals("classic")) &&
(!name.equals("dark")) && (!name.equals("light")) && (!name.equals("midnight"))) {
ctx.router().removeConfigSetting(ConfigUIHelper.PROP_THEME_PFX + name);
if (name.equals(current))
ctx.router().setConfigSetting(CSSHelper.PROP_THEME_NAME, CSSHelper.DEFAULT_THEME);
}
}
ctx.router().saveConfig();
}
FileUtil.rmdir(pluginDir, false);
Properties props = pluginProperties();
for (Iterator iter = props.keySet().iterator(); iter.hasNext(); ) {
......
......@@ -20,7 +20,29 @@ if (uri.endsWith(".css")) {
response.setContentType("image/x-icon");
}
response.setHeader("Cache-Control", "max-age=86400"); // cache for a day
String base = net.i2p.I2PAppContext.getGlobalContext().getBaseDir().getAbsolutePath() +
/*
* User or plugin themes
* If the request is for /themes/console/foo/bar/baz,
* and the property routerconsole.theme.foo=/path/to/foo,
* get the file from /path/to/foo/bar/baz
*/
String themePath = null;
final String PFX = "/themes/console/";
if (uri.startsWith(PFX) && uri.length() > PFX.length() + 1) {
String theme = uri.substring(PFX.length());
int slash = theme.indexOf('/');
if (slash > 0) {
theme = theme.substring(0, slash);
themePath = net.i2p.I2PAppContext.getGlobalContext().getProperty("routerconsole.theme." + theme);
if (themePath != null)
uri = uri.substring(PFX.length() + theme.length()); // /bar/baz
}
}
String base;
if (themePath != null)
base = themePath;
else
base = net.i2p.I2PAppContext.getGlobalContext().getBaseDir().getAbsolutePath() +
java.io.File.separatorChar + "docs";
net.i2p.util.FileUtil.readFile(uri, base, response.getOutputStream());
%>
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment