def __init__(self, objs=None, parent=None, object_name=None): if objs is not None: self.extend(objs) factory = Json2ObjectsFactory() def _get_page(page): paging = getattr(parent, "paging", False) if not paging: return PaginatedList() url = getattr(paging, page, False) if not url: return PaginatedList() obj = factory.make_object(object_name, urllib2.urlopen(url).read()) objs_list = factory.make_paginated_list(obj, object_name) if not objs_list: return PaginatedList() return objs_list self.next = lambda: _get_page("next") self.previous = lambda: _get_page("previous")
class FacebookClient(object): """ This class implements the interface to the Facebook Graph API """ FACEBOOK_URL = "https://www.facebook.com/" GRAPH_URL = "https://graph.facebook.com/" API_URL = "https://api.facebook.com/" BASE_AUTH_URL = "%soauth/authorize?" % GRAPH_URL DIALOG_BASE_URL = "%sdialog/feed?" % FACEBOOK_URL FBQL_BASE_URL = "%smethod/fql.query?" % API_URL BASE_TOKEN_URL = "%soauth/access_token?" % GRAPH_URL DEFAULT_REDIRECT_URI = "http://www.facebook.com/connect/login_success.html" #DEFAULT_SCOPE = auth.ALL_PERMISSIONS DEFAULT_SCOPE = (auth.USER_ABOUT_ME, auth.USER_READ_FRIENDLISTS, auth.FRIENDS_ABOUT_ME, auth.WRITE_PUBLISH_STREAM) DEFAULT_DIALOG_URI = "http://www.example.com/response/" #A factory to make objects from a json factory = Json2ObjectsFactory() def __init__(self, app_id, access_token=None, raw_data=None): self.app_id = app_id self.access_token = access_token self.raw_data = raw_data self.permissions = self.DEFAULT_SCOPE self.expires = None def _make_request(self, url, data=None): """ Makes a simple request. If not data is a GET else is a POST. """ if not data: data = None return urllib.urlopen(url, data).read() def _make_auth_request(self, path, **data): """ Makes a request to the facebook Graph API. This method requires authentication! Don't forget to get the access token before use it. """ if self.access_token is None: raise PyfbException( "Must Be authenticated. Did you forget to get the access token?" ) token_url = "?access_token=%s" % self.access_token url = "%s%s%s" % (self.GRAPH_URL, path, token_url) if data: post_data = urllib.urlencode(data) else: post_data = None return self._make_request(url, post_data) def _make_object(self, name, data): """ Uses the factory to make an object from a json """ if not self.raw_data: return self.factory.make_object(name, data) return self.factory.loads(data) def _get_url_path(self, dic): return urllib.urlencode(dic) def _get_auth_url(self, params, redirect_uri): """ Returns the authentication url """ if redirect_uri is None: redirect_uri = self.DEFAULT_REDIRECT_URI params['redirect_uri'] = redirect_uri url_path = self._get_url_path(params) url = "%s%s" % (self.BASE_AUTH_URL, url_path) return url def _get_permissions(self): return ",".join(self.permissions) def get_auth_token_url(self, redirect_uri): """ Returns the authentication token url """ params = { "client_id": self.app_id, "type": "user_agent", "scope": self._get_permissions(), } return self._get_auth_url(params, redirect_uri) def get_auth_code_url(self, redirect_uri, state=None): """ Returns the url to get a authentication code """ params = { "client_id": self.app_id, "scope": self._get_permissions(), } if state: params['state'] = state return self._get_auth_url(params, redirect_uri) def get_access_token(self, app_secret_key, secret_code, redirect_uri): if redirect_uri is None: redirect_uri = self.DEFAULT_REDIRECT_URI self.secret_key = app_secret_key url_path = self._get_url_path({ "client_id": self.app_id, "client_secret": app_secret_key, "redirect_uri": redirect_uri, "code": secret_code, }) url = "%s%s" % (self.BASE_TOKEN_URL, url_path) data = self._make_request(url) if not "access_token" in data: ex = self.factory.make_object('Error', data) raise PyfbException(ex.error.message) data = dict(parse_qsl(data)) self.access_token = data.get('access_token') self.expires = data.get('expires') return self.access_token def exchange_token(self, app_secret_key, exchange_token): self.secret_key = app_secret_key url_path = self._get_url_path({ "grant_type": 'fb_exchange_token', "client_id": self.app_id, "client_secret": app_secret_key, "fb_exchange_token": exchange_token, }) url = "%s%s" % (self.BASE_TOKEN_URL, url_path) data = self._make_request(url) if not "access_token" in data: ex = self.factory.make_object('Error', data) raise PyfbException(ex.error.message) data = dict(parse_qsl(data)) self.access_token = data.get('access_token') self.expires = data.get('expires') return self.access_token, self.expires def get_dialog_url(self, redirect_uri): if redirect_uri is None: redirect_uri = self.DEFAULT_DIALOG_URI url_path = self._get_url_path({ "app_id": self.app_id, "redirect_uri": redirect_uri, }) url = "%s%s" % (self.DIALOG_BASE_URL, url_path) return url def get_one(self, path, object_name): """ Gets one object """ data = self._make_auth_request(path) obj = self._make_object(object_name, data) if hasattr(obj, 'error'): raise PyfbException(obj.error.message) return obj def get_list(self, id, path, object_name=None): """ Gets A list of objects """ if id is None: id = "me" if object_name is None: object_name = path path = "%s/%s" % (id, path.lower()) obj = self.get_one(path, object_name) obj_list = self.factory.make_paginated_list(obj, object_name) if not obj_list: obj_list = obj.get("data") return obj_list def push(self, id, path, **data): """ Pushes data to facebook """ if id is None: id = "me" path = "%s/%s" % (id, path) response = self._make_auth_request(path, **data) return self._make_object("response", response) def delete(self, id): """ Deletes a object by id """ data = {"method": "delete"} response = self._make_auth_request(id, **data) return self._make_object("response", response) def _get_table_name(self, query): """ Try to get the table name from a fql query """ KEY = "FROM" try: index = query.index(KEY) + len(KEY) + 1 table = query[index:].strip().split(" ")[0] return table except Exception, e: raise PyfbException("Invalid FQL Sintax")
class FacebookClient(object): """ This class implements the interface to the Facebook Graph API """ FACEBOOK_DOMAIN = "www.facebook.com" GRAPH_DOMAIN = "graph.facebook.com" API_DOMAIN = "api.facebook.com" DEFAULT_REDIRECT_URI = "http://www.facebook.com/connect/login_success.html" DEFAULT_SCOPE = auth.ALL_PERMISSIONS DEFAULT_DIALOG_URI = "http://www.example.com/response/" # A factory to make objects from a json factory = Json2ObjectsFactory() def __init__(self, app_id, access_token=None, timeout=30): self.app_id = app_id self.access_token = access_token self.permissions = self.DEFAULT_SCOPE self.expires = None self.session = requests.Session() self.session.timeout = timeout def _make_request(self, method="get", domain=GRAPH_DOMAIN, path=None, params=None, auth=True, **data): """ Makes a request to the facebook Graph API. This method requires authentication! Don't forgot to get the access token before use it. """ if params is None: params = {} else: for key, value in params.items(): if value is None: del params[key] if auth: if self.access_token is None: raise PyfbException( "Must Be authenticated. Do you forgot to get the access token?" ) params["access_token"] = self.access_token url = "https://%s/%s" % (domain, path) response = self.session.request(method, url, params, data) if response.status_code < 200 or response.status_code > 299: if response.content: content = self.factory.make_object("Error", response.content) if hasattr(content, "error"): error = content.error raise PyfbStatusException( error.type, error.code, getattr(error, "error_subcode", None), error.message) raise PyfbException(response.content) return response.content def _build_url(self, domain, path, params): return "https://%s/%s?%s" % (domain, path, urllib.urlencode(params)) def _get_auth_url(self, params, redirect_uri): """ Returns the authentication url """ params['redirect_uri'] = redirect_uri return self._build_url(self.FACEBOOK_DOMAIN, "oauth/authorize", params) def _get_permissions(self): return ",".join(self.permissions) def get_auth_token_url(self, redirect_uri=DEFAULT_REDIRECT_URI): """ Returns the authentication token url """ params = { "client_id": self.app_id, "type": "user_agent", "scope": self._get_permissions(), } return self._get_auth_url(params, redirect_uri) def get_auth_code_url(self, redirect_uri=DEFAULT_REDIRECT_URI): """ Returns the url to get a authentication code """ params = { "client_id": self.app_id, "scope": self._get_permissions(), } return self._get_auth_url(params, redirect_uri) def get_access_token(self, app_secret_key, secret_code, redirect_uri=DEFAULT_REDIRECT_URI): params = { "client_id": self.app_id, "client_secret": app_secret_key, "redirect_uri": redirect_uri, "code": secret_code, } data = self._make_request(path="oauth/access_token", params=params, auth=False) data = simplejson.loads(data) self.access_token = data.get('access_token') self.expires = data.get('expires') return self.access_token def get_dialog_url(self, redirect_uri=DEFAULT_DIALOG_URI): params = { "app_id": self.app_id, "redirect_uri": redirect_uri, } return self._build_url(self.FACEBOOK_DOMAIN, "dialog/feed", params) def get_picture_url(self, id, ssl=False, auth=False, size=None): params = {} if ssl: params["return_ssl_resources"] = "1" if auth: params["access_token"] = self.access_token if size is not None: if isinstance(size, basestring): params["type"] = size else: if isinstance(size, (int, long)): width = height = size else: width, height = map(int, size) params["width"] = str(width) params["height"] = str(height) return self._build_url(self.GRAPH_DOMAIN, "%s/picture" % id, params) def get_one(self, path, object_name, **params): """ Gets one object """ data = self._make_request(path=path, params=params) return self.factory.make_object(object_name, data) def get_list(self, id, path, object_name=None, **params): """ Gets A list of objects """ if id is None: id = "me" if object_name is None: object_name = path path = "%s/%s" % (id, path.lower()) return self.get_one(path, object_name, **params).data def post(self, id, path, **data): """ Posts data to facebook """ if id is None: id = "me" path = "%s/%s" % (id, path) self._make_request(method="post", path=path, **data) def push(self, id, path, **data): """ Pushes data to facebook """ if id is None: id = "me" path = "%s/%s" % (id, path) self._make_request(method="put", path=path, **data) def delete(self, id): """ Deletes a object by id """ data = {"method": "delete"} self._make_request(method="delete", path=id, **data) def _get_table_name(self, query): """ Try to get the table name from a fql query """ KEY = "FROM" try: index = query.index(KEY) + len(KEY) + 1 table = query[index:].strip().split(" ")[0] return table except Exception, e: raise PyfbException("Invalid FQL Sintax")