Category Archives: Gravatar

Adobe Flex Gravatar Control

Flex Gravatar Control

I have recently been getting to grips with Adobe Flex for a project that I’ve been working on, and thought a fun little bit of work would be to write a Flex Gravatar Control. I’d done the equivalent for ASP.NET, so why not have another go?

Incidentally, I don’t know whether there’s much call for a Flex Gravatar control – if you’re reading this and find a use for it – great, but I hope that there may be something in this post that helps a budding Flex developer too.

The general idea of component development is to package up a reusable bit of code for use in applications. Since a Gravatar is just an image, it seems natural that the Gravatar component extends (otherwise known as inheriting) the Flex mx.controls.Image class. The benefit of inheritance here is that we get a bunch of functionality for free that we can use as a basis for our control. We’ll be adding our specific Gravatar code so that the image shown is a particular user’s Gravatar.

Let’s take a look at the Flex Navigator for the Gravatar Project.

Flex Navigator for the Gravatar Project
Flex Navigator for the Gravatar Project

Aside from the standard stuff, as3corelib.swc is referenced in the libs folder. If you’re not aware of it, as3corelib is described as follows over at the project page hosted on Google Code.

The corelib project is an ActionScript 3 Library that contains a number of classes and utilities for working with ActionScript 3. These include classes for MD5 and SHA 1 hashing, Image encoders, and JSON serialization as well as general String, Number and Date APIs.

Since Gravatars use hashing for their URLs, we’ll be using the MD5 aspect of corelib.

The components directory contains a single file, GravatarImage.as, which contains the code for the Gravatar component, and Gravatar.mxml is the demo application’s MXML that uses the Gravatar component.

Let’s dive straight in and take a look at the component code:

package components
{
	// import the MD5 hashing code:
	import com.adobe.crypto.MD5;
	import mx.controls.Image;
	public class GravatarImage extends Image
	{
		public function GravatarImage()
		{
			super();
		}
		override protected function updateDisplayList(unscaledWidth:Number, unscaledHeight:Number):void
		{
			super.updateDisplayList(unscaledWidth, unscaledHeight);
			this.width = _size;
			this.height = _size;
			this.source = "http://www.gravatar.com/avatar/" +
							MD5.hash(_email).toString() + "?" +
							"size=" + _size +
							"&rating=" + _rating +
							"&d=" + _defaultImage;
		}
		private var _validRatings:Array = new Array('g', 'pg', 'r', 'x');
		private var _validDefaultImageTypes:Array = new Array('default', 'identicon', 'monsterid', 'wavatar');
		[Bindable]
		private var _email:String = new String();
		[Bindable]
		private var _size:Number = 80;		// default size of 80 pixels
		[Bindable]
		private var _rating:String = "G";	// default rating of G
		[Bindable]
		private var _defaultImage:String = "default"; // default to the blue 'G'
		public function set email(value:String):void
		{
			// if the email is invalid, a default image will be returned:
			_email = value;
		}
		public function set size(value:Number):void
		{
			// sanity check on incoming value, must be between 1 and 512:
			if( value >= 1 && value < 512)
				_size = value;
			else
				_size = 80;
		}
		public function set rating(value:String):void
		{
			// do a sanity check on the rating, allowing values
			// only in the _validRatings array (defined above):
			if( _validRatings.indexOf( value.toLowerCase()) != -1)
				_rating = value;
		}
		public function set defaultImage(value:String):void
		{
			_defaultImage = value;
		}
	}
}

The code is pretty simple. The main function, updateDisplayList is called when the image should draw itself. It simply constructs a URL based on the properties that have been set, and makes a request to the gravatar service for the image. Note that the corelib’s MD5 hash is used to obfuscate the email address passed in.

The properties relate to those of the URL generated and are as follows:

email

The email address associated with the gravatar image.

size

The size property of the control can be in the range 1 to 512. If it is outside this range, a default of 80 will be used.

rating

