3 using System.Collections;
4 using System.Collections.Generic;
5 using System.Text.RegularExpressions;
7 namespace bytex64.WebThing {
8 public struct SearchHandlerPair {
9 public string Shortcut;
12 public SearchHandlerPair(string s, string p) {
19 public static List<string> ConfigPath;
20 public static string ConfigPathOut = null;
21 public static List<string> PluginPath;
23 public static Dictionary<string,string> Options;
24 public static Dictionary<string,Dictionary<string,string>> PluginOptions;
25 public static string[] Arguments;
26 public static List<string> Plugins;
27 public static List<SearchHandlerPair> SearchHandlers;
28 public static string DefaultSearchHandler;
30 private static HashSet<string> CommandLineOptions;
31 private static Regex item_re = new Regex(@"^(?:([\w.]+)\.)?(\w+)$");
32 private static Regex file_var_re = new Regex(@"^([\w.]+)\s*=\s*(.*)$");
33 private static Regex file_command_re = new Regex(@"^([\w]+)\s*(.*)$");
36 Options = new Dictionary<string,string>();
37 PluginOptions = new Dictionary<string,Dictionary<string,string>>();
38 CommandLineOptions = new HashSet<string>();
39 Plugins = new List<string>();
40 SearchHandlers = new List<SearchHandlerPair>();
43 IDictionary Env = Environment.GetEnvironmentVariables();
44 ConfigPath = new List<string>();
45 ConfigPath.Add("/etc/WebThing");
46 if (Env.Contains("HOME")) {
47 string homepath = Env["HOME"] + "/.config/WebThing";
48 ConfigPath.Add(homepath);
49 if (Directory.Exists(homepath))
50 ConfigPathOut = homepath;
52 string LocalAppData = Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData);
53 if (LocalAppData != "") {
54 string homepath = LocalAppData + "/WebThing";
55 ConfigPath.Add(homepath);
56 if (Directory.Exists(homepath))
57 ConfigPathOut = homepath;
61 PluginPath = new List<string>();
62 PluginPath.Add(Environment.GetEnvironmentVariable("WEBTHING_HOME") + "/plugins");
63 PluginPath.Add(Environment.GetEnvironmentVariable("WEBTHING_HOME") + "/searchplugins");
66 private static void ParseOption(string key, string val) {
67 Match m = item_re.Match(key);
68 string plugin = m.Groups[1].Value;
69 string name = m.Groups[2].Value;
70 if (plugin.Length > 0) { // Plugin Option
71 if (!PluginOptions.ContainsKey(plugin))
72 PluginOptions[plugin] = new Dictionary<string,string>();
73 PluginOptions[plugin][name] = val;
74 } else { // Global Option
75 switch(key.ToLower()) {
86 public static void DumpOptions() {
87 Console.WriteLine("Options:");
88 foreach (string key in Options.Keys)
89 Console.WriteLine(" {0}\t{1}", key, Options[key]);
91 Console.WriteLine("Plugin Options:");
92 foreach (string plugin in PluginOptions.Keys) {
93 Console.WriteLine(" {0}", plugin);
94 foreach (string key in PluginOptions[plugin].Keys)
95 Console.WriteLine(" {0}\t{1}", key, PluginOptions[plugin][key]);
98 Console.WriteLine("Arguments: {0}", String.Join(" ", Arguments));
101 public static void ParseCommandLine() {
102 Queue<string> q = new Queue<string>();
103 foreach (string s in System.Environment.GetCommandLineArgs()) {
106 q.Dequeue(); // Remove self argument
108 Regex SimpleOpt = new Regex(@"^-([\w.]+)(?:[:=](.*))?$");
109 Regex LongOpt = new Regex(@"^--([\w.]+)$");
110 List<string> args = new List<string>();
112 while (q.Count > 0) {
113 string opt = q.Dequeue();
116 m = SimpleOpt.Match(opt);
118 string key = m.Groups[1].Value;
119 string val = m.Groups[2].Value;
120 if (val.Length > 0) {
121 ParseOption(key, val);
123 ParseOption(key, null);
125 CommandLineOptions.Add(key);
129 m = LongOpt.Match(opt);
131 string key = m.Groups[1].Value;
133 string val = q.Peek();
134 if (!(SimpleOpt.IsMatch(val) || LongOpt.IsMatch(val))) {
136 ParseOption(key, val);
138 ParseOption(key, null);
141 ParseOption(key, null);
143 CommandLineOptions.Add(key);
151 Arguments = args.ToArray();
154 public static void Load() {
155 foreach (string path in ConfigPath) {
156 if (!Directory.Exists(path)) continue;
157 string[] ConfigFiles = Directory.GetFiles(path, "*.conf");
158 foreach (string file in ConfigFiles) {
162 if (Options.ContainsKey("config"))
163 LoadFile(Options["config"]);
166 public static void LoadFile(string filename) {
169 f = new StreamReader(filename);
170 } catch (FileNotFoundException) {
171 Console.WriteLine("Could not open configuration file {0}", filename);
176 while ((line = f.ReadLine()) != null) {
180 m = file_var_re.Match(line);
182 string key = m.Groups[1].Value;
183 if (!CommandLineOptions.Contains(key))
184 ParseOption(key, m.Groups[2].Value);
188 m = file_command_re.Match(line);
190 string cmd = m.Groups[1].Value.ToLower();
193 Plugins.Add(m.Groups[2].Value);
195 case "searchhandler":
196 string[] args = Regex.Split(m.Groups[2].Value, @"\s+");
197 if (args.Length != 2) {
198 Console.WriteLine("Expecting two arguments for SearchHandler.");
201 SearchHandlers.Add(new SearchHandlerPair(args[0], args[1]));
203 case "defaultsearchhandler":
204 DefaultSearchHandler = m.Groups[2].Value;
207 Console.WriteLine("Unknown Command in {0}: {1}", filename, line);
217 public static void SaveFile(string filename) {
220 f = new StreamWriter(filename);
221 } catch (IOException) {
222 Console.WriteLine("Could not save configuration to {0}", filename);
226 foreach (string key in Options.Keys) {
227 if (CommandLineOptions.Contains(key)) continue;
228 f.WriteLine("{0} = {1}", key, Options[key]);
231 foreach (string plugin in PluginOptions.Keys) {
232 foreach (string key in PluginOptions[plugin].Keys) {
233 string pkey = String.Format("{0}.{1}", plugin, key);
234 if (CommandLineOptions.Contains(pkey)) continue;
235 f.WriteLine("{0} = {1}", pkey, PluginOptions[plugin][key]);
242 public static void SaveFile(WebThingPlugin p, string filename) {
243 string plugin_name = p.GetType().FullName;
244 SaveFile(plugin_name, filename);
247 public static void SaveFile(string plugin_name, string filename) {
248 // TODO: Throw exception if plugin does not exist
249 TextWriter f = new StreamWriter(filename);
251 foreach (string key in PluginOptions[plugin_name].Keys) {
252 f.WriteLine("{0}.{1} = {2}", plugin_name, key, PluginOptions[plugin_name][key]);
259 public static bool ParseBool(string v) {
260 switch(v.ToLower()) {