private void Save(XDoc html, string title, string href, string path, string assembly) { html.EndAll(); // xdocs div var filepath = Path.Combine("relative", path); _fileMap.Start("item").Attr("dataid", _currentDataId).Attr("path", filepath).End(); _manifest.Start("page") .Attr("dataid", _currentDataId); if (!string.IsNullOrEmpty(title)) { _manifest.Elem("title", title); } _manifest .Elem("path", href) .Start("contents").Attr("type", "application/x.deki0805+xml").End() .End(); filepath = Path.Combine(_outputPath, filepath); Directory.CreateDirectory(Path.GetDirectoryName(filepath)); using (var stream = File.Create(filepath)) { using (var writer = new StreamWriter(stream)) { writer.Write(html.ToPrettyString()); writer.Close(); } stream.Close(); } _currentDataId++; if (string.IsNullOrEmpty(assembly)) { return; } // add assembly tag to file var assemblyString = "assembly:" + assembly; var tagDoc = new XDoc("tags") .Attr("count", 1) .Start("tag") .Attr("value", assemblyString) .Elem("type", "text") .Elem("title", assemblyString) .End(); filepath = Path.Combine("relative", Path.GetFileNameWithoutExtension(path) + ".tags"); _fileMap.Start("item").Attr("dataid", _currentDataId).Attr("path", filepath).End(); _manifest.Start("tags") .Attr("dataid", _currentDataId) .Elem("path", href) .End(); filepath = Path.Combine(_outputPath, filepath); using (var stream = File.Create(filepath)) { using (var writer = new StreamWriter(stream)) { writer.Write(tagDoc.ToPrettyString()); writer.Close(); } stream.Close(); } _currentDataId++; }
public XDoc ReloadNotification( [DekiExtParam("Page id", false)] string id ) { string containerId = "pn_" + StringUtil.CreateAlphaNumericKey(4); XUri self = Self.Uri.AsPublicUri(); XDoc doc = new XDoc("html") .Start("body").Start("div") .Attr("id", containerId) .End().End() .Start("tail") .Start("script") .Attr("type", "text/javascript") .Value(string.Format("Deki.Api.Poll({0},'{1}','{2}');", _pollInterval.TotalMilliseconds, containerId, self.At("changed", id))) .End() .End(); doc.EndAll(); return(doc); }
//--- Class Methods --- /// <summary> /// Create a service blueprint from reflection and attribute meta-data for an <see cref="IDreamService"/> implementation. /// </summary> /// <param name="type">Type of examine.</param> /// <returns>Xml formatted blueprint.</returns> public static XDoc CreateServiceBlueprint(Type type) { if(type == null) { throw new ArgumentNullException("type"); } XDoc result = new XDoc("blueprint"); // load assembly Dictionary<string, string> assemblySettings = new Dictionary<string, string>(StringComparer.Ordinal); string[] assemblyParts = type.Assembly.FullName.Split(','); foreach(string parts in assemblyParts) { string[] assign = parts.Trim().Split(new char[] { '=' }, 2); if(assign.Length == 2) { assemblySettings[assign[0].Trim()] = assign[1].Trim(); } } result.Start("assembly"); foreach(KeyValuePair<string, string> entry in assemblySettings) { result.Attr(entry.Key, entry.Value); } result.Value(assemblyParts[0]); result.End(); result.Elem("class", type.FullName); // retrieve DreamService attribute on class definition DreamServiceAttribute serviceAttrib = (DreamServiceAttribute)Attribute.GetCustomAttribute(type, typeof(DreamServiceAttribute), false); result.Elem("name", serviceAttrib.Name); result.Elem("copyright", serviceAttrib.Copyright); result.Elem("info", serviceAttrib.Info); // retrieve DreamServiceUID attributes foreach(XUri sid in serviceAttrib.GetSIDAsUris()) { result.Elem("sid", sid); } // check if service has blueprint settings foreach(DreamServiceBlueprintAttribute blueprintAttrib in Attribute.GetCustomAttributes(type, typeof(DreamServiceBlueprintAttribute), true)) { result.InsertValueAt(blueprintAttrib.Name, blueprintAttrib.Value); } // check if service has configuration information DreamServiceConfigAttribute[] configAttributes = (DreamServiceConfigAttribute[])Attribute.GetCustomAttributes(type, typeof(DreamServiceConfigAttribute), true); if(!ArrayUtil.IsNullOrEmpty(configAttributes)) { result.Start("configuration"); foreach(DreamServiceConfigAttribute configAttr in configAttributes) { result.Start("entry") .Elem("name", configAttr.Name) .Elem("valuetype", configAttr.ValueType) .Elem("description", configAttr.Description) .End(); } result.End(); } // retrieve DreamFeature attributes on method definitions result.Start("features"); MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach(MethodInfo method in methods) { // retrieve feature description Attribute[] featureAttributes = Attribute.GetCustomAttributes(method, typeof(DreamFeatureAttribute), false); if(featureAttributes.Length == 0) { continue; } if(method.IsGenericMethod || method.IsGenericMethodDefinition) { throw new NotSupportedException(string.Format("generic methods are not supported ({0})", method.Name)); } // determine access level string access; if(method.IsPublic) { access = "public"; } else if(method.IsAssembly) { access = "internal"; } else if(method.IsPrivate || method.IsFamily) { access = "private"; } else { throw new NotSupportedException(string.Format("access level is not supported ({0})", method.Name)); } // retrieve feature parameter descriptions, filters, prologues, and epilogues Attribute[] paramAttributes = Attribute.GetCustomAttributes(method, typeof(DreamFeatureParamAttribute), false); var pathAttributes = method.GetParameters().Select(p => { var attr = (PathAttribute)p.GetCustomAttributes(typeof(PathAttribute), false).FirstOrDefault(); return ((attr != null) && (attr.Name == null)) ? new PathAttribute { Description = attr.Description, Name = p.Name } : attr; }).Where(p => p != null); var queryAttributes = method.GetParameters().Select(q => { var attr = (QueryAttribute)q.GetCustomAttributes(typeof(QueryAttribute), false).FirstOrDefault(); return ((attr != null) && (attr.Name == null)) ? new QueryAttribute { Description = attr.Description, Name = q.Name } : attr; }).Where(q => q != null); Attribute[] statusAttributes = Attribute.GetCustomAttributes(method, typeof(DreamFeatureStatusAttribute), false); foreach(DreamFeatureAttribute featureAttrib in featureAttributes) { result.Start("feature"); result.Elem("obsolete", featureAttrib.Obsolete); result.Elem("pattern", featureAttrib.Pattern); result.Elem("description", featureAttrib.Description); string info = featureAttrib.Info ?? serviceAttrib.Info; if(info != null) { result.Elem("info", info); } result.Elem("method", method.Name); // add parameter descriptions (as seen on the method definition) foreach(DreamFeatureParamAttribute paramAttrib in paramAttributes) { result.Start("param"); result.Elem("name", paramAttrib.Name); if(!string.IsNullOrEmpty(paramAttrib.ValueType)) { result.Elem("valuetype", paramAttrib.ValueType); } result.Elem("description", paramAttrib.Description); result.End(); } // add parameter descriptions (as seen on the method parameters) foreach(PathAttribute pathAttrib in pathAttributes) { result.Start("param") .Elem("name", "{" + pathAttrib.Name + "}") .Elem("description", pathAttrib.Description) .End(); } // add parameter descriptions (as seen on the method parameters) foreach(QueryAttribute queryAttrib in queryAttributes) { result.Start("param") .Elem("name", queryAttrib.Name) .Elem("description", queryAttrib.Description) .End(); } // add status codes foreach(DreamFeatureStatusAttribute paramAttrib in statusAttributes) { result.Start("status"); result.Attr("value", (int)paramAttrib.Status); result.Value(paramAttrib.Description); result.End(); } // add access level result.Elem("access", access); result.End(); } } result.End(); return result.EndAll(); }
public XDoc PageActivity( [DekiExtParam("path to page", true)] string path, [DekiExtParam("format: html, xml (default: html)", true)] string format ) { if(string.IsNullOrEmpty(path)) { return null; } View[] activity; lock(_pageViews) { activity = _pageViews.ToArray(); } // Note (arnec): Since _pageViews is a queue, activity is in time sorted order and we just reverse it to get the most recent first Array.Reverse(activity); // find all views for the page List<View> pageViews = new List<View>(); foreach(View view in activity) { if(StringUtil.EqualsInvariantIgnoreCase(path, view.PagePath)) { pageViews.Add(view); } } // find the most recent user that has looked at another page since XDoc nextDestination = null; foreach(View user in pageViews) { if(user.UserUri == _anonymousUser) { continue; } foreach(View view in activity) { if(user.UserUri != view.UserUri) { continue; } if(!StringUtil.EqualsInvariantIgnoreCase(view.PagePath, user.PagePath)) { DreamMessage pageMessage = Plug.New(view.PageUri).With("apikey", _apikey).GetAsync().Wait(); nextDestination = pageMessage.ToDocument(); } break; } } XDoc doc; switch(format) { case "xml": doc = new XDoc("activity").Attr("interval", _ttl.TotalSeconds); break; default: doc = new XDoc("html").Start("body").Start("div").Attr("class", "popular-list") .Elem("p", string.Format("{0} views in last {1:0} minutes", pageViews.Count, (int)_ttl.TotalMinutes)); if(nextDestination != null) { doc.Start("p") .Value("The last visitor to this page went to ") .Start("a").Attr("href", nextDestination["uri.ui"].AsText).Value(nextDestination["title"].AsText).End() .Value(" next.") .End(); } break; } doc.EndAll(); return doc; }
//--- Class Methods --- /// <summary> /// Create a service blueprint from reflection and attribute meta-data for an <see cref="IDreamService"/> implementation. /// </summary> /// <param name="type">Type of examine.</param> /// <returns>Xml formatted blueprint.</returns> public static XDoc CreateServiceBlueprint(Type type) { if (type == null) { throw new ArgumentNullException("type"); } XDoc result = new XDoc("blueprint"); // load assembly Dictionary <string, string> assemblySettings = new Dictionary <string, string>(StringComparer.Ordinal); string[] assemblyParts = type.Assembly.FullName.Split(','); foreach (string parts in assemblyParts) { string[] assign = parts.Trim().Split(new char[] { '=' }, 2); if (assign.Length == 2) { assemblySettings[assign[0].Trim()] = assign[1].Trim(); } } result.Start("assembly"); foreach (KeyValuePair <string, string> entry in assemblySettings) { result.Attr(entry.Key, entry.Value); } result.Value(assemblyParts[0]); result.End(); result.Elem("class", type.FullName); // retrieve DreamService attribute on class definition DreamServiceAttribute serviceAttrib = (DreamServiceAttribute)Attribute.GetCustomAttribute(type, typeof(DreamServiceAttribute), false); result.Elem("name", serviceAttrib.Name); result.Elem("copyright", serviceAttrib.Copyright); result.Elem("info", serviceAttrib.Info); // retrieve DreamServiceUID attributes foreach (XUri sid in serviceAttrib.GetSIDAsUris()) { result.Elem("sid", sid); } // check if service has blueprint settings foreach (DreamServiceBlueprintAttribute blueprintAttrib in Attribute.GetCustomAttributes(type, typeof(DreamServiceBlueprintAttribute), true)) { result.InsertValueAt(blueprintAttrib.Name, blueprintAttrib.Value); } // check if service has configuration information DreamServiceConfigAttribute[] configAttributes = (DreamServiceConfigAttribute[])Attribute.GetCustomAttributes(type, typeof(DreamServiceConfigAttribute), true); if (!ArrayUtil.IsNullOrEmpty(configAttributes)) { result.Start("configuration"); foreach (DreamServiceConfigAttribute configAttr in configAttributes) { result.Start("entry") .Elem("name", configAttr.Name) .Elem("valuetype", configAttr.ValueType) .Elem("description", configAttr.Description) .End(); } result.End(); } // retrieve DreamFeature attributes on method definitions result.Start("features"); MethodInfo[] methods = type.GetMethods(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); foreach (MethodInfo method in methods) { // retrieve feature description Attribute[] featureAttributes = Attribute.GetCustomAttributes(method, typeof(DreamFeatureAttribute), false); if (featureAttributes.Length == 0) { continue; } if (method.IsGenericMethod || method.IsGenericMethodDefinition) { throw new NotSupportedException(string.Format("generic methods are not supported ({0})", method.Name)); } // determine access level string access; if (method.IsPublic) { access = "public"; } else if (method.IsAssembly) { access = "internal"; } else if (method.IsPrivate || method.IsFamily) { access = "private"; } else { throw new NotSupportedException(string.Format("access level is not supported ({0})", method.Name)); } // retrieve feature parameter descriptions, filters, prologues, and epilogues Attribute[] paramAttributes = Attribute.GetCustomAttributes(method, typeof(DreamFeatureParamAttribute), false); var pathAttributes = method.GetParameters().Select(p => { var attr = (PathAttribute)p.GetCustomAttributes(typeof(PathAttribute), false).FirstOrDefault(); return(((attr != null) && (attr.Name == null)) ? new PathAttribute { Description = attr.Description, Name = p.Name } : attr); }).Where(p => p != null); var queryAttributes = method.GetParameters().Select(q => { var attr = (QueryAttribute)q.GetCustomAttributes(typeof(QueryAttribute), false).FirstOrDefault(); return(((attr != null) && (attr.Name == null)) ? new QueryAttribute { Description = attr.Description, Name = q.Name } : attr); }).Where(q => q != null); Attribute[] statusAttributes = Attribute.GetCustomAttributes(method, typeof(DreamFeatureStatusAttribute), false); foreach (DreamFeatureAttribute featureAttrib in featureAttributes) { result.Start("feature"); result.Elem("obsolete", featureAttrib.Obsolete); result.Elem("pattern", featureAttrib.Pattern); result.Elem("description", featureAttrib.Description); string info = featureAttrib.Info ?? serviceAttrib.Info; if (info != null) { result.Elem("info", info); } result.Elem("method", method.Name); // add parameter descriptions (as seen on the method definition) foreach (DreamFeatureParamAttribute paramAttrib in paramAttributes) { result.Start("param"); result.Elem("name", paramAttrib.Name); if (!string.IsNullOrEmpty(paramAttrib.ValueType)) { result.Elem("valuetype", paramAttrib.ValueType); } result.Elem("description", paramAttrib.Description); result.End(); } // add parameter descriptions (as seen on the method parameters) foreach (PathAttribute pathAttrib in pathAttributes) { result.Start("param") .Elem("name", "{" + pathAttrib.Name + "}") .Elem("description", pathAttrib.Description) .End(); } // add parameter descriptions (as seen on the method parameters) foreach (QueryAttribute queryAttrib in queryAttributes) { result.Start("param") .Elem("name", queryAttrib.Name) .Elem("description", queryAttrib.Description) .End(); } // add status codes foreach (DreamFeatureStatusAttribute paramAttrib in statusAttributes) { result.Start("status"); result.Attr("value", (int)paramAttrib.Status); result.Value(paramAttrib.Description); result.End(); } // add access level result.Elem("access", access); result.End(); } } result.End(); return(result.EndAll()); }
public XDoc PageActivity( [DekiExtParam("path to page", true)] string path, [DekiExtParam("format: html, xml (default: html)", true)] string format ) { if (string.IsNullOrEmpty(path)) { return(null); } View[] activity; lock (_pageViews) { activity = _pageViews.ToArray(); } // Note (arnec): Since _pageViews is a queue, activity is in time sorted order and we just reverse it to get the most recent first Array.Reverse(activity); // find all views for the page List <View> pageViews = new List <View>(); foreach (View view in activity) { if (StringUtil.EqualsInvariantIgnoreCase(path, view.PagePath)) { pageViews.Add(view); } } // find the most recent user that has looked at another page since XDoc nextDestination = null; foreach (View user in pageViews) { if (user.UserUri == _anonymousUser) { continue; } foreach (View view in activity) { if (user.UserUri != view.UserUri) { continue; } if (!StringUtil.EqualsInvariantIgnoreCase(view.PagePath, user.PagePath)) { DreamMessage pageMessage = Plug.New(view.PageUri).With("apikey", _apikey).GetAsync().Wait(); nextDestination = pageMessage.ToDocument(); } break; } } XDoc doc; switch (format) { case "xml": doc = new XDoc("activity").Attr("interval", _ttl.TotalSeconds); break; default: doc = new XDoc("html").Start("body").Start("div").Attr("class", "popular-list") .Elem("p", string.Format("{0} views in last {1:0} minutes", pageViews.Count, (int)_ttl.TotalMinutes)); if (nextDestination != null) { doc.Start("p") .Value("The last visitor to this page went to ") .Start("a").Attr("href", nextDestination["uri.ui"].AsText).Value(nextDestination["title"].AsText).End() .Value(" next.") .End(); } break; } doc.EndAll(); return(doc); }
public XDoc ReloadNotification( [DekiExtParam("Page id", false)] string id ) { string containerId = "pn_" + StringUtil.CreateAlphaNumericKey(4); XUri self = Self.Uri.AsPublicUri(); XDoc doc = new XDoc("html") .Start("body").Start("div") .Attr("id", containerId) .End().End() .Start("tail") .Start("script") .Attr("type", "text/javascript") .Value(string.Format("Deki.Api.Poll({0},'{1}','{2}');", _pollInterval.TotalMilliseconds, containerId, self.At("changed", id))) .End() .End(); doc.EndAll(); return doc; }
private void Save(XDoc html, string title, string href, string path, string assembly) { html.EndAll(); // xdocs div var filepath = Path.Combine("relative", path); _fileMap.Start("item").Attr("dataid", _currentDataId).Attr("path", filepath).End(); _manifest.Start("page") .Attr("dataid", _currentDataId); if(!string.IsNullOrEmpty(title)) { _manifest.Elem("title", title); } _manifest .Elem("path", href) .Start("contents").Attr("type", "application/x.deki0805+xml").End() .End(); filepath = Path.Combine(_outputPath, filepath); Directory.CreateDirectory(Path.GetDirectoryName(filepath)); using(var stream = File.Create(filepath)) { using(var writer = new StreamWriter(stream)) { writer.Write(html.ToPrettyString()); writer.Close(); } stream.Close(); } _currentDataId++; if(string.IsNullOrEmpty(assembly)) { return; } // add assembly tag to file var assemblyString = "assembly:" + assembly; var tagDoc = new XDoc("tags") .Attr("count", 1) .Start("tag") .Attr("value", assemblyString) .Elem("type", "text") .Elem("title", assemblyString) .End(); filepath = Path.Combine("relative", Path.GetFileNameWithoutExtension(path) + ".tags"); _fileMap.Start("item").Attr("dataid", _currentDataId).Attr("path", filepath).End(); _manifest.Start("tags") .Attr("dataid", _currentDataId) .Elem("path", href) .End(); filepath = Path.Combine(_outputPath, filepath); using(var stream = File.Create(filepath)) { using(var writer = new StreamWriter(stream)) { writer.Write(tagDoc.ToPrettyString()); writer.Close(); } stream.Close(); } _currentDataId++; }
public XDoc WikiPopular( [DekiExtParam("max number of pages (default: 10)", true)] int? max ) { var popularPagesResponse = WikiApi(DekiContext.Current.Deki.Self.At("pages", "popular").With("limit", max ?? 10), null); XDoc popular = new XDoc("html").Start("body").Start("div").Start("ol"); foreach(XDoc page in popularPagesResponse["page"]) { popular.Start("li") .Start("a") .Attr("href", page["uri.ui"].AsText) .Value(page["title"].AsText) .End() .Value(string.Format(" ({0} views)", page["metrics/metric.views"].AsText)) .End(); } popular.EndAll(); return popular; }