Mercurial > public > sg101
diff forums/tools.py @ 581:ee87ea74d46b
For Django 1.4, rearranged project structure for new manage.py.
author | Brian Neal <bgneal@gmail.com> |
---|---|
date | Sat, 05 May 2012 17:10:48 -0500 |
parents | gpp/forums/tools.py@e0523e17ea43 |
children | b6d6c9e37fae |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/forums/tools.py Sat May 05 17:10:48 2012 -0500 @@ -0,0 +1,130 @@ +""" +This module contains misc. utility functions for forum management. +""" +import logging + +from forums.models import Post, Topic, Forum, ForumLastVisit, TopicLastVisit + + +def delete_user_posts(user): + """ + This function deletes all the posts for a given user. + It also cleans up any last visit database records for the user. + This function adjusts the last post foreign keys before deleting + the posts to avoid the cascading delete behavior. + """ + posts = Post.objects.filter(user=user).select_related() + + # delete attachments + for post in posts: + post.attachments.clear() + + # build a set of topics and forums affected by the post deletions + + topics = set(post.topic for post in posts) + forums = set(topic.forum for topic in topics) + + post_ids = [post.pk for post in posts] + pending_delete = [] + + for topic in topics: + if topic.last_post.pk in post_ids: + topic_posts = Post.objects.filter(topic=topic).exclude( + pk__in=post_ids) + topic.post_count = topic_posts.count() + if topic.post_count > 0: + topic.last_post = topic_posts.latest() + topic.update_date = topic.last_post.creation_date + topic.save() + else: + # Topic should be deleted, it has no posts; + # We can't delete it now as it could cascade and take out a + # forum. Remember it for later deletion. + pending_delete.append(topic) + + for forum in forums: + if forum.last_post.pk in post_ids: + forum_posts = Post.objects.filter(topic__forum=forum).exclude( + pk__in=post_ids) + forum.post_count = forum_posts.count() + if forum.post_count > 0: + forum.last_post = forum_posts.latest() + else: + forum.last_post = None + forum.save() + + # Delete pending topics now because forums have just adjusted their + # foreign keys into Post + if pending_delete: + topic_ids = [topic.pk for topic in pending_delete] + Topic.objects.filter(pk__in=topic_ids).delete() + + # Topics have been deleted, re-compute topic counts for forums + for forum in forums: + forum.topic_count = Topic.objects.filter(forum=forum).count() + forum.save() + + # All foreign keys are accounted for, we can now delete the posts in bulk. + # Since some posts in our original queryset may have been deleted already, + # run a new query (although it may be ok) + Post.objects.filter(pk__in=post_ids).delete() + + # delete all the last visit records for this user + TopicLastVisit.objects.filter(user=user).delete() + ForumLastVisit.objects.filter(user=user).delete() + + +def create_topic(forum_slug, user, topic_name, post_body, ip='', sticky=False, + locked=False): + """Programmatically create a topic & first post in a given forum. + + This function creates a new topic in the forum that has the slug + specified by the 'forum_slug' argument. Other arguments are as follows: + 'user' - create the topic and post with this user as the owner + 'topic_name' - topic name (title) + 'post_body' - topic post body (as markup, not HTML) + 'ip' - IP address for the post (as a string) + 'sticky' - if True, the post will be stickied + 'locked' - if True, the post will be locked + + """ + try: + forum = Forum.objects.get(slug=forum_slug) + except Forum.DoesNotExist: + logging.error('could not create_topic for forum_slug=%s', forum_slug) + raise + + topic = Topic(forum=forum, + name=topic_name, + user=user, + sticky=sticky, + locked=locked) + topic.save() + + post = Post(topic=topic, + user=user, + body=post_body, + user_ip=ip) + post.save() + + +def auto_favorite(post): + """ + Given a newly created post, perform an auto-favorite action if the post + creator has that option set in their profile. + + """ + profile = post.user.get_profile() + if profile.auto_favorite: + post.topic.bookmarkers.add(post.user) + + +def auto_subscribe(post): + """ + Given a newly created post, perform an auto-subscribe action if the post + creator has that option set in their profile. + + """ + profile = post.user.get_profile() + if profile.auto_subscribe: + post.topic.subscribers.add(post.user)