10

How to store the get Facebook profile picture of a user while logging in through Facebook and saving it in my userprofile model.

I found this link which says how to do so using django-social-auth, https://gist.github.com/kalamhavij/1662930. but signals is now deprecated and I have to use pipeline.

Any idea how can I do the same using python-social-auth and pipeline?

BenMorel
  • 30,280
  • 40
  • 163
  • 285
Salma Hamed
  • 1,830
  • 2
  • 25
  • 43

3 Answers3

22

This is how it worked with me. (from https://github.com/omab/python-social-auth/issues/80)

Add the following code to pipeline.py:

from requests import request, HTTPError

from django.core.files.base import ContentFile


def save_profile_picture(strategy, user, response, details,
                         is_new=False,*args,**kwargs):

    if is_new and strategy.backend.name == 'facebook':
        url = 'http://graph.facebook.com/{0}/picture'.format(response['id'])

        try:
            response = request('GET', url, params={'type': 'large'})
            response.raise_for_status()
        except HTTPError:
            pass
        else:
            profile = user.get_profile()
            profile.profile_photo.save('{0}_social.jpg'.format(user.username),
                                   ContentFile(response.content))
            profile.save()

and add to pipelines in settings.py:

SOCIAL_AUTH_PIPELINE += (
'<application>.pipelines.save_profile_picture',
)
Hasan Ramezani
  • 4,554
  • 20
  • 28
Salma Hamed
  • 1,830
  • 2
  • 25
  • 43
  • This doesn't seem to work for me. the user parameter is None. Any ideas? – gngrwzrd Jun 08 '15 at 18:28
  • One thing nobody mentions is you need to have the default pipeline variable setup properly in SOCIAL_AUTH_PIPELINE. Using += doesn't work, and simply setting the pipeline to save_profile_picture doesn't work. Make sure you set default pipeline variables here http://psa.matiasaguirre.net/docs/pipeline.html – gngrwzrd Jun 08 '15 at 19:05
  • for those who want a bigger version of the image, do : `url = 'http://graph.facebook.com/{0}/picture?type=large'.format(response['id'])` – romainm Oct 12 '15 at 15:00
  • 1
    where is the image stored? – letsc Apr 26 '16 at 17:57
6

Assuming you already configured SOCIAL_AUTH_PIPELINE, there aren't many differences with signals approach.

Just create needed pipeline (skipping all imports, they're obvious)

def update_avatar(backend, details, response, social_user, uid,\
                  user, *args, **kwargs):
    if backend.__class__ == FacebookBackend:
        url = "http://graph.facebook.com/%s/picture?type=large" % response['id']
        avatar = urlopen(url)
        profile = user.get_profile()
        profile.profile_photo.save(slugify(user.username + " social") + '.jpg', 
                            ContentFile(avatar.read()))              
        profile.save()

and add to pipelines:

SOCIAL_AUTH_PIPELINE += (
    '<application>.pipelines.update_avatar',
)
latheiere
  • 451
  • 3
  • 14
1

The above answers may not work (it did not work for me) as the facebook profile URL does not work anymore without accesstoken. The following answer worked for me.

def save_profile(backend, user, response, is_new=False, *args, **kwargs):
    if is_new and backend.name == "facebook":
    #The main part is how to get the profile picture URL and then do what you need to do
        Profile.objects.filter(owner=user).update(
            imageUrl='https://graph.facebook.com/{0}/picture/?type=large&access_token={1}'.format(response['id'],
                                                                                                  response[
                                                                                                      'access_token']))

add to the pipeline in setting.py,

SOCIAL_AUTH_PIPELINE+ = ('<full_path>.save_profile')
sadat
  • 2,339
  • 16
  • 29