Eventually I'm going to work on a way to cache the Gravatar images locally. If the user has a Gravatar image, the module will grab it and save it in the files/picture directory. This will be an interesting feature to code, but I wanted to put it out there to see if there is any interest in this.

Comments

Narno’s picture

Hmm, I'm not sure this is a real interest because our browsers already manages the cache images, especially the image is accessible by a unique URL, thus easily cached by the browser. No?

Dave Reid’s picture

Yes the Gravatars could be cached by the browser, but what I'm envisioning is having the module actually 'grab' the image file and store it so the image file will be served from the same domain as the website, instead of Gravatar.com. If a site has a lot of comments and a lot of Gravatars being displayed, this causes a lot of 'external' requests and could possibly slow down the page being displayed. Either way this would be an advanced option for people concerned with site performance.

Narno’s picture

For example Yahoo! intends to call its Javascript libraries (YUI) on a centralized server rather than to download these libraries locally, for the sake of performance for websites. This is exactly what Gravatar do.

It will be interesting to make a benchmark between the 2 solutions : externals requests on gravatar.com and internals pictures loading.

turadg’s picture

Other modules that expect the avatar in the DB would benefit from caching them. E.g. #615458: Doesn't work with site_user_list module

jumpfightgo’s picture

I think this is a great idea. Web services that on occasion are slow or unreachable (twitter especially!) can dramatically slow down the load time for a site.

hefox’s picture

Perhaps this, #658752: Gravatar size could be combined, perhaps with ImageCache Profiles module? First think I think when seeing any module is wondering if it intergrates with imagecache; no reason for separate settings if they can be combined somehow :). (Current testing seems like they don't already; haven't looked at either module to see how reasonable it would be for them to work nicely togeather).

Narno’s picture

Interesting, maybe a nice idea!

It sound good for you Dave?

jumpfightgo’s picture

There would need to be a timeout for how long the gravatar images are cached locally.

If someone updates their gravatar, you'd want that change to be reflected on your site, so the cache needs to be flushed every 24 hours or so.

If gravatar images were cached through imagecache, maybe on cron the imagecache for gravatars could be flushed?

hefox’s picture

I looked briefly into it again

The most difficult parts are
1) the images need to be local in order for imagecache to work with them
2) telling if the image has already been cached and not fetching it again if it has

Other than that module needs to be weighted below imagecache_profiles and store the path to the local image in $variables['account']->picture = $picture and imagecache_profiles handles the call to imagecache.

