Salma Hamed
Salma Hamed

Reputation: 2068

Save facebook profile picture in model using python-social-auth

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?

Upvotes: 10

Views: 8627

Answers (3)

sadat
sadat

Reputation: 4352

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

Upvotes: 1

Salma Hamed
Salma Hamed

Reputation: 2068

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',
)

Upvotes: 22

latheiere
latheiere

Reputation: 451

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',
)

Upvotes: 6

Related Questions