Python Facebook SDK:获取有关用户朋友的信息

时间:2013-11-12 21:47:27

标签: python facebook google-app-engine facebook-graph-api

我正在尝试使用找到的Facebook登录here扩展示例AppEngine应用程序。我能够让它按原样运行(我自己的访问令牌从一个单独的文件中添加),并在用户登录时显示这个漂亮的小页面(由example.html提供给你):

main.html

现在,我想访问有关用户朋友的信息;例如,他们喜欢的电影。首先,我在Facebook开发人员的仪表板(例如,friends_likes)上为我的基础应用添加了大量权限,然后保存了更改。然后我决定尝试显示一个朋友的名字,以及他或她最喜欢的电影。目前,我只是向用户显式存储这些内容,因此修改了example.py文件,如下所示(新行以“###################”结尾) ):

#!/usr/bin/env python
#
# Copyright 2010 Facebook
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.

"""
A barebones AppEngine application that uses Facebook for login.

1.  Make sure you add a copy of facebook.py (from python-sdk/src/)
    into this directory so it can be imported.
2.  Don't forget to tick Login With Facebook on your facebook app's
    dashboard and place the app's url wherever it is hosted
3.  Place a random, unguessable string as a session secret below in
    config dict.
4.  Fill app id and app secret.
5.  Change the application name in app.yaml.

"""

import facebook
import auth
import webapp2
import os
import jinja2
import urllib2

from google.appengine.ext import db
from webapp2_extras import sessions

config = {}
config['webapp2_extras.sessions'] = dict(secret_key=auth.SESSION_SECRET)


class User(db.Model):
    id = db.StringProperty(required=True)
    created = db.DateTimeProperty(auto_now_add=True)
    updated = db.DateTimeProperty(auto_now=True)
    name = db.StringProperty(required=True)
    profile_url = db.StringProperty(required=True)
    access_token = db.StringProperty(required=True)
    friend_name = db.StringProperty(required=True) ######################
    friend_movies = db.StringProperty(required=True) ####################

class BaseHandler(webapp2.RequestHandler):
    """Provides access to the active Facebook user in self.current_user

    The property is lazy-loaded on first access, using the cookie saved
    by the Facebook JavaScript SDK to determine the user ID of the active
    user. See http://developers.facebook.com/docs/authentication/ for
    more information.
    """
    @property
    def current_user(self):
        if self.session.get("user"):
            # User is logged in
            return self.session.get("user")
        else:
            # Either used just logged in or just saw the first page
            # We'll see here
            cookie = facebook.get_user_from_cookie(self.request.cookies,
                                                   auth.FACEBOOK_APP_ID,
                                                   auth.FACEBOOK_APP_SECRET)
            if cookie:
                # Okay so user logged in.
                # Now, check to see if existing user
                user = User.get_by_key_name(cookie["uid"])
                if not user:
                    # Not an existing user so get user info
                    graph = facebook.GraphAPI(cookie["access_token"])
                    profile = graph.get_object("me")
                    friends = graph.get_connections("me", "friends", fields="name")############
                    fname = friends["data"][0]["name"] ################
                    fid = friends["data"][0]["id"] ################
                    fmov = graph.get_connections(fid, "movies", fields="name")##############
                    user = User(
                        key_name=str(profile["id"]),
                        id=str(profile["id"]),
                        name=profile["name"],
                        friend_name=str(fname),##############
                        friend_movies=str(fmov),##############
                        profile_url=profile["link"],
                        access_token=cookie["access_token"]
                    )
                    user.put()
                elif user.access_token != cookie["access_token"]:
                    user.access_token = cookie["access_token"]
                    user.put()
                # User is now logged in
                self.session["user"] = dict(
                    name=user.name,
                    friend_name = user.friend_name, #################
                    friend_movies=user.friend_movies, ###############
                    profile_url=user.profile_url,
                    id=user.id,
                    access_token=user.access_token
                )
                return self.session.get("user")
        return None

    def dispatch(self):
        """
        This snippet of code is taken from the webapp2 framework documentation.
        See more at
        http://webapp-improved.appspot.com/api/webapp2_extras/sessions.html

        """
        self.session_store = sessions.get_store(request=self.request)
        try:
            webapp2.RequestHandler.dispatch(self)
        finally:
            self.session_store.save_sessions(self.response)

    @webapp2.cached_property
    def session(self):
        """
        This snippet of code is taken from the webapp2 framework documentation.
        See more at
        http://webapp-improved.appspot.com/api/webapp2_extras/sessions.html

        """
        return self.session_store.get_session()


class HomeHandler(BaseHandler):
    def get(self):
        template = jinja_environment.get_template('main.html')
        self.response.out.write(template.render(dict(
            facebook_app_id=auth.FACEBOOK_APP_ID,
            current_user=self.current_user
        )))

    def post(self):
        url = self.request.get('url')
        file = urllib2.urlopen(url)
        graph = facebook.GraphAPI(self.current_user['access_token'])
        response = graph.put_photo(file, "Test Image")
        photo_url = ("http://www.facebook.com/"
                     "photo.php?fbid={0}".format(response['id']))
        self.redirect(str(photo_url))


class LogoutHandler(BaseHandler):
    def get(self):
        if self.current_user is not None:
            self.session['user'] = None

        self.redirect('/')

jinja_environment = jinja2.Environment(
    loader=jinja2.FileSystemLoader(os.path.dirname(__file__))
)

app = webapp2.WSGIApplication(
    [('/', HomeHandler), ('/logout', LogoutHandler)],
    debug=True,
    config=config
)

我在example.html文件中添加了几行来传达新信息:

...

{% if current_user %}
    <p><a href="{{ current_user.profile_url }}">
        <img src="http://graph.facebook.com/{{ current_user.id }}/picture?type=square"/>
    </a></p>
    <p>Hello, {{ current_user.name|escape }}</p>
    <p>You have a friend named {{ current_user.friend_name|escape }}</p>  #################
    <p>Movies your friend likes, probably in some weird format: #################
        {{ current_user.friend_movies }}</p> ##############
{% endif %}

...

对于我的示例Facebook帐户,其中有一位名为“Sey Ian”的朋友,输出现在是:

enter image description here

我有两个主要问题:

  1. Sey Ian有一些喜欢的电影,为什么他们不显示?我是否需要在我的代码中执行与权限相关的其他操作?或者我使用错误的语法访问它们(例如,我需要像friend_movies=str(fmov["data"][0]["name"])这样的东西...对于这种情况下的第一部电影,有点像我如何访问第一个朋友的名字)?

  2. 在某些时候,我想提取有关用户及其朋友的更多信息。考虑到这一点,Python Facebook SDK图形调用有什么好的THOROUGH示例吗?弄清楚如何做我现在拥有的东西已经占据了永远的好处。

1 个答案:

答案 0 :(得分:0)

您应该查看Firebase身份验证page。 Firebase身份验证提供多种用户身份验证选项,包括Google,Facebook和Twitter。