/// <summary> /// Gets the Site Content /// </summary> /// <param name="ctx"></param> /// <returns></returns> public static IContent GetSiteContent(NancyContext ctx) { if (ctx.IsAdminUser()) { return(ContentModule.GetPage(ctx.GetSiteDatabase(), "/", true)); } return(_SiteContent); }
/// <summary> /// Get Page View Count /// </summary> /// <param name="arg"></param> /// <returns></returns> private dynamic GetPageViewCount(dynamic arg) { var table = (string)arg.table; var id = (int)arg.id; // invalid data type, also prevent SQL Injection attack when we replace string if (this.SiteDatabase.DataType.FromName(table) == null) { return(400); } this.Context.Items["NoCookie"] = true; var count = ContentModule.GetPageViewCount(this.SiteDatabase, this.CurrentSite, table, id); return(count.ToString()); }
/// <summary> /// Get content of given url and optionally creates the content /// </summary> /// <param name="url"></param> /// <returns></returns> public static Page GetPage(NancyBlackDatabase db, string url, bool create = false) { if (url.StartsWith("/") == false) { url = "/" + url; } url = url.ToLowerInvariant(); var page = db.Query <Page>() .Where(p => p.Url == url) .FirstOrDefault(); if (page == null && create == true) { page = ContentModule.CreatePage(db, url); } return(page); }
protected dynamic HandleContentRequest(dynamic arg) { var url = (string)arg.path; if (url == null) { url = "/"; } if (url.StartsWith("/") == false) { url = "/" + url; } url = url.ToLowerInvariant(); // invalid admin links if (url.StartsWith("/admin", StringComparison.InvariantCultureIgnoreCase)) { return(404); } // invalid system links if (url.StartsWith("/_", StringComparison.InvariantCultureIgnoreCase)) { return(404); } // invalid table get request if (url.StartsWith("/tables", StringComparison.InvariantCultureIgnoreCase)) { return(404); } IContent requestedContent = null; // see if the url is collection request or content request var parts = url.Split('/'); url = ContentModule.RewriteUrl(this.Context, arg, url); if (parts.Length > 2 && parts[1].EndsWith("s")) { // seems to be a collection var typeName = parts[1].Substring(0, parts[1].Length - 1); var datatype = this.SiteDatabase.DataType.FromName(typeName); var result = this.SiteDatabase.Query(typeName, string.Format("Url eq '{0}'", url)).FirstOrDefault(); if (result != null) { // convert it to IContent if (result is IContent) { requestedContent = result as IContent; requestedContent = ContentModule.MapPage(this.Context, requestedContent); } else { requestedContent = JObject.FromObject(result).ToObject <Page>(); (requestedContent as Page).SetTableName(typeName); } } } // if it is not table, use content table instead if (requestedContent == null) { requestedContent = ContentModule.GetPage(this.SiteDatabase, url); } if (requestedContent == null) { // won't generate path which contains extension // as user might be requesting file if (string.IsNullOrEmpty(Path.GetExtension(url)) == false) { return(404); } // only admin can generate if (this.CurrentUser.HasClaim("admin") == false) { return(404); } requestedContent = ContentModule.CreatePage(this.SiteDatabase, url); } if (string.IsNullOrEmpty((string)requestedContent.RequiredClaims) == false) { var required = ((string)requestedContent.RequiredClaims).Split(','); var user = this.Context.CurrentUser as NcbUser; if (required.Any(c => user.HasClaim(c)) == false) { // user does not have any required claims if (this.Context.CurrentUser == NcbUser.Anonymous) { return(401); } return(403); } } this.SiteDatabase.DelayedInsert(new PageView() { ContentId = requestedContent.Id, TableName = requestedContent.TableName, Request = new { QueryString = this.Request.Url.Query, Path = this.Request.Url.Path, UserIP = this.Request.Headers.Host, Referer = this.Request.Headers.Referrer, UserAgent = this.Request.Headers.UserAgent } }); if (string.IsNullOrEmpty(requestedContent.Layout)) { requestedContent.Layout = "Content"; } this.GenerateLayoutPage(this.CurrentSite, requestedContent); ContentModule.ProcessPage(this.Context, requestedContent); return(View[(string)requestedContent.Layout, new StandardModel(this, requestedContent, requestedContent)]); }
/// <summary> /// Read Content from given URL in arg /// </summary> /// <param name="arg"></param> /// <param name="processContentPart">Whether to process the content</param> /// <returns></returns> protected dynamic HandleContentRequest(dynamic arg, bool processContentPart) { var url = (string)arg.path; if (url == null) { url = "/"; } if (url.StartsWith("/") == false) { url = "/" + url; } url = url.ToLowerInvariant(); // invalid admin links if (url.StartsWith("/admin", StringComparison.InvariantCultureIgnoreCase)) { return(404); } // invalid system links if (url.StartsWith("/_", StringComparison.InvariantCultureIgnoreCase)) { return(404); } // invalid table get request if (url.StartsWith("/tables", StringComparison.InvariantCultureIgnoreCase)) { return(404); } IContent requestedContent = null; // see if the url is collection request or content request var parts = url.Split('/'); url = ContentModule.RewriteUrl(this.Context, arg, url); var subSiteName = (string)this.Context.Items[ContextItems.SubSite]; // can be /products/product1 if (parts.Length > 2 && parts[1].EndsWith("s")) { // seems to be a collection var typeName = parts[1].Substring(0, parts[1].Length - 1); var datatype = this.SiteDatabase.DataType.FromName(typeName); var contentUrl = url; // edit url when using subsite example: convert "/products/..." to "/products/subSiteName/..." // for products, blogs (end with 's') and etc if (!string.IsNullOrEmpty(subSiteName)) { contentUrl = string.Join("/", "/" + parts[1], subSiteName); contentUrl = contentUrl + "/" + string.Join("/", parts.Skip(2).ToArray()); } var result = this.SiteDatabase.Query(typeName, string.Format("Url eq '{0}'", contentUrl)).FirstOrDefault(); if (result != null) { // convert it to IContent if (result is IContent) { requestedContent = result as IContent; requestedContent = ContentModule.MapPage(this.Context, requestedContent); } else { requestedContent = JObject.FromObject(result).ToObject <Page>(); (requestedContent as Page).SetTableName(typeName); } } } // change url to subsite url ex: /contact to /micronics.in.th/contact if (!string.IsNullOrEmpty(subSiteName)) { url = "/" + subSiteName + url; } // if it is not table, use content table instead if (requestedContent == null) { requestedContent = ContentModule.GetPage(this.SiteDatabase, url); } if (requestedContent == null) { // won't generate path which contains extension // as user might be requesting file if (string.IsNullOrEmpty(Path.GetExtension(url)) == false) { return(404); } // only admin can generate if (this.CurrentUser.HasClaim("admin") == false) { return(404); } requestedContent = ContentModule.CreatePage(this.SiteDatabase, url); } if (string.IsNullOrEmpty((string)requestedContent.RequiredClaims) == false) { var required = ((string)requestedContent.RequiredClaims).Split(','); var user = this.Context.CurrentUser as NcbUser; if (required.Any(c => user.HasClaim(c)) == false) { // user does not have any required claims if (this.Context.CurrentUser.UserName == NcbUser.Anonymous) { return(401); } return(403); } } string source = null; if (this.Request.Cookies.ContainsKey("source") == true) { source = this.Request.Cookies["source"]; } if (string.IsNullOrEmpty(requestedContent.Layout)) { requestedContent.Layout = "Content"; } this.GenerateLayoutPage(this.CurrentSite, requestedContent); ContentModule.ProcessPage(this.Context, requestedContent); this.SendPageView(requestedContent); if (processContentPart) { ContentModule.ProcessContentPart(this.Context, requestedContent); } return(requestedContent); }
/// <summary> /// Gets the Summary table /// </summary> /// <returns></returns> private CloudTable GetSummaryTable(bool cache = true) { return(ContentModule.GetSummaryTable(this.CurrentSite, cache)); }
/// <summary> /// Get Page View Count for given item in table /// </summary> /// <param name="db"></param> /// <param name="table"></param> /// <param name="id"></param> /// <returns></returns> public static long GetPageViewCount(NancyBlackDatabase db, dynamic siteSettings, string table, int id) { var key = "PageViewCount-" + table + id; object cached = MemoryCache.Default.Get(key); if (cached != null) { return((long)cached); } if (siteSettings.analytics == null) { dynamic result = db.Query (string.Format("SELECT COUNT(Id) as Hit FROM PageView WHERE ContentId = {0} AND TableName = '{1}'", id, table), new { Hit = 0 }).FirstOrDefault(); if (result == null) { result = 0; } MemoryCache.Default.Add(key, result, DateTimeOffset.Now.AddMinutes(10)); return(result); } else { var content = db.QueryAsDynamic(table, "Id eq " + id).FirstOrDefault(); if (content == null) { MemoryCache.Default.Add(key, 0, DateTimeOffset.Now.AddMinutes(10)); return(0); // wrong content } string url = content.Url; if (url == null) { MemoryCache.Default.Add(key, 0, DateTimeOffset.Now.AddMinutes(10)); return(0); // cannot get Url } if (url.Contains("/archive/")) { url = url.Replace("/archive/", "/"); } url = url.Replace('/', '-'); long pageViews = 0; lock (BaseModule.GetLockObject("PageViewSummary-" + url)) // ensure only one thread is working on calculation { // if multiple threads is locked - they will arrive here when lock is released // so check the cache again cached = MemoryCache.Default.Get(key); if (cached != null) { return((int)cached); } CloudTable summaryTable = ContentModule.GetSummaryTable(siteSettings); var queryString = TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, url), TableOperators.And, TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, url)); var query = new TableQuery <PageViewSummary>(); var result = summaryTable.ExecuteQuery <PageViewSummary>(query.Where(queryString)).FirstOrDefault(); if (result == null) { result = new PageViewSummary(); result.PageViews = 0; result.Path = url; result.PrepareForAzure(); result.Timestamp = DateTimeOffset.MinValue; summaryTable.Execute(TableOperation.InsertOrReplace(result)); } // find all pageview since the pageview summary timestamp var pvQueryString = TableQuery.CombineFilters( TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, url), TableOperators.And, TableQuery.GenerateFilterConditionForDate("Timestamp", QueryComparisons.GreaterThanOrEqual, result.Timestamp)); CloudTable rawTable = ContentModule.GetPageViewTable(siteSettings); var pageviewQuery = new TableQuery <PageView>(); var count = rawTable.ExecuteQuery <PageView>(pageviewQuery.Where(pvQueryString)).Count(); result.PageViews = result.PageViews + count; summaryTable.Execute(TableOperation.InsertOrReplace(result)); pageViews = result.PageViews; MemoryCache.Default.Add(key, pageViews, DateTimeOffset.Now.AddMinutes(10)); return(pageViews); } } }
/// <summary> /// Initialize things that can share between requests /// </summary> /// <param name="ctx"></param> public void GlobalInitialize(NancyContext ctx) { ContentModule._SiteContent = ContentModule.GetPage(ctx.GetSiteDatabase(), "/", true); ContentModule.ProcessContentPart(ctx, ContentModule._SiteContent); }
/// <summary> /// Gets the Theme Content /// </summary> /// <param name="ctx"></param> /// <returns></returns> public static IContent GetThemeContent(NancyContext ctx) { return(ContentModule.GetSiteContent(ctx)); }