Beispiel #1
0
    def authenticate(self, facebook_id=None, facebook_email=None):
        '''
        Authenticate the facebook user by id OR facebook_email
        We filter using an OR to allow existing members to connect with
        their facebook ID using email.
        '''
        if facebook_id or facebook_email:
            profile_class = get_profile_class()
            profile_query = profile_class.objects.all().order_by('user')
            profile_query = profile_query.select_related('user')
            profile = None

            #filter on email or facebook id, two queries for better
            #queryplan with large data sets
            if facebook_id:
                profiles = profile_query.filter(facebook_id=facebook_id)[:1]
                profile = profiles[0] if profiles else None
            if profile is None and facebook_email:
                try:
                    profiles = profile_query.filter(
                        user__email__iexact=facebook_email)[:1]
                    profile = profiles[0] if profiles else None
                except DatabaseError:
                    try:
                        user = models.User.objects.get(email=facebook_email)
                    except models.User.DoesNotExist:
                        user = None
                    profile = user.get_profile() if user else None

            if profile:
                # populate the profile cache while we're getting it anyway
                user = profile.user
                user._profile = profile
                return user
Beispiel #2
0
    def test_user_registered_signal(self):
        # Ensure user registered, pre update and post update signals fire

        def user_registered(sender, user, facebook_data, **kwargs):
            user.registered_signal = True

        def pre_update(sender, profile, facebook_data, **kwargs):
            profile.pre_update_signal = True

        def post_update(sender, profile, facebook_data, **kwargs):
            profile.post_update_signal = True

        Profile = get_profile_class()
        signals.facebook_user_registered.connect(user_registered, sender=User)
        signals.facebook_pre_update.connect(pre_update, sender=Profile)
        signals.facebook_post_update.connect(post_update, sender=Profile)

        graph = get_facebook_graph(access_token='short_username')
        facebook = FacebookUserConverter(graph)
        user = _register_user(self.request, facebook)
        self.assertEqual(hasattr(user, 'registered_signal'), True)
        self.assertEqual(hasattr(user.get_profile(),
                                 'pre_update_signal'), True)
        self.assertEqual(hasattr(user.get_profile(),
                                 'post_update_signal'), True)
Beispiel #3
0
 def random_facebook_friends(self, user, gender=None, limit=3):
     '''
     Returns a random sample of your FB friends
     
     Limit = Number of friends
     Gender = None, M or F 
     '''
     assert gender in (None, 'M', 'F'), 'Gender %s wasnt recognized' % gender
     
     from greenroom.apps.django_facebook_patched.utils import get_profile_class
     facebook_cache_key = 'facebook_users_%s' % user.id
     non_members = cache.get(facebook_cache_key)
     profile_class = get_profile_class()
     if not non_members:
         facebook_users = list(self.filter(user_id=user.id, gender=gender)[:50])
         facebook_ids = [u.facebook_id for u in facebook_users]
         members = list(profile_class.objects.filter(facebook_id__in=facebook_ids).select_related('user'))
         member_ids = [p.facebook_id for p in members]
         non_members = [u for u in facebook_users if u.facebook_id not in member_ids]
         
         cache.set(facebook_cache_key, non_members, 60*60)
         
     random_limit = min(len(non_members), 3)
     random_facebook_users = []
     if random_limit:
         random_facebook_users = random.sample(non_members, random_limit)
         
     return random_facebook_users
     
Beispiel #4
0
    def _store_likes(self, user, likes):
        current_likes = inserted_likes = None
        
        if likes:
            from greenroom.apps.django_facebook_patched.models import FacebookLike
            base_queryset = FacebookLike.objects.filter(user_id=user.id)
            global_defaults = dict(user_id=user.id)
            id_field = 'facebook_id'
            default_dict = {}
            for like in likes:
                name = like.get('name')
                created_time_string = like.get('created_time')
                created_time = None
                if created_time_string:
                    created_time = datetime.datetime.strptime(
                        like['created_time'], "%Y-%m-%dT%H:%M:%S+0000")
                default_dict[like['id']] = dict(
                    created_time=created_time,
                    category=like.get('category'),
                    name=name
                )
            current_likes, inserted_likes = mass_get_or_create(
                FacebookLike, base_queryset, id_field, default_dict,
                global_defaults)
            logger.debug('found %s likes and inserted %s new likes',
                         len(current_likes), len(inserted_likes))

        #fire an event, so u can do things like personalizing the users' account
        #based on the likes
        signals.facebook_post_store_likes.send(sender=get_profile_class(),
            user=user, likes=likes, current_likes=current_likes,
            inserted_likes=inserted_likes,
        )
        
        return likes
Beispiel #5
0
def _remove_old_connections(facebook_id, current_user_id=None):
    '''
    Removes the facebook id for profiles with the specified facebook id
    which arent the current user id
    '''
    profile_class = get_profile_class()
    other_facebook_accounts = profile_class.objects.filter(
        facebook_id=facebook_id)
    if current_user_id:
        other_facebook_accounts = other_facebook_accounts.exclude(
            user__id=current_user_id)
    other_facebook_accounts.update(facebook_id=None)
Beispiel #6
0
    def registered_friends(self, user):
        '''
        Returns all profile models which are already registered on your site
        and a list of friends which are not on your site
        '''
        from greenroom.apps.django_facebook_patched.utils import get_profile_class
        profile_class = get_profile_class()
        friends = self.get_friends(limit=1000)

        if friends:
            friend_ids = [f['id'] for f in friends]
            friend_objects = profile_class.objects.filter(
                facebook_id__in=friend_ids).select_related('user')
            registered_ids = [f.facebook_id for f in friend_objects]
            new_friends = [f for f in friends if f['id'] not in registered_ids]
        else:
            new_friends = []
            friend_objects = profile_class.objects.none()

        return friend_objects, new_friends
Beispiel #7
0
    def _store_friends(self, user, friends):
        from greenroom.apps.django_facebook_patched.models import FacebookUser
        current_friends = inserted_friends = None
        
        #store the users for later retrieval
        if friends:
            #see which ids this user already stored
            base_queryset = FacebookUser.objects.filter(user_id=user.id)
            #if none if your friend have a gender clean the old data
            genders = FacebookUser.objects.filter(user_id=user.id, gender__in=('M','F')).count()
            if not genders:
                FacebookUser.objects.filter(user_id=user.id).delete()
            
            global_defaults = dict(user_id=user.id)
            default_dict = {}
            gender_map = dict(female='F', male='M')
            for f in friends:
                name = f.get('name')
                gender = None
                if f.get('sex'):
                    gender = gender_map[f.get('sex')]
                default_dict[str(f['id'])] = dict(name=name, gender=gender)
            id_field = 'facebook_id'

            current_friends, inserted_friends = mass_get_or_create(
                FacebookUser, base_queryset, id_field, default_dict,
                global_defaults)
            logger.debug('found %s friends and inserted %s new ones',
                         len(current_friends), len(inserted_friends))
            
        #fire an event, so u can do things like personalizing suggested users
        #to follow
        signals.facebook_post_store_friends.send(sender=get_profile_class(),
            user=user, friends=friends, current_friends=current_friends,
            inserted_friends=inserted_friends,
        )

        return friends
Beispiel #8
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']
    user_dirty = profile_dirty = False
    profile = user.get_profile()

    signals.facebook_pre_update.send(sender=get_profile_class(),
        profile=profile, facebook_data=facebook_data)

    profile_field_names = [f.name for f in profile._meta.fields]
    user_field_names = [f.name for f in user._meta.fields]

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

    #update the facebook id and access token
    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(profile.facebook_id))
        profile.facebook_id = facebook_data['facebook_id']
        profile_dirty = True
        _remove_old_connections(profile.facebook_id, user.id)

    #update all fields on both user and profile
    for f in facebook_fields:
        facebook_value = facebook_data.get(f, False)
        if facebook_value:
            if (f in profile_field_names and hasattr(profile, f) and
                not getattr(profile, f, False)):
                logger.debug('profile field %s changed from %s to %s', f,
                             getattr(profile, f), facebook_value)
                setattr(profile, f, facebook_value)
                profile_dirty = True
            elif (f in user_field_names and hasattr(user, f) and
                  not getattr(user, f, False)):
                logger.debug('user field %s changed from %s to %s', f,
                             getattr(user, f), facebook_value)
                setattr(user, f, facebook_value)
                user_dirty = True

    #write the raw data in case we missed something
    if hasattr(profile, 'raw_data'):
        serialized_fb_data = json.dumps(facebook.facebook_profile_data())
        if profile.raw_data != serialized_fb_data:
            logger.debug('profile raw data changed from %s to %s',
                         profile.raw_data, serialized_fb_data)
            profile.raw_data = serialized_fb_data
            profile_dirty = True


    image_url = facebook_data['image']
    if hasattr(profile, 'image') and not profile.image:
        profile_dirty = _update_image(profile, image_url)

    #save both models if they changed
    if user_dirty:
        user.save()
    if profile_dirty:
        profile.save()

    signals.facebook_post_update.send(sender=get_profile_class(),
        profile=profile, facebook_data=facebook_data)

    return user