From 6c50b11e5b8e72781db4195d8472bb7d542c1d3c Mon Sep 17 00:00:00 2001 From: Chip Black Date: Sun, 7 Jun 2009 03:59:11 -0500 Subject: [PATCH] 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. --- Config.cs | 65 ++++++++++++++++++++++++++++++++++++----- Makefile | 2 +- PluginManager.cs | 42 ++++++++++++++++++++++++++ WebThing | 2 +- WebThing.cs | 54 +++++++++------------------------- plugins/LoadProgress.cs | 2 +- plugins/Vimish.cs | 2 +- 7 files changed, 116 insertions(+), 53 deletions(-) create mode 100644 PluginManager.cs diff --git a/Config.cs b/Config.cs index 9ad8095..49e7203 100644 --- a/Config.cs +++ b/Config.cs @@ -1,24 +1,41 @@ 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 ConfigPath; public static Dictionary Options; public static Dictionary> PluginOptions; public static string[] Arguments; - private static HashSet CommandLineOptions; + public static List Plugins; - public static Regex item_re = new Regex(@"^(?:([\w.]+)\.)?(\w+)$"); - public static Regex file_var_re = new Regex(@"^([\w.]+)\s*=\s*(.*)$"); + private static HashSet 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(); PluginOptions = new Dictionary>(); CommandLineOptions = new HashSet(); + Plugins = new List(); + + // Set up ConfigPath + IDictionary Env = Environment.GetEnvironmentVariables(); + ConfigPath = new List(); + 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) { @@ -30,7 +47,15 @@ namespace bytex64.WebThing { PluginOptions[plugin] = new Dictionary(); 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; + } } } @@ -103,8 +128,13 @@ namespace bytex64.WebThing { } 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"]); } @@ -120,11 +150,30 @@ namespace bytex64.WebThing { 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; } } diff --git a/Makefile b/Makefile index 893e5a2..249504a 100644 --- a/Makefile +++ b/Makefile @@ -13,7 +13,7 @@ tags: 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 diff --git a/PluginManager.cs b/PluginManager.cs new file mode 100644 index 0000000..55f4d21 --- /dev/null +++ b/PluginManager.cs @@ -0,0 +1,42 @@ +using System; +using System.Reflection; +using System.Collections.Generic; +using WebKit; + +namespace bytex64.WebThing { + public class PluginManager { + public Dictionary Plugins; + + private WebThing wt; + + public PluginManager(WebThing wt) { + Plugins = new Dictionary(); + 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); + } + } + } +} diff --git a/WebThing b/WebThing index c3f8fa3..1f48064 100755 --- a/WebThing +++ b/WebThing @@ -1,6 +1,6 @@ #!/bin/sh -WEBTHING_HOME=`dirname "$0"` +export WEBTHING_HOME=`dirname "$0"` # We change directories because we don't have a proper configuration # architecture, yet. diff --git a/WebThing.cs b/WebThing.cs index 5aa52cf..c1e1806 100644 --- a/WebThing.cs +++ b/WebThing.cs @@ -1,6 +1,5 @@ using System; using System.Collections.Generic; -using System.Reflection; using System.IO; using System.Text.RegularExpressions; using System.Runtime.InteropServices; @@ -9,7 +8,7 @@ using GtkSharp; using WebKit; namespace bytex64.WebThing { - public enum CompassDirection { + public enum AttachPoint { N, E, S, W, Interior } @@ -44,14 +43,13 @@ namespace bytex64.WebThing { private Gtk.Table WidgetGrid; private Gtk.Alignment InteriorOverlay; - public Dictionary Plugins; + public PluginManager Plugins; [DllImport ("SoupSettings.dll")] private static extern void soup_settings(); public void Run() { Application.Init(); - Plugins = new Dictionary(); Config.ParseCommandLine(); Config.Load(); @@ -80,61 +78,41 @@ namespace bytex64.WebThing { 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; } @@ -150,12 +128,6 @@ namespace bytex64.WebThing { return newview; } - private void WebViewSetupPlugins(WebView view) { - foreach (string key in Plugins.Keys) { - Plugins[key].InitWebView(view); - } - } - public void CloseTab() { CloseTab(_Tabs.Page); } diff --git a/plugins/LoadProgress.cs b/plugins/LoadProgress.cs index 9da760a..d635573 100644 --- a/plugins/LoadProgress.cs +++ b/plugins/LoadProgress.cs @@ -86,7 +86,7 @@ public class LoadThrobberPlugin : WebThingPlugin { 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) { diff --git a/plugins/Vimish.cs b/plugins/Vimish.cs index ebe088c..3b4969f 100644 --- a/plugins/Vimish.cs +++ b/plugins/Vimish.cs @@ -17,7 +17,7 @@ public class Vimish : WebThingPlugin { 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(); -- 2.25.1