commit:6c50b11e5b8e72781db4195d8472bb7d542c1d3c
author:Chip Black
committer:Chip Black
date:Sun Jun 7 03:59:11 2009 -0500
parents:223e6cac5499d72fe30fd7c3da817362be7d9fef
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.
diff --git a/Config.cs b/Config.cs
line changes: +57/-8
index 9ad8095..49e7203
--- 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;
                 }
             }
 

diff --git a/Makefile b/Makefile
line changes: +1/-1
index 893e5a2..249504a
--- 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
line changes: +42/-0
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<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);
+            }
+        }
+    }
+}

diff --git a/WebThing b/WebThing
line changes: +1/-1
index c3f8fa3..1f48064
--- 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
line changes: +13/-41
index 5aa52cf..c1e1806
--- 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<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);
         }

diff --git a/plugins/LoadProgress.cs b/plugins/LoadProgress.cs
line changes: +1/-1
index 9da760a..d635573
--- 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
line changes: +1/-1
index ebe088c..3b4969f
--- 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();