def send(self, graph=None, shared_explicitly=False):
        result = None
        # update the last attempt
        self.last_attempt = datetime.now()
        self.save()

        # see if the graph is enabled
        profile = try_get_profile(self.user)
        user_or_profile = get_instance_for_attribute(
            self.user, profile, 'access_token')
        graph = graph or user_or_profile.get_offline_graph()
        user_enabled = shared_explicitly or \
            (user_or_profile.facebook_open_graph and self.facebook_user_id)
        # start sharing
        if graph and user_enabled:
            graph_location = '%s/%s' % (
                self.facebook_user_id, self.action_domain)
            share_dict = self.get_share_dict()
            from open_facebook.exceptions import OpenFacebookException
            try:
                result = graph.set(graph_location, **share_dict)
                share_id = result.get('id')
                if not share_id:
                    error_message = 'No id in Facebook response, found %s for url %s with data %s' % (
                        result, graph_location, share_dict)
                    logger.error(error_message)
                    raise OpenFacebookException(error_message)
                self.share_id = share_id
                self.error_message = None
                self.completed_at = datetime.now()
                self.save()
            except OpenFacebookException as e:
                logger.warn(
                    'Open graph share failed, writing message %s' % str(e))
                self.error_message = repr(e)
                self.save()
                # maybe we need a new access token
                new_token_required = self.exception_requires_new_token(
                    e, graph)
                # verify that the token didnt change in the mean time
                user_or_profile = user_or_profile.__class__.objects.get(
                    id=user_or_profile.id)
                token_changed = graph.access_token != user_or_profile.access_token
                logger.info('new token required is %s and token_changed is %s',
                            new_token_required, token_changed)
                if new_token_required and not token_changed:
                    logger.info(
                        'a new token is required, setting the flag on the user or profile')
                    # time to ask the user for a new token
                    update_user_attributes(self.user, profile, dict(
                        new_token_required=True), save=True)

        elif not graph:
            self.error_message = 'no graph available'
            self.save()
        elif not user_enabled:
            self.error_message = 'user not enabled'
            self.save()

        return result
Exemple #2
0
    def send(self, graph=None, shared_explicitly=False):
        result = None
        # update the last attempt
        self.last_attempt = datetime.now()
        self.save()

        # see if the graph is enabled
        profile = try_get_profile(self.user)
        user_or_profile = get_instance_for_attribute(
            self.user, profile, 'access_token')
        graph = graph or user_or_profile.get_offline_graph()
        user_enabled = shared_explicitly or \
            (user_or_profile.facebook_open_graph and self.facebook_user_id)
        # start sharing
        if graph and user_enabled:
            graph_location = '%s/%s' % (
                self.facebook_user_id, self.action_domain)
            share_dict = self.get_share_dict()
            from open_facebook.exceptions import OpenFacebookException
            try:
                result = graph.set(graph_location, **share_dict)
                share_id = result.get('id')
                if not share_id:
                    error_message = 'No id in Facebook response, found %s for url %s with data %s' % (
                        result, graph_location, share_dict)
                    logging.error(error_message)
                    raise OpenFacebookException(error_message)
                self.share_id = share_id
                self.error_message = None
                self.completed_at = datetime.now()
                self.save()
            except OpenFacebookException as e:
                logging.warn(
                    'Open graph share failed, writing message %s' % str(e))
                self.error_message = repr(e)
                self.save()
                # maybe we need a new access token
                new_token_required = self.exception_requires_new_token(
                    e, graph)
                # verify that the token didnt change in the mean time
                user_or_profile = user_or_profile.__class__.objects.get(
                    id=user_or_profile.id)
                token_changed = graph.access_token != user_or_profile.access_token
                logging.info('new token required is %s and token_changed is %s',
                             new_token_required, token_changed)
                if new_token_required and not token_changed:
                    logging.info(
                        'a new token is required, setting the flag on the user or profile')
                    # time to ask the user for a new token
                    update_user_attributes(self.user, profile, dict(
                        new_token_required=True), save=True)

        elif not graph:
            self.error_message = 'no graph available'
            self.save()
        elif not user_enabled:
            self.error_message = 'user not enabled'
            self.save()

        return result
