Giter Site home page Giter Site logo

pyfacebook's Introduction

== PyFacebook ==

PyFacebook is a Python client library for the Facebook API.

Samuel Cormier-Iijima ([email protected])
Niran Babalola ([email protected])
Shannon -jj Behrens ([email protected])
David B. Edelstein ([email protected])
Max Battcher ([email protected])
Rohan Deshpande ([email protected])
Matthew Stevens ([email protected])
Sandro Turriate ([email protected])
Benjamin Zimmerman ([email protected])
Gisle Aas ([email protected])
Rand Bradley ([email protected])
Luke Worth ([email protected])
Andreas Cederström ([email protected])
Samuel Hoffstaetter ([email protected])
Andreas Ehn ([email protected])
Lee Li ([email protected])

http://github.com/sciyoshi/pyfacebook/

== Usage ==

To use this in your own projects, do the standard:

python setup.py install


== Documentation ==

Have a look at the examples/ directory. Most of the stuff should be
self-explanatory. There is also an example Django app in
examples/facebook, which should have enough to get you started.

See the developer wiki for more information.


== License ==

Copyright (c) 2008, Samuel Cormier-Iijima
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:
    * Redistributions of source code must retain the above copyright
      notice, this list of conditions and the following disclaimer.
    * Redistributions in binary form must reproduce the above copyright
      notice, this list of conditions and the following disclaimer in the
      documentation and/or other materials provided with the distribution.
    * Neither the name of the author nor the names of its contributors may
      be used to endorse or promote products derived from this software
      without specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS``AS IS'' AND ANY
EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

pyfacebook's People

Contributors

danielroseman avatar devioustree avatar devipriyasarkar avatar douglaswth avatar ehn avatar fixthisalready avatar flashingpumpkin avatar greut avatar h avatar ignas avatar igorgue avatar imrehg avatar jellybob avatar jezdez avatar jskitz avatar kad avatar matclayton avatar mjallday avatar mrbuds avatar nuggien avatar rockstar avatar ryszard avatar sciyoshi avatar statico avatar teepark avatar tswicegood avatar ulas-tuerkmen avatar waynemoore avatar woodenbrick avatar worldmaker avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

pyfacebook's Issues

Support upload of photos on other methods than photos.upload

According to http://bugs.developers.facebook.com/show_bug.cgi?id=3961 , it is possible to send pictures by the same mechanism as photos.upload, as multipart data together with the api call.

This is already documented:
http://wiki.developers.facebook.com/index.php/Events.create

The PHP api checks for an extra parameter and calls a different API if present:

public function events_create($event_info, $file = null) {
if ($file) {
return $this->call_upload_method('facebook.events.create',
array('event_info' => $event_info),
$file,
Facebook::get_facebook_url('api-photo') . '/restserver.php');
} else {
return $this->call_method('facebook.events.create',
array('event_info' => $event_info));
}
}

OAuth & Graph API Support

Any plan for PyFacebook to support OAuth & the new Graph API? The current available python-sdk by Facebook is not good enough to support Facebook Platform App (Canvas app).

ValueError in facebook.__init__.py

When tried to connect through a django app the following error occurs.

Exception in request:
Traceback (most recent call last):
File "/base/data/home/apps/app-name/1.339079629847560090/common/zip-packages/django-1.1.zip/django/core/handlers/base.py", line 92, in get_response
response = callback(request, _callback_args, *_callback_kwargs)
File "/base/data/home/apps/app-name/1.339079629847560090/facebook/djangofb/init.py", line 87, in newview
if not fb.check_session(request):
File "/base/data/home/apps/app-name/1.339079629847560090/facebook/init.py", line 1293, in check_session
self.session_key_expires = int(params['expires'])
ValueError: invalid literal for int() with base 10: 'None'

The error could be solved by replacing line 1292 by this

if params.get('expires'):
if params['expires'] == 'None':
params['expires'] = 0
self.session_key_expires = int(params['expires'])

multiquery (suggestion)

in facebook/init.py line 218 (fql methods) insert this:
'multiquery': [('queries', json, []),],

then try this:
fbc = Facebook("your_api_key", "")
# assign session_key and secret_key
data = fbc.fql.multiquery({"query1":"select post_id, actor_id, target_id, message from stream where filter_key in (select filter_key from stream_filter where uid={your_uid} AND type='newsfeed')", "query2":"select name from user where uid in (select actor_id from #query1)",})

http://wiki.developers.facebook.com/index.php/Fql.multiquery

