Skip to content

Instantly share code, notes, and snippets.

@terrettaz
Created November 29, 2011 00:02
Show Gist options
  • Save terrettaz/1402702 to your computer and use it in GitHub Desktop.
Save terrettaz/1402702 to your computer and use it in GitHub Desktop.
Get information about facebook friends and lists
#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-
__version__ = "$Revision: 0.1 $"
__author__ = "Pierrick Terrettaz"
__date__ = "2011-11-28"
import sys
import re
import urllib
import httplib
import readline
import cmd
from pprint import pprint
try:
import json
except:
import simplejson as json
# get access token:
# http://developers.facebook.com/tools/explorer?method=GET&path=me'
access_token = 'AAAAAQC7KcXgBAJZCQlrk7Jue3Rqes6ZA3zBZCl0t11EcqbOSWu9cT9tHBnZC2xZB8oQjmZBrK8M6sIOZA8jy1ZBs8tqfpzWoPs0ZD'
# userid or useralias such as
user = 'pterrettaz'
# API Graph URL
graph = 'https://graph.facebook.com'
class Graph(object):
def __init__(self, access_token):
self.access_token = access_token
self.graph = 'graph.facebook.com'
def _path(self, args):
access_token = self.access_token
path = '/'.join(args)
return '/%(path)s?format=json&access_token=%(access_token)s' % locals()
def P(self, *args):
if self._load('POST', self._path(args)):
return 'Success'
return 'Failed'
def G(self, *args):
data = self._load('GET', self._path(args))
if data.has_key('error'):
print data['error']['message']
raise Exception()
elif data.has_key('data'):
return data['data']
return data
def D(self, *args):
if self._load('DELETE', self._path(args)):
return 'Success'
return 'Failed'
def _load(self, method, path):
print '-> loading %s' % path.split('?')[0]
conn = httplib.HTTPSConnection(self.graph)
try:
conn.request(method, path)
res = conn.getresponse()
return json.loads(res.read())
finally:
conn.close()
def load_data(graph):
friends = graph.G(user,'friends')
friendlists = graph.G(user,'friendlists')
for flist in friendlists:
flist['members'] = graph.G(flist['id'] + '/members')
"""
no_list = {
'id':-1,
'name': 'No List',
'members':[],
'list_type':'__special__'
}
no_user_list = {
'id':-1,
'name': 'No User List',
'members':[],
'list_type':'__special__'
}
friendlists.append(no_list)
friendlists.append(no_user_list)
for friend in friends:
nolist = True
nouserlist = True
for flist in friendlists:
notfound = len(filter(lambda user: user['id'] == friend['id'], flist['members'])) == 0
nolist = nolist and notfound
if flist['list_type'] == 'user_created':
nouserlist = nouserlist and notfound
if nolist:
no_list['members'].append(friend)
if nouserlist:
no_user_list['members'].append(friend)
"""
return (friends, friendlists)
class Ex(Exception):
pass
class Main(cmd.Cmd):
def __init__(self, graph):
cmd.Cmd.__init__(self)
self.graph = graph
self.prompt = '> '
self.friends = []
self.friendlists = []
def split(self, line):
return re.split('[\s]+', line)
def error_command(self, command):
print '! Error while executing command'
self.do_help(command)
def find_friends(self, name):
name = name.lower()
return filter(lambda el: el['name'].lower().find(name) > -1, self.friends)
def find_lists(self, name):
name = name.lower()
return filter(lambda el: el['name'].lower().find(name) > -1, self.friendlists)
def get_friend(self, userid):
users = filter(lambda el: el['id'] == userid, self.friends)
if len(users) == 1:
return users[0]
def get_list(self, listid):
lists = filter(lambda el: el['id'] == listid, self.friendlists)
if len(lists) == 1:
return lists[0]
def parse_friends(self, pattern):
friends = self.get_friend(pattern) or []
if len(friends) != 1:
friends = self.find_friends(pattern)
if len(friends) == 0:
raise Ex('no friend(s) found to add in list')
return friends
def parse_list(self, pattern):
flist = self.get_list(pattern) or []
if len(flist) != 1:
flist = self.find_lists(pattern)
if len(flist) == 0:
raise Ex('no list found')
return
elif len(flist) > 1:
raise Ex('multiple lists found: %s' % map(lambda x: x['name'], flist))
return flist[0]
def confirm(self, message):
sys.stdout.write('%s. Continue? [y/n]: ' % message)
return raw_input().lower() == 'y'
def _complete_list(self, text, l):
if text:
return [
el for el in l
if el.lower().startswith(text.lower())
]
else:
return l
def emptyline(self):
pass
def postloop(self):
print "Bye"
def complete_show(self, text, line, start_index, end_index):
if len(self.split(line)) == 2:
return self._complete_list(text, ['friends', 'lists'])
return []
def complete_add(self, text, line, start_index, end_index):
w = self.split(line)
if len(w) == 2:
return self._complete_list(text, map(lambda x: x['name'], self.friends))
elif len(w) == 3:
return self._complete_list(text, map(lambda x: x['name'], self.friendlists))
return []
def complete_remove(self, text, line, start_index, end_index):
w = self.split(line)
if len(w) == 2:
return self._complete_list(text, map(lambda x: x['name'], self.friends))
elif len(w) == 3:
return self._complete_list(text, map(lambda x: x['name'], self.friendlists))
return []
def do_EOF(self, line):
"""exit
Exit and say Bye"""
print
return True
def do_exit(self, line):
"""exit
Exit and say Bye"""
return True
def do_help(self, line):
"""Print help"""
cmd.Cmd.do_help(self, line)
def do_show(self, line):
"""show option
Display information
options: friends lists"""
option = self.split(line)[0]
if option == 'friends':
pprint(map(lambda x: x['name'], self.friends))
elif option == 'lists':
for l in self.friendlists:
print '%s\n members:' % l['name']
pprint(map(lambda y: '%s' % y['name'], l['members']))
else:
print 'show what ?'
def do_search(self, line):
"""search name
Search a entity (friend or list)"""
print "Friends:"
pprint(map(lambda x: x['name'], self.find_friends(line)))
print "Lists:"
pprint(map(lambda x: x['name'], self.find_lists(line)))
def do_remove(self, line):
"""remove users list
Remove one or more users from a list
need a confirmation"""
parts = self.split(line)
if len(parts) != 2:
self.error_command('remove')
return
try:
friends = self.parse_friends(parts[0])
flist = self.parse_list(parts[1])
print 'removing'
pprint((map(lambda x: x['name'], friends)))
if self.confirm('form %s' % flist['name']):
for friend in friends:
if friend in flist['members']:
self.graph.D('%s/members/%s' % (flist['id'], friend['id']) )
flist['members'].remove(friend)
print 'done'
except Ex, e:
print e.message
def do_add(self, line):
"""add users list
Add one or more users in a list
need a confirmation"""
parts = self.split(line)
if len(parts) != 2:
self.error_command('add')
return
try:
friends = self.parse_friends(parts[0])
flist = self.parse_list(parts[1])
print 'adding'
pprint((map(lambda x: x['name'], friends)))
if self.confirm('to %s' % flist['name']):
for friend in friends:
if friend not in flist['members']:
self.graph.P('%s/members/%s' % (flist['id'], friend['id']) )
flist['members'].append(friend)
print 'done'
except Ex, e:
print e.message
def do_load(self, line):
"""load
Loading friends and friendlist"""
self.friends, self.friendlists = load_data(self.graph)
if __name__ == '__main__':
try:
g = Graph(access_token)
main = Main(g)
main.cmdloop()
except:
print 'Failure, check username or access_token on top of file'
print 'Info'
print ' get access token: http://developers.facebook.com/tools/explorer?method=GET&path=me'
print ' and check the Extended Permission: "read_friendlists"'
raise
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment