예제 #1
0
        Program Parse(string source, ParserOptions parserOptions = null)
        {
            try
            {
                var parser = new JavaScriptParser();

                if (parserOptions != null)
                {
                    return(parser.Parse(source, parserOptions));
                }

                return(parser.Parse(source));
            }
            catch (Exception ex)
            {
                if (ex is ParserException)
                {
                    var pex = ex as ParserException;
                    if (pex != null)
                    {
                        var error = "JavaScript error on line" + pex.LineNumber.ToString() + ", cloumn: " + pex.Column.ToString() + " " + ex.Message;
                        throw new Exception(error, ex.InnerException);
                    }
                }

                throw;
            }
        }
예제 #2
0
        public override List <ProgramError> Compile()
        {
            List <ProgramError> errors = new List <ProgramError>();
            JavaScriptParser    jp     = new JavaScriptParser(false);

            //ParserOptions po = new ParserOptions();
            try
            {
                jp.Parse(ProgramBlock.ScriptSetup);
            }
            catch (Exception e)
            {
                // TODO: parse error message
                if (e.Message.Contains(":"))
                {
                    string[] error   = e.Message.Split(':');
                    string   message = error[1];
                    if (message != "hg is not defined") // TODO: find a better solution for this
                    {
                        int line = Int32.Parse(error[0].Split(' ')[1]);
                        errors.Add(new ProgramError()
                        {
                            Line         = line,
                            ErrorMessage = message,
                            CodeBlock    = CodeBlockEnum.TC
                        });
                    }
                }
            }
            //
            try
            {
                jp.Parse(ProgramBlock.ScriptSource);
            }
            catch (Exception e)
            {
                // TODO: parse error message
                if (!e.Message.Contains(":"))
                {
                    return(errors);
                }
                string[] error   = e.Message.Split(':');
                string   message = error[1];
                // TODO: find a better solution for this "hg is not defined" check
                if (message == "hg is not defined")
                {
                    return(errors);
                }
                int line = Int32.Parse(error[0].Split(' ')[1]);
                errors.Add(new ProgramError()
                {
                    Line         = line,
                    ErrorMessage = message,
                    CodeBlock    = CodeBlockEnum.CR
                });
            }
            return(errors);
        }
예제 #3
0
        public List <ProgramError> Compile()
        {
            List <ProgramError> errors = new List <ProgramError>();

            JavaScriptParser jp = new JavaScriptParser(false);

            //ParserOptions po = new ParserOptions();
            try
            {
                jp.Parse(programBlock.ScriptCondition);
            }
            catch (Exception e)
            {
                // TODO: parse error message
                if (e.Message.Contains(":"))
                {
                    string[] error   = e.Message.Split(':');
                    string   message = error[1];
                    if (message != "hg is not defined") // TODO: find a better solution for this
                    {
                        int line = int.Parse(error[0].Split(' ')[1]);
                        errors.Add(new ProgramError()
                        {
                            Line         = line,
                            ErrorMessage = message,
                            CodeBlock    = "TC"
                        });
                    }
                }
            }
            //
            try
            {
                jp.Parse(programBlock.ScriptSource);
            }
            catch (Exception e)
            {
                // TODO: parse error message
                if (e.Message.Contains(":"))
                {
                    string[] error   = e.Message.Split(':');
                    string   message = error[1];
                    if (message != "hg is not defined") // TODO: find a better solution for this
                    {
                        int line = int.Parse(error[0].Split(' ')[1]);
                        errors.Add(new ProgramError()
                        {
                            Line         = line,
                            ErrorMessage = message,
                            CodeBlock    = "CR"
                        });
                    }
                }
            }

            return(errors);
        }
예제 #4
0
        public JintTransform(IContext context, IReader reader) : base(context, "object")
        {
            if (IsMissing(context.Operation.Script))
            {
                return;
            }

            // automatic parameter binding
            if (!context.Operation.Parameters.Any())
            {
                var parsed = _parser.Parse(context.Operation.Script, new global::Jint.Parser.ParserOptions {
                    Tokens = true
                });

                var parameters = parsed.Tokens
                                 .Where(o => o.Type == global::Jint.Parser.Tokens.Identifier)
                                 .Select(o => o.Value.ToString())
                                 .Intersect(context.GetAllEntityFields().Select(f => f.Alias))
                                 .Distinct()
                                 .ToArray();
                if (parameters.Any())
                {
                    foreach (var parameter in parameters)
                    {
                        context.Operation.Parameters.Add(new Parameter {
                            Field = parameter
                        });
                    }
                }
            }

            // for js, always add the input parameter
            _input = MultipleInput().Union(new[] { context.Field }).Distinct().ToArray();

            // load any global scripts
            foreach (var sc in context.Process.Scripts.Where(s => s.Global))
            {
                ProcessScript(context, reader, context.Process.Scripts.First(s => s.Name == sc.Name));
            }

            // load any specified scripts
            if (context.Operation.Scripts.Any())
            {
                foreach (var sc in context.Operation.Scripts)
                {
                    ProcessScript(context, reader, context.Process.Scripts.First(s => s.Name == sc.Name));
                }
            }

            context.Debug(() => $"Script in {context.Field.Alias} : {context.Operation.Script.Replace("{", "{{").Replace("}", "}}")}");
        }
예제 #5
0
 public IEnumerable<FunctionDeclaration> GetSourceCodeGlobalFunctions()
 {
     JavaScriptParser parser = new JavaScriptParser();
     foreach (FunctionDeclaration funcDecl in parser.Parse(Code).FunctionDeclarations) {
         yield return funcDecl;
     }
 }
예제 #6
0
        public static Dictionary <string, object> JsSeriaize(string js)
        {
            var parser  = new JavaScriptParser();
            var program = parser.Parse(js);

            return(JsObjectSerialize(program) as Dictionary <string, object>);
        }
        public bool Passes(string script)
        {
            try {
                var program = _parser.Parse(script, _parserOptions);
                if (program?.Errors == null || !program.Errors.Any())
                {
                    return(true);
                }

                if (program.Errors.Any())
                {
                    foreach (var e in program.Errors)
                    {
                        _context.Error(e.Message);
                    }
                    Utility.CodeToError(_context, script);
                    return(false);
                }
            } catch (ParserException ex) {
                _context.Error(ex.Message);
                Utility.CodeToError(_context, script);
                return(false);
            }

            return(false);
        }
예제 #8
0
        public void Customize(string parent, INode node, IDictionary <string, string> parameters, ILogger logger)
        {
            if (parent != "transform")
            {
                return;
            }

            if (!node.TryAttribute("script", out var scriptAttr))
            {
                return;
            }

            var value = scriptAttr.Value.ToString();

            if (string.IsNullOrEmpty(value))
            {
                logger.Error("Script is null or empty");
                return;
            }

            try {
                var program = _jint.Parse(value, _options);
                if (program?.Errors == null || !program.Errors.Any())
                {
                    return;
                }

                foreach (var e in program.Errors)
                {
                    logger.Error("{0}, script: {1}...", e.Message, value.Left(30).Replace("{", "{{").Replace("}", "}}"));
                }
            } catch (ParserException ex) {
                logger.Error("{0}, script: {1}...", ex.Message, value.Left(30).Replace("{", "{{").Replace("}", "}}"));
            }
        }
        void Parse(IProjectContent projectContent, string fileName, string code)
        {
            var textBuffer = new FakeTextBuffer(code);

            CreateParser();
            compilationUnit = parser.Parse(projectContent, fileName, textBuffer);
        }
예제 #10
0
        public ValidatorResult Validate(string name, object value)
        {
            var result = new ValidatorResult();

            if (value == null)
            {
                return(result);
            }

            var script = value.ToString();

            if (script == string.Empty)
            {
                return(result);
            }

            try {
                var program = _jint.Parse(script, _options);
                if (program != null && program.Errors != null && program.Errors.Any())
                {
                    result.Valid = false;
                    foreach (var e in program.Errors)
                    {
                        result.Error("{0}, script: {1}...", e.Message, script.Left(30));
                    }
                }
            } catch (ParserException ex) {
                result.Valid = false;
                result.Error("{0}, script: {1}...", ex.Message, script.Left(30));
            }
            return(result);
        }
예제 #11
0
        private string DecryptWithCustomParser(string jsContent, string s)
        {
            try
            {
                // Try to get the functions out of the java script
                JavaScriptParser javaScriptParser = new JavaScriptParser(jsContent);
                FunctionData     functionData     = javaScriptParser.Parse();

                StringBuilder stringBuilder = new StringBuilder();

                foreach (var functionBody in functionData.Bodies)
                {
                    stringBuilder.Append(functionBody);
                }

                ScriptEngine engine = new ScriptEngine();

                engine.Global["window"]    = engine.Global;
                engine.Global["document"]  = engine.Global;
                engine.Global["navigator"] = engine.Global;

                engine.Execute(stringBuilder.ToString());

                return(engine.CallGlobalFunction(functionData.StartFunctionName, s).ToString());
            }
            catch (Exception ex)
            {
                Log.Info("Signature decryption with custom parser failed: {0}", ex.Message);
            }
            return(string.Empty);
        }
예제 #12
0
        public void ShouldParseThis()
        {
            var program = _parser.Parse("this");
            var body    = program.Body;

            Assert.NotNull(body);
            Assert.Single(body);
            Assert.Equal(SyntaxNodes.ThisExpression, body.First().As <ExpressionStatement>().Expression.Type);
        }
        public string TranslateCode(string code)
        {
            JavaScriptParser parser = new JavaScriptParser();
            var parsed = parser.Parse(code);
            var Init   = new CSFunctionDecl
            {
                attributes = new CSAttribute[]
                {
                    new CSAttribute
                    {
                        callee    = new CSLiteral("Init"),
                        arguments = new CSExpression[0]
                    }
                },
                name     = "Main",
                function = new CSFunction
                {
                    blocks = new List <CSStatement>()
                },
                keyWords   = CSFunctionDecl.FuncKeywords.Static,
                returnType = "void"
            };

            Program = new CSClass
            {
                declarables = new List <CSClass.Declarable>
                {
                    Init
                },
                attributes = new List <CSAttribute> {
                },
                name       = "Program",
                keyWords   = CSFunctionDecl.FuncKeywords.Static
            };
            var NameSpace = new CSNameSpace
            {
                name     = "NameSpace",
                elements = new List <CSElement>
                {
                    Program
                },
                @using = new string[] { "Bridge", "Bridge.Html5", "Bridge.Linq", "System", "System.Linq" }
            };

            foreach (var item in parsed.Body)
            {
                if (item is FunctionDeclaration)
                {
                    var funcDecl = (FunctionDeclaration)item;
                    Program.declarables.Add(Translate(funcDecl, Program));
                }
                else
                {
                    Init.function.blocks.Add(Translate(item, Program));
                }
            }
            return(NameSpace.ToString());
        }
예제 #14
0
        public IEnumerable <FunctionDeclaration> GetSourceCodeGlobalFunctions()
        {
            JavaScriptParser parser = new JavaScriptParser();

            foreach (FunctionDeclaration funcDecl in parser.Parse(Code).FunctionDeclarations)
            {
                yield return(funcDecl);
            }
        }
        /// <summary>
        /// Load a JS file and execute the main() function, passing in
        /// context information and the output from the previous execution.
        /// Modifies the internal device state with the latest values.
        /// </summary>
        public void Invoke(
            string filename,
            object scriptParams,
            Dictionary <string, object> context,
            ISmartDictionary state,
            ISmartDictionary properties)
        {
            this.deviceState      = state;
            this.deviceProperties = properties;

            var engine = new Engine();

            // Inject the logger in the JS context, to allow the JS function
            // logging into the service logs
            engine.SetValue("log", new Action <object>(this.JsLog));

            // register callback for state updates
            engine.SetValue("updateState", new Action <JsValue>(this.UpdateState));

            // register callback for property updates
            engine.SetValue("updateProperty", new Action <string, object>(this.UpdateProperty));

            // register sleep function for javascript use
            engine.SetValue("sleep", new Action <int>(this.Sleep));

            try
            {
                Program program;
                if (programs.ContainsKey(filename))
                {
                    program = programs[filename];
                }
                else
                {
                    var sourceCode = this.LoadScript(filename);

                    this.log.Info("Compiling script source code", () => new { filename });
                    program = parser.Parse(sourceCode);
                    programs.Add(filename, program);
                }

                this.log.Debug("Executing JS function", () => new { filename });

                engine.Execute(program).Invoke(
                    "main",
                    context,
                    this.deviceState.GetAll(),
                    this.deviceProperties.GetAll(),
                    scriptParams);

                this.log.Debug("JS function success", () => new { filename, this.deviceState });
            }
            catch (Exception e)
            {
                this.log.Error("JS function failure", () => new { e.Message, e.GetType().FullName });
            }
        }
        private static List <RequireCall> visit(string script)
        {
            var parser  = new JavaScriptParser();
            var program = parser.Parse(script);
            var visitor = new RequireVisitor();
            var results = visitor.Visit(program, "ProcessRequireCallShouldScript.js").GetFlattened();

            return(results);
        }
예제 #17
0
        public void ShouldParseScriptFile(string file, string version)
        {
            var parser  = new JavaScriptParser();
            var source  = GetEmbeddedFile(file);
            var sw      = new Stopwatch();
            var program = parser.Parse(source);

            Console.WriteLine("Parsed {0} {1} ({3} KB) in {2} ms", file, version, sw.ElapsedMilliseconds, (int)source.Length / 1024);
            Assert.NotNull(program);
        }
예제 #18
0
        public IScript Get(string content)
        {
            var parser = new JavaScriptParser();

            var script = new Mock<IScript>();
            script.SetupGet(s => s.File).Returns(_mockFile.FromString("js", content));
            script.SetupGet(s => s.ExpressionTree).Returns(parser.Parse(content));
            script.Name = content;

            return script.Object;
        }
예제 #19
0
        public void Process()
        {
            try
            {
                var parser  = new JavaScriptParser();
                var program = parser.Parse(OriginalString);
                var visitor = new RequireVisitor();
                var result  = visitor.Visit(program, RelativeFileName);

                var lines = GetScriptLines(OriginalString);

                var flattenedResults = result.GetFlattened();

                var deps =
                    flattenedResults.SelectMany(r => r.Dependencies)
                    .Where(r => !r.Contains("!"))
                    .Except(new List <string> {
                    "require", "module", "exports"
                });

                Dependencies = deps.Select(r => GetModulePath(r)).ToList();
                var shim = this.GetShim(RelativeFileName);
                if (shim != null)
                {
                    Dependencies.AddRange(shim.Dependencies.Select(r => this.GetModulePath(r.Dependency)));
                }

                Dependencies = Dependencies.Distinct().ToList();

                flattenedResults.ForEach(
                    x =>
                {
                    EnsureHasRange(x.ParentNode.Node, lines);
                    EnsureHasRange(x.DependencyArrayNode, lines);
                    EnsureHasRange(x.ModuleDefinitionNode, lines);
                    EnsureHasRange(x.ModuleIdentifierNode, lines);
                    EnsureHasRange(x.SingleDependencyNode, lines);
                    var arguments = x.ParentNode.Node.As <CallExpression>().Arguments;
                    foreach (var arg in arguments)
                    {
                        EnsureHasRange(arg, lines);
                    }
                });

                var transformations = this.GetTransformations(result, flattenedResults);
                var text            = OriginalString;
                transformations.ExecuteAll(ref text);
                ProcessedString = text;
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Error while processing {0}: {1}", RelativeFileName, ex.Message), ex);
            }
        }
        public IScript Get(string content)
        {
            var parser = new JavaScriptParser();

            var script = new Mock <IScript>();

            script.SetupGet(s => s.File).Returns(_mockFile.FromString("js", content));
            script.SetupGet(s => s.ExpressionTree).Returns(parser.Parse(content));
            script.Name = content;

            return(script.Object);
        }
