def _set_vote(self, user, delta): """Invoked by the user voting functions.""" assert delta in (0, 1, -1), 'you can only cast one vote' vote = _Vote.query.filter_by(user=user, post=self).first() # first things first. If the delta is zero we get rid of an # already existing vote. if delta == 0: if vote: session.delete(vote) self._revert_vote(vote, user) # otherwise we create a new vote entry or update the existing else: if vote is None: vote = _Vote(user, self, delta) else: self._revert_vote(vote, user) vote.delta = delta atomic_add(self, 'votes', delta, expire=True) # if this post is a topic, reflect the new value to the # topic table. topic = Topic.query.filter_by(question=self).first() if topic is not None: topic.votes = self.votes if delta > 0: atomic_add(user, 'upvotes', 1) if self.is_question: atomic_add(self.author, 'reputation', settings.REPUTATION_MAP['GAIN_ON_QUESTION_UPVOTE']) else: atomic_add(self.author, 'reputation', settings.REPUTATION_MAP['GAIN_ON_UPVOTE']) elif delta < 0: atomic_add(user, 'downvotes', 1) # downvoting yourself does not harm your reputation if self.author != user: atomic_add(self.author, 'reputation', -settings.REPUTATION_MAP['LOSE_ON_DOWNVOTE']) atomic_add(user, 'reputation', -settings.REPUTATION_MAP['DOWNVOTE_PENALTY']) # remember the vote in the user cache if not hasattr(user, '_vote_cache'): user._vote_cache = {} user._vote_cache[self.id] = delta # update hotness, activity and award badges if self.is_question: self.topic._update_hotness() user.touch_activity(self.topic.locale, 1) try_award('vote', user, self, delta)
def __init__(self, locale, title, text, user, date=None): self.locale = Locale.parse(locale) self.title = title # start with -1, when the question post is created the code will # increment it to zero automatically. self.reply_count = -1 self.is_deleted = False self.votes = 0 self.question = Post(self, user, text, date, is_reply=False) self.date = self.question.created self.author = self.question.author self.answer = None self.last_change = self.question.created self._update_hotness() session.add(self) try_award('new_topic', user, self)
def edit(self, new_text, editor=None, date=None): """Changes the post contents and moves the current one into the attic. """ if editor is None: editor = self.author if date is None: date = datetime.utcnow() PostRevision(self) self.text = new_text self.editor = editor self.updated = self.topic.last_change = date self.topic._update_hotness() atomic_add(self, 'edits', 1) try_award('edit', editor, self) editor.touch_activity(self.topic.locale, 20)
def __init__(self, topic, author, text, date=None, is_reply=True): self.topic = topic self.author = author self.editor = None self.text = text self.is_deleted = False self.is_answer = False self.is_question = not is_reply if date is None: date = datetime.utcnow() topic.last_change = self.updated = self.created = date self.votes = 0 self.edits = 0 self.comment_count = 0 author.touch_activity(topic.locale, 50) session.add(self) if not is_reply: try_award('reply', author, self)
def accept_answer(self, post, user=None): """Accept a post as answer.""" assert post is None or post.topic == self, \ 'that post does not belong to the topic' if self.answer is not None: self.answer.is_answer = False atomic_add(self.answer.author, 'reputation', -settings.REPUTATION_MAP['LOSE_ON_LOST_ANSWER']) if user is None: user = post and post.author or self.author if post is not None: post.is_answer = True atomic_add(post.author, 'reputation', settings.REPUTATION_MAP['GAIN_ON_ACCEPTED_ANSWER']) self.answer_author = post.author self.answer_date = post.created self.answer = post try_award('accept', user, self, post)