public static void p5_types_can_convert(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution using (new ArgsRemover(e.Args)) { // Syntax checking invocation if (!(e.Args.Value is Expression) || e.Args ["type"] == null) { throw new ArgumentException("[p5.types.can-convert] needs both an expression as its value, and a [type] parameter"); } // Figuring out type to check for string type = e.Args.GetExChildValue <string> ("type", context); // Exploiting the fact that conversions will throw exception if conversion is not possible try { // Looping through all arguments supplied foreach (var idx in XUtil.Iterate <object> (context, e.Args)) { var objValue = context.RaiseEvent(".p5.hyperlambda.get-object-value." + type, new Node("", idx)).Value; } // No exception occurred, conversion is possible e.Args.Value = true; } catch { // Oops, conversion is not possible! e.Args.Value = false; } } }
public static void p5_csv_csv2lambda(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new Utilities.ArgsRemover(e.Args, true)) { // Loops through all documents we're supposed to transform. foreach (var idxCsvDoc in XUtil.Iterate <string> (context, e.Args)) { // Converting currently iterated document, making sure we have our result node. var curFile = e.Args.Add("result").LastChild; // Reading CSV content, by creating a string reader, which we supply to the CsvParser. using (TextReader reader = new StringReader(idxCsvDoc)) { // Creating our CSV parser. var parser = new CsvParser(reader); // Looping through each row in file. while (true) { var row = parser.Read(); if (row == null) { break; // Finished! } // Adding current line into return value. var curLine = curFile.Add("").LastChild; for (int idxCell = 0; idxCell < row.Length; idxCell++) { curLine.Add(row[idxCell]); } } } } } }
public static void hyper2lambda(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args, true)) { // Using a MemoryStream as our buffer for entire Hyperlambda section. using (var stream = new MemoryStream()) { // Associating a StringWriter with it for simplicity. StreamWriter writer = new StreamWriter(stream, Encoding.UTF8); // Concatenating all Hyperlambda submitted, injecting CR/LF between each Hyperlambda snippet. foreach (var idxHyperlisp in XUtil.Iterate <string> (context, e.Args)) { // Making sure we put in a carriage return between each Hyperlambda snippet. if (stream.Length > 0) { writer.Write("\r\n"); } // Appending currently iterated Hyperlambda into StringBuilder. writer.Write(idxHyperlisp); } writer.Flush(); // Making sure we set position of underlaying stream to the beginning. stream.Position = 0; // Checking if caller wants to keep comments. var keepComments = e.Args.GetExChildValue("keep-comments", context, false); e.Args ["keep-comments"]?.UnTie(); // Creating our parser, and parsing the entire Hyperlambda, returning its results back to caller. new HyperlambdaParser(context).Parse(new StreamReader(stream), e.Args, keepComments); } } }
public static void _p5_io_file_save_to_stream(ApplicationContext context, ActiveEventArgs e) { // Retrieving stream argument. var tuple = e.Args.Value as Tuple <object, Stream>; e.Args.Value = tuple.Item1; var input = tuple.Item2; // Sanity check. if (e.Args.Value == null) { throw new LambdaException("[.p5.io.file.save-to-stream] requires a constant or an expression leading to its path", e.Args, context); } // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args)) { // Getting root folder, and converting content to blob, making sure user does use [src] and not [dest] as file content. var rootFolder = Common.GetRootFolder(context); // Iterating through each destination file path, which probably doesn't make that much sense, but to be consistent in how we // handle files, we still do this, such that "API" is similar to [load-file], etc. foreach (var idxDestination in XUtil.Iterate <string> (context, e.Args)) { // Verifying user is allowed to save to file. Common.RaiseAuthorizeEvent(context, e.Args, "modify-file", idxDestination); // Saving file. using (FileStream stream = File.Create(rootFolder + Common.GetSystemPath(context, idxDestination))) { // Writing content to file stream. input.CopyTo(stream); } } } }
/* * Allows you to iterate files and folders. */ internal static void Iterate( ApplicationContext context, Node args, bool removeArgsValue, string authorizeEvent, ObjectIteratorDelegate functor) { // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(args, removeArgsValue)) { // Getting root folder. var rootFolder = Common.GetRootFolder(context); // Iterating over all file paths given. foreach (var idxFileObject in XUtil.Iterate <string> (context, args)) { // Retrieving actual system path. var fileObjectName = Common.GetSystemPath(context, idxFileObject); // Verifying user is authorized to reading from currently iterated file. Common.RaiseAuthorizeEvent(context, args, authorizeEvent, idxFileObject); // Invoking callback delegate. functor(fileObjectName, rootFolder + fileObjectName); } } }
public static void _p5_mime_serialize_to_stream(ApplicationContext context, ActiveEventArgs e) { // Retrieving output filename, and doing some basic sanity checking. var tuple = e.Args.Value as Tuple <object, Stream>; var output = tuple.Item2; // Have to remove value of node, before iteration starts. e.Args.Value = null; // Making sure we clean up after ourselves using (new ArgsRemover(e.Args, true)) { // Iterating through each node given, either as child of main node, or through expression var mimeNode = XUtil.Iterate <Node> (context, e.Args).First(); // Making sure we keep track of, closes, and disposes all streams created during process List <Stream> streams = new List <Stream> (); try { // Creating MIME message and serializing to file. var creator = new MimeCreator( context, mimeNode, streams); creator.Create().WriteTo(output); } finally { // Disposing all streams created during process foreach (var idxStream in streams) { // Closing and disposing currently iterated stream idxStream.Close(); idxStream.Dispose(); } } } }
public static void p5_mime_create(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up after ourselves using (new ArgsRemover(e.Args, true)) { // Iterating through each node given, either as child of main node, or through expression foreach (var idxMimeNode in XUtil.Iterate <Node> (context, e.Args)) { // Making sure we keep track of, closes, and disposes all streams created during process List <Stream> streams = new List <Stream> (); try { // Creating and returning MIME message to caller as string var creator = new MimeCreator( context, idxMimeNode, streams); e.Args.Add("result", creator.Create().ToString()); } finally { // Disposing all streams created during process foreach (var idxStream in streams) { // Closing and disposing currently iterated stream idxStream.Close(); idxStream.Dispose(); } } } } }
public static void p5_data_insert_append(ApplicationContext context, ActiveEventArgs e) { // Acquiring write lock on database. using (new Common.Lock(true)) { // Making sure we keep track of which files are changed, and how many items were affected. var changed = new List <Node> (); int affectedItems = 0; // Checking if we should force insertion at the end or not. var forceAppend = e.Name == "p5.data.append" || e.Name == "append-data"; // Notice, we don't provide any transactional support here, but at least we make sure any changes are serialized to disc. try { // Looping through all nodes given as children, value, or as the result of an expression. foreach (var idx in XUtil.Iterate <Node> (context, e.Args)) { // Inserting node, clearing children, and incrementing number of affected items. InsertNode(idx, context, changed, forceAppend); idx.Clear(); affectedItems += 1; } } finally { Common.SaveAffectedFiles(context, changed); e.Args.Value = affectedItems; } } }
/* * Retrieves a specific user from system */ public static void DeleteUser(ApplicationContext context, Node args) { // Locking access to password file as we create new user object AuthFile.ModifyAuthFile( context, delegate(Node authFile) { // Iterating all users requested deleted by caller foreach (var idxUsername in XUtil.Iterate <string> (context, args)) { // Checking if user exist if (authFile ["users"] [idxUsername] == null) { throw new LambdaException( string.Format("User '{0}' does not exist", idxUsername), args, context); } // Deleting currently iterated user authFile["users"][idxUsername].UnTie(); // Deleting user's home directory context.Raise("p5.io.folder.delete", new Node("", "/users/" + idxUsername + "/")); } }); }
public static void p5_data_insert_append(ApplicationContext context, ActiveEventArgs e) { // Acquiring write lock on database, and making sure we keep track of which files are changed, and how many items were affected. var changed = new List <Node> (); int affectedItems = 0; Common.Locker.EnterWriteLock(); try { // Checking if we should force insertion at the end or not. var forceAppend = e.Name == "p5.data.append" || e.Name == "append-data"; // Looping through all nodes given as children, value, or as the result of an expression. foreach (var idx in XUtil.Iterate <Node> (context, e.Args)) { // Inserting node, clearing children, and incrementing number of affected items. InsertNode(idx, context, changed, forceAppend); idx.Clear(); affectedItems += 1; } } finally { // Saving all affected files. // Notice, we do this even though an exception has occurred, since exception is thrown before any illegal nodes are attempted to insert. // This means that if you insert several nodes, some might become inserted though, while others are not inserted. // Hence, [p5.data.insert] does not feature any sorts of "transactional insert support" at the moment. Common.SaveAffectedFiles(context, changed); e.Args.Value = affectedItems; Common.Locker.ExitWriteLock(); } }
public static void lambda2json(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args)) { // Figuring out if we should nicely format our JSON. var format = e.Name == "lambda2json" ? Formatting.None : Formatting.Indented; // Extracting nodes. var nodes = XUtil.Iterate <Node> (context, e.Args); // Checking type of JSON object we should return. if (!nodes.Any()) { // No input given. return; } else if (nodes.First().Name == "") { // Simple array value not wrapped in an object. e.Args.Value = new JArray(nodes.Select(ix => ArrayHelper(context, ix))).ToString(format); } else { // Complex object of some sort. e.Args.Value = new JObject(nodes.Select(ix => new JProperty(ix.Name, SerializeNode(context, ix)))).ToString(format); } } }
public static void p5_mime_load_file(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up after ourselves using (new ArgsRemover(e.Args, true)) { // Keeping base folder to application around string baseFolder = Common.GetRootFolder(context).TrimEnd('/'); // Looping through each filename supplied by caller foreach (var idxFilename in XUtil.Iterate <string> (context, e.Args)) { // Verifying user is authorized to reading from currently iterated file context.RaiseEvent(".p5.io.authorize.read-file", new Node("", idxFilename).Add("args", e.Args)); // Loading, processing and returning currently iterated message var parser = new helpers.MimeParser( context, e.Args, MimeEntity.Load(baseFolder + idxFilename), e.Args.GetExChildValue <string> ("attachment-folder", context)); // Parses the MimeEntity and stuffs results into e.Args node parser.Process(); } } }
/* * Helper for above two mutably evaluation events. */ static void EvalCopy(ApplicationContext context, Node args) { // Checking if we should force evaluation of children nodes, and not evaluate expression/object in main node. if (args.Value == null || !args.Name.StartsWithEx("eval")) { // Evaluating current scope. var clone = args.Clone(); args.Clear().AddRange(ExecuteBlockCopy(context, clone)).Value = clone.Value; } else { // Evaluating a value object or an expression, making sure we are able to return everything resulting from evaluation of all lambdas. var retVal = new Node(); foreach (var idxLambda in XUtil.Iterate <Node> (context, args)) { // Evaluating currently iterated lambda. var clone = idxLambda.Clone(); // Passing in arguments, in order of appearance, if there are any arguments, making sure we also insert our offset. clone.Insert(0, new Node("offset", args.Count)); clone.InsertRange(1, args.Clone().Children); // Evaluating cloned lambda, and making sure we save any return value for after iteration. retVal.AddRange(ExecuteBlockCopy(context, clone)).Value = clone.Value ?? retVal.Value; } // Returning results from all above evaluations. args.Clear().AddRange(retVal.Children).Value = retVal.Value; } }
public void p5_web_send_javascript(ApplicationContext context, ActiveEventArgs e) { // Looping through each JavaScript snippet supplied foreach (var idxSnippet in XUtil.Iterate <string> (context, e.Args)) { // Passing JavaScript to client AjaxPage.SendJavaScript(idxSnippet); } }
public void p5_web_include_javascript_file(ApplicationContext context, ActiveEventArgs e) { // Looping through each JavaScript file supplied foreach (var idxFile in XUtil.Iterate <string> (context, e.Args)) { // Passing file to client AjaxPage.IncludeJavaScriptFile(context.RaiseEvent(".p5.io.unroll-path", new Node("", idxFile)).Get <string> (context)); } }
public void p5_web_include_css_file(ApplicationContext context, ActiveEventArgs e) { // Looping through each stylesheet file supplied foreach (var idxFile in XUtil.Iterate <string> (context, e.Args)) { // Register file for inclusion back to client AjaxPage.IncludeCSSFile(context.RaiseEvent(".p5.io.unroll-path", new Node("", idxFile)).Get <string> (context)); } }
public void p5_web_widgets_find(ApplicationContext context, ActiveEventArgs e) { // Sanity check. if (!e.Args.Children.Any(ix => ix.Name != "")) { throw new LambdaException( string.Format("[{0}] requires at least one child argument, being some property/attribute to look for", e.Name), e.Args, context); } // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args, true)) { // Iterating through each argument supplied, making sure it has "cnt" as a default value, if no explicit start widget(s) are given. var list = new List <string> (); if (e.Args.Value != null) { list.AddRange(XUtil.Iterate <string> (context, e.Args)); } else { list.Add("cnt"); // Defaulting to "cnt" main root widget of application pool. } // Setting up a result node, to avoid modifying our args before entire iteration is finished. // Notice, if we hadn't done this, then each match would create a new (bogus) criteria, meaning there could never be more than one match. var retVal = new Node(); // Iterating each starting widget. foreach (var idxStartWidgetId in list) { // Retrieving start widget from where to start searching for widgets matching criteria. var startControl = FindControl <Widget> (idxStartWidgetId, Manager.AjaxPage); if (startControl == null) { continue; } // Retrieving all widgets having properties matching whatever criteria are supplied. foreach (var idxWidget in FindWidgetsMatchingCriteria(e.Args, startControl, context, e.Name.Contains("-like"), false)) { // Adding type of widget as name, and ID of widget as value. retVal.FindOrInsert(idxStartWidgetId).Add(GetTypeName(idxWidget), idxWidget.ID); // Checking if caller only wants one result for each starting widget. if (e.Name.Contains("-first")) { break; } } } e.Args.AddRange(retVal.Children); } }
/* * Returns two lists containing the object values of both sides being compared to each other */ static Tuple <List <object>, List <object> > GetBothSides(Node args, ApplicationContext context) { // Left-hand side var lhs = new List <object> (XUtil.Iterate <object> (context, args.Parent)); // Right-hand side var rhs = new List <object> (XUtil.Iterate <object> (context, args)); // Returning both sides to caller return(new Tuple <List <object>, List <object> > (lhs, rhs)); }
public static void lambda2hyper(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution using (new ArgsRemover(e.Args)) { // Using HyperlispBuilder to create Hyperlambda from p5 lambda e.Args.Value = new HyperlambdaBuilder( context, XUtil.Iterate <Node> (context, e.Args)) .Hyperlambda; } }
public static void p5_read_lock(ApplicationContext context, ActiveEventArgs e) { // Retrieving all lockers caller wants to lock var lockers = XUtil.Iterate <string> (context, e.Args).ToList(); // Recursively waits for each locker to be unlocked, evaluating given lambda, once all lockers are unlocked ReadLock( lockers, delegate { context.RaiseEvent("eval-mutable", e.Args); }); }
public void p5_web_widgets_exists(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args, true)) { // Looping through all IDs given. foreach (var widgetId in XUtil.Iterate <string> (context, e.Args)) { // Adding a boolean as result node, with specified ID as name, and boolean value, indicating if widget exists or not. e.Args.Add(widgetId, FindControl <Widget> (widgetId, Manager.AjaxPage) != null); } } }
/* * Processing a sub-template. */ private static IEnumerable <Node> ProcessSubTemplate(ApplicationContext context, Node template, Node source) { // This is a sub-template, which we treat as a new template definition, evaluating its expression relatively to the current source, // and braids together, before returning results to caller. foreach (var idxSource in XUtil.Iterate <Node> (context, template, source)) { // Braiding source with template, and returning to caller. foreach (var idx in BraidTemplateWithSource(context, template, idxSource)) { yield return(idx); } } }
public static void p5_mime_parse(ApplicationContext context, ActiveEventArgs e) { // House cleaning. using (new ArgsRemover(e.Args, true)) { // Looping through each MIME message supplied. foreach (var idxMimeMessage in XUtil.Iterate <string> (context, e.Args)) { // Sanity check. if (string.IsNullOrEmpty(idxMimeMessage)) { throw new LambdaException( "No MIME message provided to [p5.mime.parse]", e.Args, context); } // Loading MIME entity from stream. using (var writer = new StreamWriter(new MemoryStream())) { // Writing MIME content to StreamWriter, flushing the stream, and setting stream's read head back to beginning. writer.Write(idxMimeMessage); writer.Flush(); writer.BaseStream.Position = 0; // Creating the MIME entity to hold our parsed content. MimeEntity entity = null; // Checking if an explicit [Content-Type] was supplied. if (e.Args ["Content-Type"] != null) { entity = MimeEntity.Load(ContentType.Parse(e.Args ["Content-Type"].GetExValue <string> (context)), writer.BaseStream); } else { entity = MimeEntity.Load(writer.BaseStream); } // Creating our parser wrapper. var parser = new helpers.MimeParser( context, e.Args, entity, e.Args.GetExChildValue <string> ("attachment-folder", context), e.Args.GetExChildValue <bool> ("attachments-use-prefix", context, true)); // Parses the MimeEntity and stuffs results into e.Args node. parser.Process(); } } } }
public void p5_web_widgets_list(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution. using (new ArgsRemover(e.Args, true)) { // Retrieving filter, if any. var filter = XUtil.Iterate <string>(context, e.Args).ToList(); if ((e.Args.Value != null || e.Args.Count > 0) && filter.Count == 0) { return; // Possibly a filter expression, leading into oblivion. } // Recursively retrieving all widgets on page, matching filter, or all widgets, if there are no filters. ListWidgets(filter, e.Args, Manager.AjaxPage, e.Name == "p5.web.widgets.list"); } }
/* * Returns all access objects for system. */ public static void SetAccess(ApplicationContext context, Node args) { // Locking access to password file as we create new access object. AuthFile.ModifyAuthFile( context, delegate(Node authFile) { // Verifying access rights exists. if (authFile ["access"] == null) { authFile.Add("access"); } // Retrieving access root node. var access = authFile ["access"]; // Clearing all previous access objects. access.Clear(); // Iterating all access objects supplied by caller, adding them to our access node. var newAccessRights = XUtil.Iterate <Node> (context, args).ToList(); foreach (var idxAccess in newAccessRights) { // Sanity checking. var val = idxAccess.GetExValue(context, ""); if (string.IsNullOrEmpty(val)) { // Creating a new random GUID as the ID of our access object. val = Guid.NewGuid().ToString(); idxAccess.Value = val; } else { // Verifying access ID is unique. if (access.Children.Any(ix => ix.Get(context, "") == val)) { throw new LambdaException("Each access right must have a unique name/value combination, and there's already another access right with the same name/value combination in your access list", idxAccess, context); } } // Sanity checking access object. if (idxAccess.Count == 0) { throw new LambdaException("There's no actual content in your access object", idxAccess, context); } // Adding currently iterated access object. access.Add(idxAccess.Clone()); } }); }
public static void lambda2hyper(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution using (new ArgsRemover(e.Args)) { // Figuring out what to do with comments. var comments = e.Args.Value is Expression ? (e.Args.GetExChildValue("comments", context, "keep")) : "keep"; // Using HyperlispBuilder to create Hyperlambda from p5 lambda e.Args.Value = new HyperlambdaBuilder( context, XUtil.Iterate <Node> (context, e.Args), comments) .Hyperlambda; } }
public static void p5_events_list(ApplicationContext context, ActiveEventArgs e) { // Retrieving filter, if any. var filter = new List <string> (XUtil.Iterate <string> (context, e.Args)); // Acquire read lock, since we're consuming object shared amongst more than one thread (_events). _lock.EnterReadLock(); try { // Getting all dynamic Active Events, making sure we clean up after ourselves. using (new Utilities.ArgsRemover(e.Args, true)) { ListActiveEvents(_events.Keys, e.Args, filter, "dynamic", context); } } finally { // Making sure we release lock in a finally, such that we can never exit method, without releasing our lock. _lock.ExitReadLock(); } // Getting all core Active Events. ListActiveEvents(context.ActiveEvents, e.Args, filter, "static", context); // Checking if there exists a whitelist, and if so, removing everything not in our whitelist. if (context.Whitelist != null) { e.Args.Children.RemoveAll(ix => context.Whitelist[ix.Get <string> (context)] == null); } // Sorting such that static events comes first, and then having keywords coming. e.Args.Sort(delegate(Node lhs, Node rhs) { if (lhs.Name == "static" && rhs.Name == "dynamic") { return(-1); } else if (lhs.Name == "dynamic" && rhs.Name == "static") { return(1); } if (!lhs.Get <string> (context).Contains(".") && rhs.Get <string> (context).Contains(".")) { return(-1); } else if (lhs.Get <string> (context).Contains(".") && !rhs.Get <string> (context).Contains(".")) { return(1); } else { return(lhs.Get <string> (context).CompareTo(rhs.Value)); } }); }
public static void p5_html_lambda2html(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution using (new ArgsRemover(e.Args)) { // Used as buffer when converting from lambda to HTML var builder = new StringBuilder(); // Doing actual conversion from lambda to HTML Convert(context, XUtil.Iterate <Node> (context, e.Args), builder); // Returning HTML to caller e.Args.Value = builder.ToString().Trim(); } }
public static void xml2lambda(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution using (new ArgsRemover(e.Args, true)) { // Loops through all documents we're supposed to transform foreach (var idxXmlDoc in XUtil.Iterate <string> (context, e.Args)) { // Converting currently iterated document/fragment var doc = new XmlDocument(); doc.LoadXml(idxXmlDoc); ParseXmlNode(e.Args.Add("result").LastChild, doc.DocumentElement); } } }
public static void p5_html_html2lambda(ApplicationContext context, ActiveEventArgs e) { // Making sure we clean up and remove all arguments passed in after execution using (new Utilities.ArgsRemover(e.Args, true)) { // Loops through all documents we're supposed to transform foreach (var idxHtmlDoc in XUtil.Iterate <string> (context, e.Args)) { // Converting currently iterated document/fragment var doc = new HtmlDocument(); doc.LoadHtml(idxHtmlDoc); ParseHtmlDocument(e.Args, doc.DocumentNode); } } }