Created
November 29, 2011 00:02
-
-
Save terrettaz/1402702 to your computer and use it in GitHub Desktop.
Get information about facebook friends and lists
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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""" | |
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