Refactored plugin architecture out of WebThing.cs
authorChip Black <bytex64@bytex64.net>
Sun, 7 Jun 2009 08:59:11 +0000 (03:59 -0500)
committerChip Black <bytex64@bytex64.net>
Sun, 7 Jun 2009 08:59:11 +0000 (03:59 -0500)
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
Makefile
PluginManager.cs [new file with mode: 0644]
WebThing
WebThing.cs
plugins/LoadProgress.cs
plugins/Vimish.cs

index 9ad8095..49e7203 100644 (file)
--- 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<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) {
@@ -30,7 +47,15 @@ namespace bytex64.WebThing {
                     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;
+                }
             }
         }
 
@@ -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;
                 }
             }
 
index 893e5a2..249504a 100644 (file)
--- 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 (file)
index 0000000..55f4d21
--- /dev/null
@@ -0,0 +1,42 @@
+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);
+            }
+        }
+    }
+}
index c3f8fa3..1f48064 100755 (executable)
--- 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.
index 5aa52cf..c1e1806 100644 (file)
@@ -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<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();
@@ -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);
         }
index 9da760a..d635573 100644 (file)
@@ -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) {
index ebe088c..3b4969f 100644 (file)
@@ -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();