diff options
-rw-r--r-- | askbot/conf/minimum_reputation.py | 15 | ||||
-rw-r--r-- | askbot/deps/django_authopenid/util.py | 12 | ||||
-rw-r--r-- | askbot/doc/source/changelog.rst | 1 | ||||
-rw-r--r-- | askbot/models/__init__.py | 8 | ||||
-rw-r--r-- | askbot/models/post.py | 31 | ||||
-rw-r--r-- | askbot/models/signals.py | 3 | ||||
-rw-r--r-- | askbot/tasks.py | 26 | ||||
-rw-r--r-- | askbot/utils/twitter.py | 12 | ||||
-rw-r--r-- | askbot/views/writers.py | 5 |
9 files changed, 100 insertions, 13 deletions
diff --git a/askbot/conf/minimum_reputation.py b/askbot/conf/minimum_reputation.py index 94d5869e..3d0fa1cd 100644 --- a/askbot/conf/minimum_reputation.py +++ b/askbot/conf/minimum_reputation.py @@ -230,9 +230,16 @@ settings.register( 'MIN_REP_TO_TRIGGER_EMAIL', default=15, description=_('Trigger email notifications'), - help_text=_( - 'Reduces spam as notifications wont\'t be sent ' - 'to regular users for posts of low karma users' - ) + help_text=_('Reduces spam') + ) +) + +settings.register( + livesettings.IntegerValue( + MIN_REP, + 'MIN_REP_TO_TWEET_ON_OTHERS_ACCOUNTS', + default=15, + description=_('Trigger tweets on others accounts'), + help_text=_('Reduces spam') ) ) diff --git a/askbot/deps/django_authopenid/util.py b/askbot/deps/django_authopenid/util.py index 03e70922..6e19db6a 100644 --- a/askbot/deps/django_authopenid/util.py +++ b/askbot/deps/django_authopenid/util.py @@ -757,14 +757,18 @@ class OAuthConnection(object): def get_token(self): return self.request_token - def get_access_token(self, oauth_token=None, oauth_verifier=None): - """returns data as returned upon visiting te access_token_url""" + def get_client(self, oauth_token=None, oauth_verifier=None): token = oauth.Token( oauth_token['oauth_token'], oauth_token['oauth_token_secret'] ) - token.set_verifier(oauth_verifier) - client = oauth.Client(self.consumer, token = token) + if oauth_verifier: + token.set_verifier(oauth_verifier) + return oauth.Client(self.consumer, token=token) + + def get_access_token(self, oauth_token=None, oauth_verifier=None): + """returns data as returned upon visiting te access_token_url""" + client = self.get_client(self, oauth_token, oauth_verifier) url = self.parameters['access_token_url'] #there must be some provider-specific post-processing return self.send_request(client = client, url=url, method='GET') diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst index 0e5b3c32..faedeebf 100644 --- a/askbot/doc/source/changelog.rst +++ b/askbot/doc/source/changelog.rst @@ -3,6 +3,7 @@ Changes in Askbot Development version ------------------- +* Auto-tweet option for questions and answers * Added Chech and Croatian translations * Disable/enable best answer feature * Allowed post owners repost answers and comments (this used to be mod-only function). diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py index 9378b6c4..b31d9b5d 100644 --- a/askbot/models/__init__.py +++ b/askbot/models/__init__.py @@ -3690,6 +3690,12 @@ def moderate_group_joining(sender, instance=None, created=False, **kwargs): content_object = group ) +def tweet_new_post(sender, user=None, question=None, answer=None, form_data=None, **kwargs): + """seends out tweets about the new post""" + from askbot.tasks import tweet_new_post_task + post = question or answer + tweet_new_post_task.delay(post.id) + #signal for User model save changes django_signals.pre_save.connect(make_admin_if_first_user, sender=User) django_signals.pre_save.connect(calculate_gravatar_hash, sender=User) @@ -3721,6 +3727,8 @@ signals.user_updated.connect(record_user_full_updated, sender=User) signals.user_logged_in.connect(complete_pending_tag_subscriptions)#todo: add this to fake onlogin middleware signals.user_logged_in.connect(post_anonymous_askbot_content) signals.post_updated.connect(record_post_update_activity) +signals.new_answer_posted.connect(tweet_new_post) +signals.new_question_posted.connect(tweet_new_post) #probably we cannot use post-save here the point of this is #to tell when the revision becomes publicly visible, not when it is saved diff --git a/askbot/models/post.py b/askbot/models/post.py index 42905f65..2f410b27 100644 --- a/askbot/models/post.py +++ b/askbot/models/post.py @@ -404,6 +404,21 @@ class Post(models.Model): if number: self.points = int(number) + def as_tweet(self): + """a naive tweet representation of post + todo: add mentions to relevant people + """ + url = self.get_absolute_url(no_slug=True) + url = askbot_settings.APP_URL + url + if self.post_type == 'question': + tweet = _('Question: ') + elif self.post_type == 'answer': + tweet = _('Answer: ') + + chars_left = 140 - (len(url) + len(tweet) + 1) + title_str = self.thread.title[:chars_left] + return tweet + title_str + ' ' + url + def parse_post_text(self): """typically post has a field to store raw source text in comment it is called .comment, in Question and Answer it is @@ -785,11 +800,17 @@ class Post(models.Model): if self.is_answer(): if not question_post: question_post = self.thread._question_post() - url = u'%(base)s%(slug)s/?answer=%(id)d#post-id-%(id)d' % { - 'base': urlresolvers.reverse('question', args=[question_post.id]), - 'slug': django_urlquote(slugify(self.thread.title)), - 'id': self.id - } + if no_slug: + url = u'%(base)s?answer=%(id)d#post-id-%(id)d' % { + 'base': urlresolvers.reverse('question', args=[question_post.id]), + 'id': self.id + } + else: + url = u'%(base)s%(slug)s/?answer=%(id)d#post-id-%(id)d' % { + 'base': urlresolvers.reverse('question', args=[question_post.id]), + 'slug': django_urlquote(slugify(self.thread.title)), + 'id': self.id + } elif self.is_question(): url = urlresolvers.reverse('question', args=[self.id]) if thread: diff --git a/askbot/models/signals.py b/askbot/models/signals.py index f5187876..303db2a2 100644 --- a/askbot/models/signals.py +++ b/askbot/models/signals.py @@ -28,6 +28,9 @@ user_logged_in = django.dispatch.Signal(providing_args=['session']) new_answer_posted = django.dispatch.Signal( providing_args=['answer', 'user', 'form_data'] ) +new_question_posted = django.dispatch.Signal( + providing_args=['question', 'user', 'form_data'] +) answer_edited = django.dispatch.Signal( providing_args=['answer', 'user', 'form_data'] ) diff --git a/askbot/tasks.py b/askbot/tasks.py index 92cd9a1d..8d98be2c 100644 --- a/askbot/tasks.py +++ b/askbot/tasks.py @@ -26,6 +26,7 @@ from django.contrib.contenttypes.models import ContentType from django.template import Context from django.template.loader import get_template from django.utils.translation import ugettext as _ +from django.utils import simplejson from celery.decorators import task from askbot.conf import settings as askbot_settings from askbot import const @@ -34,10 +35,35 @@ from askbot.models import Post, Thread, User, ReplyAddress from askbot.models.badges import award_badges_signal from askbot.models import get_reply_to_addresses, format_instant_notification_email from askbot import exceptions as askbot_exceptions +from askbot.utils.twitter import Twitter # TODO: Make exceptions raised inside record_post_update_celery_task() ... # ... propagate upwards to test runner, if only CELERY_ALWAYS_EAGER = True # (i.e. if Celery tasks are not deferred but executed straight away) +@task(ignore_result=True) +def tweet_new_post_task(post_id): + post = Post.objects.get(id=post_id) + + is_mod = post.author.is_administrator_or_moderator() + if is_mod or post.author.reputation > askbot_settings.MIN_REP_TO_TWEET_ON_OTHERS_ACCOUNTS: + tweeters = User.objects.filter(social_sharing_mode=const.SHARE_EVERYTHING) + tweeters = tweeters.exclude(id=post.author.id) + access_tokens = tweeters.values_list('twitter_access_token', flat=True) + else: + access_tokens = list() + + tweet_text = post.as_tweet() + + twitter = Twitter() + + for raw_token in access_tokens: + token = simplejson.loads(raw_token) + twitter.tweet(tweet_text, access_token=token) + + if post.author.social_sharing_mode != const.SHARE_NOTHING: + token = simplejson.loads(post.author.twitter_access_token) + twitter.tweet(tweet_text, access_token=token) + @task(ignore_result = True) def notify_author_of_published_revision_celery_task(revision): diff --git a/askbot/utils/twitter.py b/askbot/utils/twitter.py new file mode 100644 index 00000000..1eba6147 --- /dev/null +++ b/askbot/utils/twitter.py @@ -0,0 +1,12 @@ +import urllib +from askbot.deps.django_authopenid.util import OAuthConnection + +class Twitter(OAuthConnection): + def __init__(self): + super(Twitter, self).__init__('twitter') + self.tweet_url = 'https://api.twitter.com/1.1/statuses/update.json' + + def tweet(self, text, access_token=None): + client = self.get_client(access_token) + body = urllib.urlencode({'status': text}) + return self.send_request(client, self.tweet_url, 'POST', body=body) diff --git a/askbot/views/writers.py b/askbot/views/writers.py index 4afd66cf..b3dd2b32 100644 --- a/askbot/views/writers.py +++ b/askbot/views/writers.py @@ -252,6 +252,11 @@ def ask(request):#view used to ask a new question group_id=group_id, language=language ) + signals.new_question_posted.send(None, + question=question, + user=user, + form_data=form.cleaned_data + ) return HttpResponseRedirect(question.get_absolute_url()) except exceptions.PermissionDenied, e: request.user.message_set.create(message = unicode(e)) |