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