Error 100

Hi,

I cannot get a session with an web application:

{u'error_code': 100, u'error_msg': u'Invalid parameter', u'request_args': [{u'value': u'JSON', u'key': u'format'}, {u'value': u'...', u'key': u'auth_token'}, {u'value': u'...', u'key': u'sig'}, {u'value': u'1.0', u'key': u'v'}, {u'value': u'...', u'key': u'api_key'}, {u'value': u'facebook.auth.getSession', u'key': u'method'}]}

I always get a error 100... what could be the possible errors?

I do something as simple as :

            self.api.auth_token = auth_datas['auth_token']
            # getSession sets the session_key and uid
            self.api.auth.getSession()
            self.authenticated = True

add require_facebook_session()

Right now, we have facebook.require_login() that forcefully make the user add the application.

Can we have a check where it just makes sure that the user has to be logged into facebook but not necessary has authorize the application?

I want to let all users who logged into facebook to interact with my form because the only thing i care about is their facebook uid. But lock out the users who are not logged into facebook.

Thanks.

Problem while running the test cases

I am getting following problem when I ran the tests\test.py

Traceback (most recent call last):
File "C:/source/pyfacebook/tests\tests.py", line 227, in test10
import Image
ImportError: No module named Image

fb.session_key_expires in its default state errors out

Running pyfacebook by itself causes an error to be generated.

Traceback (most recent call last):

  File "/Users/harrytruman/projects/d51/givingnetwork/parts/django/django/core/servers/basehttp.py", line 279, in run
    self.result = application(self.environ, self.start_response)

  File "/Users/harrytruman/projects/d51/givingnetwork/parts/django/django/core/servers/basehttp.py", line 651, in __call__
    return self.application(environ, start_response)

  File "/Users/harrytruman/projects/d51/givingnetwork/parts/django/django/core/handlers/wsgi.py", line 245, in __call__
    response = middleware_method(request, response)

  File "/Users/harrytruman/projects/d51/givingnetwork/parts/pyfacebook/facebook/djangofb/__init__.py", line 240, in process_response
    expire_time = datetime.utcfromtimestamp(fb.session_key_expires)

TypeError: a float is required

[PATCH]: remove redundant string concatenations, dict lookups from validate_cookie_signature()

This method popped up quite high in some profiling results. Below is a patch that removes the redundant string concatenations, dictionary lookups and join() call - the CPU time for me went from .074 to .000.

Index: facebook/__init__.py
===================================================================
--- facebook/__init__.py  (rev XXXX)
+++ facebook/__init__.py  (working copy)
@@ -1343,23 +1343,27 @@
         """
         Validate parameters passed by cookies, namely facebookconnect or js api.
         """
-        if not self.api_key in cookies.keys():
+
+        api_key = self.api_key
+        if api_key not in cookies:
             return None

-        sigkeys = []
-        params = dict()
-        for k in sorted(cookies.keys()):
-            if k.startswith(self.api_key+"_"):
-                sigkeys.append(k)
-                params[k.replace(self.api_key+"_","")] = cookies[k]
-
-
-        vals = ''.join(['%s=%s' % (x.replace(self.api_key+"_",""), cookies[x]) for x in sigkeys])
+        prefix = api_key + "_"
+       
+        params = {} 
+        vals = ''
+        for k in sorted(cookies):
+            if k.startswith(prefix):
+                key = k.replace(prefix,"")
+                value = cookies[k]
+                params[key] = value
+                vals += '%s=%s' % (key, value)
+                
         hasher = hashlib.md5(vals)

         hasher.update(self.secret_key)
         digest = hasher.hexdigest()
-        if digest == cookies[self.api_key]:
+        if digest == cookies[api_key]:
             return params
         else:
             return False

WSGI / pylons-0.9.7 fixes

Using pyfacebook with pylons has issues with redirects nesting inside the application iframe. It appears this issue was already addressed for Django with commit http://github.com/sciyoshi/pyfacebook/commit/2a6b442c0e2d7674f9c347a340045286d3ece8f2. Additionally, the transition from Paster to WebOb HTTP exceptions on an earlier commit needed some updates as some variable names differ.

Not sure of the best way to paste in this patch (all in wsgi.py), so here goes:

Top of the file:
import re

Replace CanvasRedirect definition with:
class CanvasRedirect(HTTPOk):

    """This is for redirects within the canvas using FBML."""

    try:
        from string import Template
    except ImportError:
        from webob.util.stringtemplate import Template

    html_template_obj = Template('<html><head></head><body>${body}</body></html>')
    body_template_obj = Template('<fb:redirect url="${location}" />')

    def __init__(self, location):
        HTTPOk.__init__(self, headers = { 'location': location } )

