/// <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(PostModel 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) { 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 cronjob! Console.Error.WriteLine("WARNING: Couldn't get social share count for {0}: {1}", sharer.Name, ex); count = 0; } results.Add(sharer, count); } return results; }
/// <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(PostModel post, string url, string shortUrl) { foreach (var sharer in _socialShares) { yield return new KeyValuePair<ISocialNetwork, string>(sharer, sharer.GetShareUrl(post, url, shortUrl)); } }
/// <summary> /// Gets a 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 BlogPost(this IUrlHelper urlHelper, PostModel 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("View", "Blog", new { month = post.Date.Month.ToString("00"), year = post.Date.Year, slug = post.Slug, area = string.Empty }); }
/// <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(PostModel post, string url, string shortUrl) { return SHARE_URL + new QueryBuilder { {"url", url}, {"title", post.Title} }; }
/// <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(PostModel post) { // TODO: Remove hard-coded URL from here var urlApi = $"http://dan.cx/api/posts/{post.Id}/url"; using (var client = new WebClient()) { var rawResponse = client.DownloadString(urlApi); return JsonConvert.DeserializeObject<UrlResponse>(rawResponse); } }
/// <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(PostModel post, string url, string shortUrl) { return SHARE_URL + new QueryBuilder { {"mini", "true"}, {"url", url}, {"title", post.Title}, {"source", "Daniel15"}, }; }
/// <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(PostModel post, string url, string shortUrl) { return SHARE_URL + new QueryBuilder { {"text", post.Title}, {"original_referer", url}, {"url", shortUrl}, {"via", "Daniel15"}, {"related", "Daniel15"} }; }
/// <summary> /// Updates the social media sharing counts of the specified post /// </summary> /// <param name="post">Post to update</param> private void UpdatePost(PostModel 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); }
public void BlogPosts() { var post = new PostModel { 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(PostModel post, string url, string shortUrl) { var countUrl = COUNT_URL + new QueryBuilder { {"url", url}, }; using (var client = new WebClient()) { var rawResponse = client.DownloadString(countUrl); dynamic response = JObject.Parse(rawResponse); 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(PostModel 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 QueryBuilder { {"query", query} }; var xml = XDocument.Load(queryUrl); XNamespace ns = "http://api.facebook.com/1.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 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(PostModel post, string url, string shortUrl) { var apiUrl = API_COUNT_URL + new QueryBuilder { {"url", url} }; using (var client = new WebClient()) { var responseText = client.DownloadString(apiUrl); // 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(");", ""); dynamic response = JObject.Parse(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(PostModel post, string url, string shortUrl) { var total = 0; var apiUrl = API_URL + new QueryBuilder { {"url", url} }; using (var client = new WebClient()) { var rawData = client.DownloadString(apiUrl); dynamic data = JObject.Parse(rawData); 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 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(PostModel post, string url, string shortUrl) { // No longer supported :( // https://blog.twitter.com/2015/hard-decisions-for-a-sustainable-platform return 0; }
/// <summary> /// Gets the short URL for this blog post /// </summary> /// <param name="post">Blog post</param> /// <returns>The short URL</returns> private string ShortUrl(PostModel post) { return Url.Action(MVC.Blog.ShortUrl(_urlShortener.Shorten(post)), "http"); }
/// <summary> /// Gets the short URL for this blog post /// </summary> /// <param name="post">Blog post</param> /// <returns>The short URL</returns> public string Shorten(PostModel 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 IUrlHelper urlHelper, PostModel post) { return urlHelper.Absolute(urlHelper.BlogPost(post)); }
/// <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(PostModel 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> /// Gets the short URL for this blog post /// </summary> /// <param name="post">Blog post</param> /// <returns>The short URL</returns> private string ShortUrl(PostModel post) { return Url.Action("ShortUrl", "Blog", new { alias = _urlShortener.Shorten(post) }, Request.Scheme); }
/// <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(PostModel post, string currentUrl) { return currentUrl.Replace(post.Date.Year.ToString(), "blog/" + post.Date.Year); }