def restore(self): """Restores a deleted post.""" if not self.is_deleted: return if self.is_question: self.topic.is_deleted = False for tag in self.topic.tags: atomic_add(tag, 'tagged', 1) else: atomic_add(self.topic, 'reply_count', 1) self.is_deleted = False
def touch_activity(self, locale, points): """Touches the activity of the user for the given locale.""" if not hasattr(self, '_activity_cache'): self._activity_cache = {} activity = self._activity_cache.get(locale) if activity is None: activity = _UserActivity.query.filter_by( user=self, locale=locale).first() if activity is None: activity = _UserActivity(self, locale) self._activity_cache[locale] = activity atomic_add(activity, 'counter', points) activity.last_activity = datetime.utcnow()
def touch_activity(self, locale, points): """Touches the activity of the user for the given locale.""" if not hasattr(self, '_activity_cache'): self._activity_cache = {} activity = self._activity_cache.get(locale) if activity is None: activity = _UserActivity.query.filter_by(user=self, locale=locale).first() if activity is None: activity = _UserActivity(self, locale) self._activity_cache[locale] = activity atomic_add(activity, 'counter', points) activity.last_activity = datetime.utcnow()
def delete(self): """Mark this post as deleted. Reflects that value to the topic as well. This also decreases the count on the tag so that it's no longer counted. For moderators this will cause some confusion on the tag pages but I think it's acceptable. """ if self.is_deleted: return if self.is_question: self.topic.is_deleted = True for tag in self.topic.tags: atomic_add(tag, 'tagged', -1) else: atomic_add(self.topic, 'reply_count', -1) self.is_deleted = True
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 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)
def remove(self, state, value, initiator): atomic_add(value, 'tagged', -1) return value
def append(self, state, value, initiator): atomic_add(value, 'tagged', 1) return value
def remove(self, state, value, initiator): atomic_add(state.obj(), 'comment_count', -1) return value
def append(self, state, value, initiator): atomic_add(state.obj(), 'comment_count', 1) return value
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 _revert_vote(self, vote, user): atomic_add(self, 'votes', -vote.delta) if vote.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 vote.delta < 0: atomic_add(user, 'downvotes', -1) # downvoting yourself does not harm your reputation if user != self.author: atomic_add(self.author, 'reputation', settings.REPUTATION_MAP['LOSE_ON_DOWNVOTE']) atomic_add(user, 'reputation', settings.REPUTATION_MAP['DOWNVOTE_PENALTY'])