class TopLevelRedirect(HTTPOk):

    """This is for redirects to top-level Facebook pages."""

    try:
        from string import Template
    except ImportError:
        from webob.util.stringtemplate import Template

    html_template_obj = Template('<html><head></head><body>${body}</body></html>')
    body_template_obj = Template('<script type="text/javascript">\ntop.location.href = "${location}";\n</script>')

    def __init__(self, location):
        HTTPOk.__init__(self, headers = { 'location': location } )

Change definition of redirect_to:

    def redirect_to(self, url):
        """Wrap Pylons' redirect_to function so that it works in_canvas.

        By the way, this won't work until after you call
        check_session().

        """

        if self.in_canvas:
            raise CanvasRedirect(url)
        elif re.search("^https?:\/\/([^\/]*\.)?facebook\.com(:\d+)?", url.lower()):
            raise TopLevelRedirect(url)
        else:
            pylons_redirect_to(url)

Bug in signature generation with getPublicInfo and application_canvas_name

fb.application.getPublicInfo(application_canvas_name="name")
DEBUG: {'api_key': '000000000000my_key00000000000000', 'format': 'XML', 'application_canvas_name ': 'name', 'method': 'facebook.application.getPublicInfo', 'v': '1.0'}

The DEBUG line is just a printout of the args argument to _hash_args(self, args, secret=None)

Notice that for some reason there is a ' ' space character after the application_canvas_name. This is causing signatures to fail.

The issue is on line 121 of facebook/init.py, http://github.com/sciyoshi/pyfacebook/blob/95fa6c33f002fb0b550df8ecb8619f9491848ec0/facebook/__init__.py#L121

data.getCookies

The method definition for data.getCookies is as follows:

