Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Nochmals #19

Closed
wants to merge 37 commits into from

2 participants

@sbaechler
Owner

It's actually just 18 commits (but a rebase didn't quite work).

There is a change in models.Posts. If you are using Posts you need to migrate the database schema.
There is a change in fb.User. You need to migrate the database schema

There is a new insight link in the page admin that can be used in the django-admin to link to the insights for an app.

A new batch-request function for the Graph API

New token_expires function for Page, because unlimited tokens are deprecated. Now they last only 60 days.

A new function to request long-term-tokens

A new Milestones model.

Big docs update

Deauthorize callback now working. Even has a preview function.

@sbaechler
Owner

try moving to posts module

sbaechler added some commits
@sbaechler sbaechler optionally add generic related object 6a106eb
@sbaechler sbaechler update in deauthorization callback. With preview! 531bb48
@sbaechler sbaechler modification for deauthorize callback d225c51
@sbaechler sbaechler Merge branch 'structured' of github.com:sbaechler/django-facebook-gra…
…ph into sbaechler-structured

Conflicts:
	facebook/views.py
cd2efb8
@sbaechler sbaechler add insight link to page 44a8379
@sbaechler sbaechler add batch request to graph, new pagepost intermediate model. Small fixes 18973e9
@sbaechler sbaechler fix in feincms views, add helper in posts dca3ede
@sbaechler sbaechler add expires in for page access token 51566fd
@sbaechler sbaechler add access token expires in field and adjusted admin c2222e2
@sbaechler sbaechler update user profile fields 8b2fa71
@sbaechler sbaechler add milestones 602af0d
@sbaechler sbaechler add insight link to page ef8022b
@sbaechler sbaechler add batch request to graph, new pagepost intermediate model. Small fixes 7c5380a
@sbaechler sbaechler fix in feincms views, add helper in posts b2669b6
@sbaechler sbaechler add expires in for page access token ffb7bee
@sbaechler sbaechler add access token expires in field and adjusted admin 04e0cd1
@sbaechler sbaechler update in docs 7cd9d5d
@sbaechler sbaechler uncomment post_throughs due to compatibility issues 8c1ce1c
@sbaechler sbaechler optionally add generic related object df555fa
@sbaechler sbaechler update in deauthorization callback. With preview! a397249
@sbaechler sbaechler modification for deauthorize callback e585f67
@sbaechler sbaechler cleanup in views 943273b
@sbaechler sbaechler Merge branch 'structured' of github.com:sbaechler/django-facebook-gra…
…ph into structured

Conflicts:
	facebook/modules/profile/page/admin.py
6fe59dd
@schmidsi schmidsi was assigned
@schmidsi

seems ok. good work with token expires and deauth callbacks.

@schmidsi schmidsi closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Mar 8, 2012
  1. @sbaechler

    add insight link to page

    sbaechler authored
Commits on Mar 12, 2012
  1. @sbaechler
Commits on Mar 15, 2012
  1. @sbaechler
Commits on Mar 16, 2012
  1. @sbaechler
  2. @sbaechler
Commits on Apr 3, 2012
  1. @sbaechler

    fix in feincms middleware

    sbaechler authored
Commits on Apr 11, 2012
  1. @sbaechler

    add insight link to page

    sbaechler authored
  2. @sbaechler
  3. @sbaechler
  4. @sbaechler
  5. @sbaechler
  6. @sbaechler

    update in docs

    sbaechler authored
  7. @sbaechler

    Merge branch 'structured' of github.com:sbaechler/django-facebook-gra…

    sbaechler authored
    …ph into sbaechler-structured
  8. @sbaechler
Commits on Apr 13, 2012
  1. @sbaechler
  2. @sbaechler
  3. @sbaechler
  4. @sbaechler

    Merge branch 'structured' of github.com:sbaechler/django-facebook-gra…

    sbaechler authored
    …ph into sbaechler-structured
    
    Conflicts:
    	facebook/views.py
