""" Authorisation related functions. This entire module will be removed some time in the future Many of these functions are being replaced with assertions: User.assert_can... """ import datetime from django.db import transaction from askbot.models import Repute #from askbot.models import Answer from askbot.models import signals from askbot.conf import settings as askbot_settings ########################################### ## actions and reputation changes event ########################################### @transaction.commit_on_success def onFlaggedItem(post, user, timestamp=None): if timestamp is None: timestamp = datetime.datetime.now() post.offensive_flag_count = post.offensive_flag_count + 1 post.save() flagged_user = post.author flagged_user.receive_reputation( askbot_settings.REP_LOSS_FOR_RECEIVING_FLAG ) flagged_user.save() question = post.thread._question_post() reputation = Repute( user=flagged_user, negative=askbot_settings.REP_LOSS_FOR_RECEIVING_FLAG, question=question, reputed_at=timestamp, reputation_type=-4,#todo: clean up magic number reputation=flagged_user.reputation ) reputation.save() signals.flag_offensive.send( sender=post.__class__, instance=post, mark_by=user ) if post.post_type == 'comment': #do not hide or delete comments automatically yet, #because there is no .deleted field in the comment model return #todo: These should be updated to work on same revisions. if post.offensive_flag_count == askbot_settings.MIN_FLAGS_TO_HIDE_POST: #todo: strange - are we supposed to hide the post here or the name of #setting is incorrect? flagged_user.receive_reputation( askbot_settings.REP_LOSS_FOR_RECEIVING_THREE_FLAGS_PER_REVISION ) flagged_user.save() reputation = Repute( user=flagged_user, negative=\ askbot_settings.REP_LOSS_FOR_RECEIVING_THREE_FLAGS_PER_REVISION, question=question, reputed_at=timestamp, reputation_type=-6, reputation=flagged_user.reputation ) reputation.save() elif post.offensive_flag_count == askbot_settings.MIN_FLAGS_TO_DELETE_POST: flagged_user.receive_reputation( askbot_settings.REP_LOSS_FOR_RECEIVING_FIVE_FLAGS_PER_REVISION ) flagged_user.save() reputation = Repute( user=flagged_user, negative=\ askbot_settings.REP_LOSS_FOR_RECEIVING_FIVE_FLAGS_PER_REVISION, question=question, reputed_at=timestamp, reputation_type=-7, reputation=flagged_user.reputation ) reputation.save() post.deleted = True #post.deleted_at = timestamp #post.deleted_by = Admin post.save() @transaction.commit_on_success def onUnFlaggedItem(post, user, timestamp=None): if timestamp is None: timestamp = datetime.datetime.now() post.offensive_flag_count = post.offensive_flag_count - 1 post.save() flagged_user = post.author flagged_user.receive_reputation( askbot_settings.REP_LOSS_FOR_RECEIVING_FLAG ) flagged_user.save() question = post.thread._question_post() reputation = Repute( user=flagged_user, positive=askbot_settings.REP_LOSS_FOR_RECEIVING_FLAG, question=question, reputed_at=timestamp, reputation_type=-4,#todo: clean up magic number reputation=flagged_user.reputation ) reputation.save() signals.remove_flag_offensive.send( sender=post.__class__, instance=post, mark_by=user ) if post.post_type == 'comment': #do not hide or delete comments automatically yet, #because there is no .deleted field in the comment model return #todo: These should be updated to work on same revisions. # The post fell below HIDE treshold - unhide it. if post.offensive_flag_count == askbot_settings.MIN_FLAGS_TO_HIDE_POST - 1: #todo: strange - are we supposed to hide the post here or the name of #setting is incorrect? flagged_user.receive_reputation( - askbot_settings.REP_LOSS_FOR_RECEIVING_THREE_FLAGS_PER_REVISION ) flagged_user.save() reputation = Repute( user=flagged_user, positive=\ askbot_settings.REP_LOSS_FOR_RECEIVING_THREE_FLAGS_PER_REVISION, question=question, reputed_at=timestamp, reputation_type=-6, reputation=flagged_user.reputation ) reputation.save() # The post fell below DELETE treshold, undelete it elif post.offensive_flag_count == askbot_settings.MIN_FLAGS_TO_DELETE_POST-1 : flagged_user.receive_reputation( - askbot_settings.REP_LOSS_FOR_RECEIVING_FIVE_FLAGS_PER_REVISION ) flagged_user.save() reputation = Repute( user=flagged_user, positive =\ askbot_settings.REP_LOSS_FOR_RECEIVING_FIVE_FLAGS_PER_REVISION, question=question, reputed_at=timestamp, reputation_type=-7, reputation=flagged_user.reputation ) reputation.save() post.deleted = False post.save() @transaction.commit_on_success def onAnswerAccept(answer, user, timestamp=None): answer.thread.set_accepted_answer(answer=answer, timestamp=timestamp) question = answer.thread._question_post() if answer.author != user: answer.author.receive_reputation( askbot_settings.REP_GAIN_FOR_RECEIVING_ANSWER_ACCEPTANCE ) answer.author.save() reputation = Repute(user=answer.author, positive=askbot_settings.REP_GAIN_FOR_RECEIVING_ANSWER_ACCEPTANCE, question=question, reputed_at=timestamp, reputation_type=2, reputation=answer.author.reputation) reputation.save() if answer.author == question.author and user == question.author: #a plug to prevent reputation gaming by posting a question #then answering and accepting as best all by the same person return user.receive_reputation(askbot_settings.REP_GAIN_FOR_ACCEPTING_ANSWER) user.save() reputation = Repute(user=user, positive=askbot_settings.REP_GAIN_FOR_ACCEPTING_ANSWER, question=question, reputed_at=timestamp, reputation_type=3, reputation=user.reputation) reputation.save() @transaction.commit_on_success def onAnswerAcceptCanceled(answer, user, timestamp=None): if timestamp is None: timestamp = datetime.datetime.now() answer.thread.set_accepted_answer(answer=None, timestamp=None) question = answer.thread._question_post() if user != answer.author: answer.author.receive_reputation( askbot_settings.REP_LOSS_FOR_RECEIVING_CANCELATION_OF_ANSWER_ACCEPTANCE ) answer.author.save() reputation = Repute( user=answer.author, negative=\ askbot_settings.REP_LOSS_FOR_RECEIVING_CANCELATION_OF_ANSWER_ACCEPTANCE, question=question, reputed_at=timestamp, reputation_type=-2, reputation=answer.author.reputation ) reputation.save() if answer.author == question.author and user == question.author: #a symmettric measure for the reputation gaming plug #as in the onAnswerAccept function #here it protects the user from uwanted reputation loss return user.receive_reputation( askbot_settings.REP_LOSS_FOR_CANCELING_ANSWER_ACCEPTANCE ) user.save() reputation = Repute(user=user, negative=askbot_settings.REP_LOSS_FOR_CANCELING_ANSWER_ACCEPTANCE, question=question, reputed_at=timestamp, reputation_type=-1, reputation=user.reputation) reputation.save() @transaction.commit_on_success def onUpVoted(vote, post, user, timestamp=None): if timestamp is None: timestamp = datetime.datetime.now() vote.save() if post.post_type != 'comment': post.vote_up_count = int(post.vote_up_count) + 1 post.points = int(post.points) + 1 post.save() if post.post_type == 'comment': #reputation is not affected by the comment votes return if not (post.wiki or post.is_anonymous): author = post.author todays_rep_gain = Repute.objects.get_reputation_by_upvoted_today(author) if todays_rep_gain < askbot_settings.MAX_REP_GAIN_PER_USER_PER_DAY: author.receive_reputation( askbot_settings.REP_GAIN_FOR_RECEIVING_UPVOTE ) author.save() question = post.thread._question_post() # TODO: this is suboptimal if post is already a question reputation = Repute(user=author, positive=askbot_settings.REP_GAIN_FOR_RECEIVING_UPVOTE, question=question, reputed_at=timestamp, reputation_type=1, reputation=author.reputation) reputation.save() @transaction.commit_on_success def onUpVotedCanceled(vote, post, user, timestamp=None): if timestamp is None: timestamp = datetime.datetime.now() vote.delete() if post.post_type != 'comment': post.vote_up_count = int(post.vote_up_count) - 1 if post.vote_up_count < 0: post.vote_up_count = 0 post.points = int(post.points) - 1 post.save() if post.post_type == 'comment': #comment votes do not affect reputation return if not (post.wiki or post.is_anonymous): author = post.author author.receive_reputation( askbot_settings.REP_LOSS_FOR_RECEIVING_UPVOTE_CANCELATION ) author.save() question = post.thread._question_post() # TODO: this is suboptimal if post is already a question reputation = Repute( user=author, negative=askbot_settings.REP_LOSS_FOR_RECEIVING_UPVOTE_CANCELATION, question=question, reputed_at=timestamp, reputation_type=-8, reputation=author.reputation ) reputation.save() @transaction.commit_on_success def onDownVoted(vote, post, user, timestamp=None): if timestamp is None: timestamp = datetime.datetime.now() vote.save() post.vote_down_count = int(post.vote_down_count) + 1 post.points = int(post.points) - 1 post.save() if not (post.wiki or post.is_anonymous): author = post.author author.receive_reputation( askbot_settings.REP_LOSS_FOR_RECEIVING_DOWNVOTE ) author.save() question = post.thread._question_post() # TODO: this is suboptimal if post is already a question reputation = Repute(user=author, negative=askbot_settings.REP_LOSS_FOR_RECEIVING_DOWNVOTE, question=question, reputed_at=timestamp, reputation_type=-3, reputation=author.reputation) reputation.save() user.receive_reputation( askbot_settings.REP_LOSS_FOR_DOWNVOTING, ) user.save() reputation = Repute(user=user, negative=askbot_settings.REP_LOSS_FOR_DOWNVOTING, question=question, reputed_at=timestamp, reputation_type=-5, reputation=user.reputation) reputation.save() @transaction.commit_on_success def onDownVotedCanceled(vote, post, user, timestamp=None): if timestamp is None: timestamp = datetime.datetime.now() vote.delete() post.vote_down_count = int(post.vote_down_count) - 1 if post.vote_down_count < 0: post.vote_down_count = 0 post.points = post.points + 1 post.save() if not (post.wiki or post.is_anonymous): author = post.author author.receive_reputation( askbot_settings.REP_GAIN_FOR_RECEIVING_DOWNVOTE_CANCELATION ) author.save() question = post.thread._question_post() # TODO: this is suboptimal if post is already a question reputation = Repute(user=author, positive=\ askbot_settings.REP_GAIN_FOR_RECEIVING_DOWNVOTE_CANCELATION, question=question, reputed_at=timestamp, reputation_type=4, reputation=author.reputation ) reputation.save() user.receive_reputation(askbot_settings.REP_GAIN_FOR_CANCELING_DOWNVOTE) user.save() reputation = Repute(user=user, positive=askbot_settings.REP_GAIN_FOR_CANCELING_DOWNVOTE, question=question, reputed_at=timestamp, reputation_type=5, reputation=user.reputation) reputation.save()