The ‘highest’ allowed rating of image.

  • A G rated gravatar is suitable for display on all websites with any audience type.
  • PG rated gravatars contain may contain rude gestures, provocatively dressed individuals, the lesser swear words, or mild violence.
  • R rated gravatars may contain such things as harsh profanity, intense violence, nudity, or hard drug use.
  • X rated gravatars may contain hardcore sexual imagery or extremely disturbing violence.

defaultImage

URL encoded URL, protocol included, of a GIF, JPEG, or PNG image that should be returned if either the requested email address has no associated gravatar, or that gravatar has a rating higher than is allowed by the ‘MaxAllowedRating’ property. The default image type also supports ‘default’, ‘identicon’, ‘monsterid’, and ‘wavatar’ strings for alternative Gravatar default images.

So, how do we use the control? Again, it’s pretty simple. Let’s have a look at the application MXML:

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute"
	xmlns:components="components.*">
	<mx:Script>
		<![CDATA[
			[Bindable]
			private var postComments:XML =
                <comments>
                    <comment name="Shane Porter" email="anemail@somedomain" />
					<comment name="Kate" email="someotheremail@somedomain" />
					<comment name="Mr Unknown" email="xxx@xxxyyy.com" />
                </comments>;
		]]>
	</mx:Script>
	<mx:DataGrid id="myDataGrid" dataProvider="{postComments.comment}" rowHeight="88" rowCount="3">
		<mx:columns>
            <mx:DataGridColumn dataField="@name" headerText="Name"/>
            <mx:DataGridColumn dataField="@email" headerText="Gravatar">
              	<mx:itemRenderer>
              		<mx:Component>
              			<components:GravatarImage email="{data.@email}" size="80" rating="G" defaultImage="monsterid" />
              		</mx:Component>
              	</mx:itemRenderer>
            </mx:DataGridColumn>
        </mx:columns>
    </mx:DataGrid>
</mx:Application>

There’s a component namespace reference on the outer Application element, and for illustrative purposes, some XML defined that is used as the data provider for a Data Grid control. The GravatarImage component is used as an item renderer for the ‘Gravatar’ column. The email property is set to the value of the email XML attribute, and the size, rating and defaultImage is also set.

Application in Design View
Application in Design View

When the app is run, the datagrid uses the XML as its data provider, and the Gravatars are rendered. Note that in this screenshot, I provided known email addresses associated with Gravatars. The bottom row is the same as the code shown previously, and since it is not associated with a Gravatar, the specified ‘monsterid’ default image is used.

The page shown in the browser
The page shown in the browser

ASP.NET Gravatar Control Update – Full Source Included

Gravatar ASP.NET Control

With gravatars now becoming ubiquitous in blogs and forums, I have developed an ASP.NET Control that encapsulates their functionality in a simple, reusable component. It’s so easy to use, you can download and be using it on your ASP.NET sites within minutes.

I introduced the control in February of 2008, and updated the functionality in March of 2008.

I’ve since had a lot of interest in the source code for the control, and so this post describes how the control works, as well as providing a download containing the control, as well as the full control source and example website that uses the control.

OK, let me download it already!

Download the Control and get started. Note that the demo projects included in the ZIP were written in Visual Studio 2005, so if you’re using Visual Studio 2008, you’ll need to convert the solution. If you’ve not done a conversion before, just follow the instructions that Visual Studio provides. Please also note that the solution will not open in Express Editions, since they do not support control projects. However, you can still use the control that’s included in the ZIP file.

Unzip the .zip download, and you’ll have the following folder structure:

Unzipped Folder structure

The root contains a small readme file, Visual Studio solution, FreshClickmedia.dll – the gravatar control assembly, Freshclickmedia.Web control project and GravatarSite website, which contains a few control examples.

Opening the solution in visual studio will give you this solution structure:

Gravatar Solution

Fire up the website, and you should see something like this:

Gravatar Demo Website

