Getting Twitter Avatar Via C# With 1.1 API

May 1 2013

If you know someone's Twitter handle and would like to display their twitter avatar on your website, here's some code to get the URL of their avatar.  First, you'll need to register at http://dev.twitter.com and acquire a ConsumerKey, ConsumerSecret, Token and TokenSecret -- now that Twitter supports application only authentication, there isn't any handshaking involved; you just need to craft up the right OAuthCredentials for a ProtectedResource, which the Hammock library does for you. Love that library: you can get it here: https://github.com/danielcrenna/hammock or grab it as a NuGet package: http://nuget.org/packages/Hammock

Here’s the code; nothing too fancy:

using System;
using Hammock;
using Hammock.Authentication.OAuth;
using Hammock.Web;
using Newtonsoft.Json.Linq;

namespace ExternalServices
{
    public class TwitterAvatarLookup : ITwitterAvatarLookup
    {
        const string ConsumerKey = "";
        const string ConsumerSecret = "";
        const string Token = "";
        const string TokenSecret = "";

        public string GetTwitterAvatarUrl(string twitterHandle)
        {
            string avatarUrl = string.Empty;
            var request = new RestRequest
            {
                Credentials = new OAuthCredentials
                {
                    Type = OAuthType.ProtectedResource,
                    SignatureMethod = OAuthSignatureMethod.HmacSha1,
                    ParameterHandling = OAuthParameterHandling.HttpAuthorizationHeader,
                    ConsumerKey = ConsumerKey,
                    ConsumerSecret = ConsumerSecret,
                    Token = Token,
                    TokenSecret = TokenSecret,
                }
            };
            request.Path =
                string.Format(
                    "https://api.twitter.com/1.1/users/lookup.json?screen_name={0}&include_entities=0&include_rts=0",
                    twitterHandle);

            request.Method = WebMethod.Get;
            RestClient client = new RestClient();
            try
            {
                RestResponse response = client.Request(request);
                JArray jArray = JArray.Parse(response.Content);
                avatarUrl = (string)jArray[0]["profile_image_url_https"];

            }
            catch (Exception)
            {
                return "default.png";
            }
            return avatarUrl;
        }

    }
}

If you know more than one handle whose avatar you need to get, the API supports passing multiple user handles; see https://dev.twitter.com/docs/api/1.1/get/users/lookup

Saving a PDFSharp PDF File To Azure Blob Storage

March 1 2013

Love the PDFSharp library. Here’s how I went about saving a PDF generated with that library to Azure blob storage:

const bool unicode = false;
const PdfFontEmbedding embedding = PdfFontEmbedding.Always;
PdfDocumentRenderer pdfRenderer = new PdfDocumentRenderer(unicode, embedding);
pdfRenderer.Document = document;
pdfRenderer.RenderDocument();
MemoryStream memStream = new MemoryStream();
pdfRenderer.PdfDocument.Save(memStream,false);

var client = new CloudBlobClient(new Uri("http://*.blob.core.windows.net", UriKind.Absolute),
new StorageCredentialsAccountAndKey("*",
"..."));

var container = client.GetContainerReference("temp");
memStream.Seek(0, SeekOrigin.Begin);
string filename = DateTime.Now.ToString().GetHashCode().ToString("x") + ".pdf";
var pdf = container.GetBlobReference(filename);
pdf.Properties.ContentType = "application/pdf";
pdf.UploadFromStream(memStream, new BlobRequestOptions { Timeout = TimeSpan.FromMinutes(10) });
memStream.Close();


The crux of the code is the line where pass false to the Save method of PdfDocument, which keeps the memory stream open. And, then, before giving that stream to the Azure SDK method, you need to rewind the stream to the beginning. Other than that, all pretty boilerplate.

Capture ClickOnce File Downloads With Event Tracking In Google Analytics

March 1 2013

This flummoxed me for a bit, so I figured I post it. If you wire the event up to an onClick handler as the docs suggest:

<a href="app.application" onClick="_gaq.push(['_trackEvent', 'ClickOnce', 
'Download']);">Play</a>

Your event will never fire. The trick is to add the target attribute and set it to _blank which opens a new tab in the browser and immediately closes it:

<a href="app.application" target="_blank" onClick="_gaq.push(['_trackEvent', 'ClickOnce',
'Download']);">Play</a>
 

Windows Azure Table Storage Emulator UpdateObject Error

January 21 2013

Was getting this:

<?xml version="1.0" encoding="utf-8" standalone="yes"?>
<error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata">
  <code>InvalidInput</code>
  <message xml:lang="en-US">One of the request inputs is not valid.</message>
</error>

When calling UpdateObject from the Azure SDK when using the table storage emulator. Turns out the emulator doesn’t exactly emulate as per MSDN documentation: http://msdn.microsoft.com/en-us/library/gg433135.aspx “The storage emulator does not support Insert-Or-Replace Entity or Insert-Or-Merge Entity, known as upsert features.”

So, to work around, I changed the code to delete then reinsert.  Or not. Turned out I had lots of concurrancy problems with doing a delete/insert which were resolved with the more transactional upsert. 

Sorting ListBlobs By LastModifiedUtc

December 3 2012

I had a list of JSON objects stored as individual blobs in Azure blob storage. I needed to get them out of blob storage sorted by last modified time and then reconstitute them as an array of JSON objects. Hit a few curiosities in writing this code, which someone else may benefit from. Without further ado, here’s the code:

            CloudBlobDirectory dir = eventContainer.GetDirectoryReference("http://---");
            SortedDictionary<DateTime, string> dictionary = new SortedDictionary<DateTime, string>();
            foreach (CloudBlob blob in dir.ListBlobs())
            {
                if (blob.Name == string.Format("{0}/$$$.$$$", "live")) continue;
                dictionary.Add(blob.Properties.LastModifiedUtc, blob.DownloadText());
            }
            StringBuilder json = new StringBuilder();
            json.Append("Callback([");
            foreach (string s in dictionary.Values)
            {
                json.Append(s);
                json.Append(",");
            }
            json.Remove(json.Length - 1, 1);
            json.Append("])");
            CloudBlob liveJson = dir.GetBlobReference("live.json");
            liveJson.Properties.CacheControl = cacheControl;
            liveJson.UploadText(json.ToString());

Okay, so what is going on here?

I start out with a nifty SortedDictionary, which will sort my items by the key of the dictionary as I add them.

I then call ListBlobs(). There’s this peculiar oddity with Blob Storage when you use CloudXplorer where this ghost file name $$$.$$$ gets created, which is why I have to check the name of the file. I then throw the string and the date into the dictionary.

Once that finishes, I iterate the dictionary, adding the callback and syntax for making a json array. Get rid of the final comma and then throw the whole deal back into blob storage. Hoorah!

At first, I was actually deserializing the strings into objects using JSON.Net and then I realized there was no reason to do that when all I needed to do was manipulate strings.


My VS Achievements