Exemple #3
0
    def test_follow_og_share_error(self):
        user_url = 'http://www.fashiolista.com/style/neni/'
        kwargs = dict(item=user_url)
        user = get_user_model().objects.all()[:1][0]
        profile = try_get_profile(user)
        user_or_profile = get_instance_for_attribute(
            user, profile, 'facebook_open_graph')
        user_or_profile.facebook_open_graph = True
        user_or_profile.save()

        some_content_type = ContentType.objects.all()[:1][0]
        share = OpenGraphShare.objects.create(
            user_id=user.id,
            facebook_user_id=13123123,
            action_domain='fashiolista:follow',
            content_type=some_content_type,
            object_id=user.id,
        )
        share.set_share_dict(kwargs)
        share.save()
        update_user_attributes(user, profile, dict(new_token_required=False))
        from open_facebook.exceptions import FacebookUnreachable, OAuthException
        with mock.patch('open_facebook.api.OpenFacebook') as mocked:
            instance = mocked.return_value
            instance.set = Mock(side_effect=FacebookUnreachable('broken'))
            share.send(graph=instance)
            self.assertEqual(share.error_message, 'broken')
            self.assertFalse(share.completed_at)
            user = get_user_model().objects.get(id=user.id)
            if profile:
                profile = get_profile_model().objects.get(id=profile.id)
            new_token_required = get_user_attribute(
                user, profile, 'new_token_required')
            self.assertEqual(new_token_required, False)

        # now try with an oauth exception
        return
        # Can't figure out how to test this
        with mock.patch('open_facebook.api.OpenFacebook') as mocked:
            instance = mocked.return_value
            instance.set = Mock(side_effect=OAuthException('permissions'))
            share.send(graph=instance)
            self.assertEqual(share.error_message, 'permissions')
            self.assertFalse(share.completed_at)
            user = get_user_model().objects.get(id=user.id)
            if profile:
                profile = get_profile_model().objects.get(id=profile.id)
            new_token_required = get_user_attribute(
                user, profile, 'new_token_required')
            self.assertEqual(new_token_required, True)
Exemple #4
0
 def test_send(error, expected_error_message, expected_new_token, has_permissions=False):
     user, profile, share = self.share_details
     update_user_attributes(
         user, profile, dict(new_token_required=False), save=True)
     with mock.patch('open_facebook.api.OpenFacebook') as mocked:
         instance = mocked.return_value
         instance.set = Mock(side_effect=error)
         instance.has_permissions = Mock(return_value=has_permissions)
         instance.access_token = get_user_attribute(
             user, profile, 'access_token')
         share.send(graph=instance)
         self.assertEqual(share.error_message, expected_error_message)
         self.assertFalse(share.completed_at)
         user = get_user_model().objects.get(id=user.id)
         if profile:
             profile = get_profile_model().objects.get(id=profile.id)
         new_token_required = get_user_attribute(
             user, profile, 'new_token_required')
         self.assertEqual(new_token_required, expected_new_token)
 def test_send(error, expected_error_message, expected_new_token, has_permissions=False):
     user, profile, share = self.share_details
     update_user_attributes(
         user, profile, dict(new_token_required=False), save=True)
     with mock.patch('open_facebook.api.OpenFacebook') as mocked:
         instance = mocked.return_value
         instance.set = Mock(side_effect=error)
         instance.has_permissions = Mock(return_value=has_permissions)
         instance.access_token = get_user_attribute(
             user, profile, 'access_token')
         share.send(graph=instance)
         self.assertEqual(share.error_message, expected_error_message)
         self.assertFalse(share.completed_at)
         user = get_user_model().objects.get(id=user.id)
         if profile:
             profile = get_profile_model().objects.get(id=profile.id)
         new_token_required = get_user_attribute(
             user, profile, 'new_token_required')
         self.assertEqual(new_token_required, expected_new_token)