Examining the Code

    <h1>Gravatar Examples</h1>
    <h2>My email address, size of 80 pixels:</h2>
        <fcm:Gravatar ID="Gravatar1" runat="server" Email="youremailaddress@domain.com"
             OutputGravatarSiteLink="true" Size="80" />
    <h2>No email address, with default image (absolute url) specified:</h2>
        <fcm:Gravatar ID="Gravatar2" runat="server" Size="80" DefaultImage="http://farm3.static.flickr.com/2375/2552064340_192825f989_o.jpg" />
    <h2>Email address not associated with Gravatar, with no default image:</h2>
        <fcm:Gravatar ID="Gravatar3" runat="server" Email="thisemaildoesnotexist@freshclickmedia.com" Size="80"  />

The control requires an email address:

<fcm:Gravatar ID='Gravatar1' runat='server' Email='username@domain.com' />

For my email address, I get the following generated HTML:

Output for my email address

And if we look at the generated source:

<a id="Gravatar1" href="http://www.gravatar.com" title="Get your avatar"><img width="80" height="80" src="http://www.gravatar.com/avatar.php?gravatar_id=ccf3b8c638f15d005e5d070aeb1a3923&rating=G&size=80" alt="Gravatar" /></a>

The default produces a hyperlink off to the Gravatar site with a title “Get your avatar”. The image contains the MD5 email hash, a rating of “G” (suitable for all audience types), and a size of 80.

Customisation

The control supports a number of properties supporting the customisation of its output.

Size

The size property of the control can be in the range 1 to 80. If it is outside this range, a default of 80 will be used.

MaxAllowedRating

The ‘highest’ allowed rating of image.

  • A G rated gravatar is suitable for display on all websites with any audience type.
  • PG rated gravatars contain may contain rude gestures, provocatively dressed individuals, the lesser swear words, or mild violence.
  • R rated gravatars may contain such things as harsh profanity, intense violence, nudity, or hard drug use.
  • X rated gravatars may contain hardcore sexual imagery or extremely disturbing violence.

OutputGravatarSiteLink

True by default, determines whether a hyperlink linking to the gravatar website will be output around the image.

LinkTitle

“Get your avatar” by default, allows the customisation of the ‘title’ attribute of the link (obviously doesn’t apply if OutputGravatarSiteLink property is set to false.)

DefaultImage

URL encoded URL, protocol included, of a GIF, JPEG, or PNG image that should be returned if either the requested email address has no associated gravatar, or that gravatar has a rating higher than is allowed by the “MaxAllowedRating” property.

The code snippet below shows the associated properties.

<fcm:Gravatar ID="Gravatar1" runat="server"
    Email="username@domain.com"
    DefaultImage="http://www.site.com/default.jpg"
    OutputGravatarSiteLink="true" Size="40" />

Examining the control code

The Gravatar control derives from System.Web.UI.WebControls.WebControl and overrides the Render method.

The various properties such as Email are all implemented as simple C# properties, with various attributes depending on the property.

[Bindable(true), Category("Appearance"), DefaultValue("80")]
public short Size
{
	get
	{
		return _size;
	}
	set
	{
		_size = value;
	}
}

These properties are then used in the Render method to write out HTML using the method’s HtmlTextWriter parameter.

The Render method begins by adding the default attributes to the render, ensuring that the size is within the valid range of 1 to 512, and initialises the gravatar URL:

AddAttributesToRender(output);
// if the size property has been specified, ensure it is a short, and in the range
// 1..512:
try
{
    // if it's not in the allowed range, throw an exception:
    if (Size < 1 || Size > 512)
        throw new ArgumentOutOfRangeException();
}
catch
{
    Size = 80;
}
// default the image url:
string imageUrl = "http://www.gravatar.com/avatar.php?";

If an Email address has been supplied, the MD5CryptoServiceProvider hashes the email and a StringBuilder converts this to the required format:

