tags:

views:

773

answers:

5

I have gotten the gravatar service working on my site. But I would like to know if the user has uploaded their picture or not. Is there a way to know this?

+3  A: 

What I did:

  • Generate a gravatar with a non-existing e-mailadress
  • Save the image
  • Make a MD5 checksum of the images contents and store it as a constant in your app code

After that I did this for every gravatar request:

  • Download the gravatar image
  • MD5 checksum the contents and compare it against the constant
  • If it matches it's the default image, if it doesn't it is a custom image

I also cached the gravatar image for 24 hours so you don't have to rely on gravatar all the time. Optionally you can put the first 3 points in a function and let it run once in a while to ensure that gravatar still uses the same default image allthough they haven't in at least the last couple of months (propably never).

D4V360
Pretty good idea..What is a MD5 checksum?
Luke101
MD5 checksum is a MD5 hash of the complete content of the file;Code snippet for C# here: http://sharpertutorials.com/calculate-md5-checksum-file/
D4V360
+46  A: 

When constructing the URL, use the parameter d=404. This will cause Gravitar to return a 404 error rather than an image if the user hasn't set a picture.

If you're using the .Net control linked to from the gravitar site, you'll need to modify the IconSet enumeration (and probably pull the code out of the control, so you can get at the status directly).

Andrew Aylett
--> http://www.gravatar.com/avatar/aaa?default=404
thijs
That's a much cleaner answer than all the rest. Like it - pays to read the documentation it would seem.
Paddy
+1  A: 

In PHP:

function hasGravatar($email)
{
    return (md5(file_get_contents(sprintf('http://www.gravatar.com/avatar/%s?default=identicon&size=32', md5($email)))) == '02dcccdb0707f1c5acc9a0369ac24dac') ? false : true;
}
Alix Axel
Is there an online code translater to turn this into c#?
Luke101
@Luke101: Don't know, and I'm still giving the first steps in C#. Sorry.
Alix Axel
Why the equality check to 02dcccdb0707f1c5acc9a0369ac24dac?
adrianbanks
@adrianbanks: That's the md5 of the 32px default Gravatar image.
Alix Axel
What do you class as the "default" image? If a user has not explicitly set an image, they get an image based on the identifier passed to Gravatar, so the "default" image returned will be different for every user. Try it with http://www.gravatar.com/avatar/aaa?default=identicon and http://www.gravatar.com/avatar/aab?default=identicon - the images are different. Andrew Aylett's solution works best as it will return a 404 error in every case.
adrianbanks
+1  A: 

In C#, based on the PHP code posted earlier (untested - pre-lunch source code follows):

using System;
using System.Text;
using System.Security.Cryptography;
using System.IO;
using System.Net.WebClient;

public string GenerateMD5(string plaintext)
{
    Byte[] _originalBytes;
    Byte[] _encodedBytes;
    MD5 _md5;

    _md5 = new MD5CryptoServiceProvider();
    _originalBytes = ASCIIEncoding.Default.GetBytes(plaintext);
    _encodedBytes = _md5.ComputeHash(_originalBytes);

  return BitConverter.ToString(_encodedBytes).ToLower();
}

public string file_get_contents(string url) 
{ 
    string sContents = string.Empty; 

    if (url.ToLower().IndexOf("http:") > -1) {
        System.Net.WebClient wc = new System.Net.WebClient(); 
        byte[] response = wc.DownloadData(url); 
        sContents = System.Text.Encoding.ASCII.GetString(response); 
    } else { 
        System.IO.StreamReader sr = new System.IO.StreamReader(url); 
        sContents = sr.ReadToEnd(); 
        sr.Close(); 
    } 

    return sContents;
}

public bool hasGravatar(string email)
{
    string _mailMD5 = GenerateMD5(email);
    string _url = String.Format("http://www.gravatar.com/avatar/{0}?default=identicon&size=32", _mailMD5);
    string _fileMD5 = GenerateMD5(file_get_contents(_url));

    return !(_fileMD5 == "02dcccdb0707f1c5acc9a0369ac24dac");
}
Conan
+1  A: 

I'm currently doing something similar. I have a table setup for users profiles and in that table I have one column called Avatar. This is where a Gravatar URL will be stored. The following code is what I use to manage this column.

// first gather the email address that is going to be associated with this user as
// their gravatar.
// once you have gathered the email address send it to a private method that
// will return the correct url format.
protected void uxAssocateAvatar_Click(object sender, EventArgs e)
{
if (Page.IsValid)
{
    string emailAddress = uxEmailAddress.Text;
    try
    {
        Profile.Avatar = GetGravatarUrl(emailAddress);
        Profile.Save();
        Response.Redirect("Settings.aspx", true);
    }
    catch (Exception ex)
    {
        ProcessException(ex, Page);
    }
}
}

// use this private method to hash the email address, 
// and then create the url to the gravatar service.
private string GetGravatarUrl(string dataItem)
{
    string email = dataItem;
    string hash =
        System.Web.Security.FormsAuthentication.
        HashPasswordForStoringInConfigFile(email.Trim(), "MD5");
    hash = hash.Trim().ToLower();
    string gravatarUrl = string.Format(
       "http://www.gravatar.com/avatar.php?gravatar_id={0}&rating=G&size=100",
        hash);
    return gravatarUrl;
}

// on the page where an avatar will be displayed, 
// just drop in an asp.net image control with a default image.
<asp:Image ID="uxAvatar" runat="server" ImageUrl="~/images/genericProfile.jpg"
AlternateText="" CssClass="profileAvatar" BorderWidth="1px"/>

// and on page_load or something like that, 
// check to see if the profile's avatar property is set 
if (Profile.Avatar != null)
{
    uxAvatar.ImageUrl = Profile.Avatar;
}

// by default the profile's avatar property will be null, and when a user decides
// that they no longer want an avatar, the can de-associate it by creating a null 
// property which can be checked against 
// to see if they have one or don't have one.
protected void uxRemoveAvatar_Click(object sender, EventArgs e)
{
    Profile.Avatar = null;
    Profile.Save();
    Response.Redirect("Settings.aspx", true);
}

This seems to work out pretty well for me. I always have a default avatar showing, and when a user actually wants to have their custom avatar displayed, they associate their Gravatar email (which I hash and never store as email address) which creates a URL which I can just drop in as a imageURL. When the user removes their gravatar link, I null out the database column and the imageURL goes back to my default image.

Good luck, and hope this helps you some.

Chris