diff --git a/disqus/__init__.py b/disqus/__init__.py index c3f52c8..c9fe8de 100644 --- a/disqus/__init__.py +++ b/disqus/__init__.py @@ -2,7 +2,10 @@ import urllib2 from django.core.management.base import CommandError -from django.utils import simplejson as json +try: + import json +except ImportError: + from django.utils import simplejson as json from django.conf import settings def call(method, data, post=False): diff --git a/disqus/management/commands/disqus_dumpdata.py b/disqus/management/commands/disqus_dumpdata.py index 2fae41b..fdebd2f 100644 --- a/disqus/management/commands/disqus_dumpdata.py +++ b/disqus/management/commands/disqus_dumpdata.py @@ -1,7 +1,10 @@ from optparse import make_option from django.core.management.base import NoArgsCommand, CommandError -from django.utils import simplejson as json +try: + import json +except ImportError: + from django.utils import simplejson as json from disqus.api import DisqusClient diff --git a/disqus/management/commands/disqus_export.py b/disqus/management/commands/disqus_export.py index f7f3f4a..66a6ec7 100644 --- a/disqus/management/commands/disqus_export.py +++ b/disqus/management/commands/disqus_export.py @@ -5,7 +5,6 @@ from django.contrib import comments from django.contrib.sites.models import Site from django.core.management.base import NoArgsCommand -from django.utils import simplejson as json from disqus.api import DisqusClient diff --git a/disqus/templates/disqus/sso.html b/disqus/templates/disqus/sso.html new file mode 100644 index 0000000..307e947 --- /dev/null +++ b/disqus/templates/disqus/sso.html @@ -0,0 +1,15 @@ + \ No newline at end of file diff --git a/disqus/templatetags/disqus_tags.py b/disqus/templatetags/disqus_tags.py index acc73fb..0aba07f 100644 --- a/disqus/templatetags/disqus_tags.py +++ b/disqus/templatetags/disqus_tags.py @@ -1,41 +1,47 @@ import base64 import hashlib import hmac -import simplejson +try: + import json +except ImportError: + from django.utils import simplejson as json import time from django import template from django.conf import settings from django.contrib.sites.models import Site -from django.utils.functional import curry -from django.utils.encoding import force_unicode register = template.Library() + # Set the disqus_developer variable to 0/1. Default is 0 @register.simple_tag(takes_context=True) def set_disqus_developer(context, disqus_developer): context['disqus_developer'] = disqus_developer return "" + # Set the disqus_identifier variable to some unique value. Defaults to page's URL @register.simple_tag(takes_context=True) def set_disqus_identifier(context, *args): context['disqus_identifier'] = "".join(args) return "" + # Set the disqus_url variable to some value. Defaults to page's location @register.simple_tag(takes_context=True) def set_disqus_url(context, *args): context['disqus_url'] = "".join(args) return "" + # Set the disqus_title variable to some value. Defaults to page's title or URL @register.simple_tag(takes_context=True) def set_disqus_title(context, disqus_title): context['disqus_title'] = disqus_title return "" + # Set the disqus_category_id variable to some value. No default. See # http://help.disqus.com/customer/portal/articles/472098-javascript-configuration-variables#disqus_category_id @register.simple_tag(takes_context=True) @@ -43,19 +49,21 @@ def set_disqus_category_id(context, disqus_category_id): context['disqus_category_id'] = disqus_category_id return "" + def get_config(context): """ return the formatted javascript for any disqus config variables """ conf_vars = ['disqus_developer', 'disqus_identifier', 'disqus_url', - 'disqus_title', 'disqus_category_id'] - + 'disqus_title', 'disqus_category_id'] + output = [] for item in conf_vars: if item in context: output.append('\tvar %s = "%s";' % (item, context[item])) return '\n'.join(output) + @register.simple_tag(takes_context=True) def disqus_dev(context): """ @@ -69,11 +77,11 @@ def disqus_dev(context): """ % (Site.objects.get_current().domain, context['request'].path) return "" -@register.simple_tag(takes_context=True) -def disqus_sso(context): +@register.inclusion_tag('disqus/sso.html', takes_context=True) +def disqus_sso(context, shortname='', login_url=None, logout_url=None, button_url=None, login_width=None, login_height=None): """ Return the HTML/js code to enable DISQUS SSO - so logged in users on - your site can be logged in to disqus seemlessly. + your site can be logged in to disqus seamlessly. """ # we have to make it str rather than unicode or the HMAC blows up DISQUS_SECRET_KEY = str(getattr(settings, 'DISQUS_SECRET_KEY', None)) @@ -82,34 +90,46 @@ def disqus_sso(context): DISQUS_PUBLIC_KEY = getattr(settings, 'DISQUS_PUBLIC_KEY', None) if DISQUS_PUBLIC_KEY is None: return "

