bgneal@147: """ bgneal@147: This module contains misc. utility functions for forum management. bgneal@147: """ bgneal@228: import logging bgneal@228: bgneal@147: from forums.models import Post, Topic, Forum, ForumLastVisit, TopicLastVisit bgneal@781: from forums.signals import notify_new_topic, notify_new_post bgneal@147: bgneal@147: bgneal@147: def delete_user_posts(user): bgneal@147: """ bgneal@147: This function deletes all the posts for a given user. bgneal@147: It also cleans up any last visit database records for the user. bgneal@147: This function adjusts the last post foreign keys before deleting bgneal@147: the posts to avoid the cascading delete behavior. bgneal@147: """ bgneal@147: posts = Post.objects.filter(user=user).select_related() bgneal@147: bgneal@285: # delete attachments bgneal@285: for post in posts: bgneal@285: post.attachments.clear() bgneal@285: bgneal@147: # build a set of topics and forums affected by the post deletions bgneal@147: bgneal@147: topics = set(post.topic for post in posts) bgneal@147: forums = set(topic.forum for topic in topics) bgneal@147: bgneal@147: post_ids = [post.pk for post in posts] bgneal@147: pending_delete = [] bgneal@147: bgneal@147: for topic in topics: bgneal@147: if topic.last_post.pk in post_ids: bgneal@147: topic_posts = Post.objects.filter(topic=topic).exclude( bgneal@147: pk__in=post_ids) bgneal@147: topic.post_count = topic_posts.count() bgneal@147: if topic.post_count > 0: bgneal@147: topic.last_post = topic_posts.latest() bgneal@147: topic.update_date = topic.last_post.creation_date bgneal@147: topic.save() bgneal@147: else: bgneal@147: # Topic should be deleted, it has no posts; bgneal@147: # We can't delete it now as it could cascade and take out a bgneal@147: # forum. Remember it for later deletion. bgneal@147: pending_delete.append(topic) bgneal@147: bgneal@147: for forum in forums: bgneal@147: if forum.last_post.pk in post_ids: bgneal@147: forum_posts = Post.objects.filter(topic__forum=forum).exclude( bgneal@147: pk__in=post_ids) bgneal@147: forum.post_count = forum_posts.count() bgneal@147: if forum.post_count > 0: bgneal@147: forum.last_post = forum_posts.latest() bgneal@147: else: bgneal@147: forum.last_post = None bgneal@147: forum.save() bgneal@348: bgneal@147: # Delete pending topics now because forums have just adjusted their bgneal@147: # foreign keys into Post bgneal@147: if pending_delete: bgneal@147: topic_ids = [topic.pk for topic in pending_delete] bgneal@147: Topic.objects.filter(pk__in=topic_ids).delete() bgneal@147: bgneal@147: # Topics have been deleted, re-compute topic counts for forums bgneal@147: for forum in forums: bgneal@147: forum.topic_count = Topic.objects.filter(forum=forum).count() bgneal@147: forum.save() bgneal@348: bgneal@147: # All foreign keys are accounted for, we can now delete the posts in bulk. bgneal@147: # Since some posts in our original queryset may have been deleted already, bgneal@147: # run a new query (although it may be ok) bgneal@147: Post.objects.filter(pk__in=post_ids).delete() bgneal@147: bgneal@147: # delete all the last visit records for this user bgneal@147: TopicLastVisit.objects.filter(user=user).delete() bgneal@147: ForumLastVisit.objects.filter(user=user).delete() bgneal@147: bgneal@228: bgneal@228: def create_topic(forum_slug, user, topic_name, post_body, ip='', sticky=False, bgneal@228: locked=False): bgneal@228: """Programmatically create a topic & first post in a given forum. bgneal@228: bgneal@228: This function creates a new topic in the forum that has the slug bgneal@228: specified by the 'forum_slug' argument. Other arguments are as follows: bgneal@228: 'user' - create the topic and post with this user as the owner bgneal@228: 'topic_name' - topic name (title) bgneal@228: 'post_body' - topic post body (as markup, not HTML) bgneal@228: 'ip' - IP address for the post (as a string) bgneal@228: 'sticky' - if True, the post will be stickied bgneal@228: 'locked' - if True, the post will be locked bgneal@228: bgneal@1001: The new topic is returned. bgneal@228: """ bgneal@228: try: bgneal@228: forum = Forum.objects.get(slug=forum_slug) bgneal@228: except Forum.DoesNotExist: bgneal@316: logging.error('could not create_topic for forum_slug=%s', forum_slug) bgneal@228: raise bgneal@228: bgneal@228: topic = Topic(forum=forum, bgneal@228: name=topic_name, bgneal@228: user=user, bgneal@228: sticky=sticky, bgneal@228: locked=locked) bgneal@228: topic.save() bgneal@228: bgneal@228: post = Post(topic=topic, bgneal@228: user=user, bgneal@228: body=post_body, bgneal@228: user_ip=ip) bgneal@228: post.save() bgneal@390: bgneal@781: notify_new_topic(topic) bgneal@781: notify_new_post(post) bgneal@1001: return topic bgneal@781: bgneal@390: bgneal@390: def auto_favorite(post): bgneal@390: """ bgneal@390: Given a newly created post, perform an auto-favorite action if the post bgneal@390: creator has that option set in their profile. bgneal@390: bgneal@390: """ bgneal@789: profile = post.user.profile bgneal@390: if profile.auto_favorite: bgneal@390: post.topic.bookmarkers.add(post.user) bgneal@390: bgneal@390: bgneal@390: def auto_subscribe(post): bgneal@390: """ bgneal@390: Given a newly created post, perform an auto-subscribe action if the post bgneal@390: creator has that option set in their profile. bgneal@390: bgneal@390: """ bgneal@789: profile = post.user.profile bgneal@390: if profile.auto_subscribe: bgneal@390: post.topic.subscribers.add(post.user)