Skip to content

Instantly share code, notes, and snippets.

@jonathanread
Last active August 29, 2015 14:03
Show Gist options
  • Save jonathanread/3add49d436dba1fb8fa7 to your computer and use it in GitHub Desktop.
Save jonathanread/3add49d436dba1fb8fa7 to your computer and use it in GitHub Desktop.
Hubspot post MVC widget
@model SitefinityWebApp.Mvc.Models.HubSpotPostsModel
<div class="sf_cols posts">
@{int column = 1;}
@foreach (var item in Model.Posts)
{
string colOut = "sf_3cols_" + column + "_3" + ((column == 2) ? "4" : "3");
string colIn = "sf_3cols_" + column + "in_3" + ((column == 2) ? "4" : "3");
<div class="sf_colsOut @colOut">
<div class="sf_colsIn @colIn">
<section class="post">
<a class="image" href="@item.Url" target="_blank" style="background-image:url('@item.ImageSource')"></a>
<a href="@item.Url" target="_blank">
<h1 class="postTitle">
@item.Title
</h1>
</a>
<p class="postInfo">
<span class="author-publish">by <a href="http://blog.apterainc.com/?Author=@item.AuthorDisplayName.Replace(" ", "+")" target="_blank">@item.AuthorDisplayName</a> | @item.PublishDate</span>
<a href="@item.Url" target="_blank">
<span class="description">@item.MetaDescription</span>
</a>
</p>
</section>
</div>
</div>
column++;
}
</div>
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Dynamic;
using System.Linq;
using System.Text;
using System.Web.Script.Serialization;
namespace Aptera.Sitefinity.Models
{
public sealed class DynamicJsonConverter : JavaScriptConverter
{
public override object Deserialize(IDictionary<string, object> dictionary, Type type, JavaScriptSerializer serializer)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
return type == typeof(object) ? new DynamicJsonObject(dictionary) : null;
}
public override IDictionary<string, object> Serialize(object obj, JavaScriptSerializer serializer)
{
throw new NotImplementedException();
}
public override IEnumerable<Type> SupportedTypes
{
get { return new ReadOnlyCollection<Type>(new List<Type>(new[] { typeof(object) })); }
}
#region Nested type: DynamicJsonObject
private sealed class DynamicJsonObject : DynamicObject
{
private readonly IDictionary<string, object> _dictionary;
public DynamicJsonObject(IDictionary<string, object> dictionary)
{
if (dictionary == null)
throw new ArgumentNullException("dictionary");
_dictionary = dictionary;
}
public override string ToString()
{
var sb = new StringBuilder("{");
ToString(sb);
return sb.ToString();
}
private void ToString(StringBuilder sb)
{
var firstInDictionary = true;
foreach (var pair in _dictionary)
{
if (!firstInDictionary)
sb.Append(",");
firstInDictionary = false;
var value = pair.Value;
var name = pair.Key;
if (value is string)
{
sb.AppendFormat("{0}:\"{1}\"", name, value);
}
else if (value is IDictionary<string, object>)
{
new DynamicJsonObject((IDictionary<string, object>)value).ToString(sb);
}
else if (value is ArrayList)
{
sb.Append(name + ":[");
var firstInArray = true;
foreach (var arrayValue in (ArrayList)value)
{
if (!firstInArray)
sb.Append(",");
firstInArray = false;
if (arrayValue is IDictionary<string, object>)
new DynamicJsonObject((IDictionary<string, object>)arrayValue).ToString(sb);
else if (arrayValue is string)
sb.AppendFormat("\"{0}\"", arrayValue);
else
sb.AppendFormat("{0}", arrayValue);
}
sb.Append("]");
}
else
{
sb.AppendFormat("{0}:{1}", name, value);
}
}
sb.Append("}");
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
if (!_dictionary.TryGetValue(binder.Name, out result))
{
// return null to avoid exception. caller can check for null this way...
result = null;
return true;
}
result = WrapResultObject(result);
return true;
}
public override bool TryGetIndex(GetIndexBinder binder, object[] indexes, out object result)
{
if (indexes.Length == 1 && indexes[0] != null)
{
if (!_dictionary.TryGetValue(indexes[0].ToString(), out result))
{
// return null to avoid exception. caller can check for null this way...
result = null;
return true;
}
result = WrapResultObject(result);
return true;
}
return base.TryGetIndex(binder, indexes, out result);
}
private static object WrapResultObject(object result)
{
var dictionary = result as IDictionary<string, object>;
if (dictionary != null)
return new DynamicJsonObject(dictionary);
var arrayList = result as ArrayList;
if (arrayList != null && arrayList.Count > 0)
{
return arrayList[0] is IDictionary<string, object>
? new List<object>(arrayList.Cast<IDictionary<string, object>>().Select(x => new DynamicJsonObject(x)))
: new List<object>(arrayList.Cast<object>());
}
return result;
}
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
namespace Aptera.Sitefinity.Models
{
public class HubSpotPost
{
private String _imgSrc = "";
private String _comments = "";
private String _publishDate = "";
public String Title { get; set; }
public String Guid { get; set; }
public String Body { get; set; }
public Boolean Draft { get; set; }
public String AuthorDisplayName {get; set;}
public String MetaDescription { get; set; }
public String PublishTimestamp { get; set; }
public String PublishDate
{
get { return _publishDate; }
set
{
DateTime origin = new DateTime(1970, 1, 1, 0, 0, 0, 0);
double ticks;
if (double.TryParse(value, out ticks))
{
_publishDate = origin.AddMilliseconds(ticks).ToLocalTime().ToString("MMM dd, yyyy");
}
else
{
_publishDate = DateTime.UtcNow.ToString();
}
}
}
public String Comments
{
get { return _comments; }
set
{
_comments = GetCommentsCount(value);
}
}
private string GetCommentsCount(string value)
{
string count = "0";
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.hubapi.com/blog/v1/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
HttpResponseMessage response = client.GetAsync(string.Format("posts/{0}/comments.json?hapikey=a45ec77f-66e2-437e-b3f9-e772b622d36b",value)).Result;
if (response.IsSuccessStatusCode)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
serializer.RegisterConverters(new[] { new DynamicJsonConverter() });
dynamic i = serializer.Deserialize(response.Content.ReadAsStringAsync().Result, typeof(object));
count = i.Length.ToString();
}
}
return count;
}
public String Url { get; set; }
public String ImageSource
{
get { return _imgSrc; }
set { _imgSrc = GetImageSrc(value); }
}
public List<String> Tags { get; set; }
private static string GetImageSrc(string data)
{
string source = "";
HtmlAgilityPack.HtmlDocument doc = new HtmlAgilityPack.HtmlDocument();
if (!string.IsNullOrWhiteSpace(data))
{
doc.LoadHtml(data);
if (doc != null)
{
if(doc.DocumentNode.SelectSingleNode("//img") != null)
{
source = doc.DocumentNode.SelectSingleNode("//img").Attributes["src"].Value;
if(source.IndexOf("http://blog.apterainc.com") < 0)
{
source = "http://blog.apterainc.com" +source;
}
}
}
}
return source;
}
}
}
using System;
using System.ComponentModel;
using System.Linq;
using System.Web.Mvc;
using Telerik.Sitefinity.Mvc;
using SitefinityWebApp.Mvc.Models;
using System.Net;
using System.IO;
using System.Xml.Linq;
using Aptera.Sitefinity.Models;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Web.Script.Serialization;
using System.Collections.Generic;
namespace SitefinityWebApp.Mvc.Controllers
{
[ControllerToolboxItem(Name = "HubSpotPosts", Title = "HubSpotPosts", SectionName = "MvcWidgets")]
public class HubSpotPostsController : Controller
{
/// <summary>
/// This is the default Action.
/// </summary>
[OutputCache(CacheProfile="CacheHubSpot")]
public ActionResult Index()
{
var model = new HubSpotPostsModel();
model.Posts = GetBlogPosts().Select(p => new HubSpotPost() {
Title = p.Title,
Body = p.Body,
AuthorDisplayName = p.AuthorDisplayName,
PublishDate = p.PublishTimestamp,
MetaDescription = p.MetaDescription,
ImageSource = p.Body,
Draft = p.Draft,
Guid = p.Guid,
Tags = p.Tags,
Url = p.Url
}).Take(3);
return View("Default", model);
}
private static IEnumerable<HubSpotPost> GetBlogPosts(int skip = 0)
{
IEnumerable<HubSpotPost> posts;
using (var client = new HttpClient())
{
client.BaseAddress = new Uri("https://api.hubapi.com/blog/v1/");
client.DefaultRequestHeaders.Accept.Clear();
client.DefaultRequestHeaders.Accept.Add(new MediaTypeWithQualityHeaderValue("application/json"));
// New code:
HttpResponseMessage response = client.GetAsync(string.Format("d2d4d48e-3653-4958-b0ff-2e43ac3a8539/posts.json?hapikey=a45ec77f-66e2-437e-b3f9-e772b622d36b&offset={0}", skip)).Result;
if (response.IsSuccessStatusCode)
{
JavaScriptSerializer serializer = new JavaScriptSerializer();
posts = serializer.Deserialize<IEnumerable<HubSpotPost>>(response.Content.ReadAsStringAsync().Result).Where(p => !p.Draft);
if (posts.Count() < 5)
{
var take = 5 - posts.Count();
var ps = GetBlogPosts(10).Where(p => !p.Draft).Take(take);
posts.Union(ps);
if (posts.Count() < 5)
{
var take2 = 5 - posts.Count();
var ps2 = GetBlogPosts(10).Where(p => !p.Draft).Take(take2);
posts.Union(ps2);
return posts.Take(5);
}
return posts.Take(5);
}
return posts.Take(5);
}
}
return null;
}
}
}
using Aptera.Sitefinity.Models;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
namespace SitefinityWebApp.Mvc.Models
{
public class HubSpotPostsModel
{
public IEnumerable<HubSpotPost> Posts { get; set; }
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment