I am a little dubious about the scalability of this function. Indeed, on my dev server with sqlite, this function runs well. But, when I tried to put it onto webfaction with one of their mysql instances, pages would take literally tens of seconds to load. I tried rewriting it a few times to improve the performance, but, the story was the same:
Everything is perfectly fine on the dev server and terrible on webfaction/mysql
I have to wonder if this has anything to do with http://www.djangoproject.com/weblog/2009/oct/09/security/ and old webfaction sites may be getting abused? I don't know. But, when I tried it out on my VPS with postgres, I found that it runs fine.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 | def friends_dict(request, rider):
''' set-up facebook, get the friends and then sort into different categories.
Results in a dict whose values are lists.
Each member of these lists are dictionaries representing friends.
The keys of the master dict are strings::
registered_mine - registered for your race
registered_other - registered, not for yours
interested_mine - have your interest
interested_other - have interest but not yours
connect_no_act - have connected and no more
any_act - have connected and are interested or registered
no_connect - facebook friends who have not connected
The keys of the dicts for each individual are::
[ 'name', 'pic_square', 'profile_url', 'uid' ]
'''
# setup faceboook and get friends ids
fb = setup_facebook(request)
fids = friends_ids(request, rider)
result_dict = {}
# if not fids, abort
if not fids:
return result_dict
facebook_strings = [ str(f) for f in fids ]
connected_riders = Rider.objects.filter(
facebook__in = facebook_strings
)
q = Q()
if rider.race():
q = q| Q( race = rider.race() )
if rider.race_interest():
q = q| Q( race = rider.race_interest )
# Get the lists of users
# convert the list of users into their FB id
# convert the list of facebook ids to list of dicts
if rider.race():
registered_for_mine = RaceRegistration.objects.filter(q
).values_list( 'user', flat=True )
registered_for_other = RaceRegistration.objects.exclude(q
).values_list( 'user', flat=True )
registered_mine = connected_riders.filter(
user__in = registered_for_mine,
).values_list('facebook', flat=True )
registered_other = connected_riders.filter(
user__in = registered_for_other,
).values_list('facebook', flat=True )
fb_registered_mine = fb.users.getInfo( [ int(x) for x in registered_mine ],
[ 'name', 'pic_square', 'profile_url', 'uid' ])
fb_registered_other = fb.users.getInfo( [ int(x) for x in registered_other ],
[ 'name', 'pic_square', 'profile_url', 'uid' ])
result_dict['registered_mine'] = fb_registered_mine
result_dict['registered_other'] = fb_registered_other
else:
registered_mine = []
registered_other = []
result_dict['registered_mine'] = []
result_dict['registered_other'] = []
if rider.race_interest():
interested_in_mine = RaceInterest.objects.filter(q
).values_list( 'user', flat=True )
interested_in_other = RaceInterest.objects.exclude(q
).values_list( 'user', flat=True )
interested_mine = connected_riders.filter(
user__in = interested_in_mine,
).values_list('facebook', flat=True )
interested_other = connected_riders.filter(
user__in = interested_in_other
).values_list('facebook', flat=True )
fb_interested_mine = fb.users.getInfo( [ int(x) for x in interested_mine ],
[ 'name', 'pic_square', 'profile_url', 'uid' ])
fb_interested_other = fb.users.getInfo( [ int(x) for x in interested_other ],
[ 'name', 'pic_square', 'profile_url', 'uid' ])
result_dict['interested_mine'] = fb_interested_mine
result_dict['interested_other'] = fb_interested_other
else:
interested_mine = []
interested_other = []
result_dict['interested_mine'] = []
result_dict['interested_other'] = []
# Get friends who have connected to the site
connected_set = set( connected_riders.values_list('facebook', flat=True) )
no_connect_set = set(facebook_strings) - connected_set
any_act_set = set(registered_mine).union(set(registered_other))\
.union(set(interested_mine)).union(set(interested_other))
connect_no_act_set = connected_set - any_act_set
# get facebook, lists of dicts with our sets
fb_connect_no_act = fb.users.getInfo( [ int(x) for x in connect_no_act_set ],
[ 'name', 'pic_square', 'profile_url', 'uid' ])
fb_no_connect = fb.users.getInfo( [ int(x) for x in no_connect_set ],
[ 'name', 'pic_square', 'profile_url', 'uid' ])
fb_any_act = fb.users.getInfo( [ int(x) for x in any_act_set ],
[ 'name', 'pic_square', 'profile_url', 'uid' ])
# load all of the results into out friends dict of list of dicts
result_dict['connect_no_act'] = fb_connect_no_act
result_dict['no_connect'] = fb_no_connect
result_dict['any_act'] = fb_any_act
return result_dict
|
would be interesting to see if the Postgress shared on Webfaction has same issue?
yeah, the final code is a little different than this now. I used some different queries and avoided Q() but this ran pretty well as is.
I think that would have been a good idea.
Heh, I should show the code of some of those other functions :) That's probably even more interesting than that function?
from django.conf import settings
from facebook import djangofb as facebook
def setup_facebook(request):
''' sets up the facebook session and returns the Facebook object '''
fb = facebook.Facebook(settings.FACEBOOK_API_KEY,
settings.FACEBOOK_SECRET_KEY)
fb.session_key = request.COOKIES.get('%s_session_key' %
settings.FACEBOOK_API_KEY)
fb.uid = request.COOKIES.get('%s_user' %
settings.FACEBOOK_API_KEY)
return fb
A little bit goofy with the bare except. But hey, we recalculate this enough to just return an empty list if that little try suite can't run. It's mostly for facebook network anomalies.
import random
def friends_ids(request, rider):
''' get a randomly shuffled list of friends ids from rider '''
if rider.facebook:
try:
fb = setup_facebook(request)
l = fb.friends.get()
random.shuffle(l)
return l
except:
return []
else:
return []