You need to set DISQUS_PUBLIC_KEY before you can use SSO

" + + shortname = getattr(settings, 'DISQUS_WEBSITE_SHORTNAME', shortname) + login_url = login_url if login_url else getattr(settings, 'LOGIN_URL', None) + logout_url = logout_url if logout_url else getattr(settings, 'LOGOUT_URL', None) + button_url = button_url if button_url else getattr(settings, 'DISQUS_LOGIN_BUTTON', None) + login_width = login_width if login_width else getattr(settings, 'DISQUS_LOGIN_WINDOW_WIDTH', None) + login_height = login_height if login_height else getattr(settings, 'DISQUS_LOGIN_WINDOW_HEIGHT', None) + user = context['user'] + if user.is_anonymous(): - return "" - # create a JSON packet of our data attributes - data = simplejson.dumps({ - 'id': user.id, - 'username': user.username, - 'email': user.email, - }) + # use empty JSON object as per disqus SSO guide + data = json.dumps({}) + else: + # create a JSON packet of our data attributes + data = json.dumps({ + 'id': user.id, + 'username': user.username, + 'email': user.email, + }) # encode the data to base64 message = base64.b64encode(data) # generate a timestamp for signing the message timestamp = int(time.time()) # generate our hmac signature sig = hmac.HMAC(DISQUS_SECRET_KEY, '%s %s' % (message, timestamp), hashlib.sha1).hexdigest() - - # return a script tag to insert the sso message - return """""" % dict( - message=message, - timestamp=timestamp, - sig=sig, - pub_key=DISQUS_PUBLIC_KEY, - ) + + return { + 'shortname': shortname, + 'config': get_config(context), + 'message': message, + 'hmac': sig, + 'timestamp': timestamp, + 'public_api_key': DISQUS_PUBLIC_KEY, + 'button_url': button_url, + 'login_url': login_url, + 'logout_url': logout_url, + 'login_width': login_width, + 'login_height': login_height, + } @register.inclusion_tag('disqus/num_replies.html', takes_context=True) def disqus_num_replies(context, shortname=''): @@ -118,20 +138,22 @@ def disqus_num_replies(context, shortname=''): #disqus_thread anchor into the threads comment count. """ shortname = getattr(settings, 'DISQUS_WEBSITE_SHORTNAME', shortname) - + return { 'shortname': shortname, 'config': get_config(context), } + @register.inclusion_tag('disqus/recent_comments.html', takes_context=True) -def disqus_recent_comments(context, shortname='', num_items=5, excerpt_length=200, hide_avatars=0, avatar_size=32): +def disqus_recent_comments(context, shortname='', num_items=5, + excerpt_length=200, hide_avatars=0, avatar_size=32): """ Return the HTML/js code which shows recent comments. """ shortname = getattr(settings, 'DISQUS_WEBSITE_SHORTNAME', shortname) - + return { 'shortname': shortname, 'num_items': num_items, diff --git a/docs/templatetags.rst b/docs/templatetags.rst index 3cf45e0..91ed2b7 100644 --- a/docs/templatetags.rst +++ b/docs/templatetags.rst @@ -56,6 +56,58 @@ Result:: - ``shortname``: DISQUS website shortname that should be used. The ``settings.DISQUS_WEBSITE_SHORTNAME`` setting takes precedence over this parameter. Example: ``{% disqus_show_comments "foobar" %}`` + +.. _disqus_sso: + +disqus_sso +-------------------- + +Renders the ``disqus/sso.html`` template to render a disqus SSO config block. +Values for ``settings.DISQUS_SECRET_KEY`` and ``settings.DISQUS_PUBLIC_KEY`` must +be defined. See the +`embed code `_ for +more information. + +Example:: + + {% load disqus_tags %} + {% disqus_sso %} + +Result:: + + + +**Options**: + + - ``shortname``: DISQUS website shortname that should be used. The + ``settings.DISQUS_WEBSITE_SHORTNAME`` setting takes precedence + over this parameter. + - ``login_url``: Address of the login page. The page will be opened in a new window and it + must close itself after authentication is done. That's how disqus will know it is done and + reload the page. Will default to ``settings.LOGIN_URL`` if not specified. + - ``logout_url``: Address of the logout page. This page must redirect user back to the original + page after logout. Will default to ``settings.LOGOUT_URL`` if not specified. + - ``button_url``: Address of the image that acts as a button. Refer to disqus documentation + for style guide. Will default to ``settings.DISQUS_LOGIN_BUTTON`` if not specified. + - ``login_width``: Width of the login popup window. + Will default to ``settings.DISQUS_LOGIN_WINDOW_WIDTH`` if not specified. + - ``login_height``: Height of the login popup window. + Will default to ``settings.DISQUS_LOGIN_WINDOW_HEIGHT`` if not specified. .. _disqus_recent_comments: