2011-12-30 39 views
1

这是我的第一个网络编程经验,所以我希望我的问题不会听起来很愚蠢。我被困在这个多天。了解“runwithfriends”facebook-app示例代码

我想了解一个示例代码: https://github.com/facebook/runwithfriends

但是我不理解,非常善于信息流的作品,我怎么能修改样本(代码即是如何工作的)。

例如,在代码的以下部分:

class RecentRunsHandler(BaseHandler): 
"""Show recent runs for the user and friends""" 
def get(self): 
    if self.user: 
     friends = {} 
     for friend in select_random(
       User.get_by_key_name(self.user.friends), 30): 
      friends[friend.user_id] = friend 

     self.render(u'runs', 
      friends=friends, 
      user_recent_runs=Run.find_by_user_ids(
       [self.user.user_id], limit=5), 
      friends_runs=Run.find_by_user_ids(friends.keys()), 
     ) 
    else: 
     self.render(u'welcome') 

据我所知(用HTML一起)是用于示出使用相同的应用程序的朋友有用的,并且如果正确地明白,这里是基本部分:

* friends_runs = Run.find_by_user_ids(friends.keys())*

但如果我要显示任何给定的朋友是什么。我该怎么做?

汇总,我想知道:

1-如何代码的流程运作的? (我不完全理解的解释here

2 - 如何操作代码,以便获得,例如,以显示该用户的朋友列表(没有必要使用相同的应用程序) ? 此外,我可以显示按某些特征(例如性别)过滤的朋友吗?

非常感谢!

回答

1

我使用的用于Facebook的python“SDK”我从https://gist.github.com/1190267 中拿出来,并将它与示例应用程序中的代码结合起来,以实现我希望用于canvas应用程序和网站使用的功能。

这取决于你是否使用Facebook的网站或画布应用程序。对于canvas应用程序,您可能可以使用javascript SDK做好,但对于“使用Facebook登录”,我需要在javascript关闭的情况下使用服务器端逻辑,因此我已经完成了该解决方案,并提供了可能有助于了解的详细信息。您可以尝试对该特定应用程序'runwithfriends'进行一些小改动,以了解哪些代码可以做什么。你看该项目包含虽然有些过时的做法:

  • 获取,设置cookies很可能是最好现在webapp2的的内置函数做这个,而不是自带的FB示例应用

  • 代码

    现在使用OAuth 2.0完成登录和注销操作,因此您正在查看的登录系统可能已过时,并且您需要使用描述为here的OAuth 2.0。我宁愿登录/注销serverside,所以我做了一个OAuth 2.0 pure python解决方案来登录/注销,遵循本教程中提到的来自FB的认证步骤。我必须清除cookie以记录没有记录的用户。

  • 要升级到python 2.7我还必须修改,以便HTTP标头不会转换为unicode。我不知道为什么,但除此之外,它抱怨说头“不是字符串”

要更精心回答您的具体问题:

1)您发布的requesthandler类是BaseHandler的子类,所以要充分理解它的作用,你可以看看BaseHandler类,因为你发布的是BAseHandler。 BaseHandler使用django模板进行渲染,如果你想将模板引擎切换到jinja2,那么这是可以修改的。此外,代码访问从BaseHandler继承的用户对象,并对其执行一些操作并将其呈现给模板。您可以尝试为您自己的子类BaseHandler创建一个请求处理程序,然后执行您所需的操作。

2)我可以操纵代码,我不是专家,所以你也应该能够做到。我想要一个简单的FB应用程序来显示随机图像,我可以操纵它来通过blob选择随机图像并渲染到模板,同时保持脸书的基本功能。该功能可用于获取使用图形API我这样做的用户:

def parse_signed_request(signed_request, secret): 
    """ 
    Parse signed_request given by Facebook (usually via POST), 
    decrypt with app secret. 

    Arguments: 
    signed_request -- Facebook's signed request given through POST 
    secret -- Application's app_secret required to decrpyt signed_request 
    """ 

    if '.' in signed_request: 
     (esig, payload) = signed_request.split('.') 
    else: 
     return {} 

    sig = urlsafe_b64decode(str(esig)) 
    data = _parse_json(urlsafe_b64decode(str(payload))) 

    if not isinstance(data, dict): 
     raise SignedRequestError('Pyload is not a json string!') 
     return {} 

    if data['algorithm'].upper() == 'HMAC-SHA256': 
     if hmac.new(secret, payload, hashlib.sha256).digest() == sig: 
      return data 
    else: 

     raise SignedRequestError('Not HMAC-SHA256 encrypted!') 

    return {} 