if( !string.IsNullOrEmpty( Email))
{
    // build up image url, including MD5 hash for supplied email:
    MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
    UTF8Encoding encoder = new UTF8Encoding();
    MD5CryptoServiceProvider md5Hasher = new MD5CryptoServiceProvider();
    byte[] hashedBytes = md5Hasher.ComputeHash(encoder.GetBytes(Email));
    StringBuilder sb = new StringBuilder(hashedBytes.Length * 2);
    for (int i = 0; i < hashedBytes.Length; i++)
    {
        sb.Append(hashedBytes[i].ToString("X2"));
    }
    // output parameters:
    imageUrl += "gravatar_id=" + sb.ToString().ToLower();
    imageUrl += "&rating=" + MaxAllowedRating.ToString();
    imageUrl += "&size=" + Size.ToString();
}

The final part of the method assigns a default image, if one has been specified, outputs the site ink, if required, outputs the required attributes and tags.

// output default parameter if specified
if (!string.IsNullOrEmpty(DefaultImage))
{
    imageUrl += "&default=" + HttpUtility.UrlEncode(DefaultImage);
}
// if we need to output the site link:
if (OutputGravatarSiteLink)
{
    output.AddAttribute(HtmlTextWriterAttribute.Href, "http://www.gravatar.com");
    output.AddAttribute(HtmlTextWriterAttribute.Title, LinkTitle);
    output.RenderBeginTag(HtmlTextWriterTag.A);
}
// output required attributes/img tag:
output.AddAttribute(HtmlTextWriterAttribute.Width, Size.ToString());
output.AddAttribute(HtmlTextWriterAttribute.Height, Size.ToString());
output.AddAttribute(HtmlTextWriterAttribute.Src, imageUrl);
output.AddAttribute(HtmlTextWriterAttribute.Alt, "Gravatar");
output.RenderBeginTag("img");
output.RenderEndTag();
// if we need to output the site link:
if (OutputGravatarSiteLink)
{
    output.RenderEndTag();
}

Using the control on your own projects

As previously mentioned, the download solution will not open properly in Express versions of Visual Studio, since it does not support control projects, but the control, included in the download is supported by all versions of Visual Studio, 2005 and later.

The easiest way to use the control is to add the control to the toolbox. To do this, ensure that you are in design mode (looking at a web page), and right click on the ‘Standard’ group header of the Toolbox. From the context menu, select “Choose Items” and browse to the assembly (Freshclickmedia.Web.dll), and click “OK” to add.

Adding the control to the toolbox

Once you’ve added the assembly, you should see the following:

Gravatar Toolbox Item

From there, you can drag the control onto your page and start having fun!

Gravatar Control Update

Update – 12 June 2008

An updated version of this post, containing full source for the control and explanation is available here.

Original Post

The guys over at Gravatar.com have been hard at work updating their service, and I’ve updated the ASP.NET control I developed to reflect the changes.

The maximum size of Gravatars has now been increased from 80 to 512, so there’s a code change in the Render method:

// if the size property has been specified, and in the range
// 1..512:
try
{
    // if it's not in the allowed range, throw an exception:
    if (Size < 1 || Size > 512)
        throw new ArgumentOutOfRangeException();
}
catch
{
    Size = 80;
}

So, a default of 80 will still be used if the value specified is not within the 1 to 512 range, or it is not specified, but allows for a larger size.

The avatar.php URL serving the images now supports abbreviation, but the code in the control has not been changed.

Design time view of the control

The image shows the Design time view of the control, with the width set at the default value of 80. I’ve checked the control at 512 pixels, but my Gravatar doesn’t look too good expanded out to that size, so I’ve decided to stick at size 80 for the screenshot!

Gravatar ASP.NET Control

Update – 12 June 2008

An updated version of this post, containing full source for the control and explanation is available here.

Original Post

I just got myself a freshclickmedia.com Gravatar over at gravatar.com. A Gravatar is a little avatar associated with an email address, and quite a few blogs use them to decorate post comments. Signing up is easy – all you need to do is supply an email address, and image, and give your image a content rating.

The source of the gravatar image tag points to gravatar.com’s image generator and includes an MD5 hash of the email address to prevent email harvesting. A ‘max rating’ parameter prevents the display of unsavoury content.

There are a wide number of blogging gravatar plugins, so I decided to write an ASP.NET custom control to do the job. Here I present the control and its features.

Continue reading