'data': {
    'getCookies': [
        ('uid', int, []),
        ('string', str, []),
    ],

The second argument 'string' is actually the name of the desired cookie and optional, as per http://wiki.developers.facebook.com/index.php/Data.getCookies so the method definition should actually read

'data': {
    'getCookies': [
        ('uid', int, []),
        ('string', str, ['optional']),
    ],

This is important because to get all cookies you must not specify a cookie name, so not having that parameter as optional undermines the entire utility of the method.

Error on facebook.auth.getSession()

I've used pyFacebook for weeks without any problem, but since this week every time I call
facebook.auth.getSession()
I receive this error:

Traceback (most recent call last):
File "../file.py", line 27, in nameFile
facebook.auth.getSession()
File "../pyFacebook/Facebook.py", line 669, in getSession
result = self._client('%s.getSession' % self._name, args)
File "../pyFacebook/Facebook.py", line 1110, in call
return self._parse_response(response, method)
File "../pyFacebook/Facebook.py", line 1047, in _parse_response
self._check_error(result)
File "../pyFacebook/Facebook.py", line 998, in _check_error
raise FacebookError(response['error_code'], response['error_msg'], response['request_args'])
pyFacebook.Facebook.FacebookError: Error 100: Invalid parameter

Anyone can help me?
Thank you

Detect that app is running inside FB iframe

Small change to allow an app built on pyfacebook to detect if it is being run inside an FB iframe easily.

Patch:

diff --git a/facebook/init.py b/facebook/init.py
index 3813142..a9a5ef0 100644
--- a/facebook/init.py
+++ b/facebook/init.py
@@ -856,6 +856,10 @@ class Facebook(object):
in_canvas
True if the current request is for a canvas page.

  • in_iframe
  •    True if the current request is for an HTML page to embed in Facebook
    
  •    inside an iframe.
    
    in_profile_tab
    True if the current request is for a user's tab for your application.

@@ -1264,6 +1268,9 @@ class Facebook(object):
if params.get('in_canvas') == '1':
self.in_canvas = True

  •    if params.get('in_iframe') == '1':
    
  •        self.in_iframe = True
    
    • if params.get('in_profile_tab') == '1':
      self.in_profile_tab = True

datetime confusion in djangofb

In pyfacebook/facebook/djangofb/init.py, because of the "from datetime import datetime" on line 4, it should only be datetime.fromtimestamp on line 226, not datetime.datetime.fromtimestamp.

Support for require_login(required_permissions='<list of permissions>')

It appears that pyfacebook does not support the required_permissions argument to require_login, unlike Facebook's php API: http://wiki.developers.facebook.com/index.php/Extended_permissions#Requiring_Extended_Permissions. Is this deliberate? Is there any plan to add support for this? Also, is there a workaround that would automatically prompt users adding an FBML app and "logging into" the app for the first time for extended permissions?

I've posted the same question to stackoverflow.com: http://stackoverflow.com/questions/2440327/require-extended-permissions-in-fbml-pyfacebook-app

undefined symbol: PyUnicodeUCS4_Decode in

didn't see this issue tracking system -> repost from google code site:
_parse_response(response, method)

python version 2.4.3

What steps will reproduce the problem?

  1. got latest init.py, renamed to facebook.py and dropped in same
    directory as my simple gt.py script.

  2. script looks as follows:

    !/usr/local/bin/python

    import sys
    from facebook import Facebook

    sys.stderr = sys.stdout

    print "Content-Type: text/xml" # HTML is following
    print # blank line, end of headers

    print "Hello World: running version ",sys.version

    fb = Facebook('', '')
    fb.auth.createToken()
    fb.login()
    fb.auth.getSession()
    fb.users.getInfo([fb.uid], ['name', 'birthday'])

    print ""

  3. view script via browser (Chrome v1)

What is the expected output? What do you see instead?
expected: html page displaying "hello world python 2.4.3"

instead error with stacktrace printed:

Traceback (most recent call last): File "gt.py", line 14, in ?
fb.auth.createToken()
File "/home/clientsi/public_html/northshore/gt/facebook.py", line 602, in
createToken token = self._client('%s.createToken' % self._name)
File "/home/clientsi/public_html/northshore/gt/facebook.py", line 1002, in
call return self._parse_response(response, method)
File "/home/clientsi/public_html/northshore/gt/facebook.py", line 941, in
_parse_response dom = minidom.parseString(response)
File "/usr/lib/python2.4/xml/dom/minidom.py", line 1924, in parseString
File "/usr/lib/python2.4/xml/dom/expatbuilder.py", line 32, in ?
File "/usr/lib/python2.4/xml/parsers/expat.py", line 4, in ? ImportError:
/usr/local/lib/python2.4/lib-dynload/pyexpat.so: undefined symbol:
PyUnicodeUCS4_Decode

What version of the product are you using? On what operating system?
Not sure? Can't find version info in any file on site... running on python
v2.4.3
OS & Kernel version: Linux 2.6.28.5-grsec-sg2

[Patch] test10 failed

Seems the test10 mock httplib.HTTP, however the code is using httplib.HTTPConnection.

Index: tests/test.py
===================================================================
--- tests/test.py       (revision 4720)
+++ tests/test.py       (working copy)
@@ -232,20 +232,19 @@
         fb = facebook.Facebook(my_api_key, my_secret_key)
         fb.login = self.login
         
-        facebook.httplib.HTTP = Mock('httplib.HTTP')
+        facebook.httplib.HTTPConnection = Mock('httplib.HTTPConnection')
         http_connection = Mock('http_connection')
-        facebook.httplib.HTTP.mock_returns = http_connection
+        facebook.httplib.HTTPConnection.mock_returns = http_connection
         http_connection.send.mock_returns_func = self.send
-        def _http_passes():
-            return [200,]
-        http_connection.getreply.mock_returns_func = _http_passes
-
         def read():
             response = {"stuff":"stuff"}
             response_str = simplejson.dumps(response)
             return response_str
-        http_connection.file.read.mock_returns_func = read
-        
+        mock_response = Mock('httplib.HTTPResponse')
+        mock_response.status = 200
+        mock_response.read.mock_returns_func = read
+        http_connection.getresponse.mock_returns = mock_response
+
         response = {"session_key":"key","uid":"my_uid","secret":"my_secret","expires":"my_expires"}
         response_str = simplejson.dumps(response)
         res = fb.auth.getSession()

Add support for the story_size argument to feed.publishUserAction

Here's the patch:

diff --git a/facebook/__init__.py b/facebook/__init__.py
index 70c9f12..4809f0c 100644
--- a/facebook/__init__.py
+++ b/facebook/__init__.py
@@ -203,6 +203,7 @@ METHODS = {
             ('template_data', json, ['optional']),
             ('target_ids', list, ['optional']),
             ('body_general', str, ['optional']),
+            ('story_size', int, ['optional']),
         ],
     },

I provided this patch previously in Issue 93 on the Google Code site.

Value Error

Traceback (most recent call last):

File "C:\Python26\lib\site-packages\django\core\servers\basehttp.py", line 279, in run
self.result = application(self.environ, self.start_response)

File "C:\Python26\lib\site-packages\django\core\servers\basehttp.py", line 651, in call
return self.application(environ, start_response)

File "C:\Python26\lib\site-packages\django\core\handlers\wsgi.py", line 241, in call
response = self.get_response(request)

File "C:\Python26\lib\site-packages\django\core\handlers\base.py", line 73, in get_response
response = middleware_method(request)

File "build\bdist.win32\egg\socialregistration\middleware.py", line 13, in process_request
request.facebook.check_session(request)

File "C:\Python26\lib\site-packages\facebook__init__.py", line 1293, in check_session
self.session_key_expires = int(params['expires'])

ValueError: invalid literal for int() with base 10: 'None'

`FacebookError` is not pickleable

FacebookError does not call Exception.__init__, in addition it abuses self.args, which is used by Exception to keep the original arguments used when instantiating the exception.

This is an example triggering the bug:

>>> import pickle
>>> from facebook import FacebookError
>>> x = FacebookError("code", "msg", ("arg1", "arg2", "arg3"))
>>> pickle.loads(pickle.dumps(x))
FacebookError('a', 'r', 'g', '3')

Fix for the issue is at: http://github.com/ask/pyfacebook/commit/ac4925452b1a691bc7cde9452947042d96e45de3

This fix has a side-effect in that it renames the previous .args attribute to
.extra_args, which is a backwards incompatible change.

error on check_session when "expires" param is "None"

Just ran into an issue where my various FB cookies were set to have an "expires" value of "None". This causes an issue in check_session() which assumes it's going to get something that can be run through int().

The exception message is: invalid literal for int() with base 10: 'None' and it's being thrown from line 1293 of facebook/__init__.py.

Remove post fails to validate

When the user removes the application within facebook they post this back to the application. The 'check_session' method fails to validate this condition. I added the following two lines near the end (line 1310) to address this case by triggering up the 'uninstall' parameter:

    elif 'canvas_user' in params:
        self.uid = params['canvas_user']
    elif 'uninstall' in params:                       << new
        self.uid = params['user']                   << new
    else:
        return False

Why does check_session return True when canvas_user is in params?

I was using the require_login decorator and noticed that when people arrived at my app for the first time by clicking a link from a request, it wasn't asking them to allow access, and various pyfacebook calls were failing. I tracked this down to the part of check_session:

   elif 'canvas_user' in params:
        self.uid = params['canvas_user']
   else:
        return False
   return True

In this case there is a canvas_user but we don't have a valid session_key. Shouldn't that mean that check_session returns False, and thus the require_login decorator will redirect the user to allow access?

Depreciation Warning

I am using python v. 2.6 and I get the following:

C:\Python26\lib\site-packages\facebook\djangofb__init__.py:185:
DeprecationWarning: Calling the deprecated function 'new_wrapper'
Downgrade to decorator 2.3 if you want to use this functionality
return decorator.new_wrapper(updated, f)

Add a callback to the photos.upload method

This patch adds the ability to pass in a callback to the upload method for displaying progress in an application.

--- __init__.py.orig    2009-04-20 00:18:04.000000000 +0100
+++ __init__.py 2009-05-06 13:01:04.000000000 +0100
@@ -635,7 +635,7 @@
 class PhotosProxy(PhotosProxy):
     """Special proxy for facebook.photos."""

-    def upload(self, image, aid=None, caption=None, size=(604, 1024), filename=None):
+    def upload(self, image, aid=None, caption=None, size=(604, 1024), filename=None, callback=None):
         """Facebook API call. See http://developers.facebook.com/documentation.php?v=1.0&method=photos.upload

         size -- an optional size (width, height) to resize the image to before uploading. Resizes by default
@@ -678,21 +678,38 @@
         content_type, body = self.__encode_multipart_formdata(list(args.iteritems()), [(image, data)])
         urlinfo = urlparse.urlsplit(self._client.facebook_url)
         try:
-            h = httplib.HTTP(urlinfo[1])
+            content_length = len(body)
+            chunk_size = 4096
+            
+            h = httplib.HTTPConnection(urlinfo[1])
             h.putrequest('POST', urlinfo[2])
             h.putheader('Content-Type', content_type)
-            h.putheader('Content-Length', str(len(body)))
+            h.putheader('Content-Length', str(content_length))
             h.putheader('MIME-Version', '1.0')
             h.putheader('User-Agent', 'PyFacebook Client Library')
             h.endheaders()
-            h.send(body)
-
-            reply = h.getreply()
-
-            if reply[0] != 200:
-                raise Exception('Error uploading photo: Facebook returned HTTP %s (%s)' % (reply[0], reply[1]))
-
-            response = h.file.read()
+            
+            if callback:
+                count = 0
+                while len(body) > 0:
+                    if len(body) < chunk_size:
+                        data = body
+                        body = ''
+                    else:
+                        data = body[0:chunk_size]
+                        body = body[chunk_size:]
+                    
+                    h.send(data)
+                    count += 1
+                    callback(count, chunk_size, content_length)
+            else:
+                h.send(body)
+            
+            response = h.getresponse()
+            
+            if response.status != 200:
+                raise Exception('Error uploading photo: Facebook returned HTTP %s (%s)' % (response.status, response.reason))
+            response = response.read()
         except:
             # sending the photo failed, perhaps we are using GAE
             try:

Pyfacebook does not work properly in canvas Iframe mode [Patch included]

I am sorry if am not following the correct procedures, i am not familiar with neither github nor pyfacebook development practices.

According to
http://code.google.com/p/pyfacebook/issues/detail?id=96
and
http://forum.developers.facebook.com/viewtopic.php?id=24188&p=3

pyfacebook will only properly work in Canvas Iframe mode if the parameters are always passed in
the URI.

This means that if the user clicks a link in the app, pyfacebook will ask facebook for credentials, losing whatever action was requested.

The following patch was based on facebook.php, creates Javascript cookies that are compatible with the already existing validate_cookie_signature() method.

I have included a P3P HTTP Header so that it will work on IE, but there are still issues with safari, common to all facebook Iframe apps.


[PATCH]  * Creates signed cookies from GET/POST tokens so that app properly works in Iframe canvas mode.


---
 facebook/__init__.py          |    8 ++++++++
 facebook/djangofb/__init__.py |   21 +++++++++++++++++++++
 2 files changed, 29 insertions(+), 0 deletions(-)

diff --git a/facebook/__init__.py b/facebook/__init__.py
index 3813142..b498045 100644
--- a/facebook/__init__.py
+++ b/facebook/__init__.py
@@ -856,6 +856,9 @@ class Facebook(object):
     in_canvas
         True if the current request is for a canvas page.
 
+    is_session_from_cookie
+            True if the current request session comes from a session cookie.
+
     in_profile_tab
         True if the current request is for a user's tab for your application.
 
@@ -918,6 +921,7 @@ class Facebook(object):
         self.uid = None
         self.page_id = None
         self.in_canvas = False
+        self.is_session_from_cookie = False
         self.in_profile_tab = False
         self.added = False
         self.app_name = app_name
@@ -1227,6 +1231,7 @@ class Facebook(object):
         if self.session_key and (self.uid or self.page_id):
             return True
 
+
         if request.method == 'POST':
             params = self.validate_signature(request.POST)
         else:
@@ -1253,10 +1258,12 @@ class Facebook(object):
             # first check if we are in django - to check cookies
             if hasattr(request, 'COOKIES'):
                 params = self.validate_cookie_signature(request.COOKIES)
+                self.is_session_from_cookie = True
             else:
                 # if not, then we might be on GoogleAppEngine, check their request object cookies
                 if hasattr(request,'cookies'):
                     params = self.validate_cookie_signature(request.cookies)
+                    self.is_session_from_cookie = True
 
         if not params:
             return False
@@ -1358,6 +1365,7 @@ class Facebook(object):
         hasher.update(self.secret_key)
         digest = hasher.hexdigest()
         if digest == cookies[self.api_key]:
+            params['is_session_from_cookie'] = True
             return params
         else:
             return False
diff --git a/facebook/djangofb/__init__.py b/facebook/djangofb/__init__.py
index 7d6e68e..987271b 100644
--- a/facebook/djangofb/__init__.py
+++ b/facebook/djangofb/__init__.py
@@ -5,6 +5,7 @@ import facebook
 from django.http import HttpResponse, HttpResponseRedirect
 from django.core.exceptions import ImproperlyConfigured
 from django.conf import settings
+from datetime import datetime
 
 try:
     from threading import local
@@ -213,4 +214,24 @@ class FacebookMiddleware(object):
         if not self.internal and request.facebook.session_key and request.facebook.uid:
             request.session['facebook_session_key'] = request.facebook.session_key
             request.session['facebook_user_id'] = request.facebook.uid
+
+        try:
+            fb = request.facebook
+        except:
+            return response
+
+        if not fb.is_session_from_cookie:
+            # Make sure the browser accepts our session cookies inside an Iframe
+            response['P3P'] = 'CP="NOI DSP COR NID ADMa OPTa OUR NOR"'
+            fb_cookies = {
+                'expires': fb.session_key_expires,
+                'session_key': fb.session_key,
+                'user': fb.uid,
+            }
+
+            expire_time = datetime.utcfromtimestamp(fb.session_key_expires)
+
+            for k in fb_cookies:
+                response.set_cookie(self.api_key + '_' + k, fb_cookies[k], expires=expire_time )
+            response.set_cookie(self.api_key , fb._hash_args(fb_cookies), expires=expire_time )
         return response
-- 
1.6.0.4

patch for admin.banUsers and friends.get method

diff --git a/facebook/__init__.py b/facebook/__init__.py
index 3813142..3e9a74d 100644
--- a/facebook/__init__.py
+++ b/facebook/__init__.py
@@ -127,6 +127,9 @@ METHODS = {
         'getAllocation': [
             ('integration_point_name', str, []),
         ],
+        'banUsers': [
+            ('uids', list, []),
+        ],
     },

     # auth methods
@@ -225,6 +228,7 @@ METHODS = {
         ],

         'get': [
+            ('uid', int, ['optional']),
             ('flid', int, ['optional']),
         ],

fb.added is always False

I'm having problems with the "added" instance variable. It seems to be
sticking at False even though indeed the user has authorized the
application.

Here's the relevant part of my code, I'm working in Google App Engine:

class MainPage(webapp.RequestHandler):
 def get(self):
   fb = facebook.Facebook(_FbApiKey, _FbSecret, app_name=_FbAppName)

   if fb.check_session(self.request) and fb.added:
       pass
   else:
      url = fb.get_add_url(next=fb.get_app_url())
      self.response.out.write('<script language="javascript">top.location.href="' + url + '"</script>')
      return

   self.response.out.write("<html><body>You are now logged in and you added the app!</body></html>")

It's getting into an infinite redirect cycle, because fb.added is
always False. The first time, check_session returns False, but after
logging in and authorizing the application, it returns True. In any
case, fb.added is always False.

Could someone please take a look at this. XFBML breaking app

Hi, I have been trying to solve this myself, but I cannot make any sense of it.

When I enable XFBML, my app will only log in the user once maybe twice, and then they get sent to the frontpage with a new auth_token attached to the url.

I have a thread about it here and the suggestion from XaeroDegreaz seems to be a bit off, but I am not sure.
THREADLINK: http://forum.developers.facebook.com/viewtopic.php?pid=218519

Maybe this is not affection pyFacebook directly but it is causing it to deliver a cookie/session to the XFBML parser that is then changed for some reason and therefor nothing works.

Could someone with a greater understanding of pyFacebook please take a look in my thread and see if there is anything that can be done on this end, or I will have to continue hitting the facebook dev in the head till they stop breaking things for no reason.

Many thanks for any hepl you might be able to give. If you need any more info, just say the word and I will try to produce it as fast as I can.

facebook django middleware is basically broken

the 'is_session_from_cookie' flag is not being set at all in the facebook django middleware, nor are properties like uid, session_key and session_key_expires being properly loaded. I believe this normally occurs in the 'checkSession' method, however it is not being called in the middleware at all.

The effect is that in webkit-based, and possibly other browsers (firefox doesn't seem to honor the cookie settings in the response header for some reasons), the fbconnect cookies are getting overwritten with null data, effectively logging the user out of fbconnect and making the session invalid.

Who is upstream

Hi all, it's not really an issue, but we face to a situation where we have many forks and a dead upstream (sciyoshi). Maybe I've not understand the whole power of github, but I never know which fork to merge to find the function I want. I'm never sure that I implement something new or lacking.

Is there any solution to this, or shall we define a new fork as upstream and update the doc consequently ?

For information, I've merged Mrbouyou's fork.

pyfacebook on GAE

Hi, don't know if this is the right place for this, but I couldn't find anywhere else so, here goes.

I have been trying to use pyfacebook on Google-App-Engine. The facebook app is running in iframe mode and I keep getting errors.

I have a thread about it on SO, which also includes my rather hackish solution. But maybe this will be enough for you to find the error.

http://stackoverflow.com/questions/2039366/app-engine-patch-and-pyfacebook-not-working

I will be monitoring both this issue and the thread on SO, so if you have any more questions just put them where you find it most convenient.

Add support for generate_session_secret

I use pyfacebook as a session proxy for iPhone applications using Facebook Connect. In order for Facebook to return a session secret, you must pass "generate_session_secret=1" as a GET variable in the getSession() method.

This is easily patched by adding generate_session_secret as a named paramater in init() and adding generate_session_secret to args{} in auth.getSession()

Migrations -> New Data Permissions -> Error Code: 100

New permissions dialog seems to required additional parameters.

You can try the new dialog in your Canvas application settings in Facebook (Developer App -> Your App -> Settings -> Migrations -> "New Data Permissions" -> Enable)

and then catch error:

API Error Code: 100
API Error Description: Invalid parameter
Error Message: Requires valid next URL.

Guess all of us may hit the issue in June because "(Migration ends on: June 1, 2010)"

AssertionError When GAE Is Installed But Not Used

In the situation where you have GAE accessible on your system's path, but it is not actually being used (e.g. you're currently developing a Pylons project that doesn't use GAE) there is a problem when using the urlread function, which is defined near the top of pyfacebook.py.

Because GAE is on the system, line 79 ("from google.appengine.api import urlfetch") does not raise an import error, so the GAE version of the urlread function is used. However, when it is invoked in this situation it raises an AssertionError with this explanation: 'No api proxy found for service "urlfetch"'. This is probably caused by the fact that GAE isn't actually running in this case.

The quickest fix is just to except this error and use the default behavior:

91c91,92
<         result = urlfetch.fetch(url, method=method,

---
>         try:
>             result = urlfetch.fetch(url, method=method,
92a94,96
>         except AssertionError:
>             res = urllib2.urlopen(url, data=data)
>             return res.read()

There's probably a better, long-term fix for this problem though.

auth.getSession() returns Error 100 (e.g. desktop app tute)

I just tried to go through the Desktop application tutorial (http://wiki.developers.facebook.com/index.php/User:PyFacebook_Tutorial), and it works until I try the fb.auth.getSession() which returns the following error:

Traceback (most recent call last):
File "", line 1, in ?
File "/Users/tramdas/repos/pyfacebook/facebook/init.py", line 670, in getSession
result = self._client('%s.getSession' % self._name, args)
File "/Users/tramdas/repos/pyfacebook/facebook/init.py", line 1123, in call
return self._parse_response(response, method)
File "/Users/tramdas/repos/pyfacebook/facebook/init.py", line 1056, in _parse_response
self._check_error(result)
File "/Users/tramdas/repos/pyfacebook/facebook/init.py", line 1007, in _check_error
raise FacebookError(response['error_code'], response['error_msg'], response['request_args'])
facebook.FacebookError: Error 100: Invalid parameter

This was with Python 2.4.6 on OS X, with PyFacebook checked out a couple of days ago.

This could be related to issue 6 (http://github.com/sciyoshi/pyfacebook/issues#issue/6). Seems like this problem has been coming up from time to time, e.g. see here: http://code.google.com/p/pyfacebook/issues/detail?id=50

Is this a known issue? If it is, maybe someone should make a note of it on the wiki tutorial (http://wiki.developers.facebook.com/index.php/User:PyFacebook_Tutorial) since I'm sure many other newbies like me have lost a fair bit of time trying to get it to work :-)

pages.getInfo has incorrect parameters

The method template for pages.getInfo is as follows:

'pages': {
'getInfo': [
('page_ids', list, ['optional']),
('uid', int, ['optional']),
],

This causes an Error 100 if one tries to use the getInfo method in a manner similar to users.getInfo. I think the parameters should be:

'pages': {
'getInfo': [
('fields', list, [('default', ['name'])]),
('page_ids', list, ['optional']),
],

to conform with the API. I could be wrong, however; I've jsut started using PyFacebook.

User ID > 2^31-1

I got integrity error as explained in http://forum.developers.facebook.com/viewtopic.php?pid=152522#p152522 and it's caused by a limit of pyfacebook lib or database model.

I moved id from int(11) to varchar(20) and moved from
user, created = self.get_or_create(id=int(facebook.uid))
to
user, created = self.get_or_create(id=facebook.uid)

now it works and in mysql I get 100000000130682 as a user id (that caused the error, because it was changed to 2147483647 when saving).

it seems a very strange facebook id, I think it's a problem of the library...

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.