예제 #21
0
        public void Process()
        {
            try
            {
                var parser = new JavaScriptParser();
                var program = parser.Parse(OriginalString);
                var visitor = new RequireVisitor();
                var result = visitor.Visit(program, RelativeFileName);

                var lines = GetScriptLines(OriginalString);

                var flattenedResults = result.GetFlattened();

                var deps =
                    flattenedResults.SelectMany(r => r.Dependencies)
                        .Where(r => !r.Contains("!"))
                        .Except(new List<string> { "require", "module", "exports" });

                Dependencies = deps.Select(r => GetModulePath(r)).ToList();
                var shim = this.GetShim(RelativeFileName);
                if (shim != null)
                {
                    Dependencies.AddRange(shim.Dependencies.Select(r => this.GetModulePath(r.Dependency)));
                }

                Dependencies = Dependencies.Distinct().ToList();

                flattenedResults.ForEach(
                    x =>
                    {
                        EnsureHasRange(x.ParentNode.Node, lines);
                        EnsureHasRange(x.DependencyArrayNode, lines);
                        EnsureHasRange(x.ModuleDefinitionNode, lines);
                        EnsureHasRange(x.ModuleIdentifierNode, lines);
                        EnsureHasRange(x.SingleDependencyNode, lines);
                        var arguments = x.ParentNode.Node.As<CallExpression>().Arguments;
                        foreach (var arg in arguments)
                        {
                            EnsureHasRange(arg, lines);
                        }
                    });

                var transformations = this.GetTransformations(result, flattenedResults);
                var text = OriginalString;
                transformations.ExecuteAll(ref text);
                ProcessedString = text;
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Error while processing {0}: {1}", RelativeFileName, ex.Message), ex);
            }
        }
예제 #22
0
 /// <summary>Rewrites the given program code.</summary>
 /// <param name="programcode">The jscript code to rewrite.</param>
 public void RewriteProgram(string programcode)
 {
     var parser = new JavaScriptParser();
     try
     {
         var ast = parser.Parse(programcode);
         Emit(ast);
     }
     catch(ParserException ex)
     {
         Log.Trace("jscript parsing error: {0}\n{1}", ex.Message, ex.Source);
         throw ex;
     }
 }
예제 #23
0
        static void Main(string[] args)
        {
            var filePath    = GetPath(@"Scripts\BForms\Bundles\js\components.js");
            var minimalPath = GetPath(@"Scripts\minimal.js");
            var initUIPath  = GetPath(@"Scripts\BForms\Plugins\UI\bforms.initUI.js");

            var text    = File.ReadAllText(initUIPath);
            var parser  = new JavaScriptParser();
            var program = parser.Parse(text);
            var visitor = new RequireVisitor();
            var result  = visitor.Visit(program, initUIPath);

            var lines = GetScriptLines(text);

            var flattenedResults = result.GetFlattened();

            flattenedResults.ForEach(
                x =>
            {
                EnsureHasRange(x.ParentNode.Node, lines);
                EnsureHasRange(x.DependencyArrayNode, lines);
                EnsureHasRange(x.ModuleDefinitionNode, lines);
                EnsureHasRange(x.ModuleIdentifierNode, lines);
                EnsureHasRange(x.SingleDependencyNode, lines);
                var arguments = x.ParentNode.Node.As <CallExpression>().Arguments;
                foreach (var arg in arguments)
                {
                    EnsureHasRange(arg, lines);
                }
            });

            var reqLines = flattenedResults.Select(x => GetTextFromFullScript(x.ParentNode.Node.Range, text)).ToList();

            var modifiedString      = text;
            var transformCollection = new TransformationCollection();

            foreach (var req in flattenedResults)
            {
                transformCollection.Add(ToDefineTransformation.Create(req));
                if (req.Type != RequireCallType.Define)
                {
                    transformCollection.Add(AddIdentifierTransformation.Create(req, "gogu"));
                }
            }

            transformCollection.ExecuteAll(ref modifiedString);
        }
예제 #24
0
        /// <summary>
        /// Reading a stream and try to parse it as javascript.
        /// </summary>
        public string Validate(Stream stream)
        {
            var parser    = new JavaScriptParser();
            var reader    = new StreamReader(stream);
            var rawScript = reader.ReadToEnd();

            try
            {
                parser.Parse(rawScript);
            }
            catch (Exception)
            {
                throw;
            }

            return(rawScript);
        }
예제 #25
0
        static void Main(string[] args)
        {
            var filePath = GetPath(@"Scripts\BForms\Bundles\js\components.js");
            var minimalPath = GetPath(@"Scripts\minimal.js");
            var initUIPath = GetPath(@"Scripts\BForms\Plugins\UI\bforms.initUI.js");

            var text = File.ReadAllText(initUIPath);
            var parser = new JavaScriptParser();
            var program = parser.Parse(text);
            var visitor = new RequireVisitor();
            var result = visitor.Visit(program, initUIPath);

            var lines = GetScriptLines(text);

            var flattenedResults = result.GetFlattened();

            flattenedResults.ForEach(
                x =>
                    {
                        EnsureHasRange(x.ParentNode.Node, lines);
                        EnsureHasRange(x.DependencyArrayNode, lines);
                        EnsureHasRange(x.ModuleDefinitionNode, lines);
                        EnsureHasRange(x.ModuleIdentifierNode, lines);
                        EnsureHasRange(x.SingleDependencyNode, lines);
                        var arguments = x.ParentNode.Node.As<CallExpression>().Arguments;
                        foreach (var arg in arguments)
                        {
                            EnsureHasRange(arg, lines);    
                        }
                    });

            var reqLines = flattenedResults.Select(x => GetTextFromFullScript(x.ParentNode.Node.Range, text)).ToList();
            
            var modifiedString = text;
            var transformCollection = new TransformationCollection();
            foreach (var req in flattenedResults)
            {
                transformCollection.Add(ToDefineTransformation.Create(req));
                if (req.Type != RequireCallType.Define)
                {
                    transformCollection.Add(AddIdentifierTransformation.Create(req, "gogu"));
                }
            }

            transformCollection.ExecuteAll(ref modifiedString);    
        }
예제 #26
0
        public Engine Execute(string source)
        {
            var    parser = new JavaScriptParser();
            string error  = null;

            try
            {
                return(Execute(parser.Parse(source)));
            }
            catch (Exception ex)
            {
                if (ex is JavaScriptException)
                {
                    var jsex = ex as JavaScriptException;
                    if (jsex != null)
                    {
                        error = "JavaScript execute error on line " + jsex.Location.Start.Line.ToString() +
                                ", cloumn: " + jsex.Location.Start.Column.ToString() +
                                ", error: " + jsex.Error.ToString();
                    }
                }
                else if (ex is ParserException)
                {
                    var pex = ex as ParserException;
                    if (pex != null)
                    {
                        error = "JavaScript parse error on line " + pex.LineNumber.ToString() +
                                ", cloumn: " + pex.Column.ToString() +
                                ", error: " + pex.Message;
                    }
                }
                else
                {
                    error = ex.Message;
                }
            }

            if (error != null)
            {
                throw new Exception(error);
            }

            return(null);
        }
예제 #27
0
파일: JintHelper.cs 프로젝트: xhute/Kooboo
        public static object GetAssignmentValue(string code)
        {
            var parser = new JavaScriptParser();
            var prog   = parser.Parse(code);

            var statement = prog.Body.First();

            var exp = statement as Jint.Parser.Ast.ExpressionStatement;

            var ass = exp.Expression as Jint.Parser.Ast.AssignmentExpression;

            var rightvalue = ass.Right as Jint.Parser.Ast.Literal;

            if (rightvalue != null)
            {
                return(rightvalue.Value);
            }

            return(null);
        }
예제 #28
0
파일: JintHelper.cs 프로젝트: xhute/Kooboo
        public static bool IsAssignmentExpression(string code)
        {
            if (string.IsNullOrWhiteSpace(code))
            {
                return(false);
            }

            if (code.Contains("{") || code.Contains("("))
            {
                return(false);
            }

            var parser = new JavaScriptParser();
            var prog   = parser.Parse(code);

            if (prog == null || prog.Body == null || prog.Body.Count() != 1)
            {
                return(false);
            }

            var statement = prog.Body.First();

            if (statement == null)
            {
                return(false);
            }
            var exp = statement as Jint.Parser.Ast.ExpressionStatement;

            if (exp == null)
            {
                return(false);
            }

            var t = exp.Expression.GetType();

            if (t == typeof(Jint.Parser.Ast.AssignmentExpression))
            {
                return(true);
            }
            return(false);
        }
예제 #29
0
파일: Plugin.cs 프로젝트: yohanniii/Pluton
        public Plugin(string name, string code, DirectoryInfo path, PluginType type)
        {
            Name    = name;
            Code    = code;
            RootDir = path;
            Type    = type;
            Timers  = new Dictionary <string, TimedEvent>();

            if (type == PluginType.Python)
            {
                PyEngine = IronPython.Hosting.Python.CreateEngine();
                Scope    = PyEngine.CreateScope();
                Scope.SetVariable("Plugin", this);
                Scope.SetVariable("Server", Pluton.Server.GetServer());
                Scope.SetVariable("DataStore", DataStore.GetInstance());
                Scope.SetVariable("Util", Util.GetUtil());
                Scope.SetVariable("World", World.GetWorld());
                Scope.SetVariable("Commands", PluginCommands.GetInstance());
                PyEngine.Execute(code, Scope);
                Class   = PyEngine.Operations.Invoke(Scope.GetVariable(name));
                Globals = PyEngine.Operations.GetMemberNames(Class);
            }
            else
            {
                JSEngine = new Engine(cfg => cfg.AllowClr(typeof(UnityEngine.GameObject).Assembly,
                                                          typeof(PlayerInventory).Assembly))
                           .SetValue("Server", Server.GetServer())
                           .SetValue("DataStore", DataStore.GetInstance())
                           .SetValue("Util", Util.GetUtil())
                           .SetValue("World", World.GetWorld())
                           .SetValue("Plugin", this)
                           .SetValue("Commands", PluginCommands.GetInstance())
                           .Execute(code);
                JavaScriptParser parser = new JavaScriptParser();
                Globals = (from function in parser.Parse(Code).FunctionDeclarations
                           where (function.Id.Name.StartsWith("On_") || function.Id.Name.EndsWith("Callback"))
                           select function.Id.Name).ToList <string>();
            }
        }
예제 #30
0
        public void Validate(string name, string value, IDictionary <string, string> parameters, ILogger logger)
        {
            if (string.IsNullOrEmpty(value))
            {
                logger.Error("Script is null or empty");
                return;
            }

            try {
                var program = _jint.Parse(value, _options);
                if (program?.Errors == null || !program.Errors.Any())
                {
                    return;
                }

                foreach (var e in program.Errors)
                {
                    logger.Error("{0}, script: {1}...", e.Message, value.Left(30).Replace("{", "{{").Replace("}", "}}"));
                }
            } catch (ParserException ex) {
                logger.Error("{0}, script: {1}...", ex.Message, value.Left(30).Replace("{", "{{").Replace("}", "}}"));
            }
        }
예제 #31
0
        public object Evaluate(IScriptingScope scope, string script)
        {
            if (scope == null)
            {
                throw new ArgumentNullException(nameof(scope));
            }

            var jsScope = scope as JavaScriptScope;

            if (jsScope == null)
            {
                throw new ArgumentException($"Expected a scope of type {nameof(JavaScriptScope)}", nameof(scope));
            }

            var parsedAst = _memoryCache.GetOrCreate(script, entry =>
            {
                var parser = new JavaScriptParser();
                return(parser.Parse(script));
            });

            var result = jsScope.Engine.Execute(parsedAst).GetCompletionValue()?.ToObject();

            return(result);
        }
        public void ShouldParseScriptFile(string file, string version)
        {
            const string prefix = "Jint.Tests.Parser.Scripts.";

            var assembly   = Assembly.GetExecutingAssembly();
            var scriptPath = prefix + file;
            var sw         = new Stopwatch();

            using (var stream = assembly.GetManifestResourceStream(scriptPath))
            {
                if (stream != null)
                {
                    using (var sr = new StreamReader(stream))
                    {
                        var source = sr.ReadToEnd();
                        sw.Restart();
                        var parser  = new JavaScriptParser();
                        var program = parser.Parse(source);
                        Console.WriteLine("Parsed {0} {1} ({3} KB) in {2} ms", file, version, sw.ElapsedMilliseconds, (int)source.Length / 1024);
                        Assert.NotNull(program);
                    }
                }
            }
        }
예제 #33
0
        public void ShouldParseScriptFile(string file, string version)
        {
            const string prefix = "Jint.Tests.Parser.Scripts.";

            var assembly = Assembly.GetExecutingAssembly();
            var scriptPath = prefix + file;
            var sw = new Stopwatch();

            using (var stream = assembly.GetManifestResourceStream(scriptPath))
            {
                if (stream != null)
                {
                    using (var sr = new StreamReader(stream))
                    {
                        var source = sr.ReadToEnd();
                        sw.Restart();
                        var parser = new JavaScriptParser();
                        var program = parser.Parse(source);
                        Console.WriteLine("Parsed {0} {1} ({3} KB) in {2} ms", file, version, sw.ElapsedMilliseconds, (int)source.Length/1024);
                        Assert.NotNull(program);
                    }
                }
            }
        }
