New Snippet New Snippet Recent Snippets Recent Snippets My Snippets My Snippets Web Code Search Snippets Search
Sign inor Register
Language: C#

Tweet parser / displayer

250 Views
Copy Code Show/Hide Line Numbers
   1:  private string username = "twitter-username";
   2:          private string password = "twitter-password";
   3:   
   4:          /// <summary>
   5:          /// Gets current tweet and returns JavaScript to display it
   6:          /// </summary>
   7:          /// <returns></returns>
   8:          private string CreateScript()
   9:          {
  10:              XmlNode xmlStatus = GetXml(string.Format("statuses/user_timeline/{0}.xml?count=1", username));
  11:              string script = FormatScript(xmlStatus);
  12:              return script;
  13:          }
  14:   
  15:          /// <summary>
  16:          /// Creates JavaScript for specified Tweet XML
  17:          /// </summary>
  18:          /// <param name="status">An XmlNode representing the data about a single tweet</param>
  19:          /// <returns></returns>
  20:          private string FormatScript(XmlNode status)
  21:          {
  22:              string markup = FormatMarkup(status);
  23:              markup = CleanMarkupForScript(markup);
  24:              string script = string.Format("document.getElementById('twitter').innerHTML += '{0}';", markup);
  25:              return script;
  26:          }
  27:   
  28:          /// <summary>
  29:          /// Escapes quotes in HTML to make JS-safe
  30:          /// </summary>
  31:          /// <param name="markup"></param>
  32:          /// <returns></returns>
  33:          private string CleanMarkupForScript(string markup)
  34:          {
  35:              markup = markup.Replace("\"", "\\\"");
  36:              markup = markup.Replace("'", "\\'");
  37:              return markup;
  38:          }
  39:   
  40:          /// <summary>
  41:          /// Creates an HTML representation of a tweet from the XML data specified
  42:          /// </summary>
  43:          /// <param name="status"></param>
  44:          /// <returns></returns>
  45:          private string FormatMarkup(XmlNode status)
  46:          {
  47:              string message = FormatMessage(status.SelectSingleNode("/statuses/status/text").InnerText);
  48:              string date = FormatDate(status.SelectSingleNode("/statuses/status/created_at").InnerText);
  49:              string id = status.SelectSingleNode("/statuses/status/id").InnerText;
  50:              string markup = string.Format("{0}<a class=\"date\" href=\"http://twitter.com/{1}/statuses/{2}\">&#8212; <span>{3}</span></a>",
  51:                  message,
  52:                  username,
  53:                  id,
  54:                  date);
  55:              return markup;
  56:          }
  57:   
  58:          /// <summary>
  59:          /// Creates a user-friendly datetime format given an RFC1123 date
  60:          /// (e.g. "Wed Jul 28 00:06:09 +0000 2009" -> "8:06 PM today")
  61:          /// </summary>
  62:          /// <param name="date"></param>
  63:          /// <returns></returns>
  64:          private string FormatDate(string date)
  65:          {
  66:              DateTime created = DateTime.ParseExact(date, "ddd MMM dd HH:mm:ss %K yyyy", CultureInfo.InvariantCulture.DateTimeFormat);
  67:              string tweetTime = created.ToString("h:mm tt");
  68:              string tweetDate = created.ToString(", d MMMM yyyy");
  69:              if(created.Day == DateTime.Today.Day && created.Month == DateTime.Today.Month && created.Year == DateTime.Today.Year)
  70:              {
  71:                  tweetDate = "today";
  72:              }
  73:              else if(created.Day == DateTime.Today.AddDays(-1).Day && created.Month == DateTime.Today.AddDays(-1).Month && created.Year == DateTime.Today.AddDays(-1).Year)
  74:              {
  75:                  tweetDate = "yesterday";
  76:              }
  77:              string dateString = string.Format("{0} {1}", tweetTime, tweetDate);
  78:              return dateString;
  79:          }
  80:   
  81:          /// <summary>
  82:          /// Converts the raw text of a tweet into rich HTML
  83:          /// </summary>
  84:          /// <param name="message"></param>
  85:          /// <returns></returns>
  86:          private string FormatMessage(string message)
  87:          {
  88:              message = HttpUtility.HtmlEncode(HttpUtility.HtmlDecode(message));
  89:              message = FormatFriends(message);
  90:              message = FormatUrls(message);
  91:              message = FormatHashtags(message);
  92:              message = FormatSalutation(message);
  93:              return message;
  94:          }
  95:   
  96:          /// <summary>
  97:          /// Formats tweets directed @ one or more users into
  98:          /// "To @user(s):"
  99:          /// </summary>
 100:          /// <param name="message"></param>
 101:          /// <returns></returns>
 102:          private string FormatSalutation(string message)
 103:          {
 104:              message = Regex.Replace(message, @"^(?<open><span[^>]*>)(?<friends>.+?)(?<close></span>)", "${open}To ${friends}:${close}", RegexOptions.Singleline | RegexOptions.IgnoreCase);
 105:              return message;
 106:          }
 107:   
 108:          /// <summary>
 109:          /// Converts instances of @user into &lt;a href="user"&gt;Real Name&lt;/a&gt;
 110:          /// </summary>
 111:          /// <param name="message"></param>
 112:          /// <returns></returns>
 113:          private string FormatFriends(string message)
 114:          {
 115:              MatchCollection friendSets = Regex.Matches(message, @"(?<friends>(@[A-Z0-9_]+(\s|\b))+)", RegexOptions.Singleline | RegexOptions.IgnoreCase);
 116:              foreach (Match match in friendSets)
 117:              {
 118:                  StringBuilder friendSet = new StringBuilder();
 119:                  MatchCollection friends = Regex.Matches(match.Groups["friends"].Value, "@(?<friend>[A-Za-z0-9_]+)");
 120:                  for (int i = 0; i < friends.Count; i++)
 121:                  {
 122:                      string friendLink = GetUserLink(friends[i].Groups["friend"].Value);
 123:                      if (i == 0)
 124:                      {
 125:                          friendSet.AppendFormat("<span class=\\\"salutation\\\">{0}", friendLink);
 126:                      }
 127:                      else
 128:                      {
 129:                          friendSet.AppendFormat(", {0}", friendLink);
 130:                      }
 131:                  }
 132:                  friendSet.Append("</span> ");
 133:   
 134:                  message = message.Replace(match.Value, friendSet.ToString());
 135:              }
 136:              return message;
 137:          }
 138:   
 139:          /// <summary>
 140:          /// Links URLs
 141:          /// </summary>
 142:          /// <param name="message"></param>
 143:          /// <returns></returns>
 144:          private string FormatUrls(string message)
 145:          {
 146:              MatchCollection linkMatches = Regex.Matches(message, @"(?<!<a[^>]*)(?<link>[A-Z]+://[^\s]+)", RegexOptions.Singleline | RegexOptions.IgnoreCase);
 147:              foreach (Match match in linkMatches)
 148:              {
 149:                  if (match.Success)
 150:                  {
 151:                      string link = match.Groups["link"].Value;
 152:                      message = Regex.Replace(message, link, string.Format("<a href=\"{0}\">{1}</a>", link, TruncateString(link, 16)));
 153:                  }
 154:              }
 155:              return message;
 156:          }
 157:   
 158:          /// <summary>
 159:          /// Links Hashtags
 160:          /// </summary>
 161:          /// <param name="message"></param>
 162:          /// <returns></returns>
 163:          private string FormatHashtags(string message)
 164:          {
 165:              MatchCollection hashTagMatches = Regex.Matches(message, @"(?<!://[^\s]+)#(?<hashtag>[^\s]+)", RegexOptions.Singleline | RegexOptions.IgnoreCase);
 166:              foreach (Match match in hashTagMatches)
 167:              {
 168:                  if (match.Success)
 169:                  {
 170:                      string hashTag = match.Groups["hashtag"].Value;
 171:                      message = Regex.Replace(message, "#" + hashTag, string.Format("<a href=\"http://twitter.com/#search?q=%23{0}\">#{0}</a>", hashTag));
 172:                  }
 173:              }
 174:              return message;
 175:          }
 176:   
 177:          /// <summary>
 178:          /// Trims strings longer than 16 characters and appends an elipses if necessary
 179:          /// </summary>
 180:          /// <param name="input"></param>
 181:          /// <param name="length"></param>
 182:          /// <returns></returns>
 183:          private string TruncateString(string input, int length)
 184:          {
 185:              if (input.Length > 16)
 186:              {
 187:                  input = input.Substring(0, 16) + "&#8230;";
 188:              }
 189:              return input;
 190:          }
 191:   
 192:          /// <summary>
 193:          /// Fetches data for the specified user
 194:          /// </summary>
 195:          /// <param name="name"></param>
 196:          /// <returns></returns>
 197:          private string GetUserLink(string name)
 198:          {
 199:              string firstName = GetXml(string.Format("users/show/{0}.xml", name)).SelectSingleNode("/user/name").InnerText.Split(' ')[0];
 200:              return string.Format("<a href=\"http://twitter.com/{0}\">{1}</a>", name, firstName);
 201:          }
 202:   
 203:          /// <summary>
 204:          /// Generic Twitter API data fetch
 205:          /// </summary>
 206:          /// <param name="uri"></param>
 207:          /// <returns></returns>
 208:          private XmlDocument GetXml(string uri)
 209:          {
 210:              uri = "http://twitter.com/" + uri;
 211:              HttpWebRequest request = WebRequest.Create(uri) as HttpWebRequest;
 212:              request.Credentials = new NetworkCredential(username, password);
 213:              request.Timeout = 1500;
 214:              using (WebResponse response = request.GetResponse())
 215:              {
 216:                  XmlDocument xmlReturn = new XmlDocument();
 217:                  xmlReturn.Load(response.GetResponseStream());
 218:                  response.Close();
 219:                  return xmlReturn;
 220:              }
 221:          }
by Rex
  July 28, 2009 @ 7:50pm
Tags:
Comment:
Takes a tweet like:
"@user1 @user2 check out this cool link I got from @user3: http://url.com/page.htm#anchor #coollinks"
And turns it into:
<span class="salutation">To <a href="http://twitter.com/user1">Real Name</a>, <a href="http://twitter.com/user2">Real Name</a>: </span> check out this cool link I got from <span class="salutation"><a href="http://www.twitter.com/user3">Real Name</a></span>: <a href="http://site.com/page.htm#anchor">http://site.com/...</a> <a href="http://twitter.com/#search?q=%23coollinks">#coollinks</a>

Add a comment


Report Abuse
brought to you by:
West Wind Techologies


If you find this site useful and use it frequently please consider making a donation to support this free service.
Donate