def get_user_from_cookie(cookies, app_id, app_secret): 
    """Parses the cookie set by the official Facebook JavaScript SDK. 

    cookies should be a dictionary-like object mapping cookie names to 
    cookie values. 

    If the user is logged in via Facebook, we return a dictionary with the 
    keys "uid" and "access_token". The former is the user's Facebook ID, 
    and the latter can be used to make authenticated requests to the Graph API. 
    If the user is not logged in, we return None. 

    Download the official Facebook JavaScript SDK at 
    http://github.com/facebook/connect-js/. Read more about Facebook 
    authentication at http://developers.facebook.com/docs/authentication/. 
    """ 
    cookie = cookies.get('fbsr_' + app_id, '') 
    if not cookie: 
     return None 
    response = parse_signed_request(cookie, app_secret) 
    if not response: 
     return None 

    args = dict(code=response['code'], client_id=app_id, 
       client_secret=app_secret, redirect_uri='') 

    file = \ 
     urllib.urlopen('https://graph.facebook.com/oauth/access_token?' 
         + urllib.urlencode(args)) 
    try: 
     token_response = file.read() 
    finally: 
     file.close() 

    access_token = cgi.parse_qs(token_response)['access_token'][-1] 
    logging.debug('returning cookie') 
    return dict(uid=response['user_id'], access_token=access_token) 

对于API的完整文档见http://developers.facebook.com/docs/api。你可以在http://github.com/facebook/connect-js/

得到的官方Facebook的JavaScript SDK我现在写代码同步一个webapp2_extras.auth账户与Facebook,这样的定制账户和Facebook账户是可以并存的,我们正在为这个讨论的解决方案在webapp2 groups和类别。我现在的做法是将建议的current_user添加到basehandler中,并将它用作FB身份,同时“合并”我的类FBUser,这是一个为facebook用户定制的类,它使我的网站和/或画布应用程序能够同步webapp2_extras.auth.models.User这是一个Expando模型,因此可以只添加属性它并没有如facebookid,名字,姓氏等

@property 
def current_user(self): 
    if not hasattr(self, '_current_user'): 
     self._current_user = None 
     cookie = get_user_from_cookie(self.request.cookies, 
       facebookconf.FACEBOOK_APP_ID, 
       facebookconf.FACEBOOK_APP_SECRET) 
     if cookie: 

      # Store a local instance of the user data so we don't need 
      # a round-trip to Facebook on every request 
      user = FBUser.get_by_key_name(cookie['uid']) 
      if not user: 
       graph = GraphAPI(cookie['access_token']) 
       profile = graph.get_object('me') 
       user = FBUser(key_name=str(profile['id']), 
           id=str(profile['id']), 
           name=profile['name'], 
           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() 
      self._current_user = user 
    return self._current_user 

您也可以解决的会话对象身份验证并围绕此构建您的身份验证系统。这就是我在使用自定义帐户和Facebook帐户时所做的事情,欢迎您在my repository处获得更多代码示例,以了解如何使用python 2.7对谷歌应用程序引擎进行整合facebook。

+0

谢谢。你的回答非常棒!你建议我使用或从另一个示例项目开始?正如你所提到的,这个项目包含一些过时的做法。也许https://gist.github.com/1190267更适合像我这样的新手。我来自C++低级编程,所以python和一般的web编程对我来说都是新的。 – Pdon 2011-12-30 19:10:17

+0

我建议你从纯JavaScript SDK开始,因为它很容易得到结果。然后你可以像我一样做,并将Javascript处理移动到服务器。您可以尝试将所有内容升级到webapp2,然后在webapp2组https://groups.google.com/forum/#!forum/webapp2中关注我们的进度 – 2011-12-30 19:28:48