Gravatar: How do I know if a user has a real picture
Asked Answered
G

7

40

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?

Galvani answered 20/1, 2010 at 17:50 Comment(0)
M
99

When constructing the URL, use the parameter d=404. This will cause Gravatar 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).

Mumps answered 24/1, 2010 at 21:55 Comment(4)
That's a much cleaner answer than all the rest. Like it - pays to read the documentation it would seem.Mccloskey
Once you have the 404 how do you turn this into gravatar = false?Benavides
@Benavides not sure what you mean? You should probably ask a fresh question.Mumps
@AndrewAylett Hi I have this same issue using java even i was a gravatar user , it;s always return 404 response code.Maximomaximum
M
6

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).

Millihenry answered 24/1, 2010 at 12:58 Comment(2)
MD5 checksum is a MD5 hash of the complete content of the file; Code snippet for C# here: sharpertutorials.com/calculate-md5-checksum-fileMillihenry
The chosen answer is way better but this trick is useful in some cases. For example in Javascript on a web page or browser extension if you don't want your browser to log a "404 not found" error in developer tools.Auschwitz
W
3

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;
}
Welton answered 25/1, 2010 at 1:52 Comment(4)
@Luke101: Don't know, and I'm still giving the first steps in C#. Sorry.Welton
Why the equality check to 02dcccdb0707f1c5acc9a0369ac24dac?Gynecology
@adrianbanks: That's the md5 of the 32px default Gravatar image.Welton
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 gravatar.com/avatar/aaa?default=identicon and 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.Gynecology
N
2

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");
}
Nepil answered 26/1, 2010 at 12:6 Comment(0)
E
1

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.

Electrojet answered 28/1, 2010 at 2:10 Comment(0)
P
1
private bool HasUserPublicGravatar(string email)
    {
        try
        {
            var gravatarPath = GravatarService.GetGravatarUrlForAddress(email,
            new GravatarUrlParameters { DefaultOption = GravatarDefaultUrlOptions.Error });

            WebRequest wReq = HttpWebRequest.Create(gravatarPath);
            var wRes = wReq.GetResponse();
            return true;
        }
        catch (System.Net.WebException ex)
        {
            if (ex.Message.Contains("404"))
                return false;
            else
                throw new Exception("Couldn't determine if ueser has public avatar");
        }
    }
Puerile answered 18/3, 2011 at 11:19 Comment(0)
C
0
function get_gravatar( $email, $s = 80, $d = '404', $r = 'x', $img = false, $atts = array() ) {

$url = 'http://www.gravatar.com/avatar/';
$url .= md5(strtolower(trim($email)));
$url .= "?s=$s&d=$d&r=$r";

if ( $img ) 
{
$url = '<img src="' . $url . '"';
foreach ( $atts as $key => $val )
$url .= ' ' . $key . '="' . $val . '"';
$url .= ' />';
return $url;

}

$headers = @get_headers($url);

if (!preg_match("|200|", $headers[0])) 
{
$has_valid_avatar = 'no';
} 
else 
{
$has_valid_avatar = 'yes';
}

return $has_valid_avatar;

}
Copyholder answered 19/5, 2012 at 7:13 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.