Refactored plugin architecture out of WebThing.cs
Added support for adding plugins via configuration files, obsoleting
'plugins.conf'. Moved plugin loading out of WebThing and into
PluginManager. Slight modification to WebThing launch script exports
WEBTHING_HOME, which is used in PluginManager to find the plugin
directory. Minor modifications to WebThing widget attachment names;
Vimish and LoadProgress changed to suit.
using System;
using System.IO;
+using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;
namespace bytex64.WebThing {
public class Config {
- public static string ConfigurationPrefix = "/etc";
+ public static List<string> ConfigPath;
public static Dictionary<string,string> Options;
public static Dictionary<string,Dictionary<string,string>> PluginOptions;
public static string[] Arguments;
- private static HashSet<string> CommandLineOptions;
+ public static List<string> Plugins;
- public static Regex item_re = new Regex(@"^(?:([\w.]+)\.)?(\w+)$");
- public static Regex file_var_re = new Regex(@"^([\w.]+)\s*=\s*(.*)$");
+ private static HashSet<string> CommandLineOptions;
+ private static Regex item_re = new Regex(@"^(?:([\w.]+)\.)?(\w+)$");
+ private static Regex file_var_re = new Regex(@"^([\w.]+)\s*=\s*(.*)$");
+ private static Regex file_command_re = new Regex(@"^([\w]+)\s*(.*)$");
static Config() {
Options = new Dictionary<string,string>();
PluginOptions = new Dictionary<string,Dictionary<string,string>>();
CommandLineOptions = new HashSet<string>();
+ Plugins = new List<string>();
+
+ // Set up ConfigPath
+ IDictionary Env = Environment.GetEnvironmentVariables();
+ ConfigPath = new List<string>();
+ ConfigPath.Add("/etc/WebThing");
+ if (Env.Contains("HOME")) {
+ ConfigPath.Add(Env["HOME"] + "/.config/WebThing");
+ ConfigPath.Add(Env["HOME"] + "/.WebThing");
+ }
+ string LocalAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
+ if (LocalAppData != "") {
+ ConfigPath.Add(LocalAppData + "/WebThing");
+ }
}
private static void ParseOption(string key, string val) {
PluginOptions[plugin] = new Dictionary<string,string>();
PluginOptions[plugin][name] = val;
} else { // Global Option
- Options[name] = val;
+ switch(key) {
+ case "Plugin":
+ case "plugin":
+ Plugins.Add(val);
+ break;
+ default:
+ Options[key] = val;
+ break;
+ }
}
}
}
public static void Load() {
- LoadFile(ConfigurationPrefix + "/WebThing.conf");
- LoadFile(Environment.GetEnvironmentVariable("HOME") + "/.config/WebThing/WebThing.conf");
+ foreach (string path in ConfigPath) {
+ if (!Directory.Exists(path)) continue;
+ string[] ConfigFiles = Directory.GetFiles(path, "*.conf");
+ foreach (string file in ConfigFiles) {
+ LoadFile(file);
+ }
+ }
if (Options.ContainsKey("config"))
LoadFile(Options["config"]);
}
string line;
while ((line = f.ReadLine()) != null) {
- Match m = file_var_re.Match(line.Trim());
+ Match m;
+
+ line = line.Trim();
+ m = file_var_re.Match(line);
if (m.Success) {
string key = m.Groups[1].Value;
if (!CommandLineOptions.Contains(key))
ParseOption(key, m.Groups[2].Value);
+ continue;
+ }
+
+ m = file_command_re.Match(line);
+ if (m.Success) {
+ string cmd = m.Groups[1].Value;
+ switch(cmd) {
+ case "Plugin":
+ case "plugin":
+ Plugins.Add(m.Groups[2].Value);
+ break;
+ default:
+ Console.WriteLine("Unknown Command in {0}: {1}", filename, line);
+ break;
+ }
+ continue;
}
}
WebThingMain.exe: WebThingMain.cs WebThing.dll SoupSettings.so
$(CS) $(CSFLAGS) -r:WebThing.dll -out:$@ WebThingMain.cs
-WebThing.dll: WebThing.cs WebThingView.cs WebThingPlugin.cs Config.cs
+WebThing.dll: WebThing.cs WebThingView.cs WebThingPlugin.cs Config.cs PluginManager.cs
$(CS) $(CSFLAGS) $(references) -target:library -out:$@ $^
SoupSettings.so: SoupSettings.c
+using System;
+using System.Reflection;
+using System.Collections.Generic;
+using WebKit;
+
+namespace bytex64.WebThing {
+ public class PluginManager {
+ public Dictionary<string,WebThingPlugin> Plugins;
+
+ private WebThing wt;
+
+ public PluginManager(WebThing wt) {
+ Plugins = new Dictionary<string,WebThingPlugin>();
+ this.wt = wt;
+ }
+
+ public void Load() {
+ foreach (string plugin in Config.Plugins) {
+ LoadPlugin(plugin);
+ }
+ }
+
+ public void LoadPlugin(string assemblyname) {
+ Assembly a = Assembly.LoadFile(Environment.GetEnvironmentVariable("WEBTHING_HOME") + "/plugins/" + assemblyname + ".dll");
+ Type[] types = a.GetTypes();
+ foreach (Type t in types) {
+ if (t.IsSubclassOf(typeof(WebThingPlugin))) {
+ WebThingPlugin p = (WebThingPlugin) a.CreateInstance(t.FullName, false, BindingFlags.ExactBinding, null, null, null, null);
+ p.Init(wt);
+ Plugins[t.FullName] = p;
+ Console.WriteLine("Successfully loaded {0}", t.FullName);
+ }
+ }
+ }
+
+ public void WebViewSetup(WebView view) {
+ foreach (string key in Plugins.Keys) {
+ Plugins[key].InitWebView(view);
+ }
+ }
+ }
+}
#!/bin/sh
-WEBTHING_HOME=`dirname "$0"`
+export WEBTHING_HOME=`dirname "$0"`
# We change directories because we don't have a proper configuration
# architecture, yet.
using System;
using System.Collections.Generic;
-using System.Reflection;
using System.IO;
using System.Text.RegularExpressions;
using System.Runtime.InteropServices;
using WebKit;
namespace bytex64.WebThing {
- public enum CompassDirection {
+ public enum AttachPoint {
N, E, S, W, Interior
}
private Gtk.Table WidgetGrid;
private Gtk.Alignment InteriorOverlay;
- public Dictionary<string,WebThingPlugin> Plugins;
+ public PluginManager Plugins;
[DllImport ("SoupSettings.dll")]
private static extern void soup_settings();
public void Run() {
Application.Init();
- Plugins = new Dictionary<string,WebThingPlugin>();
Config.ParseCommandLine();
Config.Load();
WebThingView newview = NewWebThingView();
- // TODO: Conf.Get("plugins") instead of hard-coded path?
- using (TextReader f = new StreamReader("plugins.conf")) {
- string line;
- while ((line = f.ReadLine()) != null) {
- line = line.Trim();
- LoadPlugin(line);
- }
- }
-
- WebViewSetupPlugins(newview.WebView);
+ Plugins = new PluginManager(this);
+ Plugins.Load();
+ Plugins.WebViewSetup(newview.WebView);
newview.WebView.GrabFocus();
Application.Run();
}
- public void LoadPlugin(string assemblyname) {
- Assembly a = Assembly.LoadFile("plugins/" + assemblyname + ".dll");
- Type[] types = a.GetTypes();
- foreach (Type t in types) {
- if (t.IsSubclassOf(typeof(WebThingPlugin))) {
- WebThingPlugin p = (WebThingPlugin) a.CreateInstance(t.FullName, false, BindingFlags.ExactBinding, null, null, null, null);
- p.Init(this);
- Plugins[t.FullName] = p;
- Console.WriteLine("Successfully loaded {0}", t.FullName);
- }
- }
- }
-
- public void AttachWidget(Gtk.Widget widget, CompassDirection direction, AttachOptions xoptions, AttachOptions yoptions) {
+ public void AttachWidget(Gtk.Widget widget, AttachPoint direction, AttachOptions xoptions, AttachOptions yoptions) {
switch(direction) {
- case CompassDirection.N:
+ case AttachPoint.N:
WidgetGrid.Attach(widget, 0, 3, 0, 1, xoptions, yoptions, 0, 0);
break;
- case CompassDirection.E:
+ case AttachPoint.E:
WidgetGrid.Attach(widget, 2, 3, 1, 2, xoptions, yoptions, 0, 0);
break;
- case CompassDirection.S:
+ case AttachPoint.S:
WidgetGrid.Attach(widget, 0, 3, 2, 3, xoptions, yoptions, 0, 0);
break;
- case CompassDirection.W:
+ case AttachPoint.W:
WidgetGrid.Attach(widget, 0, 1, 1, 2, xoptions, yoptions, 0, 0);
break;
- case CompassDirection.Interior:
+ case AttachPoint.Interior:
InteriorOverlay.Add(widget);
break;
}
}
- public void AttachWidget(Gtk.Widget widget, CompassDirection direction) {
+ public void AttachWidget(Gtk.Widget widget, AttachPoint direction) {
AttachWidget(widget, direction, 0, 0);
}
public WebView NewTab() {
WebThingView newview = NewWebThingView();
- WebViewSetupPlugins(newview.WebView);
+ Plugins.WebViewSetup(newview.WebView);
return newview.WebView;
}
return newview;
}
- private void WebViewSetupPlugins(WebView view) {
- foreach (string key in Plugins.Keys) {
- Plugins[key].InitWebView(view);
- }
- }
-
public void CloseTab() {
CloseTab(_Tabs.Page);
}
public override void Init(WebThing wt) {
lt = new LoadThrobber(wt);
- wt.AttachWidget(lt, CompassDirection.Interior);
+ wt.AttachWidget(lt, AttachPoint.Interior);
}
public override void InitWebView(WebView wv) {
commandline = new Gtk.Entry();
commandline.Activated += command_Activate;
commandline.KeyPressEvent += command_KeyPress;
- wt.AttachWidget(commandline, CompassDirection.S, AttachOptions.Fill, AttachOptions.Shrink);
+ wt.AttachWidget(commandline, AttachPoint.S, AttachOptions.Fill, AttachOptions.Shrink);
commandline.Hide();