//--- Class Methods --- public static DekiScriptMap MakeErrorObject(Exception e, DekiScriptEnv env) { DekiScriptMap exception = new DekiScriptMap(); // add call stack if one is available DekiScriptList callstack = null; if(env != null) { DekiScriptLiteral callstackVar; if(env.Vars.TryGetValue(DekiScriptEnv.CALLSTACK, out callstackVar)) { callstack = callstackVar as DekiScriptList; } } while(e is DekiScriptInvokeException) { var ex = (DekiScriptInvokeException)e; if(callstack == null) { callstack = new DekiScriptList(); } callstack.AddNativeValue(ex.FunctionName); e = ex.InnerException; } if(callstack != null) { exception.Add("callstack", callstack); } // add exception text exception.Add("message", DekiScriptExpression.Constant(e.Message)); exception.Add("stacktrace", DekiScriptExpression.Constant(e.GetCoroutineStackTrace())); if(e.InnerException != null) { exception.Add("inner", MakeErrorObject(e.InnerException, null)); } if(e is DekiScriptException) { exception.Add("source", DekiScriptExpression.Constant(((DekiScriptException)e).Location.Origin)); } return exception; }
public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { // prepare uri for invocation Plug plug = Plug.New(_endpoint); plug = runtime.PreparePlug(plug); // make web-request DreamMessage response = plug.Post(args.ToXml(), new Tasking.Result<DreamMessage>()).Wait(); if(!response.IsSuccessful) { if(response.HasDocument) { var error = response.ToDocument(); var message = error["message"]; if(error.HasName("exception") && !message.IsEmpty) { throw new DekiScriptRemoteException(Location.None, message.Contents); } } throw new DreamResponseException(response); } // convert response to literal DekiScriptLiteral list; try { list = DekiScriptLiteral.FromXml(response.ToDocument()); } catch(ArgumentException) { throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name)); } if(list.ScriptType != DekiScriptType.LIST) { throw new DekiScriptBadTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST }); } return ((DekiScriptList)list)[0]; }
public static DekiScriptMap ValidateToMap(DekiScriptParameter[] parameters, DekiScriptList args) { DekiScriptMap result = new DekiScriptMap(); // check passed in arguments int i = 0; var count = Math.Min(args.Value.Count, parameters.Length); for(; i < count; ++i) { var value = args[i]; if(value.IsNil) { if((parameters[i].ScriptType != DekiScriptType.ANY) && !parameters[i].Optional) { throw new ArgumentException(string.Format("missing value for parameter '{0}' (index {1})", parameters[i].Name, i)); } // set default value for this parameter result.Add(parameters[i].Name, parameters[i].Default); } else { result.Add(parameters[i].Name, parameters[i].Convert(value)); } } // check that missing arguments are optional for(; i < parameters.Length; ++i) { if((parameters[i].ScriptType != DekiScriptType.ANY) && !parameters[i].Optional) { throw new ArgumentException(string.Format("missing value for parameter '{0}' (index {1})", parameters[i].Name, i)); } result.Add(parameters[i].Name, parameters[i].Default); } return result; }
public static DekiScriptMap ValidateToMap(DekiScriptParameter[] parameters, DekiScriptMap args) { DekiScriptMap result = new DekiScriptMap(); // check passed in arguments for (int i = 0; i < parameters.Length; ++i) { var value = args[parameters[i].Name]; if (value.IsNil) { if ((parameters[i].ScriptType != DekiScriptType.ANY) && !parameters[i].Optional) { throw new ArgumentException(string.Format("missing value for parameter '{0}' (index {1})", parameters[i].Name, i)); } // set default value for this parameter result.Add(parameters[i].Name, parameters[i].Default); } else { result.Add(parameters[i].Name, parameters[i].Convert(value)); } } return(result); }
public DekiScriptOutputBuffer.Range Visit(DekiScriptTryCatchFinally expr, DekiScriptExpressionEvaluationState state) { int marker = state.Buffer.Marker; try { expr.Try.VisitWith(this, state); } catch (DekiScriptFatalException) { throw; } catch (DekiScriptControlFlowException) { throw; } catch (Exception e) { state.Buffer.Reset(marker); // translate exception to an error object DekiScriptMap error = DekiScriptLibrary.MakeErrorObject(e, state.Env); // capture error object in a nested environment try { state.Env.Vars.Add(expr.Variable, error); expr.Catch.VisitWith(this, state); } finally { state.Env.Vars.Add(expr.Variable, DekiScriptNil.Value); } } finally { expr.Finally.VisitWith(this, state); } return(state.Buffer.Since(marker)); }
//--- Class Constructor --- static DekiScriptRuntime() { // register built-in functions _commonFunctions = new Dictionary<XUri, DekiScriptInvocationTargetDescriptor>(); foreach(MethodInfo method in typeof(DekiScriptLibrary).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)) { // check if it has the DekiScriptFunction attribute DekiScriptFunctionAttribute functionAttribute = (DekiScriptFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(DekiScriptFunctionAttribute)); if(functionAttribute != null) { var parameters = from param in method.GetParameters() let attr = (DekiScriptParamAttribute[])param.GetCustomAttributes(typeof(DekiScriptParamAttribute), false) select ((attr != null) && (attr.Length > 0)) ? new DekiScriptNativeInvocationTarget.Parameter(attr[0].Hint, attr[0].Optional) : null; var target = new DekiScriptNativeInvocationTarget(null, method, parameters.ToArray()); var function = new DekiScriptInvocationTargetDescriptor(target.Access, functionAttribute.IsProperty, functionAttribute.IsIdempotent, functionAttribute.Name ?? method.Name, target.Parameters, target.ReturnType, functionAttribute.Description, functionAttribute.Transform, target); _commonFunctions[new XUri("native:///").At(function.SystemName)] = function; } } // build common env DekiScriptMap common = new DekiScriptMap(); // add global constants common.AddNativeValueAt("num.e", Math.E); common.AddNativeValueAt("num.pi", Math.PI); common.AddNativeValueAt("num.epsilon", double.Epsilon); common.AddNativeValueAt("num.positiveinfinity", double.PositiveInfinity); common.AddNativeValueAt("num.negativeinfinity", double.NegativeInfinity); common.AddNativeValueAt("num.nan", double.NaN); // add global functions & properties foreach(var function in _commonFunctions) { common.AddNativeValueAt(function.Value.Name, function.Key); } _commonEnv = new DekiScriptEnv(common); }
public static Hashtable MapFilter( [DekiScriptParam("map value")] Hashtable map, [DekiScriptParam("condition to execute for each item (use '$' to refer to the key-value pair)")] string condition, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.select(condition)"), condition); Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach (DictionaryEntry entry in map) { DekiScriptMap keyvalue = new DekiScriptMap(); object value = Eval(entry.Value, runtime); keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key)); keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(value)); DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if (!test.IsNilFalseZero) { result.Add(entry.Key, value); } } return(result); }
public Hashtable PopularPages( [DekiExtParam("max results (default: 10)", true)] int?max, [DekiExtParam("poll interval (only for js format, default: 30)", true)] int?interval ) { int maxResults = max ?? 10; int resultCount = 0; DekiScriptMap env = DreamContext.Current.GetState <DekiScriptMap>(); DekiScriptLiteral uriLiteral = env.GetAt("site.uri"); XUri deki = new XUri(uriLiteral.NativeValue.ToString()).At("@api", "deki"); Hashtable map = new Hashtable(StringComparer.OrdinalIgnoreCase); map.Add("interval", _ttl.TotalSeconds); ArrayList pages = new ArrayList(); map.Add("pages", pages); int total = 0; Dictionary <uint, int> rankLookup = new Dictionary <uint, int>(); lock (_pageViews) { foreach (View view in _pageViews) { if (rankLookup.ContainsKey(view.PageId)) { rankLookup[view.PageId]++; } else { rankLookup[view.PageId] = 1; } total++; } } List <Tuplet <uint, int> > rank = new List <Tuplet <uint, int> >(); foreach (KeyValuePair <uint, int> kvp in rankLookup) { rank.Add(new Tuplet <uint, int>(kvp.Key, kvp.Value)); } rank.Sort(delegate(Tuplet <uint, int> a, Tuplet <uint, int> b) { return(b.Item2.CompareTo(a.Item2)); }); map.Add("total", total); foreach (Tuplet <uint, int> page in rank) { Hashtable pageMap = new Hashtable(StringComparer.OrdinalIgnoreCase); pages.Add(pageMap); // BUGBUGBUG (arnec): the AsLocalUri should not be required after bug #5964 is resolved pageMap.Add("page", DekiScriptExpression.Constant(deki.At("$page").AsLocalUri(), new[] { DekiScriptExpression.Constant(page.Item1), DekiScriptExpression.Constant(true) })); pageMap.Add("views", page.Item2); resultCount++; if (resultCount >= maxResults) { break; } } return(map); }
private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptMap args) { // invoke script DekiScriptEnv env = (_env != null) ? _env.NewScope() : runtime.CreateEnv(); env.Vars.Add("args", args); env.Vars.Add("$", args); return runtime.Evaluate(Expression, DekiScriptEvalMode.Evaluate, env); }
public DekiScriptEnv( DekiScriptMap vars ) { if(vars == null) { throw new ArgumentNullException("vars"); } this.Vars = vars; }
private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptMap args) { // invoke script DekiScriptEnv env = (_env != null) ? _env.NewScope() : runtime.CreateEnv(); env.Vars.Add("args", args); env.Vars.Add("$", args); return(runtime.Evaluate(Expression, DekiScriptEvalMode.Evaluate, env)); }
public DekiScriptEnv( DekiScriptMap vars ) { if (vars == null) { throw new ArgumentNullException("vars"); } this.Vars = vars; }
//--- Constructors --- public DekiScriptComparer(DekiScriptRuntime runtime, DekiScriptExpression compare) { if(compare == null) { throw new ArgumentNullException("compare"); } _runtime = runtime; _compare = compare; _values = new DekiScriptMap(); _env = runtime.CreateEnv(); _env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, _values); }
//--- Constructors --- public DekiScriptComparer(DekiScriptRuntime runtime, DekiScriptExpression compare) { if (compare == null) { throw new ArgumentNullException("compare"); } _runtime = runtime; _compare = compare; _values = new DekiScriptMap(); _env = runtime.CreateEnv(); _env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, _values); }
//--- Class Methods --- internal static AMedia New(XUri uri, XDoc config) { // check if the uri is a viddler video if (uri.Scheme.EqualsInvariantIgnoreCase("kaltura")) { if (uri.Segments.Length >= 1) { string entryID = uri.Segments[0]; string partnerID = config["kaltura/partner-id"].AsText; // check if extension is configured for kaltura integration if (!string.IsNullOrEmpty(partnerID)) { bool remix = !(uri.GetParam("edit", null) ?? uri.GetParam("remix", "no")).EqualsInvariantIgnoreCase("no"); // verify that user has permission to remix content on current page if (remix) { Plug dekiApi = GetDekiApi(config); if (dekiApi != null) { try { DekiScriptMap env = DreamContext.Current.GetState <DekiScriptMap>(); string pageid = env.GetAt("page.id").AsString(); string userid = env.GetAt("user.id").AsString(); XDoc users = dekiApi.At("pages", pageid, "allowed").With("permissions", "UPDATE").Post(new XDoc("users").Start("user").Attr("id", userid).End()).ToDocument(); remix = !users[string.Format(".//user[@id='{0}']", userid)].IsEmpty; } catch (Exception e) { _log.Error("unable to verify user permission on page", e); } } } // check if SEO links are explicitly disabled bool seo = !(config["kaltura/seo-links"].AsText ?? "enabled").EqualsInvariantIgnoreCase("disabled"); // determin which UI configuration to use based on user's permissions and embed settings for video string uiConfID = remix ? config["kaltura/uiconf/player-mix"].AsText : config["kaltura/uiconf/player-nomix"].AsText; if (!string.IsNullOrEmpty(uiConfID)) { uri = config["kaltura/server-uri"].AsUri ?? new XUri("http://www.kaltura.com"); uri = uri.At("index.php", "kwidget", "wid", "_" + partnerID, "uiconf_id", uiConfID, "entry_id", entryID); return(new KalturaVideo(uri, remix, seo)); } } } } return(null); }
private static DekiScriptLiteral ToDekiScriptRecurse(XDoc doc) { XDoc xdoc = doc.Elements; switch (xdoc.Name) { case "nil": return(DekiScriptNil.Value); case "boolean": if (xdoc.Contents.GetType().Equals(typeof(String))) { return(DekiScriptExpression.Constant((xdoc.Contents.Contains("1") || xdoc.Contents.Contains("true")) ? true : false)); } return(DekiScriptExpression.Constant(xdoc.AsBool ?? false)); case "double": return(DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0)); case "int": case "i4": return(DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0)); case "string": return(DekiScriptExpression.Constant(xdoc.AsText ?? string.Empty)); case "struct": { DekiScriptMap result = new DekiScriptMap(); foreach (XDoc value in xdoc["member"]) { result.Add(value["name"].Contents, ToDekiScriptRecurse(value["value"])); } return(result); } case "array": { DekiScriptList result = new DekiScriptList(); foreach (XDoc value in xdoc["data/value"]) { result.Add(ToDekiScriptRecurse(value)); } return(result); } default: throw new ArgumentException("this type does not exist in the XML-RPC standard"); } }
private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptMap args) { // invoke script DekiScriptEnv env = _env.NewScope(); env.Vars.AddRange(DreamContext.Current.GetState <DekiScriptMap>("env.implicit")); env.Vars.Add("args", args); env.Vars.Add("$", args); var result = runtime.Evaluate(Expression, DekiScriptEvalMode.Evaluate, env); try { return(result.Convert(_returnType)); } catch (DekiScriptInvalidCastException) { throw new DekiScriptInvalidReturnCastException(Location.None, result.ScriptType, _returnType); } }
public T EnvAt <T>(string path) { if (path == null) { throw new ArgumentNullException("path"); } DekiScriptMap env = DreamContext.Current.GetState <DekiScriptMap>(); if (env == null) { return(default(T)); } DekiScriptLiteral value = env.GetAt(path); return(SysUtil.ChangeType <T>(value.NativeValue)); }
public DekiScriptLiteral GetMagicId(string id) { DekiScriptLiteral result = DekiScriptNil.Value; // check if magic IDs map already exists; if not, create one if(_magicIds == null) { _magicIds = new DekiScriptMap(); } else { result = _magicIds[id]; } // check if a magic ID was found; if not, create one if(result.IsNil) { result = DekiScriptExpression.Constant(id + "_" + StringUtil.CreateAlphaNumericKey(8)); _magicIds.Add(id, result); } return result; }
public static Hashtable MapApply( [DekiScriptParam("map value")] Hashtable map, [DekiScriptParam("expression to apply (use '$' to refer to the item)")] string expression, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.apply(expression)"), expression); Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach(DictionaryEntry entry in map) { DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key)); keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(Eval(entry.Value, runtime))); DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); result.Add(entry.Key, runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env)); } return result; }
public static ArrayList ListIntersect( [DekiScriptParam("first list")] ArrayList first, [DekiScriptParam("second list")] ArrayList second, [DekiScriptParam("expression to determine if item from the first list should be included in final list (return true to include, false to exclude; use '$left' and '$right' to refer to the current item from the first and seconds lists respectively; default: equality condition)", true)] string condition, DekiScriptRuntime runtime ) { ArrayList result = new ArrayList(); if (condition != null) { // loop over both lists and keep items from the first list based on the outcome of the condition DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.intersect(condition)"), condition); foreach (object left in first) { foreach (object right in second) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("left", DekiScriptLiteral.FromNativeValue(left)); keyvalue.Add("right", DekiScriptLiteral.FromNativeValue(right)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if (!test.IsNilFalseZero) { result.Add(left); break; } } } } else { // using simple containment check to keep items foreach (object item in first) { if (second.Contains(item)) { result.Add(item); } } } return(result); }
//--- Class Methods --- public static DekiScriptMap MakeErrorObject(Exception e, DekiScriptEnv env) { DekiScriptMap exception = new DekiScriptMap(); // add call stack if one is available DekiScriptList callstack = null; if (env != null) { DekiScriptLiteral callstackVar; if (env.Vars.TryGetValue(DekiScriptEnv.CALLSTACK, out callstackVar)) { callstack = callstackVar as DekiScriptList; } } while (e is DekiScriptInvokeException) { var ex = (DekiScriptInvokeException)e; if (callstack == null) { callstack = new DekiScriptList(); } callstack.AddNativeValue(ex.FunctionName); e = ex.InnerException; } if (callstack != null) { exception.Add("callstack", callstack); } // add exception text exception.Add("message", DekiScriptExpression.Constant(e.Message)); exception.Add("stacktrace", DekiScriptExpression.Constant(e.GetCoroutineStackTrace())); if (e.InnerException != null) { exception.Add("inner", MakeErrorObject(e.InnerException, null)); } if (e is DekiScriptException) { exception.Add("source", DekiScriptExpression.Constant(((DekiScriptException)e).Location.Origin)); } return(exception); }
public DekiScriptLiteral Visit(DekiScriptVar expr, DekiScriptEnv env) { if (expr.Name.EqualsInvariant(DekiScriptRuntime.ENV_ID)) { DekiScriptMap vars = new DekiScriptMap(); vars.AddRange(env.Globals); vars.AddRange(env.Locals); return(vars); } // check if variable exists DekiScriptLiteral result = env[expr.Name]; if (result == null) { throw new DekiScriptUndefinedNameException(expr.Line, expr.Column, expr.Name); } result = DekiScriptRuntime.EvaluateProperty(result, env); return(result); }
public static Hashtable MapApply( [DekiScriptParam("map value")] Hashtable map, [DekiScriptParam("expression to apply (use '$' to refer to the item)")] string expression, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.apply(expression)"), expression); Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach (DictionaryEntry entry in map) { DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key)); keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(Eval(entry.Value, runtime))); DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); result.Add(entry.Key, runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env)); } return(result); }
public static object ListReduce( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to compute combined value (use '$value' and '$item' to refer to the current value and item, respectively)")] string expression, [DekiScriptParam("starting value (default: nil)", true)] object value, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.reduce(expression)"), expression); foreach (object entry in list) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap values = new DekiScriptMap(); values.Add("value", DekiScriptLiteral.FromNativeValue(value)); values.Add("item", DekiScriptLiteral.FromNativeValue(entry)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, values); value = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env).NativeValue; } return(value); }
public DekiScriptExpression Visit(DekiScriptMapConstructor expr, DekiScriptExpressionEvaluationState state) { // TODO (steveb): need to figure out how to optimize maps with generators if (expr.Generator != null) { return(expr); } // optimize each item in the map var fields = new DekiScriptMapConstructor.FieldConstructor[expr.Fields.Length]; bool isLiteral = true; for (int i = 0; i < expr.Fields.Length; i++) { var current = expr.Fields[i]; DekiScriptExpression key = current.Key.VisitWith(this, state); DekiScriptExpression value = current.Value.VisitWith(this, state); fields[i] = new DekiScriptMapConstructor.FieldConstructor(current.Location, key, value); isLiteral = isLiteral && (key is DekiScriptLiteral) && (value is DekiScriptLiteral); } if (!isLiteral) { return(DekiScriptExpression.Map(expr.Location, fields)); } // convert expression to a map DekiScriptMap result = new DekiScriptMap(); foreach (var field in fields) { DekiScriptLiteral key = (DekiScriptLiteral)field.Key; // check that key is a simple type string text = key.AsString(); if (text != null) { result.Add(text, (DekiScriptLiteral)field.Value); } } return(result); }
public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { // prepare uri for invocation Plug plug = Plug.New(_endpoint); plug = runtime.PreparePlug(plug); // invoke function DreamMessage response = plug.Get(); // convert response to literal DekiScriptLiteral list; try { list = DekiScriptLiteral.FromXml(response.ToDocument()); } catch(ArgumentException) { throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name)); } if(list.ScriptType != DekiScriptType.LIST) { throw new DekiScriptBadReturnTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST }); } return ((DekiScriptList)list)[0]; }
public static Hashtable MapFilter( [DekiScriptParam("map value")] Hashtable map, [DekiScriptParam("condition to execute for each item (use '$' to refer to the key-value pair)")] string condition, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("map.select(condition)"), condition); Hashtable result = new Hashtable(StringComparer.OrdinalIgnoreCase); foreach(DictionaryEntry entry in map) { DekiScriptMap keyvalue = new DekiScriptMap(); object value = Eval(entry.Value, runtime); keyvalue.Add("key", DekiScriptLiteral.FromNativeValue(entry.Key)); keyvalue.Add("value", DekiScriptLiteral.FromNativeValue(value)); DekiScriptEnv env = runtime.CreateEnv(); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if(!test.IsNilFalseZero) { result.Add(entry.Key, value); } } return result; }
public DekiScriptLiteral GetMagicId(string id) { DekiScriptLiteral result = DekiScriptNil.Value; // check if magic IDs map already exists; if not, create one if (_magicIds == null) { _magicIds = new DekiScriptMap(); } else { result = _magicIds[id]; } // check if a magic ID was found; if not, create one if (result.IsNil) { result = DekiScriptExpression.Constant(id + "_" + StringUtil.CreateAlphaNumericKey(8)); _magicIds.Add(id, result); } return(result); }
public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { // prepare uri for invocation Plug plug = Plug.New(_endpoint); plug = runtime.PreparePlug(plug); // make web-request DreamMessage response = plug.Post(args.ToXml(), new Tasking.Result <DreamMessage>()).Wait(); if (!response.IsSuccessful) { if (response.HasDocument) { var error = response.ToDocument(); var message = error["message"]; if (error.HasName("exception") && !message.IsEmpty) { throw new DekiScriptRemoteException(Location.None, message.Contents); } } throw new DreamResponseException(response); } // convert response to literal DekiScriptLiteral list; try { list = DekiScriptLiteral.FromXml(response.ToDocument()); } catch (ArgumentException) { throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name)); } if (list.ScriptType != DekiScriptType.LIST) { throw new DekiScriptBadTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST }); } return(((DekiScriptList)list)[0]); }
public DekiScriptLiteral Visit(DekiScriptMapConstructor expr, DekiScriptEnv env) { DekiScriptMap result = new DekiScriptMap(); if (expr.Generator == null) { foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields) { DekiScriptLiteral key = field.Key.VisitWith(this, env); // check that key is a simple type string text = key.AsString(); if (text != null) { DekiScriptLiteral value = field.Value.VisitWith(this, env); result.Add(text, value); } } } else { DekiScriptGeneratorEvaluation.Instance.Generate(expr.Generator, delegate(DekiScriptEnv subEnv) { foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields) { DekiScriptLiteral key = field.Key.VisitWith(this, subEnv); // check that key is a simple type string text = key.AsString(); if (text != null) { DekiScriptLiteral value = field.Value.VisitWith(this, subEnv); result.Add(text, value); } } }, env.NewLocalScope()); } return(result); }
public DekiScriptOutputBuffer.Range Visit(DekiScriptMapConstructor expr, DekiScriptExpressionEvaluationState state) { DekiScriptMap result = new DekiScriptMap(); if (expr.Generator == null) { foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields) { DekiScriptLiteral key = state.Pop(field.Key.VisitWith(this, state)); // check that key is a simple type string text = key.AsString(); if (text != null) { DekiScriptLiteral value = state.Pop(field.Value.VisitWith(this, state)); result.Add(text, value); } } } else { DekiScriptGeneratorEvaluation.Generate(expr.Generator, delegate(DekiScriptEnv subEnv) { foreach (DekiScriptMapConstructor.FieldConstructor field in expr.Fields) { DekiScriptLiteral key = state.Pop(field.Key.VisitWith(this, state.With(subEnv))); // check that key is a simple type string text = key.AsString(); if (text != null) { DekiScriptLiteral value = state.Pop(field.Value.VisitWith(this, state.With(subEnv))); result.Add(text, value); } } }, state); } return(state.Push(result)); }
//--- Class Constructor --- static DekiScriptRuntime() { // register built-in functions _commonFunctions = new Dictionary <XUri, DekiScriptInvocationTargetDescriptor>(); foreach (MethodInfo method in typeof(DekiScriptLibrary).GetMethods(BindingFlags.Static | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.FlattenHierarchy)) { // check if it has the DekiScriptFunction attribute DekiScriptFunctionAttribute functionAttribute = (DekiScriptFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(DekiScriptFunctionAttribute)); if (functionAttribute != null) { var parameters = from param in method.GetParameters() let attr = (DekiScriptParamAttribute[])param.GetCustomAttributes(typeof(DekiScriptParamAttribute), false) select((attr != null) && (attr.Length > 0)) ? new DekiScriptNativeInvocationTarget.Parameter(attr[0].Hint, attr[0].Optional) : null; var target = new DekiScriptNativeInvocationTarget(null, method, parameters.ToArray()); var function = new DekiScriptInvocationTargetDescriptor(target.Access, functionAttribute.IsProperty, functionAttribute.IsIdempotent, functionAttribute.Name ?? method.Name, target.Parameters, target.ReturnType, functionAttribute.Description, functionAttribute.Transform, target); _commonFunctions[new XUri("native:///").At(function.SystemName)] = function; } } // build common env DekiScriptMap common = new DekiScriptMap(); // add global constants common.AddNativeValueAt("num.e", Math.E); common.AddNativeValueAt("num.pi", Math.PI); common.AddNativeValueAt("num.epsilon", double.Epsilon); common.AddNativeValueAt("num.positiveinfinity", double.PositiveInfinity); common.AddNativeValueAt("num.negativeinfinity", double.NegativeInfinity); common.AddNativeValueAt("num.nan", double.NaN); // add global functions & properties foreach (var function in _commonFunctions) { common.AddNativeValueAt(function.Value.Name, function.Key); } _commonEnv = new DekiScriptEnv(common); }
public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { // prepare uri for invocation Plug plug = Plug.New(_endpoint); plug = runtime.PreparePlug(plug); // invoke function DreamMessage response = plug.Get(); // convert response to literal DekiScriptLiteral list; try { list = DekiScriptLiteral.FromXml(response.ToDocument()); } catch (ArgumentException) { throw new DekiScriptUnsupportedTypeException(Location.None, string.Format("<{0}>", response.ToDocument().Name)); } if (list.ScriptType != DekiScriptType.LIST) { throw new DekiScriptBadReturnTypeException(Location.None, list.ScriptType, new[] { DekiScriptType.LIST }); } return(((DekiScriptList)list)[0]); }
public DekiScriptOutputBuffer.Range Visit(DekiScriptVar expr, DekiScriptExpressionEvaluationState state) { if (expr.Name.EqualsInvariant(DekiScriptRuntime.ENV_ID)) { DekiScriptMap vars = new DekiScriptMap(); vars.AddRange(state.Env.Vars); return(state.Push(vars)); } // check if variable exists DekiScriptLiteral result; if (!state.Env.Vars.TryGetValue(expr.Name, out result)) { result = state.Runtime.ResolveMissingName(expr.Name); } if (result == null) { throw new DekiScriptUndefinedNameException(expr.Location, expr.Name); } result = state.Runtime.EvaluateProperty(expr.Location, result, state.Env); return(state.Push(result)); }
//--- Methods --- private DekiScriptEnv ProcessEnvironment() { var current = DreamContext.Current; DekiScriptEnv env = current.GetState<DekiScriptEnv>("pageenv-" + _basePage.ID); // check if we already have an initialized environment if(env == null) { // create environment env = ExtensionBL.CreateEnvironment(_basePage); // add request arguments DekiScriptMap request = new DekiScriptMap(); DekiScriptMap queryArgs = new DekiScriptMap(); DreamContext context = DreamContext.CurrentOrNull; if(context != null) { if(context.Uri.Params != null) { foreach(KeyValuePair<string, string> query in context.Uri.Params) { // check that query parameter doesn't have 'dream.' prefix if(!query.Key.StartsWithInvariantIgnoreCase("dream.")) { DekiScriptLiteral value; // check if a query parameter with the same name was alreayd found if(queryArgs.TryGetValue(query.Key, out value)) { DekiScriptList list = value as DekiScriptList; // check if the current value is already a list if(list == null) { list = new DekiScriptList(); list.Add(value); // replace current value queryArgs.Add(query.Key, list); } // append new value to list list.Add(DekiScriptExpression.Constant(query.Value)); } else { // add query parameter queryArgs.Add(query.Key, DekiScriptExpression.Constant(query.Value)); } } } } // show User-Agent, Referer and Host information in __request request.Add("referer", DekiScriptExpression.Constant(context.Request.Headers.Referer)); request.Add("useragent", DekiScriptExpression.Constant(context.Request.Headers.UserAgent)); request.Add("host", DekiScriptExpression.Constant(context.Request.Headers.Host)); // determine the client IP address var clientIPs = current.Request.Headers.DreamClientIP; if(clientIPs.Length > 0) { request.Add("client", DekiScriptExpression.Constant(clientIPs[clientIPs.Length - 1])); } else { request.Add("client", DekiScriptNil.Value); } // parse form fields from a request for requests with a mimetype of application/x-www-form-urlencoded DekiScriptMap postParams; if(context.Request.ContentType.Match(MimeType.FORM_URLENCODED)) { KeyValuePair<string, string>[] formFields = XUri.ParseParamsAsPairs(context.Request.ToText()); if(!ArrayUtil.IsNullOrEmpty(formFields)) { postParams = new DekiScriptMap(); foreach(KeyValuePair<string, string> kvp in formFields) { postParams.Add(kvp.Key, DekiScriptExpression.Constant(kvp.Value)); } request.Add("fields", postParams); } } } request.Add("args", queryArgs); env.Vars.Add("__request", request); // store computed environment for subsequent calls current.SetState("pageenv-" + _basePage.ID, env); } env = env.NewScope(); // global processing variables env.Vars.Add("__include", DekiScriptExpression.Constant(_isInclude)); env.Vars.Add("__mode", DekiScriptExpression.Constant(_mode.ToString().ToLowerInvariant())); env.Vars.Add(DekiScriptEnv.SAFEMODE, DekiScriptExpression.Constant(ExtensionRuntime.IsSafeMode(_page))); env.Vars.Add("__page", DekiContext.Current.Deki.PropertyAt("$page", _page.ID, true)); // set processing settings DekiScriptMap settings = new DekiScriptMap(); settings.Add("nofollow", DekiScriptExpression.Constant(DekiContext.Current.Instance.WebLinkNoFollow)); env.Vars.Add(DekiScriptEnv.SETTINGS, settings); // add callstack (specific for each page invocation) DekiScriptList callstack = new DekiScriptList(); ParserState parseState = GetParseState(); if(parseState != null) { foreach(PageBE includingPage in parseState.ProcessingStack) { callstack.Add(DekiScriptExpression.Constant(includingPage.Title.AsPrefixedDbPath())); } env.Vars.Add(DekiScriptEnv.CALLSTACK, callstack); } // add arguments environment vars env.Vars.Add("args", _args ?? DekiScriptNil.Value); env.Vars.Add("$", _args ?? DekiScriptNil.Value); return env.NewScope(); }
private DekiScriptLiteral InvokeHelper(DekiScriptRuntime runtime, DekiScriptMap args) { // invoke script DekiScriptEnv env = _env.NewScope(); env.Vars.AddRange(DreamContext.Current.GetState<DekiScriptMap>("env.implicit")); env.Vars.Add("args", args); env.Vars.Add("$", args); var result = runtime.Evaluate(Expression, DekiScriptEvalMode.Evaluate, env); try { return result.Convert(_returnType); } catch(DekiScriptInvalidCastException) { throw new DekiScriptInvalidReturnCastException(Location.None, result.ScriptType, _returnType); } }
public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { return InvokeHelper(runtime, DekiScriptParameter.ValidateToMap(Parameters, args)); }
private void LoadScript() { _manifestPath = null; _resourcesPath = null; _manifestUri = null; _resourcesUri = null; _manifest = null; // read manifest _manifestPath = Config["manifest"].AsText; if(string.IsNullOrEmpty(_manifestPath)) { throw new ArgumentNullException("manifest"); } _manifestUri = XUri.TryParse(_manifestPath); if(_manifestUri != null) { _manifestPath = null; _manifest = Plug.New(_manifestUri).Get().ToDocument(); _resourcesUri = Config["resources"].AsUri ?? _manifestUri.WithoutLastSegment(); } else { _manifest = XDocFactory.LoadFrom(_manifestPath, MimeType.XML); _resourcesPath = Config["resources"].AsText ?? Path.GetDirectoryName(_manifestPath); } if(!_manifest.HasName("extension")) { throw new ArgumentException("invalid extension manifest"); } // initilize runtime _runtime = new DekiScriptRuntime(); // read manifest settings _title = _manifest["title"].AsText; _label = _manifest["label"].AsText; _copyright = _manifest["copyright"].AsText; _description = _manifest["description"].AsText; _help = _manifest["uri.help"].AsText; _logo = _manifest["uri.logo"].AsText; _namespace = _manifest["namespace"].AsText; // initialize evaluation environment _commonEnv = _runtime.CreateEnv(); // read functions _functions = new Dictionary<XUri, DekiScriptInvocationTargetDescriptor>(); foreach(var function in _manifest["function"]) { var descriptor = ConvertFunction(function); if(descriptor != null) { var uri = Self.At(descriptor.SystemName); DekiScriptInvocationTargetDescriptor old; if(_functions.TryGetValue(uri, out old)) { _log.WarnFormat("duplicate function name {0} in script {1}", descriptor.Name, _manifestUri); } _functions[uri] = descriptor; } } _runtime.RegisterExtensionFunctions(_functions); // add extension functions to env foreach(var function in _functions) { _commonEnv.Vars.AddNativeValueAt(function.Value.Name.ToLowerInvariant(), function.Key); } // add configuration settings DreamContext context = DreamContext.Current; DekiScriptMap scriptConfig = new DekiScriptMap(); foreach(KeyValuePair<string, string> entry in Config.ToKeyValuePairs()) { XUri local; if(XUri.TryParse(entry.Value, out local)) { local = context.AsPublicUri(local); scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(local.ToString())); } else { scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(entry.Value)); } } _commonEnv.Vars.Add("config", scriptConfig); }
private static DekiScriptLiteral ToDekiScriptRecurse(XDoc doc) { XDoc xdoc = doc.Elements; switch(xdoc.Name) { case "nil": return DekiScriptNil.Value; case "boolean": if(xdoc.Contents.GetType().Equals(typeof(String))) { return DekiScriptExpression.Constant((xdoc.Contents.Contains("1") || xdoc.Contents.Contains("true")) ? true : false); } return DekiScriptExpression.Constant(xdoc.AsBool ?? false); case "double": return DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0); case "int": case "i4": return DekiScriptExpression.Constant(xdoc.AsDouble ?? 0.0); case "string": return DekiScriptExpression.Constant(xdoc.AsText ?? string.Empty); case "struct": { DekiScriptMap result = new DekiScriptMap(); foreach(XDoc value in xdoc["member"]) { result.Add(value["name"].Contents, ToDekiScriptRecurse(value["value"])); } return result; } case "array": { DekiScriptList result = new DekiScriptList(); foreach(XDoc value in xdoc["data/value"]) { result.Add(ToDekiScriptRecurse(value)); } return result; } default: throw new ArgumentException("this type does not exist in the XML-RPC standard"); } }
public static void InitializeCustomDekiScriptHeaders(PageBE page) { var current = DreamContext.Current; DekiScriptMap env = current.GetState <DekiScriptMap>("pageimplicitenv-" + page.ID); // check if we already have an initialized environment if (env == null) { DekiContext deki = DekiContext.Current; DekiInstance instance = deki.Instance; env = new DekiScriptMap(); // add site fields DekiScriptMap siteFields = new DekiScriptMap(); siteFields.Add("name", DekiScriptExpression.Constant(instance.SiteName)); siteFields.Add("host", DekiScriptExpression.Constant(deki.UiUri.Uri.Host)); siteFields.Add("language", DekiScriptExpression.Constant(instance.SiteLanguage)); siteFields.Add("uri", DekiScriptExpression.Constant(deki.UiUri.Uri.ToString())); siteFields.Add("id", DekiScriptExpression.Constant(instance.Id)); env.Add("site", siteFields); // add page fields DekiScriptMap pageFields = new DekiScriptMap(); pageFields.Add("title", DekiScriptExpression.Constant(page.Title.AsUserFriendlyName())); pageFields.Add("path", DekiScriptExpression.Constant(page.Title.AsPrefixedDbPath())); pageFields.Add("namespace", DekiScriptExpression.Constant(Title.NSToString(page.Title.Namespace))); pageFields.Add("id", DekiScriptExpression.Constant(page.ID.ToString())); pageFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(page.Title))); pageFields.Add("date", DekiScriptExpression.Constant(page.TimeStamp.ToString("R"))); pageFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(page.Language) ? null : page.Language)); env.Add("page", pageFields); // add user fields DekiScriptMap userFields = new DekiScriptMap(); if (deki.User != null) { UserBE user = deki.User; userFields.Add("id", DekiScriptExpression.Constant(user.ID.ToString())); userFields.Add("name", DekiScriptExpression.Constant(user.Name)); userFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(Title.FromDbPath(NS.USER, user.Name, null)))); userFields.Add("emailhash", DekiScriptExpression.Constant(StringUtil.ComputeHashString((user.Email ?? string.Empty).Trim().ToLowerInvariant(), Encoding.UTF8))); userFields.Add("anonymous", DekiScriptExpression.Constant(UserBL.IsAnonymous(user).ToString().ToLowerInvariant())); userFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(user.Language) ? null : user.Language)); } else { userFields.Add("id", DekiScriptExpression.Constant("0")); userFields.Add("name", DekiScriptExpression.Constant(string.Empty)); userFields.Add("uri", DekiScriptExpression.Constant(string.Empty)); userFields.Add("emailhash", DekiScriptExpression.Constant(string.Empty)); userFields.Add("anonymous", DekiScriptExpression.Constant("true")); userFields.Add("language", DekiScriptNil.Value); } env.Add("user", userFields); // store env for later current.SetState("pageimplicitenv-" + page.ID, env); } // set implicit environment DreamContext.Current.SetState(env); }
public static DekiScriptMap GetImplicitEnvironment(DreamMessage message, DSACryptoServiceProvider publicDigitalSignature) { DekiScriptMap env = new DekiScriptMap(); // retrieve implicit arguments string[] headers = message.Headers.GetValues(IMPLICIT_ENVIRONMENT_HEADER); if (!ArrayUtil.IsNullOrEmpty(headers)) { env.AddAt("__implicit", new DekiScriptList(new ArrayList(headers))); foreach (string implicitArg in headers) { foreach (KeyValuePair <string, string> arg in HttpUtil.ParseNameValuePairs(implicitArg)) { env.AddNativeValueAt(arg.Key, arg.Value); } } } if (publicDigitalSignature != null) { bool valid = false; try { Dictionary <string, string> values = HttpUtil.ParseNameValuePairs(message.Headers[IMPLICIT_SIGNATURE_HEADER]); // verify date DateTime date = DateTime.Parse(values["date"]).ToUniversalTime(); double delta = DateTime.UtcNow.Subtract(date).TotalSeconds; if ((delta < -60) || (delta > 60)) { throw new DreamAbortException(DreamMessage.Forbidden("date in message signature is too far apart from server date")); } // verify message MemoryStream data = new MemoryStream(); byte[] bytes = null; // get message bytes bytes = message.AsBytes(); data.Write(bytes, 0, bytes.Length); // retrieve headers to verify if (!ArrayUtil.IsNullOrEmpty(headers)) { Array.Sort(headers, StringComparer.Ordinal); bytes = Encoding.UTF8.GetBytes(string.Join(",", headers)); data.Write(bytes, 0, bytes.Length); } // add request date bytes = Encoding.UTF8.GetBytes(values["date"]); data.Write(bytes, 0, bytes.Length); // verify signature byte[] signature = Convert.FromBase64String(values["dsig"]); valid = publicDigitalSignature.VerifyData(data.GetBuffer(), signature); } catch (Exception e) { if (e is DreamAbortException) { throw; } } if (!valid) { throw new DreamAbortException(DreamMessage.Forbidden("invalid or missing digital signature")); } } return(env); }
protected override Yield Start(XDoc config, Result result) { yield return(Coroutine.Invoke(base.Start, config, new Result())); // loop over all resources Type type = GetType(); string assembly = type.Assembly.FullName.Split(new char[] { ',' }, 2)[0]; foreach (DekiExtLibraryFilesAttribute files in Attribute.GetCustomAttributes(type, typeof(DekiExtLibraryFilesAttribute))) { string prefix = files.Prefix ?? type.Namespace; foreach (string filename in files.Filenames) { MimeType mime = MimeType.FromFileExtension(filename); _files[filename] = Plug.New(string.Format("resource://{0}/{1}.{2}", assembly, prefix, filename)).With("dream.out.type", mime.FullType); } } // check if a public digital signature key was provided string dsaKey = config["deki-signature"].AsText ?? config["dekiwiki-signature"].AsText; if (dsaKey != null) { try { DSACryptoServiceProvider dsa = new DSACryptoServiceProvider(); dsa.ImportCspBlob(Convert.FromBase64String(dsaKey)); _publicDigitalSignature = dsa; } catch { throw new ArgumentException("invalid digital signature provided", "deki-signature"); } } // loop over all instance methods foreach (MethodInfo method in type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic)) { // check if it has the DekiExtFunction attriute DekiExtFunctionAttribute ext = (DekiExtFunctionAttribute)Attribute.GetCustomAttribute(method, typeof(DekiExtFunctionAttribute)); if (ext != null) { // check if function has an associated script XDekiScript script = null; DekiExtFunctionScriptAttribute scriptAttr = (DekiExtFunctionScriptAttribute)Attribute.GetCustomAttribute(method, typeof(DekiExtFunctionScriptAttribute)); if (scriptAttr != null) { DreamMessage scriptresource = Plug.New(string.Format("resource://{0}/{1}.{2}", assembly, scriptAttr.Prefix ?? type.Namespace, scriptAttr.Scriptname)).With("dream.out.type", MimeType.XML.FullType).GetAsync().Wait(); if (scriptresource.IsSuccessful) { script = new XDekiScript(scriptresource.ToDocument()); } if (script == null) { throw new InvalidOperationException(string.Format("method '{0}' is declard as script, but script could not be loaded", method.Name)); } } // add function Add(ext, method, script); } } // add configuration settings var context = DreamContext.Current; _scriptConfig = new DekiScriptMap(); foreach (KeyValuePair <string, string> entry in Config.ToKeyValuePairs()) { XUri local; if (XUri.TryParse(entry.Value, out local)) { local = context.AsPublicUri(local); _scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(local.ToString())); } else { _scriptConfig.AddAt(entry.Key.Split('/'), DekiScriptExpression.Constant(entry.Value)); } } result.Return(); }
public abstract DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args);
public static ArrayList ListIntersect( [DekiScriptParam("first list")] ArrayList first, [DekiScriptParam("second list")] ArrayList second, [DekiScriptParam("expression to determine if item from the first list should be included in final list (return true to include, false to exclude; use '$left' and '$right' to refer to the current item from the first and seconds lists respectively; default: equality condition)", true)] string condition, DekiScriptRuntime runtime ) { ArrayList result = new ArrayList(); if(condition != null) { // loop over both lists and keep items from the first list based on the outcome of the condition DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.intersect(condition)"), condition); foreach(object left in first) { foreach(object right in second) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap keyvalue = new DekiScriptMap(); keyvalue.Add("left", DekiScriptLiteral.FromNativeValue(left)); keyvalue.Add("right", DekiScriptLiteral.FromNativeValue(right)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, keyvalue); DekiScriptLiteral test = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env); if(!test.IsNilFalseZero) { result.Add(left); break; } } } } else { // using simple containment check to keep items foreach(object item in first) { if(second.Contains(item)) { result.Add(item); } } } return result; }
public static DekiScriptList ValidateToList(DekiScriptParameter[] parameters, DekiScriptMap args) { DekiScriptList result = new DekiScriptList(); // check passed in arguments for(int i = 0; i < parameters.Length; ++i) { var value = args[parameters[i].Name]; if(value.IsNil) { if((parameters[i].ScriptType != DekiScriptType.ANY) && !parameters[i].Optional) { throw new ArgumentException(string.Format("missing value for parameter '{0}' (index {1})", parameters[i].Name, i)); } // set default value for this parameter result.Add(parameters[i].Default); } else { result.Add(parameters[i].Convert(value)); } } return result; }
public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { return(InvokeHelper(runtime, DekiScriptParameter.ValidateToList(Parameters, args))); }
public static object ListReduce( [DekiScriptParam("list value")] ArrayList list, [DekiScriptParam("expression to compute combined value (use '$value' and '$item' to refer to the current value and item, respectively)")] string expression, [DekiScriptParam("starting value (default: nil)", true)] object value, DekiScriptRuntime runtime ) { DekiScriptExpression expr = DekiScriptParser.Parse(new Location("list.reduce(expression)"), expression); foreach(object entry in list) { DekiScriptEnv env = runtime.CreateEnv(); DekiScriptMap values = new DekiScriptMap(); values.Add("value", DekiScriptLiteral.FromNativeValue(value)); values.Add("item", DekiScriptLiteral.FromNativeValue(entry)); env.Vars.Add(DekiScriptRuntime.DEFAULT_ID, values); value = runtime.Evaluate(expr, DekiScriptEvalMode.EvaluateSafeMode, env).NativeValue; } return value; }
public static void InitializeCustomDekiScriptHeaders(PageBE page) { var current = DreamContext.Current; DekiScriptMap env = current.GetState<DekiScriptMap>("pageimplicitenv-" + page.ID); // check if we already have an initialized environment if(env == null) { DekiContext deki = DekiContext.Current; DekiInstance instance = deki.Instance; env = new DekiScriptMap(); // add site fields DekiScriptMap siteFields = new DekiScriptMap(); siteFields.Add("name", DekiScriptExpression.Constant(instance.SiteName)); siteFields.Add("host", DekiScriptExpression.Constant(deki.UiUri.Uri.Host)); siteFields.Add("language", DekiScriptExpression.Constant(instance.SiteLanguage)); siteFields.Add("uri", DekiScriptExpression.Constant(deki.UiUri.Uri.ToString())); siteFields.Add("id", DekiScriptExpression.Constant(instance.Id)); env.Add("site", siteFields); // add page fields DekiScriptMap pageFields = new DekiScriptMap(); pageFields.Add("title", DekiScriptExpression.Constant(page.Title.AsUserFriendlyName())); pageFields.Add("path", DekiScriptExpression.Constant(page.Title.AsPrefixedDbPath())); pageFields.Add("namespace", DekiScriptExpression.Constant(Title.NSToString(page.Title.Namespace))); pageFields.Add("id", DekiScriptExpression.Constant(page.ID.ToString())); pageFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(page.Title))); pageFields.Add("date", DekiScriptExpression.Constant(page.TimeStamp.ToString("R"))); pageFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(page.Language) ? null : page.Language)); env.Add("page", pageFields); // add user fields DekiScriptMap userFields = new DekiScriptMap(); if(deki.User != null) { UserBE user = deki.User; userFields.Add("id", DekiScriptExpression.Constant(user.ID.ToString())); userFields.Add("name", DekiScriptExpression.Constant(user.Name)); userFields.Add("uri", DekiScriptExpression.Constant(Utils.AsPublicUiUri(Title.FromDbPath(NS.USER, user.Name, null)))); userFields.Add("emailhash", DekiScriptExpression.Constant(StringUtil.ComputeHashString((user.Email ?? string.Empty).Trim().ToLowerInvariant(), Encoding.UTF8))); userFields.Add("anonymous", DekiScriptExpression.Constant(UserBL.IsAnonymous(user).ToString().ToLowerInvariant())); userFields.Add("language", DekiScriptExpression.Constant(string.IsNullOrEmpty(user.Language) ? null : user.Language)); } else { userFields.Add("id", DekiScriptExpression.Constant("0")); userFields.Add("name", DekiScriptExpression.Constant(string.Empty)); userFields.Add("uri", DekiScriptExpression.Constant(string.Empty)); userFields.Add("emailhash", DekiScriptExpression.Constant(string.Empty)); userFields.Add("anonymous", DekiScriptExpression.Constant("true")); userFields.Add("language", DekiScriptNil.Value); } env.Add("user", userFields); // store env for later current.SetState("pageimplicitenv-" + page.ID, env); } // set implicit environment DreamContext.Current.SetState(env); }
//--- Constructors --- public DekiScriptEnv() { this.Vars = new DekiScriptMap(); }
public DekiScriptExpression Visit(DekiScriptMap expr, DekiScriptExpressionEvaluationState state) { return(expr); }
public static DekiScriptLiteral FromXml(XDoc doc) { // check if response is an HTML document if(doc.HasName("html")) { // TODO (steveb): this handling seems to be to specific to belong here. return new DekiScriptList().Add(new DekiScriptXml(doc)); } // check if response is a DekiScript XML document if(!doc.HasName("value") || (doc["@type"].AsText == null)) { throw new ArgumentException("doc"); } switch(doc["@type"].AsText) { case "nil": return DekiScriptNil.Value; case "bool": return Constant(doc.AsBool ?? false); case "num": return Constant(doc.AsDouble ?? 0.0); case "str": return Constant(doc.AsText ?? string.Empty); case "uri": { return Constant(doc.AsUri); } case "map": { DekiScriptMap result = new DekiScriptMap(); foreach(XDoc value in doc["value"]) { result.Add(value["@key"].AsText, FromXml(value)); } return result; } case "list": { DekiScriptList result = new DekiScriptList(); foreach(XDoc value in doc["value"]) { result.Add(FromXml(value)); } return result; } case "xml": if((doc.AsXmlNode.ChildNodes.Count == 1) && (doc.AsXmlNode.ChildNodes[0].NodeType == XmlNodeType.Element)) { return new DekiScriptXml(doc[doc.AsXmlNode.ChildNodes[0]]); } return DekiScriptNil.Value; default: throw new ArgumentException("doc"); } }
public override DekiScriptLiteral InvokeMap(DekiScriptRuntime runtime, DekiScriptMap args) { throw new DekiScriptBadTypeException(Location.None, args.ScriptType, new[] { DekiScriptType.LIST }); }