Commits on May 19, 2012
  1. @sbaechler

    add insight link to page

    sbaechler authored sbaechler committed
  2. @sbaechler
  3. @sbaechler

    fix in feincms views, add helper in posts

    sbaechler authored sbaechler committed
  4. @sbaechler

    add expires in for page access token

    sbaechler authored sbaechler committed
  5. @sbaechler

    add access token expires in field and adjusted admin

    sbaechler authored sbaechler committed
  6. @sbaechler

    update user profile fields

    sbaechler authored
  7. @sbaechler

    add milestones

    sbaechler authored
  8. @sbaechler

    add insight link to page

    sbaechler authored sbaechler committed
  9. @sbaechler
  10. @sbaechler

    fix in feincms views, add helper in posts

    sbaechler authored sbaechler committed
  11. @sbaechler

    add expires in for page access token

    sbaechler authored sbaechler committed
  12. @sbaechler

    add access token expires in field and adjusted admin

    sbaechler authored sbaechler committed
  13. @sbaechler

    update in docs

    sbaechler authored sbaechler committed
  14. @sbaechler

    uncomment post_throughs due to compatibility issues

    sbaechler authored sbaechler committed
  15. @sbaechler

    optionally add generic related object

    sbaechler authored sbaechler committed
  16. @sbaechler

    update in deauthorization callback. With preview!

    sbaechler authored sbaechler committed
  17. @sbaechler

    modification for deauthorize callback

    sbaechler authored sbaechler committed
  18. @sbaechler

    cleanup in views

    sbaechler authored
  19. @sbaechler

    Merge branch 'structured' of github.com:sbaechler/django-facebook-gra…

    sbaechler authored
    …ph into structured
    
    Conflicts:
    	facebook/modules/profile/page/admin.py
