/*public NginxWebCache(UrlHelper urlHelper) * { * _urlHelper = urlHelper; * }*/ /// <summary> /// Clear the cache for this blog post /// </summary> /// <param name="post">The blog post</param> public void ClearCache(PostSummaryModel post) { ClearCache(_urlHelper.BlogPostAbsolute(post)); ClearCache(_urlHelper.ActionAbsolute(MVC.Site.Index())); ClearCache(_urlHelper.ActionAbsolute(MVC.Blog.Index())); // TODO: Clear tags and categories if they're ever cached }
/// <summary> /// Gets the URL to share this post on all available social networks /// </summary> /// <param name="post">The blog post</param> /// <param name="url">Full URL to this post</param> /// <param name="shortUrl">Short URL to this post</param> /// <returns>Sharing URLs for this post</returns> public IEnumerable <KeyValuePair <ISocialNetwork, string> > ShareUrls(PostSummaryModel post, string url, string shortUrl) { foreach (var sharer in _socialShares) { yield return(new KeyValuePair <ISocialNetwork, string>(sharer, sharer.GetShareUrl(post, url, shortUrl))); } }
/// <summary> /// Gets the number of times this URL has been shared on this social network. /// </summary> /// <param name="post">The blog post</param> /// <param name="url">Full URL to this post</param> /// <param name="shortUrl">Short URL to this post</param> /// <returns>Share count for this post</returns> public IDictionary <ISocialNetwork, int> ShareCounts(PostSummaryModel post, string url, string shortUrl) { IDictionary <ISocialNetwork, int> results = new Dictionary <ISocialNetwork, int>(_socialShares.Count); var legacyUrl = GetLegacyUrl(post, url); foreach (var sharer in _socialShares) { using (MiniProfiler.Current.Step("Sharing count for " + sharer.Name)) { int count; try { count = sharer.GetShareCount(post, url, shortUrl); count += sharer.GetShareCount(post, legacyUrl, string.Empty); } catch (Exception ex) { // If an error occured, just set the count to 0 and log it. // These aren't overly important - They shouldn't crash the page! // TODO: Figure out how to use ELMAH outside of websites //Elmah.ErrorSignal.FromCurrentContext().Raise(new Exception("Couldn't get social share count for " + sharer.Name, ex)); Console.Error.WriteLine("WARNING: Couldn't get social share count for {0}: {1}", sharer.Name, ex); count = 0; } results.Add(sharer, count); } } return(results); }
public void OnGet() { bool PostFilter(Post p) => p.IsPublic; bool DeletedPostFilter(Post p) => !p.IsDeleted; var postModels = _dataStore.GetAllPosts().Where(PostFilter).Where(DeletedPostFilter); var posts = postModels as Post[] ?? postModels.ToArray(); CurrentPost = posts.Select(p => new PostSummaryModel { Id = p.Id, Slug = p.Slug, Title = p.Title, Excerpt = p.Excerpt, PublishTime = p.PubDate, CommentCount = p.Comments.Count(c => c.IsPublic), }).Take(1).FirstOrDefault(); NextPost = posts.Select(p => new PostSummaryModel { Id = p.Id, Slug = p.Slug, Title = p.Title, Excerpt = p.Excerpt, PublishTime = p.PubDate, CommentCount = p.Comments.Count(c => c.IsPublic), }).Skip(1).Take(1).FirstOrDefault(); PostSummaries = posts.Select(p => new PostSummaryModel { Id = p.Id, Slug = p.Slug, Title = p.Title, Excerpt = p.Excerpt, PublishTime = p.PubDate, CommentCount = p.Comments.Count(c => c.IsPublic), }).Skip(2).Take(5); }
/// <summary> /// Set the tags this blog post is tagged with /// </summary> /// <param name="post">The post</param> /// <param name="tagIds">Tag IDs</param> public void SetTags(PostSummaryModel post, IEnumerable <int> tagIds) { // Find all the currently selected tags var current = Connection .Select <PostTagModel>(x => x.PostId == post.Id) .Select(x => x.TagId) .ToList(); // Remove items that are in the current list but NOT in the new list var toRemove = current.Except(tagIds).ToList(); if (toRemove.Count > 0) { Connection.Delete <PostTagModel>("post_id = {0} AND tag_ids IN ({1})".Params(post.Id, toRemove.SqlInValues())); } // Add items that are in the new list but NOT in the current list var toAdd = tagIds.Except(current).ToList(); if (toAdd.Count > 0) { Connection.InsertAll(toAdd.Select(tagId => new PostTagModel { PostId = post.Id, TagId = tagId })); } }
/// <summary> /// Gets the number of times this URL has been shared on this social network. /// </summary> /// <param name="post">The blog post</param> /// <param name="url">Full URL to this post</param> /// <param name="shortUrl">Short URL to this post</param> /// <returns>Share count for this post</returns> public int GetShareCount(PostSummaryModel post, string url, string shortUrl) { // Get the count using FQL. Returns *both* like count and share count. var query = string.Format(LINK_QUERY, url); var queryUrl = QUERY_URL + "?" + new Dictionary <string, object> { { "query", query } }.ToQueryString(); var xml = XDocument.Load(queryUrl); XNamespace ns = "http://api.facebook.com/1.0/"; if (xml.Root == null) { return(0); } var linkStat = xml.Root.Element(ns + "link_stat"); if (linkStat == null) { return(0); } var totalCount = linkStat.Element(ns + "total_count"); return(totalCount == null ? 0 : Convert.ToInt32(totalCount.Value)); }
/// <summary> /// Gets the URL to the specified blog post /// </summary> /// <param name="post">Blog post to get URL of</param> /// <returns>URL of the blog post</returns> private UrlResponse GetBlogUrl(PostSummaryModel post) { // TODO: Remove hard-coded URL from here var urlApi = string.Format("http://dan.cx/api/posts/{0}/url", post.Id); return(urlApi.GetJsonFromUrl().FromJson <UrlResponse>()); }
/// <summary> /// Gets a URL to edit the specified blog post /// </summary> /// <param name="urlHelper">The URL helper.</param> /// <param name="post">Blog post to link to</param> /// <returns>URL to edit this blog post</returns> public static string BlogPostEdit(this UrlHelper urlHelper, PostSummaryModel post) { // Post date needs to be padded with a 0 (eg. "01" for January) - T4MVC doesn't work in this // case because it's strongly-typed (can't pass a string for an int param) //return urlHelper.Action(MVC.Blog.View(post.Date.Month, post.Date.Year, post.Slug)); return(urlHelper.Action("Edit", "Blog", new { area = "Admin", month = post.Date.Month.ToString("00"), year = post.Date.Year, slug = post.Slug })); }
/// <summary> /// Gets the URL to share this post on this social network. /// </summary> /// <param name="post">The blog post</param> /// <param name="url">Full URL to this post</param> /// <param name="shortUrl">Short URL to this post</param> /// <returns>Sharing URL for this post</returns> public string GetShareUrl(PostSummaryModel post, string url, string shortUrl) { return(SHARE_URL + "?" + new Dictionary <string, object> { { "u", url }, { "t", post.Title }, }.ToQueryString()); }
/// <summary> /// Gets the tags for the specified blog post /// </summary> /// <param name="post">Blog post</param> /// <returns>Tags for this blog post</returns> public IList <TagModel> TagsForPost(PostSummaryModel post) { return(Connection.Select <TagModel>(@" SELECT blog_tags.id, blog_tags.title, blog_tags.slug FROM blog_post_tags INNER JOIN blog_tags ON blog_tags.id = blog_post_tags.tag_id WHERE blog_post_tags.post_id = {0} ORDER BY blog_tags.title" , post.Id)); }
/// <summary> /// Gets the URL to share this post on this social network. /// </summary> /// <param name="post">The blog post</param> /// <param name="url">Full URL to this post</param> /// <param name="shortUrl">Short URL to this post</param> /// <returns>Sharing URL for this post</returns> public string GetShareUrl(PostSummaryModel post, string url, string shortUrl) { return(SHARE_URL + "?" + new Dictionary <string, object> { { "mini", "true" }, { "url", url }, { "title", post.Title }, { "source", "Daniel15" }, }.ToQueryString()); }
/// <summary> /// Gets the URL to share this post on this social network. /// </summary> /// <param name="post">The blog post</param> /// <param name="url">Full URL to this post</param> /// <param name="shortUrl">Short URL to this post</param> /// <returns>Sharing URL for this post</returns> public string GetShareUrl(PostSummaryModel post, string url, string shortUrl) { return(SHARE_URL + "?" + new Dictionary <string, object> { { "text", post.Title }, { "original_referer", url }, { "url", shortUrl }, { "via", "Daniel15" }, { "related", "Daniel15" } }.ToQueryString()); }
/// <summary> /// Gets the categories for the specified blog post /// </summary> /// <param name="post">Blog post</param> /// <returns>Categories for this blog post</returns> public IList <CategoryModel> CategoriesForPost(PostSummaryModel post) { return(Connection.Select <CategoryModel>(@" SELECT blog_categories.id, blog_categories.title, blog_categories.slug, blog_categories.parent_category_id, parent.slug AS parent_slug FROM blog_post_categories INNER JOIN blog_categories ON blog_categories.id = blog_post_categories.category_id LEFT OUTER JOIN blog_categories AS parent ON parent.id = blog_categories.parent_category_id WHERE blog_post_categories.post_id = {0} ORDER BY blog_categories.title" , post.Id)); }
/// <summary> /// Gets the social network URLs and share counts for the specified post /// </summary> /// <param name="post">Post to get statistics on</param> /// <returns>Social network URLs and share counts for the post</returns> private IEnumerable <PostSocialNetworkModel> GetSocialNetworks(PostSummaryModel post) { var shareCounts = post.ShareCounts ?? new Dictionary <string, int>(); var socialNetworks = _socialManager.ShareUrls(post, Url.BlogPostAbsolute(post), ShortUrl(post)); return(socialNetworks.Select(x => new PostSocialNetworkModel { SocialNetwork = x.Key, Url = x.Value, Count = shareCounts.ContainsKey(x.Key.Id) ? shareCounts[x.Key.Id] : 0 })); }
/// <summary> /// Saves this entity to the database. First tries to load the entity to check if it exists /// If it exists, does an update. /// </summary> /// <param name="entity">The entity to save</param> public void Save(PostSummaryModel entity) { // Assume it's new if the ID isn't set yet var isNew = entity.Id == 0; Connection.Save(entity); // Update the ID if (isNew) { entity.Id = Convert.ToInt32(Connection.GetLastInsertId()); } }
/// <summary> /// Updates the social media sharing counts of the specified post /// </summary> /// <param name="post">Post to update</param> private void UpdatePost(PostSummaryModel post) { // TODO: Move this elsewhere (Business Layer) var urls = GetBlogUrl(post); var counts = _socialManager.ShareCounts(post, urls.Url, urls.ShortUrl).ToDictionary(x => x.Key.Id, x => x.Value); post.ShareCounts = counts; _blogRepository.Save(post); var total = counts.Sum(x => x.Value); Console.WriteLine("Updated '{0}' ({1} shares in total)", post.Title, total); }
/// <summary> /// Gets the number of times this URL has been shared on this social network. /// </summary> /// <param name="post">The blog post</param> /// <param name="url">Full URL to this post</param> /// <param name="shortUrl">Short URL to this post</param> /// <returns>Share count for this post</returns> public int GetShareCount(PostSummaryModel post, string url, string shortUrl) { var countUrl = COUNT_URL + "?" + new Dictionary <string, object> { { "url", url }, }.ToQueryString(); var response = Json.Decode(countUrl.GetJsonFromUrl()); if (response == null || response.count == null) { return(0); } return(Convert.ToInt32(response.count)); }
public void BlogPosts() { var post = new PostSummaryModel { Id = 123, Date = new DateTime(2012, 1, 1), Title = "Test Post", Slug = "test-post", Published = true, }; var mocks = new Mocks(); Assert.AreEqual("/blog/2012/01/test-post", BlogUrlHelperExtensions.BlogPost(mocks.UrlHelper, post)); Assert.AreEqual("/blog/2012/01/test-post/edit", BlogUrlHelperExtensions.BlogPostEdit(mocks.UrlHelper, post)); Assert.AreEqual("http://localhost/blog/2012/01/test-post", BlogUrlHelperExtensions.BlogPostAbsolute(mocks.UrlHelper, post)); }
/// <summary> /// Gets the number of times this URL has been shared on this social network. /// </summary> /// <param name="post">The blog post</param> /// <param name="url">Full URL to this post</param> /// <param name="shortUrl">Short URL to this post</param> /// <returns>Share count for this post</returns> public int GetShareCount(PostSummaryModel post, string url, string shortUrl) { var apiUrl = API_COUNT_URL + "?" + new Dictionary <string, object> { { "url", url } }.ToQueryString(); var responseText = apiUrl.GetJsonFromUrl(); // Ugly hack to get JSON data from the JavaScript method call // This API call is usually used client-side via JSONP... responseText = responseText.Replace("IN.Tags.Share.handleCount(", "").Replace(");", ""); var response = Json.Decode(responseText); if (response == null || response.count == null) { return(0); } return(Convert.ToInt32(response.count)); }
/// <summary> /// Gets the number of times this URL has been shared on this social network. /// </summary> /// <param name="post">The blog post</param> /// <param name="url">Full URL to this post</param> /// <param name="shortUrl">Short URL to this post</param> /// <returns>Share count for this post</returns> public int GetShareCount(PostSummaryModel post, string url, string shortUrl) { var total = 0; var apiUrl = API_URL + "?" + new Dictionary <string, object> { { "url", url } }.ToQueryString(); var data = Json.Decode(apiUrl.GetJsonFromUrl()); if (data == null || data.data == null || data.data.children == null) { return(0); } // Need to add up the points in every submission of this URL foreach (var child in data.data.children) { total += Convert.ToInt32(child.data.score); } return(total); }
/// <summary> /// Gets a legacy URL to the specified blog post (containing /blog/ at the start) /// </summary> /// <param name="post">Blog post to link to</param> /// <param name="currentUrl">Current URL to the blog post</param> /// <returns>Legacy URL to this blog post</returns> private string GetLegacyUrl(PostSummaryModel post, string currentUrl) { return(currentUrl.Replace(post.Date.Year.ToString(), "blog/" + post.Date.Year)); }
/// <summary> /// Clear the cache for this blog post /// </summary> /// <param name="post">The blog post</param> public void ClearCache(PostSummaryModel post) { }
/// <summary> /// Gets the short URL for this blog post /// </summary> /// <param name="post">Blog post</param> /// <returns>The short URL</returns> public string Shorten(PostSummaryModel post) { return(Shorten(post.Id)); }
/// <summary> /// Gets an absolute URL to the specified blog post /// </summary> /// <param name="urlHelper">The URL helper.</param> /// <param name="post">Blog post to link to</param> /// <returns>URL to this blog post</returns> public static string BlogPostAbsolute(this UrlHelper urlHelper, PostSummaryModel post) { return(urlHelper.Absolute(urlHelper.BlogPost(post))); }
/// <summary> /// Gets the short URL for this blog post /// </summary> /// <param name="post">Blog post</param> /// <returns>The short URL</returns> private string ShortUrl(PostSummaryModel post) { return(Url.Action(MVC.Blog.ShortUrl(_urlShortener.Shorten(post)), "http")); }