예제 #34
0
        public JsValue Call(JsValue thisObject, JsValue[] arguments, bool directCall)
        {
            if (arguments.At(0).Type != Types.String)
            {
                return(arguments.At(0));
            }

            var code = TypeConverter.ToString(arguments.At(0));

            try
            {
                var parser  = new JavaScriptParser(StrictModeScope.IsStrictModeCode);
                var program = parser.Parse(code);
                using (new StrictModeScope(program.Strict))
                {
                    using (new EvalCodeScope())
                    {
                        LexicalEnvironment strictVarEnv = null;

                        try
                        {
                            if (!directCall)
                            {
                                Engine.EnterExecutionContext(Engine.GlobalEnvironment, Engine.GlobalEnvironment, Engine.Global);
                            }

                            if (StrictModeScope.IsStrictModeCode)
                            {
                                strictVarEnv = LexicalEnvironment.NewDeclarativeEnvironment(Engine, Engine.ExecutionContext.LexicalEnvironment);
                                Engine.EnterExecutionContext(strictVarEnv, strictVarEnv, Engine.ExecutionContext.ThisBinding);
                            }

                            Engine.DeclarationBindingInstantiation(DeclarationBindingType.EvalCode, program.FunctionDeclarations, program.VariableDeclarations, this, arguments);

                            var result = _engine.ExecuteStatement(program);

                            if (result.Type == Completion.Throw)
                            {
                                throw result.Exception ?? new JavaScriptException(result.GetValueOrDefault())
                                      .SetCallstack(_engine, result.Location);
                            }
                            else
                            {
                                return(result.GetValueOrDefault());
                            }
                        }
                        finally
                        {
                            if (strictVarEnv != null)
                            {
                                Engine.LeaveExecutionContext();
                            }

                            if (!directCall)
                            {
                                Engine.LeaveExecutionContext();
                            }
                        }
                    }
                }
            }
            catch (ParserException)
            {
                throw new JavaScriptException(Engine.SyntaxError);
            }
        }