I know image_resize_filter locally stores images to resizes them, but their code is very image resize specific (http://drupalcode.org/viewvc/drupal/contributions/modules/image_resize_f... )

gausarts’s picture

Subscribing. Thanks

Dave Reid’s picture

Version: 6.x-1.x-dev » 8.x-1.x-dev
Status: Postponed » Active

Working on this for 7.x, most likely can backport to 6.x as well.

cap60552’s picture

Subscribing. Thanks for your work on this!

Dave Reid’s picture

Initial code is *super* easy to do with Drupal 7 actually. It's working really well saving the image locally and formatting as an image profile. But because it's built into core it's a lot easier than the code for Drupal 6.

alberto56’s picture

Subscribing. See also #850582: CCK support

pipsqueaks’s picture

Version: 8.x-1.x-dev » 6.x-1.7

Subscribing. I'd love the gravatar module to play nicely with image cache on Drupal 6.x!

hefox’s picture

Version: 6.x-1.7 » 8.x-1.x-dev

Version number reflects what branch the maintainer is working as can be noticed in comment #11.

sylv3st3r’s picture

+1 would love to see it done. It also can fix alpha7 user pictures issues, http://drupal.org/node/926292 and http://drupal.org/node/931898

hunt3r’s picture

Anyone make any progress on this recently? It would be really sweet to have imagecache profile and gravatar.

If Gravatar, pull local copy, operate on gravatar image via imagecache. Basically Gravatar is the authoritative source for the base image only.

Dave Reid’s picture

Version: 8.x-1.x-dev » 7.x-1.x-dev
Dave Reid’s picture

Status: Active » Postponed

This may have to wait just a little bit. I'm working on a 'user picture API' because this problem is not just for gravatar, it's for any external user picture provider, like Facebook, etc. So I think my plan is that 7.x-1.0 is focused on a straight port of the module to D7, then we open up a 7.x-2.x branch that can use the new user picture API.

ianchan’s picture

subscribe

sylv3st3r’s picture

Just a little bit of idea that I used on my site to store gravatar image locally (sorry for hacking your module code directly)
Basically I added another check before fetching gravatar image using gravatar_get_gravatar inside user_picture preprocess :

$result=db_query(
  "SELECT uri FROM {file_managed} WHERE filename = :filename",
  array(
    ':filename' => $hash = md5(drupal_strtolower($account->mail)),
  )
)->fetchObject();
if($result){
  //LOCAL IMAGE FOUND
  $picture=$result->uri;
}else{
  $picture=gravatar_get_gravatar($account->mail);
  //SAVE IT TO LOCAL DIRECTORY
  $im = @imagecreatefrompng($picture);
  if($im){
    //CREATE GRAVATAR DIRECTORY UNDER PUBLIC FILES DIRECTORY
    $destination = "public://gravatar";
    file_prepare_directory($destination, FILE_CREATE_DIRECTORY);
    //CREATE FILE CONTAINER
    $file = file_save_data('', $destination,FILE_EXISTS_REPLACE);
    $wrapper = file_stream_wrapper_get_instance_by_uri($file->uri);
    imagepng($im,$wrapper->realpath());
    imagedestroy($im);
    clearstatcache();
    $hash=md5(drupal_strtolower($account->mail));
    $new=str_replace($file->filename,$hash,$file->uri);
    //FIX THIS TO DETECT FILE MIME TYPE
    $file->filemime='image/png';
    $file->uid=$account->uid;
    //SET FILE TO BE REMOVED ON CRON
    $file->status=0;
    $file->uri="public://gravatar/".$new;
    $file->filename=$new;
    $file = file_save($file); 
    rename($file->uri,$new);
    $picture=$file->uri;
  }
}

Well, it's very basic and raw. But at least I hope you get the idea.

amitaibu’s picture

Another reason to cache it locally is that this will never work:


function gravatar_preprocess_user_picture(&$variables) {
 // ...
      if (module_exists('image') && file_valid_uri($filepath) && $style = variable_get('user_picture_style', '')) {
        $variables['user_picture'] = theme('image_style', array('style_name' => $style, 'path' => $filepath, 'alt' => $alt, 'title' => $alt, 'getsize' => FALSE));
      }

// ...

Since the schema is HTTP.

Dave Reid’s picture

We understand perfectly why it needs to happen, thanks.

amitaibu’s picture

Sorry, I didn't explain myself properly. While looking at the code I had the impression I will get the gravatar formatted by the image style, but this doesn't happen as the schema is http. So the reason of my comment was actually to document the fact it currently doesn't, not as a critic to the module maintainers.

Dave Reid’s picture

I know this is fairly major for everyone and I really, really want to get a solution that I'm working on finished, but I think for D7CX purposes, we need to roll a 7.0 release without this, and make this the biggest priority for a 7.1 release shortly afterwards.

Dave Reid’s picture

Status: Postponed » Active

7.x-1.0 has been tagged and released to fulfill our D7CX pledge. Moving this issue back to active.

Rosamunda’s picture

I´m sorry, is this issue commited in 6.x-1.9?
Thanks!

mlncn’s picture

Still going with a user API approach, or fixing it in Gravatar first?

mrfelton’s picture

Also looking for this feature in 6.x - is it available yet?

tsvenson’s picture

Just ran into this problem myself. Since I use the user picture on many different places, and sizes, I have set Gravatar to get a 300px picture so that I can avoid having to upscale a smaller picture. It wasn't until I noticed the big picture in the profile view I saw this problem. In comments, using Bartik, this doesn't seem to be an issue.

I do understand that this is more complicated than simply storing local version of the file, especially in regards to how to check if the Gravatar picture has been updated.

As I see it there are a couple of solutions for this. For anonymous users, i.e. those not having an account, I suspect that in almost 100% of the cases the image will be used for comments. Wouldn't it then be possible for the module to distinguish if the picture it shall view is for an account or not? Maybe that would help increasing performance a bit since no update check then needs to be done for those pictures.

For users with accounts, where they use their Gravatar image in the account, I can see to options:

1 - Set set default to check/regenerate picture every x day.
2 - Users can manually click an update button in their profile that will then regenerate the picture.

Preferable both options should be available.

ekristen’s picture

Yes I'd definitely like to see this feature. Where are you with this? Have you been able to start working on it? Do you have any code that you'd like tested? I am working on a site right now that uses views and I'd like to be able to use the image styles that are native to d7 to size them accordingly.

7wonders’s picture

sub

hefox’s picture

Dropping in to leave a link to https://github.com/bran/imagecache_external; just wandered into it.

lightsurge’s picture

I'm using image cache external to cache images from a website screenshot service and it works very well. Could be fiddly to get working here though I suppose, essentially you would need imagecache profiles to combine it with their module, so that it would take either an external or internal image for a profile picture.

lightsurge’s picture

lightsurge’s picture

I have caching working fine with Gravatar, ICE does all the fetching/caching of external images, ICP styles them.

In this context Gravatar has to alter the profile images in advance of ICP working on them, so as well as the changes in ICP (#1300064: Integrate imagecache external with imagecache profiles), to get Gravatar working you need to reduce it's weight to -1, and add $variables['picture_override'] to fish out the untainted image url to pass on to ICP.

function gravatar_preprocess_user_picture(&$variables) {
  $variables['picture'] = '';

  if (variable_get('user_pictures', 0)) {
    // Load the full user object since it is not provided with nodes, comments,
    // or views displays.
    $account = _gravatar_load_account($variables['account']);
    $picture = _gravatar_get_account_user_picture($account);

    if (!empty($picture)) {
      $alt = t("@user's picture", array('@user' => $account->name));
      $variables['picture_override'] = $picture; // passes a picture_override variable to the ICP preprocess
      $variables['picture'] = theme('image', $picture, $alt, $alt, NULL, FALSE);

I suppose it would be nice to get the cached avatars 'expiring' after a given period... Which would probably be easy enough to do with cron and ICE's flush mechanism.

lightsurge’s picture

Forgot, also need to adjust this:

function _gravatar_get_account_user_picture($account) {
  if (!empty($account->picture) && file_exists($account->picture)) {
    // If the user has an uploaded picture, use it first.
    if (module_exists(imagecache_profiles) {
      return $account->picture;
    }
    else {
      return file_create_url($account->picture);
    }
  }
markhalliwell’s picture

Linking #957320-55: Enable the support for user profile pictures. Caching would help from a security standpoint.

dpi’s picture

Anyone that is interested in this may want to take a look at User Pic Kit.

deggertsen’s picture

Unfortunately, User Pic Kit didn't work for me. I'm still having the issue of gravatar pictures caching with a messed up URL. The code in #37 also appears to be out of date with the current version of the module.

Wim Leers’s picture

Issue summary: View changes

Looks like this module doesn't need to be ported to Drupal 8, because https://www.drupal.org/project/avatars looks far superior :) It even has local caching already built-in, so it also contains this much-wanted feature.

nickonom’s picture

I believe this issue could be closed, because the https://www.drupal.org/project/gravatar_style does exactly what's wanted in the subject matter here.

Wim Leers’s picture

Status: Active » Closed (works as designed)

Lovely!