Я пытаюсь расширить пример приложения AppEngine с помощью Facebook для входа в систему here. Мне удалось заставить его работать как есть (с добавлением собственного файла токена доступа, добавленного из отдельного файла), и он отображает эту симпатичную маленькую страницу (представленную вами example.html), когда пользователь входит в систему:Python Facebook SDK: Получение информации о друзьях пользователя
Теперь я хочу получить информацию о друзьях пользователей; например, фильмы, которые им понравились. Для начала я добавил множество разрешений в основное приложение на панели инструментов разработчика 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 счета, который имеет один друг с именем «Сэй Ян», на данный момент:
У меня есть два основных вопроса:
Сэй Ян есть некоторые понравились фильмы, так почему они не отображаются? Нужно ли мне делать что-то другое в моем коде? Или я обращаюсь к ним с неправильным синтаксисом (например, мне нужно что-то вроде
friend_movies=str(fmov["data"][0]["name"])
... для первого фильма в этом случае, вроде как я получаю доступ к имени первого друга)?В какой-то момент я хочу извлечь еще больше информации о пользователе и его друзьях. Имея это в виду, есть ли какие-нибудь хорошие, интересные примеры графических вызовов Python Facebook SDK? Выяснение того, как делать то, что у меня сейчас, взяло на себя большую часть НАВСЕГДА.