comparison 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
comparison
equal deleted inserted replaced
580:c525f3e0b5d0 581:ee87ea74d46b
1 """
2 This module contains misc. utility functions for forum management.
3 """
4 import logging
5
6 from forums.models import Post, Topic, Forum, ForumLastVisit, TopicLastVisit
7
8
9 def delete_user_posts(user):
10 """
11 This function deletes all the posts for a given user.
12 It also cleans up any last visit database records for the user.
13 This function adjusts the last post foreign keys before deleting
14 the posts to avoid the cascading delete behavior.
15 """
16 posts = Post.objects.filter(user=user).select_related()
17
18 # delete attachments
19 for post in posts:
20 post.attachments.clear()
21
22 # build a set of topics and forums affected by the post deletions
23
24 topics = set(post.topic for post in posts)
25 forums = set(topic.forum for topic in topics)
26
27 post_ids = [post.pk for post in posts]
28 pending_delete = []
29
30 for topic in topics:
31 if topic.last_post.pk in post_ids:
32 topic_posts = Post.objects.filter(topic=topic).exclude(
33 pk__in=post_ids)
34 topic.post_count = topic_posts.count()
35 if topic.post_count > 0:
36 topic.last_post = topic_posts.latest()
37 topic.update_date = topic.last_post.creation_date
38 topic.save()
39 else:
40 # Topic should be deleted, it has no posts;
41 # We can't delete it now as it could cascade and take out a
42 # forum. Remember it for later deletion.
43 pending_delete.append(topic)
44
45 for forum in forums:
46 if forum.last_post.pk in post_ids:
47 forum_posts = Post.objects.filter(topic__forum=forum).exclude(
48 pk__in=post_ids)
49 forum.post_count = forum_posts.count()
50 if forum.post_count > 0:
51 forum.last_post = forum_posts.latest()
52 else:
53 forum.last_post = None
54 forum.save()
55
56 # Delete pending topics now because forums have just adjusted their
57 # foreign keys into Post
58 if pending_delete:
59 topic_ids = [topic.pk for topic in pending_delete]
60 Topic.objects.filter(pk__in=topic_ids).delete()
61
62 # Topics have been deleted, re-compute topic counts for forums
63 for forum in forums:
64 forum.topic_count = Topic.objects.filter(forum=forum).count()
65 forum.save()
66
67 # All foreign keys are accounted for, we can now delete the posts in bulk.
68 # Since some posts in our original queryset may have been deleted already,
69 # run a new query (although it may be ok)
70 Post.objects.filter(pk__in=post_ids).delete()
71
72 # delete all the last visit records for this user
73 TopicLastVisit.objects.filter(user=user).delete()
74 ForumLastVisit.objects.filter(user=user).delete()
75
76
77 def create_topic(forum_slug, user, topic_name, post_body, ip='', sticky=False,
78 locked=False):
79 """Programmatically create a topic & first post in a given forum.
80
81 This function creates a new topic in the forum that has the slug
82 specified by the 'forum_slug' argument. Other arguments are as follows:
83 'user' - create the topic and post with this user as the owner
84 'topic_name' - topic name (title)
85 'post_body' - topic post body (as markup, not HTML)
86 'ip' - IP address for the post (as a string)
87 'sticky' - if True, the post will be stickied
88 'locked' - if True, the post will be locked
89
90 """
91 try:
92 forum = Forum.objects.get(slug=forum_slug)
93 except Forum.DoesNotExist:
94 logging.error('could not create_topic for forum_slug=%s', forum_slug)
95 raise
96
97 topic = Topic(forum=forum,
98 name=topic_name,
99 user=user,
100 sticky=sticky,
101 locked=locked)
102 topic.save()
103
104 post = Post(topic=topic,
105 user=user,
106 body=post_body,
107 user_ip=ip)
108 post.save()
109
110
111 def auto_favorite(post):
112 """
113 Given a newly created post, perform an auto-favorite action if the post
114 creator has that option set in their profile.
115
116 """
117 profile = post.user.get_profile()
118 if profile.auto_favorite:
119 post.topic.bookmarkers.add(post.user)
120
121
122 def auto_subscribe(post):
123 """
124 Given a newly created post, perform an auto-subscribe action if the post
125 creator has that option set in their profile.
126
127 """
128 profile = post.user.get_profile()
129 if profile.auto_subscribe:
130 post.topic.subscribers.add(post.user)