diff options
-rw-r--r-- | askbot/deps/django_authopenid/util.py | 15 | ||||
-rw-r--r-- | askbot/media/js/user.js | 82 | ||||
-rw-r--r-- | askbot/media/style/style.css | 7 | ||||
-rw-r--r-- | askbot/media/style/style.less | 12 | ||||
-rw-r--r-- | askbot/templates/user_profile/twitter_sharing_controls.html | 12 | ||||
-rw-r--r-- | askbot/urls.py | 15 | ||||
-rw-r--r-- | askbot/views/__init__.py | 1 | ||||
-rw-r--r-- | askbot/views/sharing.py | 53 |
8 files changed, 186 insertions, 11 deletions
diff --git a/askbot/deps/django_authopenid/util.py b/askbot/deps/django_authopenid/util.py index 7e78da16..03e70922 100644 --- a/askbot/deps/django_authopenid/util.py +++ b/askbot/deps/django_authopenid/util.py @@ -757,11 +757,8 @@ class OAuthConnection(object): def get_token(self): return self.request_token - def get_user_id(self, oauth_token = None, oauth_verifier = None): - """Returns user ID within the OAuth provider system, - based on ``oauth_token`` and ``oauth_verifier`` - """ - + def get_access_token(self, oauth_token=None, oauth_verifier=None): + """returns data as returned upon visiting te access_token_url""" token = oauth.Token( oauth_token['oauth_token'], oauth_token['oauth_token_secret'] @@ -770,7 +767,13 @@ class OAuthConnection(object): client = oauth.Client(self.consumer, token = token) url = self.parameters['access_token_url'] #there must be some provider-specific post-processing - data = self.send_request(client = client, url=url, method='GET') + return self.send_request(client = client, url=url, method='GET') + + def get_user_id(self, oauth_token = None, oauth_verifier = None): + """Returns user ID within the OAuth provider system, + based on ``oauth_token`` and ``oauth_verifier`` + """ + data = self.get_access_token(oauth_token, oauth_verifier) data['consumer_key'] = self.parameters['consumer_key'] data['consumer_secret'] = self.parameters['consumer_secret'] return self.parameters['get_user_id_function'](data) diff --git a/askbot/media/js/user.js b/askbot/media/js/user.js index 251ee004..a1ea840b 100644 --- a/askbot/media/js/user.js +++ b/askbot/media/js/user.js @@ -993,6 +993,82 @@ UserGroupsEditor.prototype.decorate = function(element){ //todo - add group deleters }; +/** + * controls that set up automatic tweeting to the user account + */ +var Tweeting = function() { + WrappedElement.call(this); +}; +inherits(Tweeting, WrappedElement); + +Tweeting.prototype.getStartHandler = function() { + var url = this._startUrl; + return function() { + window.location.href = url; + }; +}; + +Tweeting.prototype.getMode = function() { + return this._modeSelector.val(); +}; + +Tweeting.prototype.getModeSelectorHandler = function() { + var me = this; + var url = this._changeModeUrl; + return function() { + $.ajax({ + type: 'POST', + dataType: 'json', + url: url, + data: {'mode': me.getMode() }, + cache: false + }); + }; +}; + +Tweeting.prototype.getAccount = function() { + return this._accountSelector.val(); +}; + +Tweeting.prototype.getAccountSelectorHandler = function() { + var selectAccountUrl = this._changeModeUrl; + var startUrl = this._startUrl; + var me = this; + return function() { + var account = me.getAccount(); + if (account === 'existing-handle') { + $.ajax({ + type: 'POST', + dataType: 'json', + url: selectAccountUrl, + data: {'mode': 'share-my-posts' }, + cache: false + }); + } else if (account === 'new-handle') { + window.location.href = startUrl; + } + } +}; + +Tweeting.prototype.decorate = function(element) { + this._element = element; + this._changeModeUrl = element.data('changeModeUrl'); + this._startUrl = element.data('startUrl'); + if (element.hasClass('disabled')) { + this._startButton = element.find('.start-tweeting'); + this._startUrl = this._startButton.data('url'); + setupButtonEventHandlers(this._startButton, this.getStartHandler()); + } else if (element.hasClass('inactive')) { + //decorate choose account selector + this._accountSelector = element.find('select'); + this._accountSelector.change(this.getAccountSelectorHandler()); + } else if (element.hasClass('enabled')) { + //decorate choose mode selector + this._modeSelector = element.find('select'); + this._modeSelector.change(this.getModeSelectorHandler()); + } +}; + (function(){ var fbtn = $('.follow-user-toggle'); if (fbtn.length === 1){ @@ -1010,4 +1086,10 @@ UserGroupsEditor.prototype.decorate = function(element){ } else { $('#add-group').remove(); } + + var tweeting = $('.auto-tweeting'); + if (tweeting.length) { + var tweetingControl = new Tweeting(); + tweetingControl.decorate(tweeting); + } })(); diff --git a/askbot/media/style/style.css b/askbot/media/style/style.css index e818c493..7e60afd2 100644 --- a/askbot/media/style/style.css +++ b/askbot/media/style/style.css @@ -2980,6 +2980,9 @@ a:hover.medal { .user-details h3 { font-size: 16px; } +.user-details td { + padding-right: 10px; +} .user-about { background-color: #EEEEEE; height: 200px; @@ -4345,3 +4348,7 @@ textarea.tipped-input { .tag-subscriptions ul.tags li { margin: 2px 5px; } +.auto-tweeting select { + width: auto; + margin-bottom: 0; +} diff --git a/askbot/media/style/style.less b/askbot/media/style/style.less index f3f70679..6e622311 100644 --- a/askbot/media/style/style.less +++ b/askbot/media/style/style.less @@ -3088,9 +3088,12 @@ a:hover.medal { .user-details { font-size: 13px; - h3{ + h3 { font-size:16px; } + td { + padding-right: 10px; + } } .user-about { @@ -4535,3 +4538,10 @@ textarea.tipped-input { margin: 2px 5px; } } + +.auto-tweeting { + select { + width: auto; + margin-bottom: 0; + } +} diff --git a/askbot/templates/user_profile/twitter_sharing_controls.html b/askbot/templates/user_profile/twitter_sharing_controls.html index 1e3c3879..bb44ea0c 100644 --- a/askbot/templates/user_profile/twitter_sharing_controls.html +++ b/askbot/templates/user_profile/twitter_sharing_controls.html @@ -1,14 +1,17 @@ {% set auto_tweeting_status = view_user.get_social_sharing_status('twitter') %} -<tr class="auto-tweeting {{ auto_tweeting_status }}"> +{% set handle = view_user.twitter_handle|escape %} +<tr class="auto-tweeting {{ auto_tweeting_status }}" + data-change-mode-url="{% url 'change_social_sharing_mode' %}" + data-start-url="{% url 'start_sharing_twitter' %}" +> {% if auto_tweeting_status == 'enabled' %} - {% set handle = view_user.twitter_handle|escape %} <td>{% trans %}Auto-tweeting to @{{ handle }}{% endtrans %}</td> <td> <select class="select-mode"> {% set mode = view_user.get_social_sharing_mode() %} {% if mode == 'share-my-posts' %} <option selected="selected" value="share-my-posts">{% trans %}my posts{% endtrans %}</option> - <option value="all-posts">{% trans %}all posts{% endtrans %}</option> + <option value="share-everything">{% trans %}all posts{% endtrans %}</option> {% else %} <option selected="selected" value="all-posts">{% trans %}all posts{% endtrans %}</option> <option value="share-my-posts">{% trans %}my posts{% endtrans %}</option> @@ -27,6 +30,7 @@ </td> {% else %} <td>{% trans %}Auto-tweeting is off{% endtrans %}</td> - <td><button class="submit start-tweeting">{% trans %}Start tweeting{% endtrans %}</button></td> + <td><button class="submit start-tweeting">{% trans %}Start tweeting{% endtrans %}</button> + </td> {% endif %} </tr> diff --git a/askbot/urls.py b/askbot/urls.py index b140a44a..bd0c3a15 100644 --- a/askbot/urls.py +++ b/askbot/urls.py @@ -515,6 +515,21 @@ urlpatterns = patterns('', views.widgets.question_widget, name = 'question_widget' ), + url( + r'^start-sharing-twitter/$', + views.sharing.start_sharing_twitter, + name='start_sharing_twitter' + ), + url( + r'^save-twitter-access-token/$', + views.sharing.save_twitter_access_token, + name='save_twitter_access_token' + ), + url(#ajax post only + r'^change-social-sharing-mode/$', + views.sharing.change_social_sharing_mode, + name='change_social_sharing_mode' + ), #upload url is ajax only url( r'^%s$' % _('upload/'), views.writers.upload, name='upload'), url(r'^%s$' % _('feedback/'), views.meta.feedback, name='feedback'), diff --git a/askbot/views/__init__.py b/askbot/views/__init__.py index a3c5e06d..167e231a 100644 --- a/askbot/views/__init__.py +++ b/askbot/views/__init__.py @@ -6,6 +6,7 @@ from askbot.views import writers from askbot.views import commands from askbot.views import users from askbot.views import meta +from askbot.views import sharing from askbot.views import widgets from django.conf import settings if 'avatar' in settings.INSTALLED_APPS: diff --git a/askbot/views/sharing.py b/askbot/views/sharing.py new file mode 100644 index 00000000..0ba7686c --- /dev/null +++ b/askbot/views/sharing.py @@ -0,0 +1,53 @@ +from askbot import const +from askbot.deps.django_authopenid.util import OAuthConnection +from askbot.utils import decorators +from django.contrib.auth.decorators import login_required +from django.core.urlresolvers import reverse +from django.http import HttpResponseRedirect +from django.views.decorators import csrf +from django.utils import simplejson + +@login_required +def start_sharing_twitter(request): + #start oauth process to authorize tweeting + #on behalf of user + callback_url = reverse('save_twitter_access_token') + connection = OAuthConnection('twitter', callback_url=callback_url) + connection.start() + request.session['oauth_token'] = connection.get_token() + oauth_url = connection.get_auth_url(login_only=False) + return HttpResponseRedirect(oauth_url) + +@login_required +def save_twitter_access_token(request): + oauth_token = request.GET['oauth_token'] + session_oauth_token = request.session['oauth_token'] + assert(oauth_token == session_oauth_token['oauth_token']) + oauth = OAuthConnection('twitter') + access_token_data = oauth.get_access_token( + oauth_token = session_oauth_token, + oauth_verifier = request.GET['oauth_verifier'] + ) + #save the access token + request.user.twitter_access_token = simplejson.dumps(access_token_data) + request.user.twitter_handle = access_token_data['screen_name'] + if request.user.social_sharing_mode == const.SHARE_NOTHING: + request.user.social_sharing_mode = const.SHARE_MY_POSTS + request.user.save() + #todo: set up user associaton for the login via twitter + #todo: save message that user can also login via twitter + return HttpResponseRedirect(request.user.get_profile_url()) + +@csrf.csrf_exempt +@decorators.ajax_only +@decorators.post_only +def change_social_sharing_mode(request): + mode = request.POST['mode'] + if mode == 'share-nothing': + request.user.social_sharing_mode = const.SHARE_NOTHING + elif mode == 'share-my-posts': + request.user.social_sharing_mode = const.SHARE_MY_POSTS + else: + assert(mode == 'share-everything') + request.user.social_sharing_mode = const.SHARE_EVERYTHING + request.user.save() |