Exemple #6
0
    def test_update_access_token(self):
        request = RequestMock().get('/')
        request.session = {}
        request.user = AnonymousUser()
        graph = get_persistent_graph(request, access_token='paul')
        action, user = connect_user(self.request, facebook_graph=graph)
        first_user_id = user.id

        # new token required should start out as False
        profile = try_get_profile(user)
        new_token_required = get_user_attribute(user, profile,
                                                'new_token_required')
        self.assertEqual(new_token_required, False)

        # we manually set it to true
        update_user_attributes(user,
                               profile,
                               dict(new_token_required=True),
                               save=True)
        if profile:
            profile = get_profile_model().objects.get(id=profile.id)
        user = get_user_model().objects.get(id=user.id)
        new_token_required = get_user_attribute(user, profile,
                                                'new_token_required')
        self.assertEqual(new_token_required, True)

        # another update should however set it back to False
        request.facebook = None
        graph = get_facebook_graph(request, access_token='paul2')
        logger.info('and the token is %s', graph.access_token)
        action, user = connect_user(self.request, facebook_graph=graph)
        user = get_user_model().objects.get(id=user.id)
        self.assertEqual(user.id, first_user_id)
        if profile:
            profile = get_profile_model().objects.get(id=profile.id)
        user = get_user_model().objects.get(id=user.id)
        new_token_required = get_user_attribute(user, profile,
                                                'new_token_required')
        self.assertEqual(new_token_required, False)
Exemple #7
0
    def test_update_access_token(self):
        request = RequestMock().get('/')
        request.session = {}
        request.user = AnonymousUser()
        graph = get_persistent_graph(request, access_token='paul')
        action, user = connect_user(self.request, facebook_graph=graph)
        first_user_id = user.id

        # new token required should start out as False
        profile = try_get_profile(user)
        new_token_required = get_user_attribute(
            user, profile, 'new_token_required')
        self.assertEqual(new_token_required, False)

        # we manually set it to true
        update_user_attributes(
            user, profile, dict(new_token_required=True), save=True)
        if profile:
            profile = get_profile_model().objects.get(id=profile.id)
        user = get_user_model().objects.get(id=user.id)
        new_token_required = get_user_attribute(
            user, profile, 'new_token_required')
        self.assertEqual(new_token_required, True)

        # another update should however set it back to False
        request.facebook = None
        graph = get_facebook_graph(request, access_token='paul2')
        logger.info('and the token is %s', graph.access_token)
        action, user = connect_user(self.request, facebook_graph=graph)
        user = get_user_model().objects.get(id=user.id)
        self.assertEqual(user.id, first_user_id)
        if profile:
            profile = get_profile_model().objects.get(id=profile.id)
        user = get_user_model().objects.get(id=user.id)
        new_token_required = get_user_attribute(
            user, profile, 'new_token_required')
        self.assertEqual(new_token_required, False)
def _update_user(user, facebook, overwrite=True):
    '''
    Updates the user and his/her profile with the data from facebook
    '''
    # if you want to add fields to ur user model instead of the
    # profile thats fine
    # partial support (everything except raw_data and facebook_id is included)
    facebook_data = facebook.facebook_registration_data(username=False)
    facebook_fields = ['facebook_name', 'facebook_profile_url', 'gender',
                       'date_of_birth', 'about_me', 'website_url', 'first_name', 'last_name']

    profile = try_get_profile(user)
    # which attributes to update
    attributes_dict = {}

    # send the signal that we're updating
    signals.facebook_pre_update.send(sender=get_user_model(), user=user,
                                     profile=profile, facebook_data=facebook_data)

    # set the facebook id and make sure we are the only user with this id
    current_facebook_id = get_user_attribute(user, profile, 'facebook_id')
    facebook_id_changed = facebook_data['facebook_id'] != current_facebook_id
    overwrite_allowed = overwrite or not current_facebook_id

    # update the facebook id and access token
    facebook_id_overwritten = False
    if facebook_id_changed and overwrite_allowed:
        # when not overwriting we only update if there is no
        # profile.facebook_id
        logger.info('profile facebook id changed from %s to %s',
                    repr(facebook_data['facebook_id']),
                    repr(current_facebook_id))
        attributes_dict['facebook_id'] = facebook_data['facebook_id']
        facebook_id_overwritten = True

    if facebook_id_overwritten:
        _remove_old_connections(facebook_data['facebook_id'], user.id)

    # update all fields on both user and profile
    for f in facebook_fields:
        facebook_value = facebook_data.get(f, False)
        current_value = get_user_attribute(user, profile, f, None)
        if facebook_value and not current_value:
            attributes_dict[f] = facebook_value

    # write the raw data in case we missed something
    serialized_fb_data = json.dumps(facebook.facebook_profile_data())
    current_raw_data = get_user_attribute(user, profile, 'raw_data')
    if current_raw_data != serialized_fb_data:
        attributes_dict['raw_data'] = serialized_fb_data

    image_url = facebook_data['image']
    # update the image if we are allowed and have to
    if facebook_settings.FACEBOOK_STORE_LOCAL_IMAGE:
        image_field = get_user_attribute(user, profile, 'image', True)
        if not image_field:
            image_name, image_file = _update_image(
                facebook_data['facebook_id'], image_url)
            image_field.save(image_name, image_file)

    # save both models if they changed
    update_user_attributes(user, profile, attributes_dict)
    if getattr(user, '_fb_is_dirty', False):
        user.save()
    if getattr(profile, '_fb_is_dirty', False):
        profile.save()

    signals.facebook_post_update.send(sender=get_user_model(),
                                      user=user, profile=profile, facebook_data=facebook_data)

    return user
Exemple #9
0
def _update_user(user, facebook, overwrite=True):
    '''
    Updates the user and his/her profile with the data from facebook
    '''
    # if you want to add fields to ur user model instead of the
    # profile thats fine
    # partial support (everything except raw_data and facebook_id is included)
    facebook_data = facebook.facebook_registration_data(username=False)
    facebook_fields = [
        'facebook_name', 'facebook_profile_url', 'gender', 'date_of_birth',
        'about_me', 'website_url', 'first_name', 'last_name'
    ]

    # prepare first_name and last_name
    name = facebook_data.get('name', ' ').split()
    if len(name):
        facebook_data['first_name'] = name[0]
    if len(name) > 1:
        facebook_data['last_name'] = ' '.join(name[1:])

    facebook_data['facebook_profile_url'] = facebook_data.get('image')

    profile = try_get_profile(user)
    # which attributes to update
    attributes_dict = {}

    # send the signal that we're updating
    signals.facebook_pre_update.send(sender=get_user_model(),
                                     user=user,
                                     profile=profile,
                                     facebook_data=facebook_data)

    # set the facebook id and make sure we are the only user with this id
    current_facebook_id = get_user_attribute(user, profile, 'facebook_id')
    facebook_id_changed = facebook_data['facebook_id'] != current_facebook_id
    overwrite_allowed = overwrite or not current_facebook_id

    # update the facebook id and access token
    facebook_id_overwritten = False
    if facebook_id_changed and overwrite_allowed:
        # when not overwriting we only update if there is no
        # profile.facebook_id
        logger.info('profile facebook id changed from %s to %s',
                    repr(facebook_data['facebook_id']),
                    repr(current_facebook_id))
        attributes_dict['facebook_id'] = facebook_data['facebook_id']
        facebook_id_overwritten = True

    if facebook_id_overwritten:
        _remove_old_connections(facebook_data['facebook_id'], user.id)

    # update all fields on both user and profile
    for f in facebook_fields:
        facebook_value = facebook_data.get(f, False)
        current_value = get_user_attribute(user, profile, f, None)
        if facebook_value and not current_value:
            attributes_dict[f] = facebook_value

    # write the raw data in case we missed something
    serialized_fb_data = json.dumps(facebook.facebook_profile_data())
    current_raw_data = get_user_attribute(user, profile, 'raw_data')
    if current_raw_data != serialized_fb_data:
        attributes_dict['raw_data'] = serialized_fb_data

    image_url = facebook_data['image']
    # update the image if we are allowed and have to
    if facebook_settings.FACEBOOK_STORE_LOCAL_IMAGE:
        image_field = get_user_attribute(user, profile, 'image', True)
        if not image_field:
            image_name, image_file = _update_image(
                facebook_data['facebook_id'], image_url)
            image_field.save(image_name, image_file)

    # save both models if they changed
    update_user_attributes(user, profile, attributes_dict)
    if getattr(user, '_fb_is_dirty', False):
        user.save()
    if getattr(profile, '_fb_is_dirty', False):
        profile.save()

    signals.facebook_post_update.send(sender=get_user_model(),
                                      user=user,
                                      profile=profile,
                                      facebook_data=facebook_data)

    return user
Exemple #10
0
def update_user_profile(user):
    graph = user.get_offline_graph()
    user_details = graph.get("me")
    del user_details['id']
    update_user_attributes(user, None, user_details, save=True)