예제 #35
0
파일: Config.cs 프로젝트: Qu3uk/HomeGenie
        public void ProcessRequest(MIGClientRequest request, MIGInterfaceCommand migCommand)
        {
            string response = "";
            switch (migCommand.Command)
            {
            case "Interfaces.List":
                migCommand.Response = "[ ";
                foreach (var kv in homegenie.Interfaces)
                {
                    var migInterface = kv.Value;
                    var ifaceConfig = homegenie.SystemConfiguration.MIGService.GetInterface(migInterface.Domain);
                    if (ifaceConfig == null || !ifaceConfig.IsEnabled)
                    {
                        continue;
                    }
                    migCommand.Response += "{ \"Domain\" : \"" + migInterface.Domain + "\", \"IsConnected\" : \"" + migInterface.IsConnected + "\" },";
                }
                if (homegenie.UpdateChecker != null && homegenie.UpdateChecker.IsUpdateAvailable)
                {
                    migCommand.Response += "{ \"Domain\" : \"" + Domains.HomeGenie_UpdateChecker + "\", \"IsConnected\" : \"True\" }";
                    migCommand.Response += " ]";
                }
                else
                {
                    migCommand.Response = migCommand.Response.Substring(0, migCommand.Response.Length - 1) + " ]";
                }
                break;

            case "Interfaces.ListConfig":
                migCommand.Response = "[ ";
                foreach (var kv in homegenie.Interfaces)
                {
                    var migInterface = kv.Value;
                    var ifaceConfig = homegenie.SystemConfiguration.MIGService.GetInterface(migInterface.Domain);
                    if (ifaceConfig == null)
                        continue;
                    migCommand.Response += JsonConvert.SerializeObject(ifaceConfig) + ",";
                }
                migCommand.Response = migCommand.Response.Substring(0, migCommand.Response.Length - 1) + " ]";
                break;

            //TODO: should this be moved somewhere to MIG?
            case "Interfaces.Configure":
                switch (migCommand.GetOption(0))
                {
                case "Hardware.SerialPorts":
                    if (Environment.OSVersion.Platform == PlatformID.Unix)
                    {
                        var serialPorts = System.IO.Ports.SerialPort.GetPortNames();
                        var portList = new List<string>();
                        for (int p = serialPorts.Length - 1; p >= 0; p--)
                        {
                            if (serialPorts[p].Contains("/ttyS") || serialPorts[p].Contains("/ttyUSB"))
                            {
                                portList.Add(serialPorts[p]);
                            }
                        }
                        if (Raspberry.Board.Current.IsRaspberryPi)
                        {
                            if (!portList.Contains("/dev/ttyAMA0"))
                                portList.Add("/dev/ttyAMA0"); // RaZberry
                            if (!portList.Contains("/dev/ttyACM0"))
                                portList.Add("/dev/ttyACM0"); // ZME_UZB1
                        }
                        migCommand.Response = JsonHelper.GetSimpleResponse(JsonConvert.SerializeObject(portList));
                    }
                    else
                    {
                        var portNames = System.IO.Ports.SerialPort.GetPortNames();
                        migCommand.Response = JsonHelper.GetSimpleResponse(JsonConvert.SerializeObject(portNames));
                    }
                    break;

                }
                break;

            case "Interface.Import":
                string downloadUrl = migCommand.GetOption(0);
                response = "";
                string ifaceFileName = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "mig_interface_import.zip");
                string outputFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "mig");
                Utility.FolderCleanUp(outputFolder);

                try
                {
                    if (String.IsNullOrWhiteSpace(downloadUrl))
                    {
                        // file uploaded by user
                        MIG.Gateways.WebServiceUtility.SaveFile(request.InputStream, ifaceFileName);
                    }
                    else
                    {
                        // download file from url
                        var client = new WebClient();
                        client.DownloadFile(downloadUrl, ifaceFileName);
                        client.Dispose();
                    }
                }
                catch
                {
                    // TODO: report exception
                }

                try
                {
                    if (!Directory.Exists(outputFolder))
                    {
                        Directory.CreateDirectory(outputFolder);
                    }
                    Utility.UncompressZip(ifaceFileName, outputFolder);
                    File.Delete(ifaceFileName);

                    var migInt = GetInterfaceConfig(Path.Combine(outputFolder, "configuration.xml"));
                    if (migInt != null)
                    {
                        response = String.Format("{0} ({1})\n{2}\n", migInt.Domain, migInt.AssemblyName, migInt.Description);
                        // Check for README notes and append them to the response
                        var readmeFile = Path.Combine(outputFolder, "README.TXT");
                        if (File.Exists(readmeFile))
                        {
                            response += File.ReadAllText(readmeFile);
                        }
                        migCommand.Response = JsonHelper.GetSimpleResponse(response);
                    }
                    else
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("NOT A VALID ADD-ON PACKAGE");
                    }
                }
                catch
                {
                }
                break;

            case "Interface.Install":

                // install the interface package
                string outFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "mig");
                string configFile = Path.Combine(outFolder, "configuration.xml");
                var iface = GetInterfaceConfig(configFile);
                if (iface != null)
                {
                    File.Delete(configFile);
                    //
                    homegenie.MigService.RemoveInterface(iface.Domain);
                    //
                    string configletName = iface.Domain.Substring(iface.Domain.LastIndexOf(".") + 1).ToLower();
                    string configletPath = Path.Combine("html", "pages", "configure", "interfaces", "configlet", configletName + ".html");
                    if (File.Exists(configletPath))
                    {
                        File.Delete(configletPath);
                    }
                    File.Move(Path.Combine(outFolder, "configlet.html"), configletPath);
                    //
                    string logoPath = Path.Combine("html", "images", "interfaces", configletName + ".png");
                    if (File.Exists(logoPath))
                    {
                        File.Delete(logoPath);
                    }
                    File.Move(Path.Combine(outFolder, "logo.png"), logoPath);
                    // copy other interface files to mig folder (dll and dependencies)
                    string migFolder = "mig";
                    Utility.FolderCleanUp(migFolder);
                    DirectoryInfo dir = new DirectoryInfo(outFolder);
                    foreach (var f in dir.GetFiles())
                    {
                        string destFile = Path.Combine(migFolder, Path.GetFileName(f.FullName));
                        if (File.Exists(destFile))
                        {
                            File.Move(destFile, Path.Combine(destFile, ".old"));
                            File.Delete(Path.Combine(destFile, ".old"));
                        }
                        File.Move(f.FullName, destFile);
                    }
                    //
                    homegenie.SystemConfiguration.MIGService.Interfaces.RemoveAll(i => i.Domain == iface.Domain);
                    homegenie.SystemConfiguration.MIGService.Interfaces.Add(iface);
                    homegenie.SystemConfiguration.Update();
                    homegenie.MigService.AddInterface(iface.Domain, iface.AssemblyName);

                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                else
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("NOT A VALID ADD-ON PACKAGE");
                }
                break;

            case "System.Configure":
                if (migCommand.GetOption(0) == "Service.Restart")
                {
                    Program.Quit(true);
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                else if (migCommand.GetOption(0) == "UpdateManager.UpdatesList")
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.UpdateChecker.RemoteUpdates);
                }
                else if (migCommand.GetOption(0) == "UpdateManager.Check")
                {
                    homegenie.UpdateChecker.Check();
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                else if (migCommand.GetOption(0) == "UpdateManager.DownloadUpdate")
                {
                    var resultMessage = "ERROR";
                    bool success = homegenie.UpdateChecker.DownloadUpdateFiles();
                    if (success)
                    {
                        if (homegenie.UpdateChecker.IsRestartRequired)
                        {
                            resultMessage = "RESTART";
                        }
                        else
                        {
                            resultMessage = "OK";
                        }
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(resultMessage);
                }
                else if (migCommand.GetOption(0) == "UpdateManager.InstallUpdate") //UpdateManager.InstallProgramsCommit")
                {
                    string resultMessage = "OK";
                    if (!homegenie.UpdateChecker.InstallFiles())
                    {
                        resultMessage = "ERROR";
                    }
                    else
                    {
                        if (homegenie.UpdateChecker.IsRestartRequired)
                        {
                            resultMessage = "RESTART";
                            Utility.RunAsyncTask(() =>
                            {
                                Thread.Sleep(2000);
                                Program.Quit(true);
                            });
                        }
                        else
                        {
                            homegenie.LoadConfiguration();
                            homegenie.MigService.ClearWebCache();
                            homegenie.UpdateChecker.Check();
                        }
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(resultMessage);
                }
                else if (migCommand.GetOption(0) == "HttpService.SetWebCacheEnabled")
                {
                    if (migCommand.GetOption(1) == "1")
                    {
                        homegenie.MigService.IsWebCacheEnabled = true;
                        homegenie.SystemConfiguration.MIGService.EnableWebCache = "true";
                    }
                    else
                    {
                        homegenie.MigService.IsWebCacheEnabled = false;
                        homegenie.SystemConfiguration.MIGService.EnableWebCache = "false";
                    }
                    homegenie.SystemConfiguration.Update();
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                else if (migCommand.GetOption(0) == "HttpService.GetWebCacheEnabled")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse(homegenie.MigService.IsWebCacheEnabled ? "1" : "0");
                }
                else if (migCommand.GetOption(0) == "HttpService.GetPort")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse(homegenie.SystemConfiguration.HomeGenie.ServicePort.ToString());
                }
                else if (migCommand.GetOption(0) == "HttpService.SetPort")
                {
                    try
                    {
                        homegenie.SystemConfiguration.HomeGenie.ServicePort = int.Parse(migCommand.GetOption(1));
                        homegenie.SystemConfiguration.Update();
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "HttpService.GetHostHeader")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse(homegenie.SystemConfiguration.HomeGenie.ServiceHost.ToString());
                }
                else if (migCommand.GetOption(0) == "HttpService.SetHostHeader")
                {
                    try
                    {
                        homegenie.SystemConfiguration.HomeGenie.ServiceHost = migCommand.GetOption(1);
                        homegenie.SystemConfiguration.Update();
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "Statistics.GetStatisticsDatabaseMaximumSize")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse(homegenie.SystemConfiguration.HomeGenie.Statistics.MaxDatabaseSizeMBytes.ToString());
                }
                else if (migCommand.GetOption(0) == "Statistics.SetStatisticsDatabaseMaximumSize")
                {
                    try
                    {
                        homegenie.SystemConfiguration.HomeGenie.Statistics.MaxDatabaseSizeMBytes = int.Parse(migCommand.GetOption(1));
                        homegenie.SystemConfiguration.Update();
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "SystemLogging.DownloadCsv")
                {
                    string csvlog = "";
                    string logpath = Path.Combine("log", "homegenie.log");
                    if (migCommand.GetOption(1) == "1")
                    {
                        logpath = Path.Combine("log", "homegenie.log.bak");
                    }
                    if (File.Exists(logpath))
                    {
                        using (var fs = new FileStream(logpath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        using (var sr = new StreamReader(fs, Encoding.Default))
                        {
                            csvlog = sr.ReadToEnd();
                        }
                    }
                    (request.Context as HttpListenerContext).Response.AddHeader("Content-Disposition", "attachment;filename=homegenie_log_" + migCommand.GetOption(1) + ".csv");
                    migCommand.Response = csvlog;
                }
                else if (migCommand.GetOption(0) == "SystemLogging.Enable")
                {
                    SystemLogger.Instance.OpenLog();
                    homegenie.SystemConfiguration.HomeGenie.EnableLogFile = "true";
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "SystemLogging.Disable")
                {
                    SystemLogger.Instance.CloseLog();
                    homegenie.SystemConfiguration.HomeGenie.EnableLogFile = "false";
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "SystemLogging.IsEnabled")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse((homegenie.SystemConfiguration.HomeGenie.EnableLogFile.ToLower().Equals("true") ? "1" : "0"));
                }
                else if (migCommand.GetOption(0) == "Security.SetPassword")
                {
                    // password only for now, with fixed user login 'admin'
                    string pass = migCommand.GetOption(1) == "" ? "" : MIG.Utility.Encryption.SHA1.GenerateHashString(migCommand.GetOption(1));
                    homegenie.MigService.SetWebServicePassword(pass);
                    homegenie.SystemConfiguration.HomeGenie.UserPassword = pass;
                    // regenerate encrypted files
                    homegenie.SystemConfiguration.Update();
                    homegenie.UpdateModulesDatabase();
                }
                else if (migCommand.GetOption(0) == "Security.ClearPassword")
                {
                    homegenie.MigService.SetWebServicePassword("");
                    homegenie.SystemConfiguration.HomeGenie.UserPassword = "";
                    // regenerate encrypted files
                    homegenie.SystemConfiguration.Update();
                    homegenie.UpdateModulesDatabase();
                }
                else if (migCommand.GetOption(0) == "Security.HasPassword")
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse((homegenie.SystemConfiguration.HomeGenie.UserPassword != "" ? "1" : "0"));
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestore")
                {
                    // file uploaded by user
                    string archivename = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "homegenie_restore_config.zip");
                    Utility.FolderCleanUp(Utility.GetTmpFolder());
                    try
                    {
                        MIG.Gateways.WebServiceUtility.SaveFile(request.InputStream, archivename);
                        Utility.UncompressZip(archivename, Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder()));
                        File.Delete(archivename);
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestoreS1")
                {
                    var serializer = new XmlSerializer(typeof(List<ProgramBlock>));
                    var reader = new StreamReader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "programs.xml"));
                    var newProgramsData = (List<ProgramBlock>)serializer.Deserialize(reader);
                    reader.Close();
                    var newProgramList = new List<ProgramBlock>();
                    foreach (ProgramBlock program in newProgramsData)
                    {
                        if (program.Address >= ProgramEngine.USER_SPACE_PROGRAMS_START)
                        {
                            ProgramBlock p = new ProgramBlock();
                            p.Address = program.Address;
                            p.Name = program.Name;
                            p.Description = program.Description;
                            newProgramList.Add(p);
                        }
                    }
                    newProgramList.Sort(delegate(ProgramBlock p1, ProgramBlock p2)
                    {
                        string c1 = p1.Address.ToString();
                        string c2 = p2.Address.ToString();
                        return c1.CompareTo(c2);
                    });
                    migCommand.Response = JsonConvert.SerializeObject(newProgramList);
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestoreS2")
                {
                    var serializer = new XmlSerializer(typeof(List<Group>));
                    var reader = new StreamReader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "automationgroups.xml"));
                    var automationGroups = (List<Group>)serializer.Deserialize(reader);
                    reader.Close();
                    //
                    foreach (var automationGroup in automationGroups)
                    {
                        if (homegenie.AutomationGroups.Find(g => g.Name == automationGroup.Name) == null)
                        {
                            homegenie.AutomationGroups.Add(automationGroup);
                        }
                    }
                    //
                    homegenie.UpdateGroupsDatabase("Automation");
                    //
                    //File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "tmp", "automationgroups.xml"), "./automationgroups.xml", true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "groups.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "groups.xml"), true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "lircconfig.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "lircconfig.xml"), true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "modules.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "modules.xml"), true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "scheduler.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "scheduler.xml"), true);
                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "systemconfig.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "systemconfig.xml"), true);
                    //
                    homegenie.LoadConfiguration();
                    //
                    // Restore automation programs
                    string selectedPrograms = migCommand.GetOption(1);
                    serializer = new XmlSerializer(typeof(List<ProgramBlock>));
                    reader = new StreamReader(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "programs.xml"));
                    var newProgramsData = (List<ProgramBlock>)serializer.Deserialize(reader);
                    reader.Close();
                    foreach (var program in newProgramsData)
                    {
                        var currentProgram = homegenie.ProgramEngine.Programs.Find(p => p.Address == program.Address);
                        program.IsRunning = false;
                        // Only restore user space programs
                        if (selectedPrograms.Contains("," + program.Address.ToString() + ",") && program.Address >= ProgramEngine.USER_SPACE_PROGRAMS_START)
                        {
                            int oldPid = program.Address;
                            if (currentProgram == null)
                            {
                                var newPid = ((currentProgram != null && currentProgram.Address == program.Address) ? homegenie.ProgramEngine.GeneratePid() : program.Address);
                                try
                                {
                                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "programs", program.Address + ".dll"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", newPid + ".dll"), true);
                                }
                                catch
                                {
                                }
                                program.Address = newPid;
                                homegenie.ProgramEngine.ProgramAdd(program);
                            }
                            else if (currentProgram != null)
                            {
                                homegenie.ProgramEngine.ProgramRemove(currentProgram);
                                try
                                {
                                    File.Copy(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "programs", program.Address + ".dll"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", program.Address + ".dll"), true);
                                }
                                catch
                                {
                                }
                                homegenie.ProgramEngine.ProgramAdd(program);
                            }
                            // Restore Arduino program folder ...
                            // TODO: this is untested yet...
                            if (program.Type.ToLower() == "arduino")
                            {
                                string sourceFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "programs", "arduino", oldPid.ToString());
                                string arduinoFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", "arduino", program.Address.ToString());
                                if (Directory.Exists(arduinoFolder))
                                    Directory.Delete(arduinoFolder, true);
                                Directory.CreateDirectory(arduinoFolder);
                                foreach (string newPath in Directory.GetFiles(sourceFolder))
                                {
                                    File.Copy(newPath, newPath.Replace(sourceFolder, arduinoFolder), true);
                                }
                            }
                        }
                        else if (currentProgram != null && program.Address < ProgramEngine.USER_SPACE_PROGRAMS_START)
                        {
                            // Only restore Enabled/Disabled status of system programs
                            currentProgram.IsEnabled = program.IsEnabled;
                        }
                    }
                    //
                    homegenie.UpdateProgramsDatabase();
                    //
                    // regenerate encrypted files
                    homegenie.UpdateModulesDatabase();
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationReset")
                {
                    homegenie.RestoreFactorySettings();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationBackup")
                {
                    homegenie.BackupCurrentSettings();
                    (request.Context as HttpListenerContext).Response.Redirect("/hg/html/homegenie_backup_config.zip");
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationLoad")
                {
                    homegenie.LoadConfiguration();
                }
                break;

            case "Modules.Get":
                try
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    migCommand.Response = Utility.Module2Json(module, false);
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.List":
                try
                {
                    homegenie.modules_Sort();
                    migCommand.Response = homegenie.GetJsonSerializedModules(migCommand.GetOption(0).ToLower() == "short");
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.RoutingReset":
                try
                {
                    for (int m = 0; m < homegenie.Modules.Count; m++)
                    {
                        homegenie.Modules[m].RoutingNode = "";
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.Save":
                string body = new StreamReader(request.InputStream).ReadToEnd();
                var newModules = JsonConvert.DeserializeObject(body) as JArray;
                for (int i = 0; i < newModules.Count; i++)
                {
                    try
                    {
                        var module = homegenie.Modules.Find(m => m.Address == newModules[i]["Address"].ToString() && m.Domain == newModules[i]["Domain"].ToString());
                        module.Name = newModules[i]["Name"].ToString();
                        //
                        try
                        {
                            module.DeviceType = (MIG.ModuleTypes)Enum.Parse(typeof(MIG.ModuleTypes), newModules[i]["DeviceType"].ToString(), true);
                        }
                        catch
                        {
                            // TODO: check what's wrong here...
                        }
                        //
                        var moduleProperties = newModules[i]["Properties"] as JArray;
                        for (int p = 0; p < moduleProperties.Count; p++)
                        {
                            string propertyName = moduleProperties[p]["Name"].ToString();
                            string propertyValue = moduleProperties[p]["Value"].ToString();
                            ModuleParameter parameter = null;
                            parameter = module.Properties.Find(delegate(ModuleParameter mp)
                            {
                                return mp.Name == propertyName;
                            });
                            //
                            if (propertyName == ModuleParameters.MODPAR_VIRTUALMETER_WATTS)
                            {
                                try
                                {
                                    propertyValue = double.Parse(propertyValue.Replace(",", "."), System.Globalization.CultureInfo.InvariantCulture).ToString();
                                }
                                catch
                                {
                                    propertyValue = "0";
                                }
                            }
                            //
                            if (parameter == null)
                            {
                                module.Properties.Add(new ModuleParameter() {
                                    Name = propertyName,
                                    Value = propertyValue
                                });
                            }
                            else
                            {
                                if (moduleProperties[p]["NeedsUpdate"] != null && moduleProperties[p]["NeedsUpdate"].ToString() == "true")
                                {
                                    parameter.Value = propertyValue;
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                        //TODO: notify exception?
                    }
                }
                homegenie.UpdateModulesDatabase();//write modules
                break;

            case "Modules.Update":
                string streamContent = new StreamReader(request.InputStream).ReadToEnd();
                var newModule = JsonConvert.DeserializeObject<Module>(streamContent);
                var currentModule = homegenie.Modules.Find(p => p.Domain == newModule.Domain && p.Address == newModule.Address);
                //
                if (currentModule == null)
                {
                    homegenie.Modules.Add(newModule);
                }
                else
                {
                    currentModule.Name = newModule.Name;
                    currentModule.Description = newModule.Description;
                    currentModule.DeviceType = newModule.DeviceType;
                    foreach (var newParameter in newModule.Properties)
                    {
                        var currentParameter = currentModule.Properties.Find(mp => mp.Name == newParameter.Name);
                        if (currentParameter == null)
                        {
                            currentModule.Properties.Add(newParameter);
                        }
                        else if (newParameter.NeedsUpdate)
                        {
                            // reset current reporting Watts if VMWatts field is set to 0
                            if (newParameter.Name == ModuleParameters.MODPAR_VIRTUALMETER_WATTS && newParameter.DecimalValue == 0 && currentParameter.DecimalValue != 0)
                            {
                                homegenie.migService_InterfacePropertyChanged(new InterfacePropertyChangedAction() {
                                    Domain = currentModule.Domain,
                                    SourceId = currentModule.Address,
                                    SourceType = currentModule.Description,
                                    Path = ModuleParameters.MODPAR_METER_WATTS,
                                    Value = "0.0"
                                });
                            }
                            currentParameter.Value = newParameter.Value;
                        }
                    }
                    // look for deleted properties
                    var deletedParameters = new List<ModuleParameter>();
                    foreach (var parameter in currentModule.Properties)
                    {
                        var currentParameter = newModule.Properties.Find(mp => mp.Name == parameter.Name);
                        if (currentParameter == null)
                        {
                            deletedParameters.Add(parameter);
                        }
                    }
                    foreach (var parameter in deletedParameters)
                    {
                        currentModule.Properties.Remove(parameter);
                    }
                    deletedParameters.Clear();
                }
                //
                homegenie.UpdateModulesDatabase();
                break;

            case "Modules.Delete":
                var deletedModule = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                if (deletedModule != null)
                {
                    homegenie.Modules.Remove(deletedModule);
                }
                migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                //
                homegenie.UpdateModulesDatabase();
                break;

            case "Stores.List":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        //module.Stores
                        migCommand.Response = "[";
                        for (int s = 0; s < module.Stores.Count; s++)
                        {
                            migCommand.Response += "{ \"Name\": \"" + Utility.XmlEncode(module.Stores[s].Name) + "\", \"Description\": \"" + Utility.XmlEncode(module.Stores[s].Description) + "\" },";
                        }
                        migCommand.Response = migCommand.Response.TrimEnd(',') + "]";
                    }

                }
                break;

            case "Stores.Delete":
                break;

            case "Stores.ItemList":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        migCommand.Response = "[";
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        for (int p = 0; p < store.List.Count; p++)
                        {
                            migCommand.Response += "{ \"Name\": \"" + Utility.XmlEncode(store.List[p].Name) + "\", \"Description\": \"" + Utility.XmlEncode(store.List[p].Description) + "\" },";
                        }
                        migCommand.Response = migCommand.Response.TrimEnd(',') + "]";
                    }
                }
                break;

            case "Stores.ItemDelete":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var name = migCommand.GetOption(3);
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        store.List.RemoveAll(i => i.Name == name);
                    }
                }
                break;

            case "Stores.ItemGet":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        migCommand.Response += JsonConvert.SerializeObject(store.Get(migCommand.GetOption(3)));
                    }
                }
                break;

            case "Stores.ItemSet":
                {
                    // value is the POST body
                    string itemData = new StreamReader(request.InputStream).ReadToEnd();
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        store.Get(migCommand.GetOption(3)).Value = itemData;
                    }
                }
                break;

            case "Groups.ModulesList":
                var theGroup = homegenie.Groups.Find(z => z.Name.ToLower() == migCommand.GetOption(0).Trim().ToLower());
                if (theGroup != null)
                {
                    string jsonmodules = "[";
                    for (int m = 0; m < theGroup.Modules.Count; m++)
                    {
                        var groupModule = homegenie.Modules.Find(mm => mm.Domain == theGroup.Modules[m].Domain && mm.Address == theGroup.Modules[m].Address);
                        if (groupModule != null)
                        {
                            jsonmodules += Utility.Module2Json(groupModule, false) + ",\n";
                        }
                    }
                    jsonmodules = jsonmodules.TrimEnd(',', '\n');
                    jsonmodules += "]";
                    migCommand.Response = jsonmodules;
                }
                break;
            case "Groups.List":
                try
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.GetGroups(migCommand.GetOption(0)));
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.Rename":
                string oldName = migCommand.GetOption(1);
                string newName = new StreamReader(request.InputStream).ReadToEnd();
                var currentGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == oldName);
                var newGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == newName);
                // ensure that the new group name is not already defined
                if (newGroup == null && currentGroup != null)
                {
                    currentGroup.Name = newName;
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                    //cmd.response = JsonHelper.GetSimpleResponse("OK");
                }
                else
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("New name already in use.");
                }
                break;

            case "Groups.Sort":
                using (var reader = new StreamReader(request.InputStream))
                {
                    var newGroupList = new List<Group>();
                    string[] newPositionOrder = reader.ReadToEnd().Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < newPositionOrder.Length; i++)
                    {
                        newGroupList.Add(homegenie.GetGroups(migCommand.GetOption(0))[int.Parse(newPositionOrder[i])]);
                    }
                    homegenie.GetGroups(migCommand.GetOption(0)).Clear();
                    homegenie.GetGroups(migCommand.GetOption(0)).RemoveAll(g => true);
                    homegenie.GetGroups(migCommand.GetOption(0)).AddRange(newGroupList);
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                }
                //
                try
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.GetGroups(migCommand.GetOption(0)));
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.SortModules":
                using (var reader = new StreamReader(request.InputStream))
                {
                    string groupName = migCommand.GetOption(1);
                    Group sortGroup = null;
                    try
                    {
                        sortGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(zn => zn.Name == groupName);
                    }
                    catch
                    {
                    }
                    //
                    if (sortGroup != null)
                    {
                        var newModulesReference = new List<ModuleReference>();
                        string[] newPositionOrder = reader.ReadToEnd().Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < newPositionOrder.Length; i++)
                        {
                            newModulesReference.Add(sortGroup.Modules[int.Parse(newPositionOrder[i])]);
                        }
                        sortGroup.Modules.Clear();
                        sortGroup.Modules = newModulesReference;
                        homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                    }
                }

                try
                {
                    migCommand.Response = JsonConvert.SerializeObject(homegenie.GetGroups(migCommand.GetOption(0)));
                }
                catch (Exception ex)
                {
                    migCommand.Response = JsonHelper.GetSimpleResponse("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.Add":
                string newGroupName = new StreamReader(request.InputStream).ReadToEnd();
                homegenie.GetGroups(migCommand.GetOption(0)).Add(new Group() { Name = newGroupName });
                homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                break;

            case "Groups.Delete":
                string deletedGroupName = new StreamReader(request.InputStream).ReadToEnd();
                Group deletedGroup = null;
                try
                {
                    deletedGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(zn => zn.Name == deletedGroupName);
                }
                catch
                {
                }
                //
                if (deletedGroup != null)
                {
                    homegenie.GetGroups(migCommand.GetOption(0)).Remove(deletedGroup);
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                    if (migCommand.GetOption(0).ToLower() == "automation")
                    {
                        var groupPrograms = homegenie.ProgramEngine.Programs.FindAll(p => p.Group.ToLower() == deletedGroup.Name.ToLower());
                        if (groupPrograms != null)
                        {
                            // delete group association from programs
                            foreach (ProgramBlock program in groupPrograms)
                            {
                                program.Group = "";
                            }
                        }
                    }
                }
                break;

            case "Groups.Save":
                string jsonGroups = new StreamReader(request.InputStream).ReadToEnd();
                var newGroups = JsonConvert.DeserializeObject<List<Group>>(jsonGroups);
                for (int i = 0; i < newGroups.Count; i++)
                {
                    try
                    {
                        var group = homegenie.Groups.Find(z => z.Name == newGroups[i].Name);
                        group.Modules.Clear();
                        group.Modules = newGroups[i].Modules;
                    }
                    catch
                    {
                    }
                }
                homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                break;

            case "Groups.WallpaperList":
                List<string> wallpaperList = new List<string>();
                var images = Directory.GetFiles(groupWallpapersPath);
                for (int i = 0; i < images.Length; i++)
                {
                    wallpaperList.Add(Path.GetFileName(images[i]));
                }
                migCommand.Response = JsonConvert.SerializeObject(wallpaperList);

                break;

            case "Groups.WallpaperAdd":
                {
                    string wallpaperFile = "";
                    try
                    {
                        wallpaperFile = MIG.Gateways.WebServiceUtility.SaveFile(request.InputStream, groupWallpapersPath);
                    }
                    catch
                    {
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(Path.GetFileName(wallpaperFile));
                }
                break;

            case "Groups.WallpaperSet":
                {
                    string wpGroupName = migCommand.GetOption(0);
                    var wpGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == wpGroupName);
                    if (wpGroup != null)
                    {
                        wpGroup.Wallpaper = migCommand.GetOption(1);
                        homegenie.UpdateGroupsDatabase("Control");
                    }
                }
                break;

            case "Groups.WallpaperDelete":
                {
                    string wallpaperFile = migCommand.GetOption(0);
                    wallpaperFile = Path.Combine(groupWallpapersPath, Path.GetFileName(wallpaperFile));
                    if (File.Exists(wallpaperFile))
                    {
                        File.Delete(wallpaperFile);
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                }
                break;

            case "Widgets.List":
                List<string> widgetsList = new List<string>();
                var groups = Directory.GetDirectories(widgetBasePath);
                for (int d = 0; d < groups.Length; d++)
                {
                    var categories = Directory.GetDirectories(groups[d]);
                    for (int c = 0; c < categories.Length; c++)
                    {
                        var widgets = Directory.GetFiles(categories[c], "*.js");
                        var group = groups[d].Replace(widgetBasePath, "").Substring(1);
                        var category = categories[c].Replace(groups[d], "").Substring(1);
                        for (int w = 0; w < widgets.Length; w++)
                        {
                            widgetsList.Add(group + "/" + category + "/" + Path.GetFileNameWithoutExtension(widgets[w]));
                        }
                    }
                }
                migCommand.Response = JsonConvert.SerializeObject(widgetsList);
                break;

            case "Widgets.Add":
                {
                    response = "ERROR";
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    widgetParts[0] = new String(widgetParts[0].Where(Char.IsLetter).ToArray()).ToLower();
                    widgetParts[1] = new String(widgetParts[1].Where(Char.IsLetter).ToArray()).ToLower();
                    widgetParts[2] = new String(widgetParts[2].Where(Char.IsLetter).ToArray()).ToLower();
                    if (!String.IsNullOrWhiteSpace(widgetParts[0]) && !String.IsNullOrWhiteSpace(widgetParts[1]) && !String.IsNullOrWhiteSpace(widgetParts[2]))
                    {
                        string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                        if (!Directory.Exists(filePath))
                        {
                            Directory.CreateDirectory(filePath);
                        }
                        // copy widget template into the new widget
                        var htmlFile = Path.Combine(filePath, widgetParts[2] + ".html");
                        var jsFile = Path.Combine(filePath, widgetParts[2] + ".js");
                        if (!File.Exists(htmlFile) && !File.Exists(jsFile))
                        {
                            File.Copy(Path.Combine(widgetBasePath, "template.html"), htmlFile);
                            File.Copy(Path.Combine(widgetBasePath, "template.js"), jsFile);
                            response = "OK";
                        }
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(response);
                }
                break;

            case "Widgets.Save":
                {
                    response = "ERROR";
                    string widgetData = new StreamReader(request.InputStream).ReadToEnd();
                    string fileType = migCommand.GetOption(0);
                    string widgetPath = migCommand.GetOption(1); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                    switch (fileType)
                    {
                    // html/javascript source
                    case "html":
                    case "js":
                        using (TextWriter widgetWriter = new StreamWriter(Path.Combine(filePath, widgetParts[2] + "." + fileType)))
                        {
                            widgetWriter.Write(widgetData);
                        }
                        response = "OK";
                        break;
                    // style sheet file
                    case "css":
                        break;
                    // locale file
                    case "json":
                        break;
                    // image file
                    case "jpg":
                    case "png":
                    case "gif":
                        break;
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(response);
                }
                break;

            case "Widgets.Delete":
                {
                    response = "ERROR";
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1], widgetParts[2] + ".");
                    if (File.Exists(filePath + "html"))
                    {
                        File.Delete(filePath + "html");
                        response = "OK";
                    }
                    if (File.Exists(filePath + "js"))
                    {
                        File.Delete(filePath + "js");
                        response = "OK";
                    }
                    migCommand.Response = JsonHelper.GetSimpleResponse(response);
                }
                break;

            case "Widgets.Export":
                {
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string widgetBundle = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "export", widgetPath.Replace('/', '_') + ".zip");
                    if (File.Exists(widgetBundle))
                    {
                        File.Delete(widgetBundle);
                    }
                    else if (!Directory.Exists(Path.GetDirectoryName(widgetBundle)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(widgetBundle));
                    }
                    string inputPath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                    string outputPath = Path.Combine(widgetParts[0], widgetParts[1]);
                    string infoFilePath = Path.Combine(inputPath, "widget.info");
                    File.WriteAllText(infoFilePath, "HomeGenie exported widget.");
                    Utility.AddFileToZip(widgetBundle, infoFilePath, "widget.info");
                    Utility.AddFileToZip(widgetBundle, Path.Combine(inputPath, widgetParts[2] + ".html"), Path.Combine(outputPath, widgetParts[2] + ".html"));
                    Utility.AddFileToZip(widgetBundle, Path.Combine(inputPath, widgetParts[2] + ".js"), Path.Combine(outputPath, widgetParts[2] + ".js"));
                    //
                    byte[] bundleData = File.ReadAllBytes(widgetBundle);
                    (request.Context as HttpListenerContext).Response.AddHeader("Content-Disposition", "attachment; filename=\"" + widgetPath.Replace('/', '_') + ".zip\"");
                    (request.Context as HttpListenerContext).Response.OutputStream.Write(bundleData, 0, bundleData.Length);
                }
                break;

            case "Widgets.Import":
                {
                    string archiveFile = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "import_widget.zip");
                    string importPath = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, Utility.GetTmpFolder(), "import");
                    if (Directory.Exists(importPath))
                        Directory.Delete(importPath, true);
                    MIG.Gateways.WebServiceUtility.SaveFile(request.InputStream, archiveFile);
                    if (WidgetImport(archiveFile, importPath))
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                    }
                    else
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("ERROR");
                    }
                }
                break;

            case "Widgets.Parse":
                {
                    string widgetData = new StreamReader(request.InputStream).ReadToEnd();
                    var parser = new JavaScriptParser();
                    try
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("OK");
                        parser.Parse(widgetData);
                    }
                    catch (Jint.Parser.ParserException e)
                    {
                        migCommand.Response = JsonHelper.GetSimpleResponse("ERROR (" + e.LineNumber + "," + e.Column + "): " + e.Description);
                    }
                }
                break;
            }
        }