This page is out of date. Refresh to see the latest.
View
6 docs/installation.rst
@@ -54,7 +54,7 @@ entry for every app in your project. It is recommended to use different app
'CANVAS-PAGE': 'https://apps.facebook.com/yourapp',
'CANVAS-URL': '',
'SECURE-CANVAS-URL': '',
- 'REDIRECT-URL': '',
+ 'REDIRECT-URL': 'mydomain.com/facebook/redirect/?next=%2F%2Fwww.facebook.com%2Fpages%2F',
'DOMAIN' : 'localhost.local:8000',
'NAMESPACE': 'mynamespace',
}
@@ -75,7 +75,7 @@ Add this to the header section of your base template::
{% load fb_tags %}
<script type="text/javascript">
FACEBOOK_APP_ID = '{% fb_app_id %}';
- FACEBOOK_REDIRECT_URL = '{% fb_redirect_url %}';
+ FACEBOOK_REDIRECT_URL = document.location.protocol + '//' + '{% fb_redirect_url %}';
FACEBOOK_CHANNEL_URL = '{% url channel %}';
FACEBOOK_APP_NAMESPACE = '{% fb_app_namespace %}'; // needed for og actions.
</script>
@@ -87,7 +87,7 @@ Facebook applications in one installation::
{% load fb_tags %}
<script type="text/javascript">
FACEBOOK_APP_ID = '{% fb_app_id feincms_page.facebook_application %}';
- FACEBOOK_REDIRECT_URL = '{% fb_redirect_url feincms_page.facebook_application %}';
+ FACEBOOK_REDIRECT_URL = document.location.protocol + '//' + '{% fb_redirect_url feincms_page.facebook_application %}';
FACEBOOK_CHANNEL_URL = '{% url channel %}';
</script>
<script type="text/javascript" src="{{ STATIC_URL }}facebook/fb_utils.js"></script>
View
22 docs/reference.rst
@@ -8,3 +8,25 @@ Django-facebook-graph reference
installation
clientside
+
+Deauthorization callback
+------------------------
+
+There is a default url that can be called for the deauthorization callback::
+
+ http://<canvas url>/facebook/deauthorize/<app name>/
+
+The app name parameter is optional but needed if you have multiple apps to
+decrypt the signed request. The default action is to delete the user model and
+all related entries.
+
+
+Testing the deauthorization callback
+------------------------------------
+
+If you are logged in to django you can test the deauthorization callback by calling this url::
+
+ http://localhost.local:8000/facebook/deauthorize/<app name>/?userid=<user_id>
+
+You will be shown a page like the one in the django admin
+that shows you which entries would be deleted on a deauthorization callback.
View
3  facebook/feincms/middleware.py
@@ -9,6 +9,9 @@ class PreventForeignApp(object):
associated page """
def process_request(self, request):
+ if 'deauthorize' in request.path:
+ return None
+
if 'facebook' in request.session and 'signed_request' in request.session['facebook']:
facebook_page = get_page_from_request(request)
signed_request = request.session['facebook']['signed_request']
View
8 facebook/feincms/views.py
@@ -1,4 +1,5 @@
from django.conf import settings
+from django.http import HttpResponse
from django.shortcuts import redirect
from feincms.module.page.models import Page
@@ -9,8 +10,9 @@ def redirect_to_slug(request):
try:
facebook_page = request.session['facebook']['signed_request']['page']
- except e:
- return '<!-- could not redirect to slug via facebook page signed request params: %s -->' % e
+ except KeyError as e:
+ return HttpResponse('<!-- could not redirect to slug via facebook page signed request params: %s -->' % e)
+
page = Page.objects.from_request(request, best_match=True)
if facebook_page['admin'] and facebook_page['liked']:
@@ -32,4 +34,4 @@ def redirect_to_slug(request):
try:
return redirect(page.get_children().filter(slug='unliked')[0])
except IndexError:
- return '<!-- no childpage with matching slug found. looked for slugs: admin-liked, liked, admin, unliked -->'
+ return HttpResponse('<!-- no childpage with matching slug found. looked for slugs: admin-liked, liked, admin, unliked -->')
View
12 facebook/graph.py
@@ -84,9 +84,19 @@ def get_objects(self, ids, **args):
return self.request("", args)
def get_connections(self, id, connection_name, **args):
- """Fetchs the connections for given object."""
+ """Fetches the connections for given object."""
return self.request(id + "/" + connection_name, args)
+ def batch_request(self, batch):
+ """ Combines multiple requests into one.
+ Batch must be a List of Dicts in the format:
+ [{"method": "GET", "relative_url": "me"},
+ {"method": "GET", "relative_url": "me/friends?limit=50"}]
+ It returns a list of response dicts:
+ http://developers.facebook.com/docs/reference/api/batch/
+ """
+ return self.request('', None, {'batch': json.dumps(batch)})
+
def put_object(self, parent_object, connection_name, **data):
"""Writes the given object to the graph, connected to the given parent.
View
4 facebook/middleware.py
@@ -31,6 +31,10 @@ def process_request(self, request):
logger.debug('Request Method = %s\n, AccessToken=%s' % (request.method, fb.access_token))
+ if 'deauthorize' in request.path:
+ logger.debug('deauthorize call, SignedRequestMiddleware returning...')
+ return None
+
if 'feincms' in settings.INSTALLED_APPS:
# if feincms is installed, try to get the application from the page
from facebook.feincms.utils import get_application_from_request
View
7 facebook/modules/base.py
@@ -120,6 +120,9 @@ def to_django(self, response, graph=None, save_related=True):
obj.get_from_facebook(graph=graph, save=True)
elif created and not save_related and 'name' in val:
obj._name = val['name']
+ elif not created and 'name' in val:
+ # make sure name is defined:
+ obj._name = val['name']
elif isinstance(fieldclass, models.DateField):
# Check for Birthday:
setattr(self, field, datetime.strptime(val, "%m/%d/%Y").date())
@@ -133,8 +136,8 @@ def to_django(self, response, graph=None, save_related=True):
setattr(self, '_%s_id' % prop, val['id'])
- def save_from_facebook(self, response, update_slug=False, save_related=True):
- self.to_django(response, save_related)
+ def save_from_facebook(self, response, update_slug=False, save_related=True, graph=None):
+ self.to_django(response, graph=graph, save_related=save_related)
if update_slug or not self.slug:
self.generate_slug()
self.save()
View
0  facebook/modules/connections/milestone/__init__.py
No changes.
View
26 facebook/modules/connections/milestone/models.py
@@ -0,0 +1,26 @@
+from django.db import models
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.contenttypes import generic
+from facebook.modules.base import Base
+
+class Milestone(Base):
+ id = models.BigIntegerField(primary_key=True)
+ # from is a Generic FK to User or Page.
+ _from = generic.GenericForeignKey('__profile_type', '__profile_id')
+ __profile_id = models.BigIntegerField()
+ __profile_type = models.ForeignKey(ContentType)
+ _created_time = models.DateTimeField(blank=True, null=True)
+ _updated_time = models.DateTimeField(blank=True, null=True)
+ _start_time = models.DateTimeField(blank=True, null=True)
+ _end_time = models.DateTimeField(blank=True, null=True)
+ _title = models.CharField(max_lenght=255, blank=True, null=True)
+ _description = models.TextField()
+
+ class Meta:
+ ordering = ['-_start_time']
+ get_latest_by = '_start_time'
+ verbose_name = _('Milestone')
+ verbose_name_plural = _('Milestones')
+
+ def __unicode__(self):
+ return self.title
View
4 facebook/modules/connections/post/admin.py
@@ -1,5 +1,8 @@
+from django.contrib.admin.options import InlineModelAdmin
from facebook.modules.base import AdminBase
+from django.contrib.contenttypes.models import ContentType
+
class PostAdmin(AdminBase):
def picture_link(self, obj):
return '<img src="%s" />' % (obj._picture)
@@ -17,3 +20,4 @@ def icon_link(self, obj):
'_properties', '_actions', '_privacy', '_likes', '_comments', '_targeting')
date_hierarchy = '_updated_time'
list_filter = ('_type',)
+
View
23 facebook/modules/connections/post/models.py
@@ -1,5 +1,7 @@
from django.db import models
from django.utils.translation import ugettext_lazy as _
+from django.contrib.contenttypes.models import ContentType
+from django.contrib.contenttypes import generic
from facebook.fields import JSONField
from facebook.modules.base import Base
@@ -55,7 +57,7 @@ class Facebook:
def __unicode__(self):
- return u'%s, %s %s' % (self.id, self._message[:50], self._picture)
+ return u'%s, %s' % (self.id, self._message[:50])
# Deal with changes from Facebook
@property
@@ -70,6 +72,8 @@ def _subject(self):
# Note has no type attribute.
def guess_type(self):
+ if self._type:
+ return self._type
if self._subject:
self._type = 'note'
elif self._story and self._picture:
@@ -126,9 +130,26 @@ def status(self):
class Post(PostBase):
+
class Meta(PostBase.Meta):
app_label = 'facebook'
verbose_name = _('Post')
verbose_name_plural = _('Posts')
abstract = False
+
+class PagePost(models.Model):
+ """ This is a generic intermediate model to attach posts to Pages or Profiles
+ """
+ post = models.ForeignKey(Post)
+ content_type = models.ForeignKey(ContentType)
+ object_id = models.BigIntegerField()
+ to = generic.GenericForeignKey()
+ created = models.DateTimeField(auto_now_add=True)
+
+ class Meta:
+ app_label = 'facebook'
+ unique_together = (('post', 'content_type', 'object_id'),)
+
+ def __unicode__(self):
+ return u'%s to %s' % (self.post, self.to)
View
11 facebook/modules/profile/models.py
@@ -1,7 +1,8 @@
+from django.contrib.contenttypes import generic
from django.db import models
from django.template.defaultfilters import slugify
from django.utils.translation import ugettext_lazy as _
-from django import forms
+from django.conf import settings
from facebook.modules.base import Base, AdminBase
@@ -18,6 +19,12 @@ class Profile(Base):
_pic_large = models.URLField(max_length=500, blank=True, null=True, verify_exists=False, editable=False)
_pic_crop = models.URLField(max_length=500, blank=True, null=True, verify_exists=False, editable=False)
+ # get all posts for the selected profile
+ # posts = [p.post for p in page.post_throughs.select_related('post').all()]
+ if 'facebook.modules.connections.post' in settings.INSTALLED_APPS:
+ post_throughs = generic.GenericRelation('PagePost',
+ related_name="%(app_label)s_%(class)s_related")
+
class Meta(Base.Meta):
abstract = True
app_label = 'facebook'
@@ -45,4 +52,4 @@ class ProfileAdmin(AdminBase):
def pic_img(self, obj):
return '<img src="%s" height="75" />' % obj._picture if obj._picture else ''
pic_img.allow_tags = True
- pic_img.short_description = _('Picture')
+ pic_img.short_description = _('Picture')
View
33 facebook/modules/profile/page/admin.py
@@ -13,7 +13,6 @@
from .models import Page
-
class PageAdmin(ProfileAdmin):
def has_access(self, obj):
if obj.updated + datetime.timedelta(days=60) < datetime.datetime.now():
@@ -23,7 +22,30 @@ def has_access(self, obj):
has_access.short_description = _('Access Token')
has_access.boolean = True
- list_display = ('id', 'profile_link', 'slug', '_name', 'pic_img', '_likes', 'has_access')
+ def token_expires_in(self, obj):
+ if not obj._access_token_expires:
+ return ''
+ expires_in = (obj._access_token_expires - datetime.datetime.now()).days
+ if expires_in > 10:
+ return _('%s days' % expires_in)
+ elif expires_in < 0:
+ return _('<span style="color:red;font-weight:bold;">expired</span>')
+ else:
+ return _('<span style="color:orange;font-weight:bold;">%s days</span>' % expires_in)
+
+ token_expires_in.short_description = _('expires in')
+ token_expires_in.allow_tags = True
+
+ def insight_link(self, obj):
+ if '?' in obj.facebook_link:
+ return u'<a href="%s&sk=page_insights" target="_blank">%s</a>' % (obj.facebook_link, obj._name)
+ else:
+ return u'<a href="%s?sk=page_insights" target="_blank">%s</a>' % (obj.facebook_link, obj._name)
+ insight_link.allow_tags = True
+ insight_link.short_description = _('Name')
+
+
+ list_display = ('id', 'profile_link', 'slug', 'insight_link', 'pic_img', '_likes', 'has_access', 'token_expires_in')
readonly_fields = ('_name', '_picture', '_likes', '_graph', '_link', '_location', '_phone',
'_checkins', '_website', '_talking_about_count','_username', '_category')
actions = ['get_page_access_token']
@@ -34,14 +56,17 @@ def get_page_access_token(self, request, queryset):
app_dict = get_app_dict(default_post_app)
token_exchange = do_exchange_token(app_dict, graph.access_token)
logger.debug('exchanged token: %s' % token_exchange)
+ token_expires_in = datetime.timedelta(minutes=60)
if 'access_token' in token_exchange:
graph.access_token = token_exchange['access_token']
+ token_expires_in = datetime.timedelta(days=60)
try:
response = graph.request('me/accounts/')
except GraphAPIError as e:
self.message_user(request, 'There was an error: %s' % e.message )
return False
#logger.debug(response)
+ token_expires_in = datetime.datetime.now() + token_expires_in
if response and response.get('data', False):
data = response['data']
message = {'count': 0, 'message': u''}
@@ -51,7 +76,8 @@ def get_page_access_token(self, request, queryset):
for page in queryset:
if accounts.get(page._id, None):
if accounts[page._id].get('access_token', False):
- queryset.filter(id=page._id).update(_access_token=accounts[page._id]['access_token'])
+ queryset.filter(id=page._id).update(_access_token=accounts[page._id]['access_token'],
+ _access_token_expires=token_expires_in)
message['message'] = u'%sSet access token for page %s\n' % (message['message'], page._name)
else:
message['message'] = u'%sDid not get access token for page %s\n' % (message['message'], page._name)
@@ -63,5 +89,4 @@ def get_page_access_token(self, request, queryset):
get_page_access_token.short_description = _('Get an access token for the selected page(s)')
-
admin.site.register(Page, PageAdmin)
View
1  facebook/modules/profile/page/models.py
@@ -13,6 +13,7 @@ class PageBase(Profile):
# Cached Facebook Graph fields for db lookup
_likes = models.IntegerField(blank=True, null=True, help_text=_('Cached fancount of the page'))
_access_token = models.CharField(max_length=255, blank=True, null=True)
+ _access_token_expires = models.DateTimeField(blank=True, null=True)
_category = models.CharField(_('category'), max_length=255, blank=True, null=True)
_location = JSONField(_('location'), blank=True, null=True)
_phone = models.CharField(_('phone'), max_length=255, blank=True, null=True)
View
2  facebook/modules/profile/user/models.py
@@ -21,6 +21,8 @@ class UserBase(Profile):
_location = models.CharField(max_length=70, blank=True, null=True)
_gender = models.CharField(max_length=10, blank=True, null=True)
_locale = models.CharField(max_length=6, blank=True, null=True)
+ _timezone = models.IntegerField(blank=True, null=True)
+ _verified = models.BooleanField(blank=True)
friends = models.ManyToManyField('self')
View
2  facebook/templates/admin/facebook/change_form.html
@@ -14,7 +14,7 @@
<option value="{{ app }}">{{ app }}</option>
{% endfor %}
</select-->Application: {% fb_first_app %} &nbsp;
- <fb:login-button show-faces="false" width="200" max-rows="1" scope="user_events, email, rsvp_event, create_event, friends_events, read_stream, publish_stream, user_photos, manage_pages"></fb:login-button>
+ <fb:login-button show-faces="false" width="200" max-rows="1" scope="user_events, email, rsvp_event, create_event, friends_events, read_stream, publish_stream, user_photos, manage_pages, read_insights"></fb:login-button>
</div>
<p>App Access Token: {{ graph.access_token }}, via {{ graph.via }}</p>
<p>User Access Token: <span id="user-access-token">None</span></p>
View
2  facebook/templates/admin/facebook/change_list.html
@@ -9,7 +9,7 @@
<p>Make sure your page has an access token if you would like to post a message in the future. (Select 'get access token' from the menu above.)</p>
<p>The access token is only for the application {% fb_first_app %}.</p>
<div id="fb-login-button" style="display:block;">
- <fb:login-button show-faces="false" width="200" max-rows="1" scope="user_events, email, rsvp_event, create_event, friends_events, read_stream, publish_stream, user_photos, manage_pages"></fb:login-button>
+ <fb:login-button show-faces="false" width="200" max-rows="1" scope="user_events, email, rsvp_event, create_event, friends_events, read_stream, publish_stream, user_photos, manage_pages, read_insights"></fb:login-button>
</div>
<p>App Access Token: {% access_token request %}</p>
<p>User Access Token: <span id="user-access-token">None</span></p>
View
2  facebook/urls.py
@@ -10,7 +10,7 @@
urlpatterns = patterns('',
- url(r'^deauthorize/$', 'facebook.views.deauthorize_and_delete', name='deauthorize'),
+ url(r'^deauthorize/(?:(?P<app_name>[A-Za-z0-9_-]+)/)?$', 'facebook.views.deauthorize_and_delete', name='deauthorize'),
url(r'^fql/$', 'facebook.views.fql_console', name="fql_console"),
url(r'^log_error/$', 'facebook.views.log_error', name="log_error"),
url(r'^channel.html$', 'facebook.views.channel', name='channel'),
View
56 facebook/views.py
@@ -1,15 +1,17 @@
import sys, logging, urllib2
from datetime import datetime, timedelta
-import urllib
-import urlparse
from django.conf import settings
+from django.contrib import admin
+from django.contrib.admin.util import get_deleted_objects
+from django.db import router
from django.http import HttpResponse, HttpResponseBadRequest, HttpResponseForbidden,\
Http404
from django.views.decorators.csrf import csrf_exempt
from django.shortcuts import render_to_response, get_object_or_404, render
from django.template import loader, RequestContext
from django.views.decorators.http import require_POST
+from django.contrib.admin import helpers
from facebook.utils import validate_redirect, do_exchange_token
from facebook.graph import get_graph
@@ -17,6 +19,8 @@
from facebook.session import get_session
from facebook.modules.profile.application.utils import get_app_dict
from facebook.modules.profile.user.models import User
+from facebook.modules.profile.user.admin import UserAdmin
+from django.utils.translation import ugettext_lazy as _
logger = logging.getLogger(__name__)
@@ -94,14 +98,50 @@ def channel(request):
# Deauthorize callback, signed request: {u'issued_at': 1305126336, u'user_id': u'xxxx', u'user': {u'locale': u'de_DE', u'country': u'ch'}, u'algorithm': u'HMAC-SHA256'}
@csrf_exempt
-def deauthorize_and_delete(request):
+def deauthorize_and_delete(request, app_name=None):
""" Deletes a user on a deauthorize callback. """
if request.method == 'GET':
- raise Http404
+ if request.user.is_superuser:
+ application = get_app_dict(app_name)
+ # Preview callback
+ if 'userid' in request.GET:
+ queryset = User.objects.filter(id=int(request.GET.get('userid'), 0))
+ opts = User._meta
+ modeladmin = UserAdmin(User, admin.site)
+ using = router.db_for_write(User)
+ # Populate deletable_objects, a data structure of all related objects that
+ # will also be deleted.
+ deletable_objects, perms_needed, protected = get_deleted_objects(
+ queryset, opts, request.user, modeladmin.admin_site, using)
+
+ context = {
+ "title": _("Preview deauthorization callback"),
+ "objects_name": 'User',
+ "deletable_objects": [deletable_objects],
+ 'queryset': queryset,
+ "perms_lacking": perms_needed,
+ "protected": protected,
+ "opts": opts,
+ "root_path": modeladmin.admin_site.root_path,
+ "app_label": 'facebook',
+ 'action_checkbox_name': helpers.ACTION_CHECKBOX_NAME,
+ }
+
+ return render(request, [
+ "admin/facebook/delete_selected_confirmation.html",
+ "admin/delete_selected_confirmation.html"
+ ], context)
+ else:
+ return HttpResponse(u"""Deauthorize callback for app %s
+ with id %s called with GET. Call with userid= as
+ parameter to preview cascade.""" % (app_name, application['ID']))
+ else:
+ raise Http404
if 'signed_request' in request.POST:
- application = get_app_dict()
- parsed_request = parseSignedRequest(request.REQUEST['signed_request'], application['SECRET'])
- user = get_object_or_404(User, id=parsed_request['user_id'])
+ application = get_app_dict(app_name)
+ parsed_request = parseSignedRequest(request.POST.get('signed_request'), application['SECRET'])
+ user = get_object_or_404(User, id=int(parsed_request.get('user_id')))
+
if settings.DEBUG == False:
user.delete()
logger.info('Deleting User: %s' % user)
@@ -139,8 +179,8 @@ def internal_redirect(request):
return HttpResponseForbidden('The next= paramater is not an allowed redirect url.')
-""" Allows to register client-side errors. """
def log_error(request):
+ """ Allows to register client-side errors. """
if not request.is_ajax() or not request.method == 'POST':
raise Http404
logger.error(request.POST.get('message'))
Something went wrong with that request. Please try again.