예제 #36
0
 public void ShouldParseScriptFile(string file, string version)
 {
     var parser = new JavaScriptParser();
     var source = GetEmbeddedFile(file);
     var sw = new Stopwatch();
     var program = parser.Parse(source);
     Console.WriteLine("Parsed {0} {1} ({3} KB) in {2} ms", file, version, sw.ElapsedMilliseconds, (int)source.Length/1024);
     Assert.NotNull(program);
 }
예제 #37
0
        public void Process()
        {
            try
            {
                var parser = new JavaScriptParser();
                var program = parser.Parse(OriginalString);
                var visitor = new RequireVisitor();
                var result = visitor.Visit(program, RelativeFileName);

                var lines = GetScriptLines(OriginalString);

                var flattenedResults = result.GetFlattened();

                var deps = flattenedResults
                    .SelectMany(r => r.Dependencies)
                    .Where(r => !r.Contains("!"))
                    .Except(new List<string> { "require", "module", "exports" });

                //Make existing relative paths relative to the Scripts folder
                var scriptPath = System.IO.Path.GetDirectoryName(RelativeFileName).Replace(@"\", "/") + "/";
                deps = deps.Select(r =>
                {
                    if (r.StartsWith("."))
                    {
                        r = scriptPath + r;
                    }
                    return r;
                });

                //Expand named paths relative to the scripts folder
                Dependencies = deps.Select(r => ExpandPaths(r, configuration)).ToList();

                var shim = this.GetShim(RelativeFileName);
                if (shim != null)
                {
                    Dependencies.AddRange(shim.Dependencies.Select(r => ExpandPaths(r.Dependency, configuration)));
                }

                Dependencies = Dependencies.Distinct().ToList();

                flattenedResults.ForEach(
                    x =>
                    {
                        EnsureHasRange(x.ParentNode.Node, lines);
                        EnsureHasRange(x.DependencyArrayNode, lines);
                        EnsureHasRange(x.ModuleDefinitionNode, lines);
                        EnsureHasRange(x.ModuleIdentifierNode, lines);
                        EnsureHasRange(x.SingleDependencyNode, lines);
                        var arguments = x.ParentNode.Node.As<CallExpression>().Arguments;
                        foreach (var arg in arguments)
                        {
                            EnsureHasRange(arg, lines);
                        }
                    });

                var transformations = this.GetTransformations(result, flattenedResults);
                var text = OriginalString;
                transformations.ExecuteAll(ref text);
                ProcessedString = text;
            }
            catch (Exception ex)
            {
                throw new Exception(string.Format("Error while processing {0}: {1}", RelativeFileName, ex.Message), ex);
            }
        }
예제 #38
0
        public List<ProgramError> Compile()
        {
            List<ProgramError> errors = new List<ProgramError>();

            JavaScriptParser jp = new JavaScriptParser(false);
            //ParserOptions po = new ParserOptions();
            try
            {
                jp.Parse(programBlock.ScriptCondition);
            }
            catch (Exception e)
            {
                // TODO: parse error message
                if (e.Message.Contains(":"))
                {
                    string[] error = e.Message.Split(':');
                    string message = error[1];
                    if (message != "hg is not defined") // TODO: find a better solution for this
                    {
                        int line = int.Parse(error[0].Split(' ')[1]);
                        errors.Add(new ProgramError() {
                            Line = line,
                            ErrorMessage = message,
                            CodeBlock = "TC"
                        });
                    }
                }
            }
            //
            try
            {
                jp.Parse(programBlock.ScriptSource);
            }
            catch (Exception e)
            {
                // TODO: parse error message
                if (e.Message.Contains(":"))
                {
                    string[] error = e.Message.Split(':');
                    string message = error[1];
                    if (message != "hg is not defined") // TODO: find a better solution for this
                    {
                        int line = int.Parse(error[0].Split(' ')[1]);
                        errors.Add(new ProgramError() {
                            Line = line,
                            ErrorMessage = message,
                            CodeBlock = "CR"
                        });
                    }
                }
            }

            return errors;
        }
예제 #39
0
파일: Engine.cs 프로젝트: skipme/jint
 public Engine Execute(string source, ParserOptions parserOptions)
 {
     var parser = new JavaScriptParser();
     return Execute(parser.Parse(source, parserOptions));
 }
예제 #40
0
파일: Engine.cs 프로젝트: skipme/jint
 public Engine Execute(string source)
 {
     var parser = new JavaScriptParser();
     return Execute(parser.Parse(source));
 }
예제 #41
0
        public JsValue Call(JsValue thisObject, JsValue[] arguments, bool directCall)
        {
            if (arguments.At(0).Type != Types.String)
            {
                return arguments.At(0);
            }

            var code = TypeConverter.ToString(arguments.At(0));

            try
            {
                var parser = new JavaScriptParser(StrictModeScope.IsStrictModeCode);
                var program = parser.Parse(code);
                using (new StrictModeScope(program.Strict))
                {
                    using (new EvalCodeScope())
                    {
                        LexicalEnvironment strictVarEnv = null;

                        try
                        {
                            if (!directCall)
                            {
                                Engine.EnterExecutionContext(Engine.GlobalEnvironment, Engine.GlobalEnvironment, Engine.Global);
                            }

                            if (StrictModeScope.IsStrictModeCode)
                            {
                                strictVarEnv = LexicalEnvironment.NewDeclarativeEnvironment(Engine, Engine.ExecutionContext.LexicalEnvironment);
                                Engine.EnterExecutionContext(strictVarEnv, strictVarEnv, Engine.ExecutionContext.ThisBinding);
                            }

                            Engine.DeclarationBindingInstantiation(DeclarationBindingType.EvalCode, program.FunctionDeclarations, program.VariableDeclarations, this, arguments);
                            
                            var result = _engine.ExecuteStatement(program);

                            if (result.Type == Completion.Throw)
                            {
                                throw new JavaScriptException(result.GetValueOrDefault());
                            }
                            else
                            {
                                return result.GetValueOrDefault();
                            }
                        }
                        finally
                        {
                            if (strictVarEnv != null)
                            {
                                Engine.LeaveExecutionContext();
                            }

                            if (!directCall)
                            {
                                Engine.LeaveExecutionContext();
                            }
                        }
                    }
                }
            }
            catch (ParserException)
            {
                throw new JavaScriptException(Engine.SyntaxError);
            }
        }
예제 #42
0
        /// <summary>
        /// Get student infos from the JavaScript variables in the schedule page.
        /// </summary>
        /// <returns></returns>
        public Dictionary<string, object> GetStudentInfoFromSchedulePage()
        {
            var schedulePageHtml = WebClientEx.Instance.Get(Constants.SCHEDULE_PAGE_URL);
            HtmlDocument htmlDoc = new HtmlDocument();
            htmlDoc.LoadHtml(schedulePageHtml);
            var docNode = htmlDoc.DocumentNode;
            var scriptNodes = docNode.QuerySelectorAll("script");
            List<HtmlNode> targetNodes = new List<HtmlNode>();
            foreach (var node in scriptNodes)
            {
                if (node.Attributes["src"] == null)
                {
                    if (!node.InnerHtml.Trim().StartsWith("debug") && node.InnerHtml.Length >= 100)
                    {
                        targetNodes.Add(node);
                    }
                }
            }

            Dictionary<string, object> Variables = new Dictionary<string, object>();

            if (targetNodes != null && targetNodes.Count >= 1)
            {
                foreach (var targetNode in targetNodes)
                {
                    JavaScriptParser par = new JavaScriptParser();
                    var jsObj = par.Parse(targetNode.InnerHtml);
                    var jsBody = jsObj.Body;
                    foreach (var body in jsBody)
                    {
                        if (body is VariableDeclaration)
                        {
                            var var = body as VariableDeclaration;
                            foreach (var dec in var.Declarations)
                            {
                                var name = dec.Id.Name;
                                var value = dec.Init.As<Literal>().Value;
                                Variables.Add(name, value);
                            }
                        }
                    }
                }
            }
            Core.StudentInfo = Variables;
            return Variables;
        }
예제 #43
0
        public Engine Execute(string source)
        {
            var parser = new JavaScriptParser();

            return(Execute(parser.Parse(source)));
        }
예제 #44
0
        public Engine Execute(string source, ParserOptions parserOptions)
        {
            var parser = new JavaScriptParser();

            return(Execute(parser.Parse(source, parserOptions)));
        }
예제 #45
0
        public void ProcessRequest(MigClientRequest request)
        {
            var migCommand = request.Command;

            string response = "";
            switch (migCommand.Command)
            {
            case "Interfaces.List":
                response = "[ ";
                foreach (var migInterface in homegenie.Interfaces)
                {
                    var ifaceConfig = homegenie.SystemConfiguration.MigService.GetInterface(migInterface.GetDomain());
                    if (ifaceConfig == null || !ifaceConfig.IsEnabled)
                    {
                        continue;
                    }
                    response += "{ \"Domain\" : \"" + migInterface.GetDomain() + "\", \"IsConnected\" : \"" + migInterface.IsConnected + "\" },";
                }
                if (homegenie.UpdateChecker != null && homegenie.UpdateChecker.IsUpdateAvailable)
                {
                    response += "{ \"Domain\" : \"" + Domains.HomeGenie_UpdateChecker + "\", \"IsConnected\" : \"True\" }";
                    response += " ]";
                }
                else
                {
                    response = response.Substring(0, response.Length - 1) + " ]";
                }
                request.ResponseData = response;
                break;

            case "Interfaces.ListConfig":
                response = "[ ";
                foreach (var migInterface in homegenie.Interfaces)
                {
                    var ifaceConfig = homegenie.SystemConfiguration.MigService.GetInterface(migInterface.GetDomain());
                    if (ifaceConfig == null)
                        continue;
                    response += JsonConvert.SerializeObject(ifaceConfig) + ",";
                }
                response = response.Substring(0, response.Length - 1) + " ]";
                request.ResponseData = response;
                break;

            //TODO: should this be moved somewhere to MIG?
            case "Interfaces.Configure":
                switch (migCommand.GetOption(0))
                {
                case "Hardware.SerialPorts":
                    if (Environment.OSVersion.Platform == PlatformID.Unix)
                    {
                        var serialPorts = System.IO.Ports.SerialPort.GetPortNames();
                        var portList = new List<string>();
                        for (int p = serialPorts.Length - 1; p >= 0; p--)
                        {
                            if (serialPorts[p].Contains("/ttyS") 
                                || serialPorts[p].Contains("/ttyUSB") 
                                || serialPorts[p].Contains("/ttyAMA")   // RaZberry
                                || serialPorts[p].Contains("/ttyACM"))  // ZME_UZB1
                            {
                                portList.Add(serialPorts[p]);
                            }
                        }
                        request.ResponseData = portList;
                    }
                    else
                    {
                        var portNames = System.IO.Ports.SerialPort.GetPortNames();
                        request.ResponseData = portNames;
                    }
                    break;

                }
                break;

            case "Interface.Import":
                string downloadUrl = migCommand.GetOption(0);
                response = "";
                string ifaceFileName = Path.Combine(tempFolderPath, "mig_interface_import.zip");
                string outputFolder = Path.Combine(tempFolderPath, "mig");
                Utility.FolderCleanUp(outputFolder);

                try
                {
                    if (String.IsNullOrWhiteSpace(downloadUrl))
                    {
                        // file uploaded by user
                        MIG.Gateways.WebServiceUtility.SaveFile(request.RequestData, ifaceFileName);
                    }
                    else
                    {
                        // download file from url
                        using (var client = new WebClient())
                        {
                            client.DownloadFile(downloadUrl, ifaceFileName);
                            client.Dispose();
                        }
                    }
                }
                catch
                { 
                    // TODO: report exception
                }

                try
                {
                    if (!Directory.Exists(outputFolder))
                    {
                        Directory.CreateDirectory(outputFolder);
                    }
                    Utility.UncompressZip(ifaceFileName, outputFolder);
                    File.Delete(ifaceFileName);

                    var migInt = GetInterfaceConfig(Path.Combine(outputFolder, "configuration.xml"));
                    if (migInt != null)
                    {
                        response = String.Format("{0} ({1})\n{2}\n", migInt.Domain, migInt.AssemblyName, migInt.Description);
                        // Check for README notes and append them to the response
                        var readmeFile = Path.Combine(outputFolder, "README.TXT");
                        if (File.Exists(readmeFile))
                        {
                            response += File.ReadAllText(readmeFile);
                        }
                        request.ResponseData = new ResponseText(response);
                    }
                    else
                    {
                        request.ResponseData = new ResponseText("NOT A VALID ADD-ON PACKAGE");
                    }
                }
                catch
                {
                    // TODO: report exception
                }
                break;

            case "Interface.Install":
                // install the interface package from the unpacked archive folder
                if (InterfaceInstall(Path.Combine(tempFolderPath, "mig")))
                    request.ResponseData = new ResponseText("OK");
                else
                    request.ResponseData = new ResponseText("NOT A VALID ADD-ON PACKAGE");
                break;

            case "System.GetVersion":
                request.ResponseData = homegenie.UpdateChecker.GetCurrentRelease();
                break;

            case "System.Configure":
                if (migCommand.GetOption(0) == "Service.Restart")
                {
                    Program.Quit(true);
                    request.ResponseData = new ResponseText("OK");
                }
                else if (migCommand.GetOption(0) == "UpdateManager.UpdatesList")
                {
                    request.ResponseData = homegenie.UpdateChecker.RemoteUpdates;
                }
                else if (migCommand.GetOption(0) == "UpdateManager.Check")
                {
                    homegenie.UpdateChecker.Check();
                    request.ResponseData = new ResponseText("OK");
                }
                else if (migCommand.GetOption(0) == "UpdateManager.DownloadUpdate")
                {
                    var resultMessage = "ERROR";
                    bool success = homegenie.UpdateChecker.DownloadUpdateFiles();
                    if (success)
                    {
                        if (homegenie.UpdateChecker.IsRestartRequired)
                        {
                            resultMessage = "RESTART";
                        }
                        else
                        {
                            resultMessage = "OK";
                        }
                    }
                    request.ResponseData = new ResponseText(resultMessage);
                }
                else if (migCommand.GetOption(0) == "UpdateManager.InstallUpdate") //UpdateManager.InstallProgramsCommit")
                {
                    string resultMessage = "OK";
                    homegenie.SaveData();
                    if (!homegenie.UpdateChecker.InstallFiles())
                    {
                        resultMessage = "ERROR";
                    }
                    else
                    {
                        if (homegenie.UpdateChecker.IsRestartRequired)
                        {
                            resultMessage = "RESTART";
                            Utility.RunAsyncTask(() =>
                            {
                                Thread.Sleep(2000);
                                Program.Quit(true);
                            });
                        }
                        else
                        {
                            homegenie.LoadConfiguration();
                            homegenie.UpdateChecker.Check();
                        }
                    }
                    request.ResponseData = new ResponseText(resultMessage);
                }
                else if (migCommand.GetOption(0) == "Statistics.GetStatisticsDatabaseMaximumSize")
                {
                    request.ResponseData = new ResponseText(homegenie.SystemConfiguration.HomeGenie.Statistics.MaxDatabaseSizeMBytes.ToString());
                }
                else if (migCommand.GetOption(0) == "Statistics.SetStatisticsDatabaseMaximumSize")
                {
                    try
                    {
                        int sizeLimit = int.Parse(migCommand.GetOption(1));
                        homegenie.SystemConfiguration.HomeGenie.Statistics.MaxDatabaseSizeMBytes = sizeLimit;
                        homegenie.SystemConfiguration.Update();
                        homegenie.Statistics.SizeLimit = sizeLimit * 1024 * 1024;
                    }
                    catch
                    {
                    }
                }
                else if (migCommand.GetOption(0) == "SystemLogging.DownloadCsv")
                {
                    string csvlog = "";
                    string logpath = Path.Combine("log", "homegenie.log");
                    if (migCommand.GetOption(1) == "1")
                    {
                        logpath = Path.Combine("log", "homegenie.log.bak");
                    }
                    if (File.Exists(logpath))
                    {
                        using (var fs = new FileStream(logpath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
                        using (var sr = new StreamReader(fs, Encoding.Default))
                        {
                            csvlog = sr.ReadToEnd();
                        }
                    }
                    (request.Context.Data as HttpListenerContext).Response.AddHeader("Content-Disposition", "attachment;filename=homegenie_log_" + migCommand.GetOption(1) + ".csv");
                    request.ResponseData = csvlog;
                }
                else if (migCommand.GetOption(0) == "SystemLogging.Enable")
                {
                    SystemLogger.Instance.OpenLog();
                    homegenie.SystemConfiguration.HomeGenie.EnableLogFile = "true";
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "SystemLogging.Disable")
                {
                    SystemLogger.Instance.CloseLog();
                    homegenie.SystemConfiguration.HomeGenie.EnableLogFile = "false";
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "SystemLogging.IsEnabled")
                {
                    request.ResponseData = new ResponseText((homegenie.SystemConfiguration.HomeGenie.EnableLogFile.ToLower().Equals("true") ? "1" : "0"));
                }
                else if (migCommand.GetOption(0) == "Security.SetPassword")
                {
                    // password only for now, with fixed user login 'admin'
                    string pass = migCommand.GetOption(1) == "" ? "" : MIG.Utility.Encryption.SHA1.GenerateHashString(migCommand.GetOption(1));
                    homegenie.MigService.GetGateway("WebServiceGateway").SetOption("Password", pass);
                    homegenie.SaveData();
                }
                else if (migCommand.GetOption(0) == "Security.ClearPassword")
                {
                    homegenie.MigService.GetGateway("WebServiceGateway").SetOption("Password", "");
                    homegenie.SaveData();
                }
                else if (migCommand.GetOption(0) == "Security.HasPassword")
                {
                    var webGateway = homegenie.MigService.GetGateway("WebServiceGateway");
                    var password = webGateway.GetOption("Password");
                    request.ResponseData = new ResponseText((password == null || String.IsNullOrEmpty(password.Value) ? "0" : "1"));
                }
                else if (migCommand.GetOption(0) == "HttpService.SetWebCacheEnabled")
                {
                    if (migCommand.GetOption(1) == "1")
                    {
                        homegenie.MigService.GetGateway("WebServiceGateway").SetOption("EnableFileCaching", "true");
                    }
                    else
                    {
                        homegenie.MigService.GetGateway("WebServiceGateway").SetOption("EnableFileCaching", "false");
                    }
                    homegenie.SystemConfiguration.Update();
                    request.ResponseData = new ResponseText("OK");
                }
                else if (migCommand.GetOption(0) == "HttpService.GetWebCacheEnabled")
                {
                    var fileCaching = homegenie.MigService.GetGateway("WebServiceGateway").GetOption("EnableFileCaching");
                    request.ResponseData = new ResponseText(fileCaching != null ? fileCaching.Value : "false");  
                }
                else if (migCommand.GetOption(0) == "HttpService.GetPort")
                {
                    var port = homegenie.MigService.GetGateway("WebServiceGateway").GetOption("Port");
                    request.ResponseData = new ResponseText(port != null ? port.Value : "8080");
                }
                else if (migCommand.GetOption(0) == "HttpService.SetPort")
                {
                    homegenie.MigService.GetGateway("WebServiceGateway").SetOption("Port", migCommand.GetOption(1));
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "HttpService.GetHostHeader")
                {
                    var host = homegenie.MigService.GetGateway("WebServiceGateway").GetOption("Host");
                    request.ResponseData = new ResponseText(host != null ? host.Value : "*");
                }
                else if (migCommand.GetOption(0) == "HttpService.SetHostHeader")
                {
                    homegenie.MigService.GetGateway("WebServiceGateway").SetOption("Host", migCommand.GetOption(1));
                    homegenie.SystemConfiguration.Update();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestore")
                {
                    // file uploaded by user
                    string archivename = Path.Combine(tempFolderPath, "homegenie_restore_config.zip");
                    Utility.FolderCleanUp(Utility.GetTmpFolder());
                    try
                    {
                        MIG.Gateways.WebServiceUtility.SaveFile(request.RequestData, archivename);
                        Utility.UncompressZip(archivename, tempFolderPath);
                        File.Delete(archivename);
                        request.ResponseData = new ResponseStatus(Status.Ok);
                    }
                    catch
                    {
                        request.ResponseData = new ResponseStatus(Status.Error);
                    }
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestoreS1")
                {
                    var serializer = new XmlSerializer(typeof(List<ProgramBlock>));
                    var reader = new StreamReader(Path.Combine(tempFolderPath, "programs.xml"));
                    var newProgramsData = (List<ProgramBlock>)serializer.Deserialize(reader);
                    reader.Close();
                    var newProgramList = new List<ProgramBlock>();
                    foreach (ProgramBlock program in newProgramsData)
                    {
                        if (program.Address >= ProgramManager.USER_SPACE_PROGRAMS_START)
                        {
                            ProgramBlock p = new ProgramBlock();
                            p.Address = program.Address;
                            p.Name = program.Name;
                            p.Description = program.Description;
                            newProgramList.Add(p);
                        }
                    }
                    newProgramList.Sort(delegate(ProgramBlock p1, ProgramBlock p2)
                    {
                        string c1 = p1.Address.ToString();
                        string c2 = p2.Address.ToString();
                        return c1.CompareTo(c2);
                    });
                    request.ResponseData = newProgramList;
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationRestoreS2")
                {
                    // Import automation groups
                    var serializer = new XmlSerializer(typeof(List<Group>));
                    var reader = new StreamReader(Path.Combine(tempFolderPath, "automationgroups.xml"));
                    var automationGroups = (List<Group>)serializer.Deserialize(reader);
                    reader.Close();
                    foreach (var automationGroup in automationGroups)
                    {
                        if (homegenie.AutomationGroups.Find(g => g.Name == automationGroup.Name) == null)
                        {
                            homegenie.AutomationGroups.Add(automationGroup);
                        }
                    }
                    homegenie.UpdateGroupsDatabase("Automation");
                    // Copy system configuration files
                    File.Copy(Path.Combine(tempFolderPath, "groups.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "groups.xml"), true);
                    File.Copy(Path.Combine(tempFolderPath, "modules.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "modules.xml"), true);
                    File.Copy(Path.Combine(tempFolderPath, "scheduler.xml"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "scheduler.xml"), true);
                    // TODO: add backward compatibility for systemconfig.xml from HG 1.0 < r494
                    UpdateSystemConfig();
                    // Copy MIG configuration files if present (from folder lib/mig/*.xml)
                    string migLibFolder = Path.Combine(tempFolderPath, "lib", "mig");
                    if (Directory.Exists(migLibFolder))
                    {
                        foreach (string f in Directory.GetFiles(migLibFolder, "*.xml"))
                        {
                            File.Copy(f, Path.Combine("lib", "mig", Path.GetFileName(f)), true);
                        }
                    }
                    homegenie.SoftReload();
                    // Restore automation programs
                    string selectedPrograms = migCommand.GetOption(1);
                    serializer = new XmlSerializer(typeof(List<ProgramBlock>));
                    reader = new StreamReader(Path.Combine(tempFolderPath, "programs.xml"));
                    var newProgramsData = (List<ProgramBlock>)serializer.Deserialize(reader);
                    reader.Close();
                    foreach (var program in newProgramsData)
                    {
                        var currentProgram = homegenie.ProgramManager.Programs.Find(p => p.Address == program.Address);
                        program.IsRunning = false;
                        // Only restore user space programs
                        if (selectedPrograms.Contains("," + program.Address.ToString() + ",") && program.Address >= ProgramManager.USER_SPACE_PROGRAMS_START)
                        {
                            int oldPid = program.Address;
                            if (currentProgram == null)
                            {
                                var newPid = ((currentProgram != null && currentProgram.Address == program.Address) ? homegenie.ProgramManager.GeneratePid() : program.Address);
                                try
                                {
                                    File.Copy(Path.Combine(tempFolderPath, "programs", program.Address + ".dll"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", newPid + ".dll"), true);
                                }
                                catch
                                {
                                }
                                program.Address = newPid;
                                homegenie.ProgramManager.ProgramAdd(program);
                            }
                            else if (currentProgram != null)
                            {
                                homegenie.ProgramManager.ProgramRemove(currentProgram);
                                try
                                {
                                    File.Copy(Path.Combine(tempFolderPath, "programs", program.Address + ".dll"), Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", program.Address + ".dll"), true);
                                }
                                catch
                                {
                                }
                                homegenie.ProgramManager.ProgramAdd(program);
                            }
                            // Restore Arduino program folder ...
                            // TODO: this is untested yet...
                            if (program.Type.ToLower() == "arduino")
                            {
                                string sourceFolder = Path.Combine(tempFolderPath, "programs", "arduino", oldPid.ToString());
                                string arduinoFolder = Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "programs", "arduino", program.Address.ToString());
                                if (Directory.Exists(arduinoFolder))
                                    Directory.Delete(arduinoFolder, true);
                                Directory.CreateDirectory(arduinoFolder);
                                foreach (string newPath in Directory.GetFiles(sourceFolder))
                                {
                                    File.Copy(newPath, newPath.Replace(sourceFolder, arduinoFolder), true);
                                }
                            }
                        }
                        else if (currentProgram != null && program.Address < ProgramManager.USER_SPACE_PROGRAMS_START)
                        {
                            // Only restore Enabled/Disabled status of system programs
                            currentProgram.IsEnabled = program.IsEnabled;
                        }
                    }
                    homegenie.UpdateProgramsDatabase();
                    homegenie.SaveData();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationReset")
                {
                    homegenie.RestoreFactorySettings();
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationBackup")
                {
                    homegenie.BackupCurrentSettings();
                    (request.Context.Data as HttpListenerContext).Response.Redirect("/hg/html/homegenie_backup_config.zip");
                }
                else if (migCommand.GetOption(0) == "System.ConfigurationLoad")
                {
                    homegenie.SoftReload();
                }
                break;

            case "Modules.Get":
                try
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    request.ResponseData = Utility.Module2Json(module, false);
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.ParameterGet":
                try
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    var parameter = Utility.ModuleParameterGet(module, migCommand.GetOption(2));
                    if (parameter != null)
                        request.ResponseData = JsonConvert.SerializeObject(parameter, Formatting.Indented);
                    else
                        request.ResponseData = new ResponseText("ERROR: Unknown parameter '" + migCommand.GetOption(2) + "'");
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.ParameterSet":
                try
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    var parameter = Utility.ModuleParameterSet(module, migCommand.GetOption(2), migCommand.GetOption(3));
                    request.ResponseData = new ResponseText("OK");
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.StatisticsGet":
                try
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    var parameter = Utility.ModuleParameterGet(module, migCommand.GetOption(2));
                    if (parameter != null)
                        request.ResponseData = JsonConvert.SerializeObject(parameter.Statistics, Formatting.Indented);
                    else
                        request.ResponseData = new ResponseText("ERROR: Unknown parameter '" + migCommand.GetOption(2) + "'");
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.List":
                try
                {
                    homegenie.modules_Sort();
                    request.ResponseData = homegenie.GetJsonSerializedModules(migCommand.GetOption(0).ToLower() == "short");
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.RoutingReset":
                try
                {
                    for (int m = 0; m < homegenie.Modules.Count; m++)
                    {
                        homegenie.Modules[m].RoutingNode = "";
                    }
                    request.ResponseData = new ResponseText("OK");
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Modules.Save":
                string body = request.RequestText;
                var newModules = JsonConvert.DeserializeObject(body) as JArray;
                for (int i = 0; i < newModules.Count; i++)
                {
                    try
                    {
                        var module = homegenie.Modules.Find(m => m.Address == newModules[i]["Address"].ToString() && m.Domain == newModules[i]["Domain"].ToString());
                        module.Name = newModules[i]["Name"].ToString();
                        //
                        try
                        {
                            module.DeviceType = (MIG.ModuleTypes)Enum.Parse(typeof(MIG.ModuleTypes), newModules[i]["DeviceType"].ToString(), true);
                        }
                        catch
                        {
                            // TODO: check what's wrong here...
                        }
                        //
                        var moduleProperties = newModules[i]["Properties"] as JArray;
                        for (int p = 0; p < moduleProperties.Count; p++)
                        {
                            string propertyName = moduleProperties[p]["Name"].ToString();
                            string propertyValue = moduleProperties[p]["Value"].ToString();
                            ModuleParameter parameter = null;
                            parameter = module.Properties.Find(delegate(ModuleParameter mp)
                            {
                                return mp.Name == propertyName;
                            });
                            //
                            if (propertyName == Properties.VirtualMeterWatts)
                            {
                                try
                                {
                                    propertyValue = double.Parse(propertyValue.Replace(",", "."), System.Globalization.CultureInfo.InvariantCulture).ToString();
                                }
                                catch
                                {
                                    propertyValue = "0";
                                }
                            }
                            //
                            if (parameter == null)
                            {
                                module.Properties.Add(new ModuleParameter() {
                                    Name = propertyName,
                                    Value = propertyValue
                                });
                            }
                            else
                            {
                                if (moduleProperties[p]["NeedsUpdate"] != null && moduleProperties[p]["NeedsUpdate"].ToString() == "true")
                                {
                                    parameter.Value = propertyValue;
                                }
                            }
                        }
                    }
                    catch (Exception)
                    {
                        //TODO: notify exception?
                    }
                }
                homegenie.UpdateModulesDatabase();//write modules
                break;

            case "Modules.Update":
                string streamContent = request.RequestText;
                var newModule = JsonConvert.DeserializeObject<Module>(streamContent);
                var currentModule = homegenie.Modules.Find(p => p.Domain == newModule.Domain && p.Address == newModule.Address);
                //
                if (currentModule == null)
                {
                    homegenie.Modules.Add(newModule);
                }
                else
                {
                    currentModule.Name = newModule.Name;
                    currentModule.Description = newModule.Description;
                    currentModule.DeviceType = newModule.DeviceType;
                    foreach (var newParameter in newModule.Properties)
                    {
                        var currentParameter = currentModule.Properties.Find(mp => mp.Name == newParameter.Name);
                        if (currentParameter == null)
                        {
                            currentModule.Properties.Add(newParameter);
                        }
                        else if (newParameter.NeedsUpdate)
                        {
                            // reset current reporting Watts if VMWatts field is set to 0
                            if (newParameter.Name == Properties.VirtualMeterWatts && newParameter.DecimalValue == 0 && currentParameter.DecimalValue != 0)
                            {
                                homegenie.RaiseEvent(
                                    Domains.HomeGenie_System,
                                    currentModule.Domain,
                                    currentModule.Address,
                                    currentModule.Description,
                                    Properties.MeterWatts,
                                    "0.0"
                                );
                            }
                            currentParameter.Value = newParameter.Value;
                        }
                    }
                    // look for deleted properties
                    var deletedParameters = new List<ModuleParameter>();
                    foreach (var parameter in currentModule.Properties)
                    {
                        var currentParameter = newModule.Properties.Find(mp => mp.Name == parameter.Name);
                        if (currentParameter == null)
                        {
                            deletedParameters.Add(parameter);
                        }
                    }
                    foreach (var parameter in deletedParameters)
                    {
                        currentModule.Properties.Remove(parameter);
                    }
                    deletedParameters.Clear();
                }
                //
                homegenie.UpdateModulesDatabase();
                break;

            case "Modules.Delete":
                var deletedModule = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                if (deletedModule != null)
                {
                    homegenie.Modules.Remove(deletedModule);
                }
                request.ResponseData = new ResponseText("OK");
                //
                homegenie.UpdateModulesDatabase();
                break;

            case "Stores.List":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        //module.Stores
                        response = "[";
                        for (int s = 0; s < module.Stores.Count; s++)
                        {
                            response += "{ \"Name\": \"" + Utility.XmlEncode(module.Stores[s].Name) + "\", \"Description\": \"" + Utility.XmlEncode(module.Stores[s].Description) + "\" },";
                        }
                        response = response.TrimEnd(',') + "]";
                        request.ResponseData = response;
                    }

                }
                break;

            case "Stores.Delete":
                break;

            case "Stores.ItemList":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        response = "[";
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        for (int p = 0; p < store.List.Count; p++)
                        {
                            response += "{ \"Name\": \"" + Utility.XmlEncode(store.List[p].Name) + "\", \"Description\": \"" + Utility.XmlEncode(store.List[p].Description) + "\" },";
                        }
                        response = response.TrimEnd(',') + "]";
                        request.ResponseData = response;
                    }
                }
                break;

            case "Stores.ItemDelete":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var name = migCommand.GetOption(3);
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        store.List.RemoveAll(i => i.Name == name);
                    }
                }
                break;

            case "Stores.ItemGet":
                {
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        request.ResponseData = store.Get(migCommand.GetOption(3));
                    }
                }
                break;

            case "Stores.ItemSet":
                {
                    // value is the POST body
                    string itemData = request.RequestText;
                    var module = homegenie.Modules.Find(m => m.Domain == migCommand.GetOption(0) && m.Address == migCommand.GetOption(1));
                    if (module != null)
                    {
                        var store = new StoreHelper(module.Stores, migCommand.GetOption(2));
                        store.Get(migCommand.GetOption(3)).Value = itemData;
                    }
                }
                break;

            case "Groups.ModulesList":
                var theGroup = homegenie.Groups.Find(z => z.Name.ToLower() == migCommand.GetOption(0).Trim().ToLower());
                if (theGroup != null)
                {
                    string jsonmodules = "[";
                    for (int m = 0; m < theGroup.Modules.Count; m++)
                    {
                        var groupModule = homegenie.Modules.Find(mm => mm.Domain == theGroup.Modules[m].Domain && mm.Address == theGroup.Modules[m].Address);
                        if (groupModule != null)
                        {
                            jsonmodules += Utility.Module2Json(groupModule, false) + ",\n";
                        }
                    }
                    jsonmodules = jsonmodules.TrimEnd(',', '\n');
                    jsonmodules += "]";
                    request.ResponseData = jsonmodules;
                }
                break;
            case "Groups.List":
                try
                {
                    request.ResponseData = homegenie.GetGroups(migCommand.GetOption(0));
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.Rename":
                string oldName = migCommand.GetOption(1);
                string newName = request.RequestText;
                var currentGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == oldName);
                var newGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == newName);
                // ensure that the new group name is not already defined
                if (newGroup == null && currentGroup != null)
                {
                    currentGroup.Name = newName;
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                    //cmd.response = JsonHelper.GetSimpleResponse("OK");
                }
                else
                {
                    request.ResponseData = new ResponseText("New name already in use.");
                }
                break;

            case "Groups.Sort":
                {
                    var newGroupList = new List<Group>();
                    string[] newPositionOrder = request.RequestText.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                    for (int i = 0; i < newPositionOrder.Length; i++)
                    {
                        newGroupList.Add(homegenie.GetGroups(migCommand.GetOption(0))[int.Parse(newPositionOrder[i])]);
                    }
                    homegenie.GetGroups(migCommand.GetOption(0)).Clear();
                    homegenie.GetGroups(migCommand.GetOption(0)).RemoveAll(g => true);
                    homegenie.GetGroups(migCommand.GetOption(0)).AddRange(newGroupList);
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                }
                try
                {
                    request.ResponseData = homegenie.GetGroups(migCommand.GetOption(0));
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.SortModules":
                {
                    string groupName = migCommand.GetOption(1);
                    Group sortGroup = null;
                    sortGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(zn => zn.Name == groupName);
                    if (sortGroup != null)
                    {
                        var newModulesReference = new List<ModuleReference>();
                        string[] newPositionOrder = request.RequestText.Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
                        for (int i = 0; i < newPositionOrder.Length; i++)
                        {
                            newModulesReference.Add(sortGroup.Modules[int.Parse(newPositionOrder[i])]);
                        }
                        sortGroup.Modules.Clear();
                        sortGroup.Modules = newModulesReference;
                        homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));
                    }
                }
                try
                {
                    request.ResponseData = homegenie.GetGroups(migCommand.GetOption(0));
                }
                catch (Exception ex)
                {
                    request.ResponseData = new ResponseText("ERROR: \n" + ex.Message + "\n\n" + ex.StackTrace);
                }
                break;

            case "Groups.Add":
                string newGroupName = request.RequestText;
                homegenie.GetGroups(migCommand.GetOption(0)).Add(new Group() { Name = newGroupName });
                homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                break;

            case "Groups.Delete":
                string deletedGroupName = request.RequestText;
                Group deletedGroup = null;
                try
                {
                    deletedGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(zn => zn.Name == deletedGroupName);
                }
                catch
                {
                }
                //
                if (deletedGroup != null)
                {
                    homegenie.GetGroups(migCommand.GetOption(0)).Remove(deletedGroup);
                    homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                    if (migCommand.GetOption(0).ToLower() == "automation")
                    {
                        var groupPrograms = homegenie.ProgramManager.Programs.FindAll(p => p.Group.ToLower() == deletedGroup.Name.ToLower());
                        if (groupPrograms != null)
                        {
                            // delete group association from programs
                            foreach (ProgramBlock program in groupPrograms)
                            {
                                program.Group = "";
                            }
                        }
                    }
                }
                break;

            case "Groups.Save":
                string jsonGroups = request.RequestText;
                var newGroups = JsonConvert.DeserializeObject<List<Group>>(jsonGroups);
                for (int i = 0; i < newGroups.Count; i++)
                {
                    try
                    {
                        var group = homegenie.Groups.Find(z => z.Name == newGroups[i].Name);
                        group.Modules.Clear();
                        group.Modules = newGroups[i].Modules;
                    }
                    catch
                    {
                    }
                }
                homegenie.UpdateGroupsDatabase(migCommand.GetOption(0));//write groups
                break;

            case "Groups.WallpaperList":
                List<string> wallpaperList = new List<string>();
                var images = Directory.GetFiles(groupWallpapersPath);
                for (int i = 0; i < images.Length; i++)
                {
                    wallpaperList.Add(Path.GetFileName(images[i]));
                }
                request.ResponseData = wallpaperList;

                break;

            case "Groups.WallpaperAdd":
                {
                    string wallpaperFile = "";
                    try
                    {
                        wallpaperFile = MIG.Gateways.WebServiceUtility.SaveFile(request.RequestData, groupWallpapersPath);
                    }
                    catch
                    {
                    }
                    request.ResponseData = new ResponseText(Path.GetFileName(wallpaperFile));
                }
                break;

            case "Groups.WallpaperSet":
                {
                    string wpGroupName = migCommand.GetOption(0);
                    var wpGroup = homegenie.GetGroups(migCommand.GetOption(0)).Find(g => g.Name == wpGroupName);
                    if (wpGroup != null)
                    {
                        wpGroup.Wallpaper = migCommand.GetOption(1);
                        homegenie.UpdateGroupsDatabase("Control");
                    }
                }
                break;

            case "Groups.WallpaperDelete":
                {
                    string wallpaperFile = migCommand.GetOption(0);
                    wallpaperFile = Path.Combine(groupWallpapersPath, Path.GetFileName(wallpaperFile));
                    if (File.Exists(wallpaperFile))
                    {
                        File.Delete(wallpaperFile);
                    }
                    request.ResponseData = new ResponseText("OK");
                }
                break;

            case "Widgets.List":
                List<string> widgetsList = new List<string>();
                var groups = Directory.GetDirectories(widgetBasePath);
                for (int d = 0; d < groups.Length; d++)
                {
                    var categories = Directory.GetDirectories(groups[d]);
                    for (int c = 0; c < categories.Length; c++)
                    {
                        var widgets = Directory.GetFiles(categories[c], "*.js");
                        var group = groups[d].Replace(widgetBasePath, "").Substring(1);
                        var category = categories[c].Replace(groups[d], "").Substring(1);
                        for (int w = 0; w < widgets.Length; w++)
                        {
                            widgetsList.Add(group + "/" + category + "/" + Path.GetFileNameWithoutExtension(widgets[w]));
                        }
                    }
                }
                request.ResponseData = widgetsList;
                break;

            case "Widgets.Add":
                {
                    var status = Status.Error;
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    widgetParts[0] = new String(widgetParts[0].Where(Char.IsLetter).ToArray()).ToLower();
                    widgetParts[1] = new String(widgetParts[1].Where(Char.IsLetter).ToArray()).ToLower();
                    widgetParts[2] = new String(widgetParts[2].Where(Char.IsLetter).ToArray()).ToLower();
                    if (!String.IsNullOrWhiteSpace(widgetParts[0]) && !String.IsNullOrWhiteSpace(widgetParts[1]) && !String.IsNullOrWhiteSpace(widgetParts[2]))
                    {
                        string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                        if (!Directory.Exists(filePath))
                        {
                            Directory.CreateDirectory(filePath);
                        }
                        // copy widget template into the new widget
                        var htmlFile = Path.Combine(filePath, widgetParts[2] + ".html");
                        var jsFile = Path.Combine(filePath, widgetParts[2] + ".js");
                        if (!File.Exists(htmlFile) && !File.Exists(jsFile))
                        {
                            File.Copy(Path.Combine(widgetBasePath, "template.html"), htmlFile);
                            File.Copy(Path.Combine(widgetBasePath, "template.js"), jsFile);
                            status = Status.Ok;
                        }
                    }
                    request.ResponseData = new ResponseStatus(status);
                }
                break;

            case "Widgets.Save":
                {
                    var status = Status.Error;
                    string widgetData = request.RequestText;
                    string fileType = migCommand.GetOption(0);
                    string widgetPath = migCommand.GetOption(1); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                    if (!Directory.Exists(filePath))
                    {
                        Directory.CreateDirectory(filePath);
                    }
                    switch (fileType)
                    {
                    // html/javascript source
                    case "html":
                    case "js":
                        using (TextWriter widgetWriter = new StreamWriter(Path.Combine(filePath, widgetParts[2] + "." + fileType)))
                        {
                            widgetWriter.Write(widgetData);
                        }
                        status = Status.Ok;
                        break;
                    // style sheet file
                    case "css":
                        break;
                    // locale file
                    case "json":
                        break;
                    // image file
                    case "jpg":
                    case "png":
                    case "gif":
                        break;
                    }
                    request.ResponseData = new ResponseStatus(status);
                }
                break;

            case "Widgets.Delete":
                {
                    var status = Status.Error;
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string filePath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1], widgetParts[2] + ".");
                    if (File.Exists(filePath + "html"))
                    {
                        File.Delete(filePath + "html");
                        status = Status.Ok;
                    }
                    if (File.Exists(filePath + "js"))
                    {
                        File.Delete(filePath + "js");
                        status = Status.Ok;
                    }
                    request.ResponseData = new ResponseStatus(status);
                }
                break;

            case "Widgets.Export":
                {
                    string widgetPath = migCommand.GetOption(0); // eg. homegenie/generic/dimmer
                    string[] widgetParts = widgetPath.Split('/');
                    string widgetBundle = Path.Combine(tempFolderPath, "export", widgetPath.Replace('/', '_') + ".zip");
                    if (File.Exists(widgetBundle))
                    {
                        File.Delete(widgetBundle);
                    }
                    else if (!Directory.Exists(Path.GetDirectoryName(widgetBundle)))
                    {
                        Directory.CreateDirectory(Path.GetDirectoryName(widgetBundle));
                    }
                    string inputPath = Path.Combine(widgetBasePath, widgetParts[0], widgetParts[1]);
                    string outputPath = Path.Combine(widgetParts[0], widgetParts[1]);
                    string infoFilePath = Path.Combine(inputPath, "widget.info");
                    File.WriteAllText(infoFilePath, "HomeGenie exported widget.");
                    Utility.AddFileToZip(widgetBundle, infoFilePath, "widget.info");
                    Utility.AddFileToZip(widgetBundle, Path.Combine(inputPath, widgetParts[2] + ".html"), Path.Combine(outputPath, widgetParts[2] + ".html"));
                    Utility.AddFileToZip(widgetBundle, Path.Combine(inputPath, widgetParts[2] + ".js"), Path.Combine(outputPath, widgetParts[2] + ".js"));
                    //
                    byte[] bundleData = File.ReadAllBytes(widgetBundle);
                    (request.Context.Data as HttpListenerContext).Response.AddHeader("Content-Disposition", "attachment; filename=\"" + widgetPath.Replace('/', '_') + ".zip\"");
                    (request.Context.Data as HttpListenerContext).Response.OutputStream.Write(bundleData, 0, bundleData.Length);
                }
                break;
                
            case "Widgets.Import":
                {
                    string archiveFile = Path.Combine(tempFolderPath, "import_widget.zip");
                    string importPath = Path.Combine(tempFolderPath, "import");
                    if (Directory.Exists(importPath))
                        Directory.Delete(importPath, true);
                    MIG.Gateways.WebServiceUtility.SaveFile(request.RequestData, archiveFile);
                    if (WidgetImport(archiveFile, importPath))
                    {
                        request.ResponseData = new ResponseText("OK");
                    }
                    else
                    {
                        request.ResponseData = new ResponseText("ERROR");
                    }
                }
                break;

            case "Widgets.Parse":
                {
                    string widgetData = request.RequestText;
                    var parser = new JavaScriptParser();
                    try
                    {
                        request.ResponseData = new ResponseText("OK");
                        parser.Parse(widgetData);
                    }
                    catch (Jint.Parser.ParserException e)
                    {
                        request.ResponseData = new ResponseText("ERROR (" + e.LineNumber + "," + e.Column + "): " + e.Description);
                    }
                }
                break;

            case "Package.Install":
                {
                    string pkgBaseUrl = migCommand.GetOption(0);
                    string installFolder = Path.Combine(tempFolderPath, "pkg");
                    dynamic pkgData = null;
                    bool success = true;
                    // Download package specs
                    homegenie.RaiseEvent(
                        Domains.HomeGenie_System,
                        Domains.HomeGenie_PackageInstaller,
                        SourceModule.Master,
                        "HomeGenie Package Installer",
                        Properties.InstallProgressMessage,
                        "= Downloading: package.json"
                    );
                    using (var client = new WebClient())
                    {
                        try
                        {
                            string pkgJson = "[" + client.DownloadString(pkgBaseUrl + "/package.json") + "]";
                            pkgData = (JsonConvert.DeserializeObject(pkgJson) as JArray)[0];
                        }
                        catch
                        {
                            success = false;
                        }
                        client.Dispose();
                    }
                    // Download and install package files
                    if (success && pkgData != null)
                    {
                        // Import Automation Programs in package
                        foreach (var program in pkgData.programs)
                        {
                            homegenie.RaiseEvent(
                                Domains.HomeGenie_System,
                                Domains.HomeGenie_PackageInstaller,
                                SourceModule.Master,
                                "HomeGenie Package Installer",
                                Properties.InstallProgressMessage,
                                "= Downloading: " + program.file.ToString()
                            );
                            Utility.FolderCleanUp(installFolder);
                            string programFile = Path.Combine(installFolder, program.file.ToString());
                            if (File.Exists(programFile))
                                File.Delete(programFile);
                            using (var client = new WebClient())
                            {
                                try
                                {
                                    client.DownloadFile(pkgBaseUrl + "/" + program.file.ToString(), programFile);
                                }
                                catch
                                {
                                    success = false;
                                }
                                client.Dispose();
                            }
                            if (success)
                            {
                                homegenie.RaiseEvent(
                                    Domains.HomeGenie_System,
                                    Domains.HomeGenie_PackageInstaller,
                                    SourceModule.Master,
                                    "HomeGenie Package Installer",
                                    Properties.InstallProgressMessage,
                                    "= Installing: " + program.name.ToString()
                                );
                                int pid = int.Parse(program.uid.ToString());
                                var oldProgram = homegenie.ProgramManager.ProgramGet(pid);
                                if (oldProgram != null)
                                {
                                    homegenie.RaiseEvent(
                                        Domains.HomeGenie_System,
                                        Domains.HomeGenie_PackageInstaller,
                                        SourceModule.Master,
                                        "HomeGenie Package Installer",
                                        Properties.InstallProgressMessage,
                                        "= Replacing: '" + oldProgram.Name + "' with pid " + pid
                                    );
                                    homegenie.ProgramManager.ProgramRemove(oldProgram);
                                }
                                var programBlock = ProgramImport(homegenie, pid, programFile, program.group.ToString());
                                if (programBlock != null)
                                {
                                    programBlock.IsEnabled = true;
                                    homegenie.RaiseEvent(
                                        Domains.HomeGenie_System,
                                        Domains.HomeGenie_PackageInstaller,
                                        SourceModule.Master,
                                        "HomeGenie Package Installer",
                                        Properties.InstallProgressMessage,
                                        "= Installed: '" + program.name.ToString() + "' as pid " + pid
                                    );
                                }
                                else
                                {
                                    // TODO: report error and stop the package install procedure
                                    success = false;
                                }
                            }
                        }
                        // Import Widgets in package
                        foreach (var widget in pkgData.widgets)
                        {
                            homegenie.RaiseEvent(
                                Domains.HomeGenie_System,
                                Domains.HomeGenie_PackageInstaller,
                                SourceModule.Master,
                                "HomeGenie Package Installer",
                                Properties.InstallProgressMessage,
                                "= Downloading: " + widget.file.ToString()
                            );
                            Utility.FolderCleanUp(installFolder);
                            string widgetFile = Path.Combine(installFolder, widget.file.ToString());
                            if (File.Exists(widgetFile))
                                File.Delete(widgetFile);
                            using (var client = new WebClient())
                            {
                                try
                                {
                                    client.DownloadFile(pkgBaseUrl + "/" + widget.file.ToString(), widgetFile);
                                }
                                catch
                                {
                                    success = false;
                                }
                                client.Dispose();
                            }
                            if (success && WidgetImport(widgetFile, installFolder))
                            {
                                homegenie.RaiseEvent(
                                    Domains.HomeGenie_System,
                                    Domains.HomeGenie_PackageInstaller,
                                    SourceModule.Master,
                                    "HomeGenie Package Installer",
                                    Properties.InstallProgressMessage,
                                    "= Installed: '" + widget.name.ToString() + "'"
                                );
                            }
                            else
                            {
                                // TODO: report error and stop the package install procedure
                                success = false;
                            }
                        }
                        // Import MIG Interfaces in package
                        foreach (var migface in pkgData.interfaces)
                        {
                            homegenie.RaiseEvent(
                                Domains.HomeGenie_System,
                                Domains.HomeGenie_PackageInstaller,
                                SourceModule.Master,
                                "HomeGenie Package Installer",
                                Properties.InstallProgressMessage,
                                "= Downloading: " + migface.file.ToString()
                            );
                            Utility.FolderCleanUp(installFolder);
                            string migfaceFile = Path.Combine(installFolder, migface.file.ToString());
                            if (File.Exists(migfaceFile))
                                File.Delete(migfaceFile);
                            using (var client = new WebClient())
                            {
                                try
                                {
                                    client.DownloadFile(pkgBaseUrl + "/" + migface.file.ToString(), migfaceFile);
                                    Utility.UncompressZip(migfaceFile, installFolder);
                                    File.Delete(migfaceFile);
                                }
                                catch
                                {
                                    success = false;
                                }
                                client.Dispose();
                            }
                            if (success && InterfaceInstall(installFolder))
                            {
                                homegenie.RaiseEvent(
                                    Domains.HomeGenie_System,
                                    Domains.HomeGenie_PackageInstaller,
                                    SourceModule.Master,
                                    "HomeGenie Package Installer",
                                    Properties.InstallProgressMessage,
                                    "= Installed: '" + migface.name.ToString() + "'"
                                );
                            }
                            else
                            {
                                // TODO: report error and stop the package install procedure
                                success = false;
                            }
                        }
                    }
                    else
                    {
                        success = false;
                    }
                    if (success)
                    {
                        // TODO: add package info to the list of installed packages
                        // TODO: this package file must be included in the backup file also
                        // TODO: and the restore process should also download and install
                        // TODO: all packages included in it
                        homegenie.RaiseEvent(
                            Domains.HomeGenie_System,
                            Domains.HomeGenie_PackageInstaller,
                            SourceModule.Master,
                            "HomeGenie Package Installer",
                            Properties.InstallProgressMessage,
                            "= Status: Package Install Successful"
                        );
                    }
                    else
                    {
                        homegenie.RaiseEvent(
                            Domains.HomeGenie_System,
                            Domains.HomeGenie_PackageInstaller,
                            SourceModule.Master,
                            "HomeGenie Package Installer",
                            Properties.InstallProgressMessage,
                            "= Status: Package Install Error"
                        );
                    }
                    request.ResponseData = new ResponseText(success ? "OK" : "ERROR");
                }
                break;
            }
        }