Compare View
Commits (2)
Showing
2 changed files
Show diff stats
forum/views/topic.py
| 1 | # coding: utf-8 | 1 | # coding: utf-8 |
| 2 | 2 | ||
| 3 | import json, math, hashlib | 3 | import json, math, hashlib |
| 4 | from django.http import HttpResponse, Http404 | 4 | from django.http import HttpResponse, Http404 |
| 5 | from django.shortcuts import render_to_response, redirect, get_object_or_404 | 5 | from django.shortcuts import render_to_response, redirect, get_object_or_404 |
| 6 | from django.contrib import auth | 6 | from django.contrib import auth |
| 7 | from django.contrib.auth.decorators import login_required | 7 | from django.contrib.auth.decorators import login_required |
| 8 | from django.template import RequestContext | 8 | from django.template import RequestContext |
| 9 | from django.utils import timezone | 9 | from django.utils import timezone |
| 10 | from django.conf import settings | 10 | from django.conf import settings |
| 11 | from forum.models import ForumUser, Topic, Favorite, Vote, Reply, Node, Notification, Plane | 11 | from forum.models import ForumUser, Topic, Favorite, Vote, Reply, Node, Notification, Plane |
| 12 | from forum.forms.topic import ReplyForm, CreateForm | 12 | from forum.forms.topic import ReplyForm, CreateForm |
| 13 | from common import find_mentions | 13 | from common import find_mentions |
| 14 | 14 | ||
| 15 | 15 | ||
| 16 | def get_index(request): | 16 | def get_index(request): |
| 17 | user = request.user | 17 | user = request.user |
| 18 | if user.is_authenticated(): | 18 | if user.is_authenticated(): |
| 19 | counter = { | 19 | counter = { |
| 20 | 'topics': user.topic_author.all().count(), | 20 | 'topics': user.topic_author.all().count(), |
| 21 | 'replies': user.reply_author.all().count(), | 21 | 'replies': user.reply_author.all().count(), |
| 22 | 'favorites': user.fav_user.all().count() | 22 | 'favorites': user.fav_user.all().count() |
| 23 | } | 23 | } |
| 24 | notifications_count = user.notify_user.filter(status=0).count() | 24 | notifications_count = user.notify_user.filter(status=0).count() |
| 25 | 25 | ||
| 26 | status_counter = { | 26 | status_counter = { |
| 27 | 'users': ForumUser.objects.all().count(), | 27 | 'users': ForumUser.objects.all().count(), |
| 28 | 'nodes': Node.objects.all().count(), | 28 | 'nodes': Node.objects.all().count(), |
| 29 | 'topics': Topic.objects.all().count(), | 29 | 'topics': Topic.objects.all().count(), |
| 30 | 'replies': Reply.objects.all().count(), | 30 | 'replies': Reply.objects.all().count(), |
| 31 | } | 31 | } |
| 32 | 32 | ||
| 33 | try: | 33 | try: |
| 34 | current_page = int(request.GET.get('p', '1')) | 34 | current_page = int(request.GET.get('p', '1')) |
| 35 | except ValueError: | 35 | except ValueError: |
| 36 | current_page = 1 | 36 | current_page = 1 |
| 37 | 37 | ||
| 38 | topics, topic_page = Topic.objects.get_all_topic(current_page=current_page) | 38 | topics, topic_page = Topic.objects.get_all_topic(current_page=current_page) |
| 39 | planes = Plane.objects.all().prefetch_related('node_set') | 39 | planes = Plane.objects.all().prefetch_related('node_set') |
| 40 | # hot_nodes = Node.objects.get_all_hot_nodes() | 40 | # hot_nodes = Node.objects.get_all_hot_nodes() |
| 41 | hot_nodes = Node.objects.all() | 41 | hot_nodes = Node.objects.all() |
| 42 | active_page = 'topic' | 42 | active_page = 'topic' |
| 43 | return render_to_response('topic/topics.html', locals(), | 43 | return render_to_response('topic/topics.html', locals(), |
| 44 | context_instance=RequestContext(request)) | 44 | context_instance=RequestContext(request)) |
| 45 | 45 | ||
| 46 | 46 | ||
| 47 | def get_view(request, topic_id, errors=None): | 47 | def get_view(request, topic_id, errors=None): |
| 48 | try: | 48 | try: |
| 49 | topic = Topic.objects.get_topic_by_topic_id(topic_id) | 49 | topic = Topic.objects.get_topic_by_topic_id(topic_id) |
| 50 | except Topic.DoesNotExist: | 50 | except Topic.DoesNotExist: |
| 51 | raise Http404 | 51 | raise Http404 |
| 52 | |||
| 52 | 53 | user = request.user | |
| 53 | user = request.user | 54 | if user.is_authenticated(): |
| 54 | if user.is_authenticated(): | 55 | counter = { |
| 55 | counter = { | 56 | 'topics': user.topic_author.all().count(), |
| 56 | 'topics': user.topic_author.all().count(), | 57 | 'replies': user.reply_author.all().count(), |
| 57 | 'replies': user.reply_author.all().count(), | 58 | 'favorites': user.fav_user.all().count() |
| 58 | 'favorites': user.fav_user.all().count() | 59 | } |
| 59 | } | 60 | notifications_count = user.notify_user.filter(status=0).count() |
| 60 | notifications_count = user.notify_user.filter(status=0).count() | 61 | topic_favorited = Favorite.objects.filter(involved_topic=topic, owner_user=user).exists() |
| 61 | topic_favorited = Favorite.objects.filter(involved_topic=topic, owner_user=user).exists() | 62 | |
| 62 | 63 | reply_num = 106 | |
| 63 | reply_num = 106 | 64 | reply_count = topic.reply_count |
| 64 | reply_count = topic.reply_count | 65 | reply_last_page = (reply_count // reply_num + (reply_count % reply_num and 1)) or 1 |
| 65 | reply_last_page = (reply_count // reply_num + (reply_count % reply_num and 1)) or 1 | 66 | try: |
| 66 | try: | 67 | current_page = int(request.GET.get('p', reply_last_page)) |
| 67 | current_page = int(request.GET.get('p', reply_last_page)) | 68 | except ValueError: |
| 68 | except ValueError: | 69 | current_page = reply_last_page |
| 69 | current_page = reply_last_page | 70 | |
| 70 | 71 | replies, reply_page = Reply.objects.get_all_replies_by_topic_id(topic.id, current_page=current_page, num = reply_num) | |
| 71 | replies, reply_page = Reply.objects.get_all_replies_by_topic_id(topic.id, current_page=current_page, num = reply_num) | 72 | active_page = 'topic' |
| 72 | active_page = 'topic' | 73 | floor = reply_num * (current_page - 1) |
| 73 | floor = reply_num * (current_page - 1) | 74 | |
| 74 | 75 | topic.reply_count = reply_page.total | |
| 75 | topic.reply_count = reply_page.total | 76 | topic.hits = (topic.hits or 0) + 1 |
| 76 | topic.hits = (topic.hits or 0) + 1 | 77 | topic.save() |
| 77 | topic.save() | 78 | return render_to_response('topic/view.html', locals(), |
| 78 | return render_to_response('topic/view.html', locals(), | 79 | context_instance=RequestContext(request)) |
| 79 | context_instance=RequestContext(request)) | 80 | |
| 80 | 81 | ||
| 81 | 82 | @login_required | |
| 82 | @login_required | 83 | def post_view(request, topic_id): |
| 83 | def post_view(request, topic_id): | 84 | try: |
| 84 | try: | 85 | topic = Topic.objects.select_related('author').get(pk=topic_id) |
| 85 | topic = Topic.objects.select_related('author').get(pk=topic_id) | 86 | except Topic.DoesNotExist: |
| 86 | except Topic.DoesNotExist: | 87 | raise Http404 |
| 87 | raise Http404 | 88 | form = ReplyForm(request.POST) |
| 88 | form = ReplyForm(request.POST) | 89 | if not form.is_valid(): |
| 89 | if not form.is_valid(): | 90 | return get_view(request, topic_id, errors=form.errors) |
| 90 | return get_view(request, topic_id, errors=form.errors) | 91 | |
| 91 | 92 | user = request.user | |
| 92 | user = request.user | 93 | try: |
| 93 | try: | 94 | last_reply = topic.reply_set.all().order_by('-created')[0] |
| 94 | last_reply = topic.reply_set.all().order_by('-created')[0] | 95 | except IndexError: |
| 95 | except IndexError: | 96 | last_reply = None |
| 96 | last_reply = None | 97 | if last_reply: |
| 97 | if last_reply: | 98 | last_replied_fingerprint = hashlib.sha1(str(topic.id) + str(last_reply.author_id) + last_reply.content).hexdigest() |
| 98 | last_replied_fingerprint = hashlib.sha1(str(topic.id) + str(last_reply.author_id) + last_reply.content).hexdigest() | 99 | new_replied_fingerprint = hashlib.sha1(str(topic.id) + str(user.id) + form.cleaned_data.get('content')).hexdigest() |
| 99 | new_replied_fingerprint = hashlib.sha1(str(topic.id) + str(user.id) + form.cleaned_data.get('content')).hexdigest() | 100 | if last_replied_fingerprint == new_replied_fingerprint: |
| 100 | if last_replied_fingerprint == new_replied_fingerprint: | 101 | errors = {'duplicated_reply': [u'回复重复提交']} |
| 101 | errors = {'duplicated_reply': [u'回复重复提交']} | 102 | return get_view(request, topic.id, errors=errors) |
| 102 | return get_view(request, topic.id, errors=errors) | 103 | |
| 103 | 104 | now = timezone.now() | |
| 104 | now = timezone.now() | 105 | reply = Reply( |
| 105 | reply = Reply( | 106 | topic = topic, |
| 106 | topic = topic, | 107 | author = user, |
| 107 | author = user, | 108 | content = form.cleaned_data.get('content'), |
| 108 | content = form.cleaned_data.get('content'), | 109 | created = now, |
| 109 | created = now, | 110 | ) |
| 110 | ) | 111 | reply.save() |
| 111 | reply.save() | 112 | Topic.objects.filter(pk=topic.id).update(last_replied_by=user, last_replied_time=now, last_touched=now) |
| 112 | Topic.objects.filter(pk=topic.id).update(last_replied_by=user, last_replied_time=now, last_touched=now) | 113 | |
| 113 | 114 | notifications = [] | |
| 114 | notifications = [] | 115 | if user.id != topic.author.id: |
| 115 | if user.id != topic.author.id: | 116 | notification = Notification( |
| 116 | notification = Notification( | 117 | content = form.cleaned_data.get('content'), |
| 117 | content = form.cleaned_data.get('content'), | 118 | status = 0, |
| 118 | status = 0, | 119 | involved_type = 1, # 0: mention, 1: reply |
| 119 | involved_type = 1, # 0: mention, 1: reply | 120 | involved_user = topic.author, |
| 120 | involved_user = topic.author, | 121 | involved_topic = topic, |
| 121 | involved_topic = topic, | 122 | trigger_user = user, |
| 122 | trigger_user = user, | 123 | occurrence_time = now, |
| 123 | occurrence_time = now, | 124 | ) |
| 124 | ) | 125 | notifications.append(notification) |
| 125 | notifications.append(notification) | 126 | |
| 126 | 127 | mentions = find_mentions(form.cleaned_data.get('content')) | |
| 127 | mentions = find_mentions(form.cleaned_data.get('content')) | 128 | if user.username in mentions: |
| 128 | if user.username in mentions: | 129 | mentions.remove(user.username) |
| 129 | mentions.remove(user.username) | 130 | if topic.author.username in mentions: |
| 130 | if topic.author.username in mentions: | 131 | mentions.remove(topic.author.username) |
| 131 | mentions.remove(topic.author.username) | 132 | if mentions: |
| 132 | if mentions: | 133 | mention_users = ForumUser.objects.filter(username__in=mentions) |
| 133 | mention_users = ForumUser.objects.filter(username__in=mentions) | 134 | if mention_users: |
| 134 | if mention_users: | 135 | for mention_user in mention_users: |
| 135 | for mention_user in mention_users: | 136 | notification = Notification( |
| 136 | notification = Notification( | 137 | content = form.cleaned_data.get('content'), |
| 137 | content = form.cleaned_data.get('content'), | 138 | status = 0, |
| 138 | status = 0, | 139 | involved_type = 0, # 0: mention, 1: reply |
| 139 | involved_type = 0, # 0: mention, 1: reply | 140 | involved_user = mention_user, |
| 140 | involved_user = mention_user, | 141 | involved_topic = topic, |
| 141 | involved_topic = topic, | 142 | trigger_user = user, |
| 142 | trigger_user = user, | 143 | occurrence_time = now, |
| 143 | occurrence_time = now, | 144 | ) |
| 144 | ) | 145 | notifications.append(notification) |
| 145 | notifications.append(notification) | 146 | if notifications: |
| 146 | if notifications: | 147 | Notification.objects.bulk_create(notifications) |
| 147 | Notification.objects.bulk_create(notifications) | 148 | |
| 148 | 149 | if user.id != topic.author.id: | |
| 149 | if user.id != topic.author.id: | 150 | topic_time_diff = timezone.now() - topic.created |
| 150 | topic_time_diff = timezone.now() - topic.created | 151 | reputation = topic.author.reputation or 0 |
| 151 | reputation = topic.author.reputation or 0 | 152 | reputation = reputation + 2 * math.log(user.reputation or 0 + topic_time_diff.days + 10, 10) |
| 152 | reputation = reputation + 2 * math.log(user.reputation or 0 + topic_time_diff.days + 10, 10) | 153 | ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) |
| 153 | ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) | 154 | |
| 154 | 155 | return get_view(request, topic_id, errors=form.errors) | |
| 155 | return get_view(request, topic_id, errors=form.errors) | 156 | |
| 156 | 157 | ||
| 157 | 158 | @login_required | |
| 158 | @login_required | 159 | def get_create(request, slug=None, errors=None): |
| 159 | def get_create(request, slug=None, errors=None): | 160 | node = get_object_or_404(Node, slug=slug) |
| 160 | node = get_object_or_404(Node, slug=slug) | 161 | user = request.user |
| 161 | user = request.user | 162 | counter = { |
| 162 | counter = { | 163 | 'topics': user.topic_author.all().count(), |
| 163 | 'topics': user.topic_author.all().count(), | 164 | 'replies': user.reply_author.all().count(), |
| 164 | 'replies': user.reply_author.all().count(), | 165 | 'favorites': user.fav_user.all().count() |
| 165 | 'favorites': user.fav_user.all().count() | 166 | } |
| 166 | } | 167 | notifications_count = user.notify_user.filter(status=0).count() |
| 167 | notifications_count = user.notify_user.filter(status=0).count() | 168 | node_slug = node.slug |
| 168 | node_slug = node.slug | 169 | active_page = 'topic' |
| 169 | active_page = 'topic' | 170 | return render_to_response('topic/create.html', locals(), |
| 170 | return render_to_response('topic/create.html', locals(), | 171 | context_instance=RequestContext(request)) |
| 171 | context_instance=RequestContext(request)) | 172 | |
| 172 | 173 | ||
| 173 | 174 | @login_required | |
| 174 | @login_required | 175 | def post_create(request, slug=None): |
| 175 | def post_create(request, slug=None): | 176 | node = get_object_or_404(Node, slug=slug) |
| 176 | node = get_object_or_404(Node, slug=slug) | 177 | |
| 177 | 178 | form = CreateForm(request.POST) | |
| 178 | form = CreateForm(request.POST) | 179 | if not form.is_valid(): |
| 179 | if not form.is_valid(): | 180 | return get_create(request, slug=slug, errors=form.errors) |
| 180 | return get_create(request, slug=slug, errors=form.errors) | 181 | |
| 181 | 182 | user = request.user | |
| 182 | user = request.user | 183 | try: |
| 183 | try: | 184 | last_created = user.topic_author.all().order_by('-created')[0] |
| 184 | last_created = user.topic_author.all().order_by('-created')[0] | 185 | except IndexError: |
| 185 | except IndexError: | 186 | last_created = None |
| 186 | last_created = None | 187 | |
| 187 | 188 | if last_created: # 如果用户最后一篇的标题内容与提交的相同 | |
| 188 | if last_created: # 如果用户最后一篇的标题内容与提交的相同 | 189 | last_created_fingerprint = hashlib.sha1(last_created.title + \ |
| 189 | last_created_fingerprint = hashlib.sha1(last_created.title + \ | 190 | last_created.content + str(last_created.node_id)).hexdigest() |
| 190 | last_created.content + str(last_created.node_id)).hexdigest() | 191 | new_created_fingerprint = hashlib.sha1(form.cleaned_data.get('title') + \ |
| 191 | new_created_fingerprint = hashlib.sha1(form.cleaned_data.get('title') + \ | 192 | form.cleaned_data.get('content') + str(node.id)).hexdigest() |
| 192 | form.cleaned_data.get('content') + str(node.id)).hexdigest() | 193 | |
| 193 | 194 | if last_created_fingerprint == new_created_fingerprint: | |
| 194 | if last_created_fingerprint == new_created_fingerprint: | 195 | errors = {'duplicated_topic': [u'帖子重复提交']} |
| 195 | errors = {'duplicated_topic': [u'帖子重复提交']} | 196 | return get_create(request, slug=slug, errors=errors) |
| 196 | return get_create(request, slug=slug, errors=errors) | 197 | |
| 197 | 198 | now = timezone.now() | |
| 198 | now = timezone.now() | 199 | topic = Topic( |
| 199 | topic = Topic( | 200 | title = form.cleaned_data.get('title'), |
| 200 | title = form.cleaned_data.get('title'), | 201 | content = form.cleaned_data.get('content'), |
| 201 | content = form.cleaned_data.get('content'), | 202 | created = now, |
| 202 | created = now, | 203 | node = node, |
| 203 | node = node, | 204 | author = user, |
| 204 | author = user, | 205 | reply_count = 0, |
| 205 | reply_count = 0, | 206 | last_touched = now, |
| 206 | last_touched = now, | 207 | ) |
| 207 | ) | 208 | topic.save() |
| 208 | topic.save() | 209 | |
| 209 | 210 | reputation = user.reputation or 0 | |
| 210 | reputation = user.reputation or 0 | 211 | reputation = reputation - 5 # 每次发布话题扣除用户威望5点 |
| 211 | reputation = reputation - 5 # 每次发布话题扣除用户威望5点 | 212 | reputation = 0 if reputation < 0 else reputation |
| 212 | reputation = 0 if reputation < 0 else reputation | 213 | ForumUser.objects.filter(pk=user.id).update(reputation=reputation) |
| 213 | ForumUser.objects.filter(pk=user.id).update(reputation=reputation) | 214 | |
| 214 | 215 | return redirect('/') | |
| 215 | return redirect('/') | 216 | |
| 216 | 217 | ||
| 217 | 218 | @login_required | |
| 218 | @login_required | 219 | def get_edit(request, topic_id, errors=None): |
| 219 | def get_edit(request, topic_id, errors=None): | 220 | topic = get_object_or_404(Topic, pk=topic_id) |
| 220 | topic = get_object_or_404(Topic, pk=topic_id) | 221 | |
| 221 | 222 | user = request.user | |
| 222 | user = request.user | 223 | counter = { |
| 223 | counter = { | 224 | 'topics': user.topic_author.all().count(), |
| 224 | 'topics': user.topic_author.all().count(), | 225 | 'replies': user.reply_author.all().count(), |
| 225 | 'replies': user.reply_author.all().count(), | 226 | 'favorites': user.fav_user.all().count() |
| 226 | 'favorites': user.fav_user.all().count() | 227 | } |
| 227 | } | 228 | notifications_count = user.notify_user.filter(status=0).count() |
| 228 | notifications_count = user.notify_user.filter(status=0).count() | 229 | |
| 229 | 230 | active_page = 'topic' | |
| 230 | active_page = 'topic' | 231 | return render_to_response('topic/edit.html', locals(), |
| 231 | return render_to_response('topic/edit.html', locals(), | 232 | context_instance=RequestContext(request)) |
| 232 | context_instance=RequestContext(request)) | 233 | |
| 233 | 234 | ||
| 234 | 235 | @login_required | |
| 235 | @login_required | 236 | def post_edit(request, topic_id): |
| 236 | def post_edit(request, topic_id): | 237 | topic = get_object_or_404(Topic, pk=topic_id) |
| 237 | topic = get_object_or_404(Topic, pk=topic_id) | 238 | |
| 238 | 239 | form = CreateForm(request.POST) | |
| 239 | form = CreateForm(request.POST) | 240 | if not form.is_valid(): |
| 240 | if not form.is_valid(): | 241 | return get_edit(request, topic_id, errors=form.errors) |
| 241 | return get_edit(request, topic_id, errors=form.errors) | 242 | |
| 242 | 243 | user = request.user | |
| 243 | user = request.user | 244 | if topic.author_id != user.id: |
| 244 | if topic.author_id != user.id: | 245 | errors = {'invalid_permission': [u'没有权限修改该主题']} |
| 245 | errors = {'invalid_permission': [u'没有权限修改该主题']} | 246 | return get_edit(request, topic_id, errors=errors) |
| 246 | return get_edit(request, topic_id, errors=errors) | 247 | |
| 247 | 248 | now = timezone.now() | |
| 248 | now = timezone.now() | 249 | Topic.objects.filter(pk=topic.id).update(updated=now, last_touched=now, **form.cleaned_data) |
| 249 | Topic.objects.filter(pk=topic.id).update(updated=now, last_touched=now, **form.cleaned_data) | 250 | |
| 250 | 251 | reputation = user.reputation or 0 | |
| 251 | reputation = user.reputation or 0 | 252 | reputation = reputation - 2 # 每次修改回复扣除用户威望2点 |
| 252 | reputation = reputation - 2 # 每次修改回复扣除用户威望2点 | 253 | reputation = 0 if reputation < 0 else reputation |
| 253 | reputation = 0 if reputation < 0 else reputation | 254 | ForumUser.objects.filter(pk=user.id).update(reputation=reputation) |
| 254 | ForumUser.objects.filter(pk=user.id).update(reputation=reputation) | 255 | |
| 255 | 256 | return redirect('/t/%s/' % topic.id) | |
| 256 | return redirect('/t/%s/' % topic.id) | 257 | |
| 257 | 258 | ||
| 258 | 259 | @login_required | |
| 259 | @login_required | 260 | def get_reply_edit(request, reply_id, errors=None): |
| 260 | def get_reply_edit(request, reply_id, errors=None): | 261 | reply = get_object_or_404(Reply, pk=reply_id) |
| 261 | reply = get_object_or_404(Reply, pk=reply_id) | 262 | user = request.user |
| 262 | user = request.user | 263 | counter = { |
| 263 | counter = { | 264 | 'topics': user.topic_author.all().count(), |
| 264 | 'topics': user.topic_author.all().count(), | 265 | 'replies': user.reply_author.all().count(), |
| 265 | 'replies': user.reply_author.all().count(), | 266 | 'favorites': user.fav_user.all().count() |
| 266 | 'favorites': user.fav_user.all().count() | 267 | } |
| 267 | } | 268 | notifications_count = user.notify_user.filter(status=0).count() |
| 268 | notifications_count = user.notify_user.filter(status=0).count() | 269 | active_page = 'topic' |
| 269 | active_page = 'topic' | 270 | return render_to_response('topic/reply_edit.html', locals(), |
| 270 | return render_to_response('topic/reply_edit.html', locals(), | 271 | context_instance=RequestContext(request)) |
| 271 | context_instance=RequestContext(request)) | 272 | |
| 272 | 273 | ||
| 273 | 274 | @login_required | |
| 274 | @login_required | 275 | def post_reply_edit(request, reply_id): |
| 275 | def post_reply_edit(request, reply_id): | 276 | reply = get_object_or_404(Reply, pk=reply_id) |
| 276 | reply = get_object_or_404(Reply, pk=reply_id) | 277 | |
| 277 | 278 | form = ReplyForm(request.POST) | |
| 278 | form = ReplyForm(request.POST) | 279 | if not form.is_valid(): |
| 279 | if not form.is_valid(): | 280 | return get_reply_edit(request, reply_id, errors=form.errors) |
| 280 | return get_reply_edit(request, reply_id, errors=form.errors) | 281 | |
| 281 | 282 | user = request.user | |
| 282 | user = request.user | 283 | if reply.author_id != user.id: |
| 283 | if reply.author_id != user.id: | 284 | errors = {'invalid_permission': [u'没有权限修改该回复']} |
| 284 | errors = {'invalid_permission': [u'没有权限修改该回复']} | 285 | return get_reply_edit(request, reply_id, errors=errors) |
| 285 | return get_reply_edit(request, reply_id, errors=errors) | 286 | |
| 286 | 287 | Reply.objects.filter(pk=reply.id).update(updated=timezone.now(), **form.cleaned_data) | |
| 287 | Reply.objects.filter(pk=reply.id).update(updated=timezone.now(), **form.cleaned_data) | 288 | |
| 288 | 289 | reputation = user.reputation or 0 | |
| 289 | reputation = user.reputation or 0 | 290 | reputation = reputation - 2 # 每次修改回复扣除用户威望2点 |
| 290 | reputation = reputation - 2 # 每次修改回复扣除用户威望2点 | 291 | reputation = 0 if reputation < 0 else reputation |
| 291 | reputation = 0 if reputation < 0 else reputation | 292 | ForumUser.objects.filter(pk=user.id).update(reputation=reputation) |
| 292 | ForumUser.objects.filter(pk=user.id).update(reputation=reputation) | 293 | |
| 293 | 294 | return redirect('/t/%s/' % reply.topic_id) | |
| 294 | return redirect('/t/%s/' % reply.topic_id) | 295 | |
| 295 | 296 | ||
| 296 | 297 | def get_node_topics(request, slug): | |
| 297 | def get_node_topics(request, slug): | 298 | node = get_object_or_404(Node, slug=slug) |
| 298 | node = get_object_or_404(Node, slug=slug) | 299 | |
| 299 | 300 | user = request.user | |
| 300 | user = request.user | 301 | if user.is_authenticated(): |
| 301 | if user.is_authenticated(): | 302 | counter = { |
| 302 | counter = { | 303 | 'topics': user.topic_author.all().count(), |
| 303 | 'topics': user.topic_author.all().count(), | 304 | 'replies': user.reply_author.all().count(), |
| 304 | 'replies': user.reply_author.all().count(), | 305 | 'favorites': user.fav_user.all().count() |
| 305 | 'favorites': user.fav_user.all().count() | 306 | } |
| 306 | } | 307 | notifications_count = user.notify_user.filter(status=0).count() |
| 307 | notifications_count = user.notify_user.filter(status=0).count() | 308 | |
| 308 | 309 | try: | |
| 309 | try: | 310 | current_page = int(request.GET.get('p', '1')) |
| 310 | current_page = int(request.GET.get('p', '1')) | 311 | except ValueError: |
| 311 | except ValueError: | 312 | current_page = 1 |
| 312 | current_page = 1 | 313 | |
| 313 | 314 | topics, topic_page = Topic.objects.get_all_topics_by_node_slug(node_slug=slug, current_page=current_page) | |
| 314 | topics, topic_page = Topic.objects.get_all_topics_by_node_slug(node_slug=slug, current_page=current_page) | 315 | active_page = 'topic' |
| 315 | active_page = 'topic' | 316 | return render_to_response('topic/node_topics.html', locals(), |
| 316 | return render_to_response('topic/node_topics.html', locals(), | 317 | context_instance=RequestContext(request)) |
| 317 | context_instance=RequestContext(request)) | 318 | |
| 318 | 319 | ||
| 319 | 320 | def get_user_topics(request, uid): | |
| 320 | def get_user_topics(request, uid): | 321 | try: |
| 321 | try: | 322 | if uid.isdigit(): |
| 322 | if uid.isdigit(): | 323 | user_info = ForumUser.objects.get(pk=uid) |
| 323 | user_info = ForumUser.objects.get(pk=uid) | 324 | else: |
| 324 | else: | 325 | user_info = ForumUser.objects.get(username=uid) |
| 325 | user_info = ForumUser.objects.get(username=uid) | 326 | except ForumUser.DoesNotExist: |
| 326 | except ForumUser.DoesNotExist: | 327 | raise Http404 |
| 327 | raise Http404 | 328 | |
| 328 | 329 | try: | |
| 329 | try: | 330 | current_page = int(request.GET.get('p', '1')) |
| 330 | current_page = int(request.GET.get('p', '1')) | 331 | except ValueError: |
| 331 | except ValueError: | 332 | current_page = 1 |
| 332 | current_page = 1 | 333 | |
| 333 | 334 | counter = { | |
| 334 | counter = { | 335 | 'topics': user_info.topic_author.all().count(), |
| 335 | 'topics': user_info.topic_author.all().count(), | 336 | 'replies': user_info.reply_author.all().count(), |
| 336 | 'replies': user_info.reply_author.all().count(), | 337 | 'favorites': user_info.fav_user.all().count() |
| 337 | 'favorites': user_info.fav_user.all().count() | 338 | } |
| 338 | } | 339 | |
| 339 | 340 | user = request.user | |
| 340 | user = request.user | 341 | if user.is_authenticated(): |
| 341 | if user.is_authenticated(): | 342 | notifications_count = user.notify_user.filter(status=0).count() |
| 342 | notifications_count = user.notify_user.filter(status=0).count() | 343 | |
| 343 | 344 | topics, topic_page = Topic.objects.get_user_all_topics(user_info.id, current_page=current_page) | |
| 344 | topics, topic_page = Topic.objects.get_user_all_topics(user_info.id, current_page=current_page) | 345 | active_page = 'topic' |
| 345 | active_page = 'topic' | 346 | return render_to_response('topic/user_topics.html', locals(), |
| 346 | return render_to_response('topic/user_topics.html', locals(), | 347 | context_instance=RequestContext(request)) |
| 347 | context_instance=RequestContext(request)) | 348 | |
| 348 | 349 | ||
| 349 | 350 | def get_user_replies(request, uid): | |
| 350 | def get_user_replies(request, uid): | 351 | try: |
| 351 | try: | 352 | if uid.isdigit(): |
| 352 | if uid.isdigit(): | 353 | user_info = ForumUser.objects.get(pk=uid) |
| 353 | user_info = ForumUser.objects.get(pk=uid) | 354 | else: |
| 354 | else: | 355 | user_info = ForumUser.objects.get(username=uid) |
| 355 | user_info = ForumUser.objects.get(username=uid) | 356 | except ForumUser.DoesNotExist: |
| 356 | except ForumUser.DoesNotExist: | 357 | raise Http404 |
| 357 | raise Http404 | 358 | |
| 358 | 359 | try: | |
| 359 | try: | 360 | current_page = int(request.GET.get('p', '1')) |
| 360 | current_page = int(request.GET.get('p', '1')) | 361 | except ValueError: |
| 361 | except ValueError: | 362 | current_page = 1 |
| 362 | current_page = 1 | 363 | |
| 363 | 364 | counter = { | |
| 364 | counter = { | 365 | 'topics': user_info.topic_author.all().count(), |
| 365 | 'topics': user_info.topic_author.all().count(), | 366 | 'replies': user_info.reply_author.all().count(), |
| 366 | 'replies': user_info.reply_author.all().count(), | 367 | 'favorites': user_info.fav_user.all().count() |
| 367 | 'favorites': user_info.fav_user.all().count() | 368 | } |
| 368 | } | 369 | |
| 369 | 370 | user = request.user | |
| 370 | user = request.user | 371 | if user.is_authenticated(): |
| 371 | if user.is_authenticated(): | 372 | notifications_count = user.notify_user.filter(status=0).count() |
| 372 | notifications_count = user.notify_user.filter(status=0).count() | 373 | |
| 373 | 374 | replies, reply_page = Reply.objects.get_user_all_replies(user_info.id, current_page=current_page) | |
| 374 | replies, reply_page = Reply.objects.get_user_all_replies(user_info.id, current_page=current_page) | 375 | active_page = 'topic' |
| 375 | active_page = 'topic' | 376 | return render_to_response('topic/user_replies.html', locals(), |
| 376 | return render_to_response('topic/user_replies.html', locals(), | 377 | context_instance=RequestContext(request)) |
| 377 | context_instance=RequestContext(request)) | 378 | |
| 378 | 379 | ||
| 379 | 380 | def get_user_favorites(request, uid): | |
| 380 | def get_user_favorites(request, uid): | 381 | try: |
| 381 | try: | 382 | if uid.isdigit(): |
| 382 | if uid.isdigit(): | 383 | user_info = ForumUser.objects.get(pk=uid) |
| 383 | user_info = ForumUser.objects.get(pk=uid) | 384 | else: |
| 384 | else: | 385 | user_info = ForumUser.objects.get(username=uid) |
| 385 | user_info = ForumUser.objects.get(username=uid) | 386 | except ForumUser.DoesNotExist: |
| 386 | except ForumUser.DoesNotExist: | 387 | raise Http404 |
| 387 | raise Http404 | 388 | |
| 388 | 389 | try: | |
| 389 | try: | 390 | current_page = int(request.GET.get('p', '1')) |
| 390 | current_page = int(request.GET.get('p', '1')) | 391 | except ValueError: |
| 391 | except ValueError: | 392 | current_page = 1 |
| 392 | current_page = 1 | 393 | |
| 393 | 394 | counter = { | |
| 394 | counter = { | 395 | 'topics': user_info.topic_author.all().count(), |
| 395 | 'topics': user_info.topic_author.all().count(), | 396 | 'replies': user_info.reply_author.all().count(), |
| 396 | 'replies': user_info.reply_author.all().count(), | 397 | 'favorites': user_info.fav_user.all().count() |
| 397 | 'favorites': user_info.fav_user.all().count() | 398 | } |
| 398 | } | 399 | |
| 399 | 400 | user = request.user | |
| 400 | user = request.user | 401 | if user.is_authenticated(): |
| 401 | if user.is_authenticated(): | 402 | notifications_count = user.notify_user.filter(status=0).count() |
| 402 | notifications_count = user.notify_user.filter(status=0).count() | 403 | |
| 403 | 404 | favorites, favorite_page = Favorite.objects.get_user_all_favorites(user_info.id, current_page=current_page) | |
| 404 | favorites, favorite_page = Favorite.objects.get_user_all_favorites(user_info.id, current_page=current_page) | 405 | active_page = 'topic' |
| 405 | active_page = 'topic' | 406 | return render_to_response('topic/user_favorites.html', locals(), |
| 406 | return render_to_response('topic/user_favorites.html', locals(), | 407 | context_instance=RequestContext(request)) |
| 407 | context_instance=RequestContext(request)) | 408 | |
| 408 | 409 | ||
| 409 | 410 | def get_profile(request, uid): | |
| 410 | def get_profile(request, uid): | 411 | try: |
| 411 | try: | 412 | if uid.isdigit(): |
| 412 | if uid.isdigit(): | 413 | user_info = ForumUser.objects.get(pk=uid) |
| 413 | user_info = ForumUser.objects.get(pk=uid) | 414 | else: |
| 414 | else: | 415 | user_info = ForumUser.objects.get(username=uid) |
| 415 | user_info = ForumUser.objects.get(username=uid) | 416 | except ForumUser.DoesNotExist: |
| 416 | except ForumUser.DoesNotExist: | 417 | raise Http404 |
| 417 | raise Http404 | 418 | |
| 418 | 419 | try: | |
| 419 | try: | 420 | current_page = int(request.GET.get('p', '1')) |
| 420 | current_page = int(request.GET.get('p', '1')) | 421 | except ValueError: |
| 421 | except ValueError: | 422 | current_page = 1 |
| 422 | current_page = 1 | 423 | |
| 423 | 424 | counter = { | |
| 424 | counter = { | 425 | 'topics': user_info.topic_author.all().count(), |
| 425 | 'topics': user_info.topic_author.all().count(), | 426 | 'replies': user_info.reply_author.all().count(), |
| 426 | 'replies': user_info.reply_author.all().count(), | 427 | 'favorites': user_info.fav_user.all().count() |
| 427 | 'favorites': user_info.fav_user.all().count() | 428 | } |
| 428 | } | 429 | |
| 429 | 430 | user = request.user | |
| 430 | user = request.user | 431 | if user.is_authenticated(): |
| 431 | if user.is_authenticated(): | 432 | notifications_count = user.notify_user.filter(status=0).count() |
| 432 | notifications_count = user.notify_user.filter(status=0).count() | 433 | |
| 433 | 434 | topics, topic_page = Topic.objects.get_user_all_topics(user_info.id, current_page=current_page) | |
| 434 | topics, topic_page = Topic.objects.get_user_all_topics(user_info.id, current_page=current_page) | 435 | replies, reply_page = Reply.objects.get_user_all_replies(user_info.id, current_page=current_page) |
| 435 | replies, reply_page = Reply.objects.get_user_all_replies(user_info.id, current_page=current_page) | 436 | active_page = '_blank' |
| 436 | active_page = '_blank' | 437 | return render_to_response('topic/profile.html', locals(), |
| 437 | return render_to_response('topic/profile.html', locals(), | 438 | context_instance=RequestContext(request)) |
| 438 | context_instance=RequestContext(request)) | 439 | |
| 439 | 440 | ||
| 440 | 441 | def get_vote(request): | |
| 441 | def get_vote(request): | 442 | user = request.user |
| 442 | user = request.user | 443 | if not user.is_authenticated(): |
| 443 | if not user.is_authenticated(): | 444 | return HttpResponse(json.dumps({ |
| 444 | return HttpResponse(json.dumps({ | 445 | 'success': 0, |
| 445 | 'success': 0, | 446 | 'message': 'user_not_login' |
| 446 | 'message': 'user_not_login' | 447 | }), content_type='application/json') |
| 447 | }), content_type='application/json') | 448 | |
| 448 | 449 | try: | |
| 449 | try: | 450 | topic_id = int(request.GET.get('topic_id')) |
| 450 | topic_id = int(request.GET.get('topic_id')) | 451 | except (TypeError, ValueError): |
| 451 | except (TypeError, ValueError): | 452 | topic_id = None |
| 452 | topic_id = None | 453 | topic = None |
| 453 | topic = None | 454 | if topic_id: |
| 454 | if topic_id: | 455 | try: |
| 455 | try: | 456 | topic = Topic.objects.select_related('author').get(pk=topic_id) |
| 456 | topic = Topic.objects.select_related('author').get(pk=topic_id) | 457 | except Topic.DoesNotExist: |
| 457 | except Topic.DoesNotExist: | 458 | pass |
| 458 | pass | 459 | |
| 459 | 460 | if not (topic_id and topic): | |
| 460 | if not (topic_id and topic): | 461 | return HttpResponse(json.dumps({ |
| 461 | return HttpResponse(json.dumps({ | 462 | 'success': 0, |
| 462 | 'success': 0, | 463 | 'message': 'topic_not_exist' |
| 463 | 'message': 'topic_not_exist' | 464 | }), content_type='application/json') |
| 464 | }), content_type='application/json') | 465 | |
| 465 | 466 | if user.id == topic.author.id: | |
| 466 | if user.id == topic.author.id: | 467 | return HttpResponse(json.dumps({ |
| 467 | return HttpResponse(json.dumps({ | 468 | 'success': 0, |
| 468 | 'success': 0, | 469 | 'message': 'can_not_vote_your_topic' |
| 469 | 'message': 'can_not_vote_your_topic' | 470 | }), content_type='application/json') |
| 470 | }), content_type='application/json') | 471 | |
| 471 | 472 | if Vote.objects.filter(trigger_user=user, involved_topic=topic).exists(): | |
| 472 | if Vote.objects.filter(trigger_user=user, involved_topic=topic).exists(): | 473 | return HttpResponse(json.dumps({ |
| 473 | return HttpResponse(json.dumps({ | 474 | 'success': 0, |
| 474 | 'success': 0, | 475 | 'message': 'already_voted' |
| 475 | 'message': 'already_voted' | 476 | }), content_type='application/json') |
| 476 | }), content_type='application/json') | 477 | |
| 477 | 478 | vote = Vote(trigger_user=user, involved_type=0, involved_topic=topic, \ | |
| 478 | vote = Vote(trigger_user=user, involved_type=0, involved_topic=topic, \ | 479 | involved_user=topic.author, status=0, occurrence_time=timezone.now()) |
| 479 | involved_user=topic.author, status=0, occurrence_time=timezone.now()) | 480 | vote.save() |
| 480 | vote.save() | 481 | |
| 481 | 482 | # 更新话题作者声誉 | |
| 482 | # 更新话题作者声誉 | 483 | topic_time_diff = timezone.now() - topic.created |
| 483 | topic_time_diff = timezone.now() - topic.created | 484 | reputation = topic.author.reputation or 0 |
| 484 | reputation = topic.author.reputation or 0 | 485 | reputation = reputation + 2 * math.log((user.reputation or 0) + topic_time_diff.days + 10, 10) |
| 485 | reputation = reputation + 2 * math.log((user.reputation or 0) + topic_time_diff.days + 10, 10) | 486 | ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) |
| 486 | ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) | 487 | |
| 487 | 488 | return HttpResponse(json.dumps({ | |
| 488 | return HttpResponse(json.dumps({ | 489 | 'success': 1, |
| 489 | 'success': 1, | 490 | 'message': 'thanks_for_your_vote' |
| 490 | 'message': 'thanks_for_your_vote' | 491 | }), content_type='application/json') |
| 491 | }), content_type='application/json') | 492 | |
| 492 | 493 | ||
| 493 | 494 | def get_favorite(request): | |
| 494 | def get_favorite(request): | 495 | user = request.user |
| 495 | user = request.user | 496 | if not user.is_authenticated(): |
| 496 | if not user.is_authenticated(): | 497 | return HttpResponse(json.dumps({ |
| 497 | return HttpResponse(json.dumps({ | 498 | 'success': 0, |
| 498 | 'success': 0, | 499 | 'message': 'user_not_login' |
| 499 | 'message': 'user_not_login' | 500 | }), content_type='application/json') |
| 500 | }), content_type='application/json') | 501 | |
| 501 | 502 | try: | |
| 502 | try: | 503 | topic_id = int(request.GET.get('topic_id')) |
| 503 | topic_id = int(request.GET.get('topic_id')) | 504 | except (TypeError, ValueError): |
| 504 | except (TypeError, ValueError): | 505 | topic_id = None |
| 505 | topic_id = None | 506 | topic = None |
| 506 | topic = None | 507 | if topic_id: |
| 507 | if topic_id: | 508 | try: |
| 508 | try: | 509 | topic = Topic.objects.select_related('author').get(pk=topic_id) |
| 509 | topic = Topic.objects.select_related('author').get(pk=topic_id) | 510 | except Topic.DoesNotExist: |
| 510 | except Topic.DoesNotExist: | 511 | pass |
| 511 | pass | 512 | |
| 512 | 513 | if not (topic_id and topic): | |
| 513 | if not (topic_id and topic): | 514 | return HttpResponse(json.dumps({ |
| 514 | return HttpResponse(json.dumps({ | 515 | 'success': 0, |
| 515 | 'success': 0, | 516 | 'message': 'topic_not_exist' |
| 516 | 'message': 'topic_not_exist' | 517 | }), content_type='application/json') |
| 517 | }), content_type='application/json') | 518 | |
| 518 | 519 | if user.id == topic.author.id: | |
| 519 | if user.id == topic.author.id: | 520 | return HttpResponse(json.dumps({ |
| 520 | return HttpResponse(json.dumps({ | 521 | 'success': 0, |
| 521 | 'success': 0, | 522 | 'message': 'can_not_favorite_your_topic' |
| 522 | 'message': 'can_not_favorite_your_topic' | 523 | }), content_type='application/json') |
| 523 | }), content_type='application/json') | 524 | |
| 524 | 525 | if Favorite.objects.filter(owner_user=user, involved_topic=topic).exists(): | |
| 525 | if Favorite.objects.filter(owner_user=user, involved_topic=topic).exists(): | 526 | return HttpResponse(json.dumps({ |
| 526 | return HttpResponse(json.dumps({ | 527 | 'success': 0, |
| 527 | 'success': 0, | 528 | 'message': 'already_favorited' |
| 528 | 'message': 'already_favorited' | 529 | }), content_type='application/json') |
| 529 | }), content_type='application/json') | 530 | |
| 530 | 531 | favorite = Favorite(owner_user=user, involved_type=0, involved_topic=topic, created=timezone.now()) | |
| 531 | favorite = Favorite(owner_user=user, involved_type=0, involved_topic=topic, created=timezone.now()) | 532 | favorite.save() |
| 532 | favorite.save() | 533 | |
| 533 | 534 | # 更新话题作者声誉 | |
| 534 | # 更新话题作者声誉 | 535 | topic_time_diff = timezone.now() - topic.created |
| 535 | topic_time_diff = timezone.now() - topic.created | 536 | reputation = topic.author.reputation or 0 |
| 536 | reputation = topic.author.reputation or 0 | 537 | reputation = reputation + 2 * math.log((user.reputation or 0) + topic_time_diff.days + 10, 10) |
| 537 | reputation = reputation + 2 * math.log((user.reputation or 0) + topic_time_diff.days + 10, 10) | 538 | ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) |
| 538 | ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) | 539 | |
| 539 | 540 | return HttpResponse(json.dumps({ | |
| 540 | return HttpResponse(json.dumps({ | 541 | 'success': 1, |
| 541 | 'success': 1, | 542 | 'message': 'cancel_favorite_success' |
| 542 | 'message': 'cancel_favorite_success' | 543 | }), content_type='application/json') |
| 543 | }), content_type='application/json') | 544 | |
| 544 | 545 | ||
| 545 | 546 | def get_cancel_favorite(request): | |
| 546 | def get_cancel_favorite(request): | 547 | user = request.user |
| 547 | user = request.user | 548 | if not user.is_authenticated(): |
| 548 | if not user.is_authenticated(): | 549 | return HttpResponse(json.dumps({ |
| 549 | return HttpResponse(json.dumps({ | 550 | 'success': 0, |
| 550 | 'success': 0, | 551 | 'message': 'user_not_login' |
| 551 | 'message': 'user_not_login' | 552 | }), content_type='application/json') |
| 552 | }), content_type='application/json') | 553 | |
| 553 | 554 | try: | |
| 554 | try: | 555 | topic_id = int(request.GET.get('topic_id')) |
| 555 | topic_id = int(request.GET.get('topic_id')) | 556 | except (TypeError, ValueError): |
| 556 | except (TypeError, ValueError): | 557 | topic_id = None |
| 557 | topic_id = None | 558 | topic = None |
| 558 | topic = None | 559 | if topic_id: |
| 559 | if topic_id: | 560 | try: |
| 560 | try: | 561 | topic = Topic.objects.select_related('author').get(pk=topic_id) |
| 561 | topic = Topic.objects.select_related('author').get(pk=topic_id) | 562 | except Topic.DoesNotExist: |
| 562 | except Topic.DoesNotExist: | 563 | pass |
| 563 | pass | 564 | |
| 564 | 565 | if not (topic_id and topic): | |
| 565 | if not (topic_id and topic): | 566 | return HttpResponse(json.dumps({ |
| 566 | return HttpResponse(json.dumps({ | 567 | 'success': 0, |
| 567 | 'success': 0, | 568 | 'message': 'topic_not_exist' |
| 568 | 'message': 'topic_not_exist' | 569 | }), content_type='application/json') |
| 569 | }), content_type='application/json') | 570 | |
| 570 | 571 | try: | |
| 571 | try: | 572 | favorite = Favorite.objects.get(owner_user=user, involved_topic=topic) |
| 572 | favorite = Favorite.objects.get(owner_user=user, involved_topic=topic) | 573 | except Favorite.DoesNotExist: |
| 573 | except Favorite.DoesNotExist: | 574 | favorite = None |
| 574 | favorite = None | 575 | |
| 575 | 576 | if not favorite: | |
| 576 | if not favorite: | 577 | return HttpResponse(json.dumps({ |
| 577 | return HttpResponse(json.dumps({ | 578 | 'success': 0, |
| 578 | 'success': 0, | 579 | 'message': 'not_been_favorited' |
| 579 | 'message': 'not_been_favorited' | 580 | }), content_type='application/json') |
| 580 | }), content_type='application/json') | 581 | |
| 581 | 582 | favorite.delete() | |
| 582 | favorite.delete() | 583 | |
| 583 | 584 | # 更新话题作者声誉 | |
| 584 | # 更新话题作者声誉 | 585 | topic_time_diff = timezone.now() - topic.created |
| 585 | topic_time_diff = timezone.now() - topic.created | 586 | reputation = topic.author.reputation or 0 |
| 586 | reputation = topic.author.reputation or 0 | 587 | reputation = reputation - math.log(user.reputation or 0 + topic_time_diff.days + 10, 15) |
| 587 | reputation = reputation - math.log(user.reputation or 0 + topic_time_diff.days + 10, 15) | 588 | ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) |
| 588 | ForumUser.objects.filter(pk=topic.author.id).update(reputation=reputation) | 589 | |
| 589 | 590 | return HttpResponse(json.dumps({ | |
| 590 | return HttpResponse(json.dumps({ | 591 | 'success': 1, |
| 591 | 'success': 1, | 592 | 'message': 'cancel_favorite_success' |
| 592 | 'message': 'cancel_favorite_success' | 593 | }), content_type='application/json') |
| 593 | }), content_type='application/json') | 594 | |
| 594 | 595 | ||
| 595 | 596 | def get_members(request): | |
| 596 | def get_members(request): | 597 | user = request.user |
| 597 | user = request.user | 598 | if user.is_authenticated(): |
| 598 | if user.is_authenticated(): | 599 | counter = { |
| 599 | counter = { | 600 | 'topics': user.topic_author.all().count(), |
| 600 | 'topics': user.topic_author.all().count(), | 601 | 'replies': user.reply_author.all().count(), |
| 601 | 'replies': user.reply_author.all().count(), | 602 | 'favorites': user.fav_user.all().count() |
| 602 | 'favorites': user.fav_user.all().count() | 603 | } |
| 603 | } | 604 | notifications_count = user.notify_user.filter(status=0).count() |
| 604 | notifications_count = user.notify_user.filter(status=0).count() | 605 | |
| 605 | 606 | members = ForumUser.objects.all().order_by('-id')[:49] | |
| 606 | members = ForumUser.objects.all().order_by('-id')[:49] | 607 | active_members = ForumUser.objects.all().order_by('-last_login')[:49] |
| 607 | active_members = ForumUser.objects.all().order_by('-last_login')[:49] | 608 | active_page = 'members' |
| 608 | active_page = 'members' | 609 | return render_to_response('topic/members.html', locals(), |
| 609 | return render_to_response('topic/members.html', locals(), | 610 | context_instance=RequestContext(request)) |
| 610 | context_instance=RequestContext(request)) | 611 |
xp/settings.py
| 1 | # coding: utf-8 | 1 | # coding: utf-8 |
| 2 | # Django settings for xp project. | 2 | # Django settings for xp project. |
| 3 | 3 | ||
| 4 | DEBUG = True | 4 | DEBUG = True |
| 5 | TEMPLATE_DEBUG = DEBUG | 5 | TEMPLATE_DEBUG = DEBUG |
| 6 | 6 | ||
| 7 | ADMINS = ( | 7 | ADMINS = ( |
| 8 | # ('Your Name', 'your_email@example.com'), | 8 | # ('Your Name', 'your_email@example.com'), |
| 9 | ) | 9 | ) |
| 10 | 10 | ||
| 11 | MANAGERS = ADMINS | 11 | MANAGERS = ADMINS |
| 12 | 12 | ||
| 13 | DATABASES = { | 13 | DATABASES = { |
| 14 | 'default': { | 14 | 'default': { |
| 15 | 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. | 15 | 'ENGINE': 'django.db.backends.mysql', # Add 'postgresql_psycopg2', 'mysql', 'sqlite3' or 'oracle'. |
| 16 | 'NAME': 'forum', # Or path to database file if using sqlite3. | 16 | 'NAME': 'forum', # Or path to database file if using sqlite3. |
| 17 | # The following settings are not used with sqlite3: | 17 | # The following settings are not used with sqlite3: |
| 18 | 'USER': 'root', | 18 | 'USER': 'root', |
| 19 | 'PASSWORD': 'nineteen', | 19 | 'PASSWORD': 'nineteen', |
| 20 | 'HOST': '127.0.0.1', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP. | 20 | 'HOST': '127.0.0.1', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP. |
| 21 | 'PORT': '3306', # Set to empty string for default. | 21 | 'PORT': '3306', # Set to empty string for default. |
| 22 | } | 22 | } |
| 23 | } | 23 | } |
| 24 | 24 | ||
| 25 | # Hosts/domain names that are valid for this site; required if DEBUG is False | 25 | # Hosts/domain names that are valid for this site; required if DEBUG is False |
| 26 | # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts | 26 | # See https://docs.djangoproject.com/en/1.5/ref/settings/#allowed-hosts |
| 27 | ALLOWED_HOSTS = ['*'] | 27 | ALLOWED_HOSTS = ['*'] |
| 28 | 28 | ||
| 29 | # Local time zone for this installation. Choices can be found here: | 29 | # Local time zone for this installation. Choices can be found here: |
| 30 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name | 30 | # http://en.wikipedia.org/wiki/List_of_tz_zones_by_name |
| 31 | # although not all choices may be available on all operating systems. | 31 | # although not all choices may be available on all operating systems. |
| 32 | # In a Windows environment this must be set to your system time zone. | 32 | # In a Windows environment this must be set to your system time zone. |
| 33 | TIME_ZONE = 'Asia/Shanghai' | 33 | TIME_ZONE = 'Asia/Shanghai' |
| 34 | 34 | ||
| 35 | # Language code for this installation. All choices can be found here: | 35 | # Language code for this installation. All choices can be found here: |
| 36 | # http://www.i18nguy.com/unicode/language-identifiers.html | 36 | # http://www.i18nguy.com/unicode/language-identifiers.html |
| 37 | LANGUAGE_CODE = 'zh-CN' | 37 | LANGUAGE_CODE = 'zh-CN' |
| 38 | 38 | ||
| 39 | SITE_ID = 1 | 39 | SITE_ID = 1 |
| 40 | 40 | ||
| 41 | # If you set this to False, Django will make some optimizations so as not | 41 | # If you set this to False, Django will make some optimizations so as not |
| 42 | # to load the internationalization machinery. | 42 | # to load the internationalization machinery. |
| 43 | USE_I18N = True # 只有用admin的时候需要开启 | 43 | USE_I18N = True # 只有用admin的时候需要开启 |
| 44 | 44 | ||
| 45 | # If you set this to False, Django will not format dates, numbers and | 45 | # If you set this to False, Django will not format dates, numbers and |
| 46 | # calendars according to the current locale. | 46 | # calendars according to the current locale. |
| 47 | USE_L10N = False | 47 | USE_L10N = False |
| 48 | 48 | ||
| 49 | # If you set this to False, Django will not use timezone-aware datetimes. | 49 | # If you set this to False, Django will not use timezone-aware datetimes. |
| 50 | USE_TZ = False | 50 | USE_TZ = False |
| 51 | 51 | ||
| 52 | # Absolute filesystem path to the directory that will hold user-uploaded files. | 52 | # Absolute filesystem path to the directory that will hold user-uploaded files. |
| 53 | # Example: "/var/www/example.com/media/" | 53 | # Example: "/var/www/example.com/media/" |
| 54 | MEDIA_ROOT = '' | 54 | MEDIA_ROOT = '' |
| 55 | 55 | ||
| 56 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a | 56 | # URL that handles the media served from MEDIA_ROOT. Make sure to use a |
| 57 | # trailing slash. | 57 | # trailing slash. |
| 58 | # Examples: "http://example.com/media/", "http://media.example.com/" | 58 | # Examples: "http://example.com/media/", "http://media.example.com/" |
| 59 | MEDIA_URL = '' | 59 | MEDIA_URL = '' |
| 60 | 60 | ||
| 61 | # Absolute path to the directory static files should be collected to. | 61 | # Absolute path to the directory static files should be collected to. |
| 62 | # Don't put anything in this directory yourself; store your static files | 62 | # Don't put anything in this directory yourself; store your static files |
| 63 | # in apps' "static/" subdirectories and in STATICFILES_DIRS. | 63 | # in apps' "static/" subdirectories and in STATICFILES_DIRS. |
| 64 | # Example: "/var/www/example.com/static/" | 64 | # Example: "/var/www/example.com/static/" |
| 65 | STATIC_ROOT = '' | 65 | STATIC_ROOT = '' |
| 66 | 66 | ||
| 67 | # URL prefix for static files. | 67 | # URL prefix for static files. |
| 68 | # Example: "http://example.com/static/", "http://static.example.com/" | 68 | # Example: "http://example.com/static/", "http://static.example.com/" |
| 69 | STATIC_URL = '/static/' | 69 | STATIC_URL = '/static/' |
| 70 | 70 | ||
| 71 | # Additional locations of static files | 71 | # Additional locations of static files |
| 72 | STATICFILES_DIRS = ( | 72 | STATICFILES_DIRS = ( |
| 73 | # Put strings here, like "/home/html/static" or "C:/www/django/static". | 73 | # Put strings here, like "/home/html/static" or "C:/www/django/static". |
| 74 | # Always use forward slashes, even on Windows. | 74 | # Always use forward slashes, even on Windows. |
| 75 | # Don't forget to use absolute paths, not relative paths. | 75 | # Don't forget to use absolute paths, not relative paths. |
| 76 | ) | 76 | ) |
| 77 | 77 | ||
| 78 | # List of finder classes that know how to find static files in | 78 | # List of finder classes that know how to find static files in |
| 79 | # various locations. | 79 | # various locations. |
| 80 | STATICFILES_FINDERS = ( | 80 | STATICFILES_FINDERS = ( |
| 81 | 'django.contrib.staticfiles.finders.FileSystemFinder', | 81 | 'django.contrib.staticfiles.finders.FileSystemFinder', |
| 82 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', | 82 | 'django.contrib.staticfiles.finders.AppDirectoriesFinder', |
| 83 | # 'django.contrib.staticfiles.finders.DefaultStorageFinder', | 83 | # 'django.contrib.staticfiles.finders.DefaultStorageFinder', |
| 84 | ) | 84 | ) |
| 85 | 85 | ||
| 86 | # Make this unique, and don't share it with anybody. | 86 | # Make this unique, and don't share it with anybody. |
| 87 | SECRET_KEY = 'h6=yzee&jze#4p1@twhksg1wg6hv%pzwomw(!o($qsly%lzlhe' | 87 | SECRET_KEY = 'h6=yzee&jze#4p1@twhksg1wg6hv%pzwomw(!o($qsly%lzlhe' |
| 88 | 88 | ||
| 89 | # List of callables that know how to import templates from various sources. | 89 | # List of callables that know how to import templates from various sources. |
| 90 | TEMPLATE_LOADERS = ( | 90 | TEMPLATE_LOADERS = ( |
| 91 | 'django.template.loaders.filesystem.Loader', | 91 | 'django.template.loaders.filesystem.Loader', |
| 92 | 'django.template.loaders.app_directories.Loader', | 92 | 'django.template.loaders.app_directories.Loader', |
| 93 | # 'django.template.loaders.eggs.Loader', | 93 | # 'django.template.loaders.eggs.Loader', |
| 94 | ) | 94 | ) |
| 95 | 95 | ||
| 96 | MIDDLEWARE_CLASSES = ( | 96 | MIDDLEWARE_CLASSES = ( |
| 97 | 'django.middleware.cache.UpdateCacheMiddleware', # 缓存中间件,必须放在开头 | ||
| 98 | 'django.middleware.common.CommonMiddleware', | 97 | 'django.middleware.common.CommonMiddleware', |
| 99 | 'django.contrib.sessions.middleware.SessionMiddleware', | 98 | 'django.contrib.sessions.middleware.SessionMiddleware', |
| 100 | 'django.middleware.csrf.CsrfViewMiddleware', # 开启了CSRF,记得在POST表单中加{% csrf_token %},使用RequestContext | 99 | 'django.middleware.csrf.CsrfViewMiddleware', # 开启了CSRF,记得在POST表单中加{% csrf_token %},使用RequestContext |
| 101 | 'django.contrib.auth.middleware.AuthenticationMiddleware', | 100 | 'django.contrib.auth.middleware.AuthenticationMiddleware', |
| 102 | 'django.contrib.messages.middleware.MessageMiddleware', | 101 | 'django.contrib.messages.middleware.MessageMiddleware', |
| 103 | # Uncomment the next line for simple clickjacking protection: | 102 | # Uncomment the next line for simple clickjacking protection: |
| 104 | # 'django.middleware.clickjacking.XFrameOptionsMiddleware', | 103 | # 'django.middleware.clickjacking.XFrameOptionsMiddleware', |
| 105 | 'django.middleware.cache.FetchFromCacheMiddleware', # 缓存中间件,必须放在最后 | 104 | 'django.middleware.cache.FetchFromCacheMiddleware', # 缓存中间件,必须放在最后 |
| 106 | ) | 105 | ) |
| 107 | 106 | ||
| 108 | ROOT_URLCONF = 'xp.urls' | 107 | ROOT_URLCONF = 'xp.urls' |
| 109 | 108 | ||
| 110 | # Python dotted path to the WSGI application used by Django's runserver. | 109 | # Python dotted path to the WSGI application used by Django's runserver. |
| 111 | WSGI_APPLICATION = 'xp.wsgi.application' | 110 | WSGI_APPLICATION = 'xp.wsgi.application' |
| 112 | 111 | ||
| 113 | TEMPLATE_DIRS = ( | 112 | TEMPLATE_DIRS = ( |
| 114 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". | 113 | # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates". |
| 115 | # Always use forward slashes, even on Windows. | 114 | # Always use forward slashes, even on Windows. |
| 116 | # Don't forget to use absolute paths, not relative paths. | 115 | # Don't forget to use absolute paths, not relative paths. |
| 117 | ) | 116 | ) |
| 118 | 117 | ||
| 119 | TEMPLATE_CONTEXT_PROCESSORS = ( # F2E中有current_user对象和request对象,这里设置可在模板中使用RquestContext | 118 | TEMPLATE_CONTEXT_PROCESSORS = ( # F2E中有current_user对象和request对象,这里设置可在模板中使用RquestContext |
| 120 | 'django.contrib.auth.context_processors.auth', # user对象等等 | 119 | 'django.contrib.auth.context_processors.auth', # user对象等等 |
| 121 | 'django.core.context_processors.request', # request对象等等 | 120 | 'django.core.context_processors.request', # request对象等等 |
| 122 | 'django.core.context_processors.static', # 在模板中使用{{ STATIC_URL }}获取静态文件路径 | 121 | 'django.core.context_processors.static', # 在模板中使用{{ STATIC_URL }}获取静态文件路径 |
| 123 | 'forum.context_processors.custom_proc', # 自定义模板上下文处理器 | 122 | 'forum.context_processors.custom_proc', # 自定义模板上下文处理器 |
| 124 | ) | 123 | ) |
| 125 | 124 | ||
| 126 | INSTALLED_APPS = ( | 125 | INSTALLED_APPS = ( |
| 127 | 'django.contrib.auth', | 126 | 'django.contrib.auth', |
| 128 | 'django.contrib.contenttypes', | 127 | 'django.contrib.contenttypes', |
| 129 | 'django.contrib.sessions', | 128 | 'django.contrib.sessions', |
| 130 | 'django.contrib.sites', | 129 | 'django.contrib.sites', |
| 131 | 'django.contrib.messages', | 130 | 'django.contrib.messages', |
| 132 | 'django.contrib.staticfiles', | 131 | 'django.contrib.staticfiles', |
| 133 | # Uncomment the next line to enable the admin: | 132 | # Uncomment the next line to enable the admin: |
| 134 | 'django.contrib.admin', | 133 | 'django.contrib.admin', |
| 135 | # Uncomment the next line to enable admin documentation: | 134 | # Uncomment the next line to enable admin documentation: |
| 136 | # 'django.contrib.admindocs', | 135 | # 'django.contrib.admindocs', |
| 137 | 'django.contrib.sitemaps', # Django sitemap framework | 136 | 'django.contrib.sitemaps', # Django sitemap framework |
| 138 | 'forum', | 137 | 'forum', |
| 139 | ) | 138 | ) |
| 140 | 139 | ||
| 141 | # A sample logging configuration. The only tangible logging | 140 | # A sample logging configuration. The only tangible logging |
| 142 | # performed by this configuration is to send an email to | 141 | # performed by this configuration is to send an email to |
| 143 | # the site admins on every HTTP 500 error when DEBUG=False. | 142 | # the site admins on every HTTP 500 error when DEBUG=False. |
| 144 | # See http://docs.djangoproject.com/en/dev/topics/logging for | 143 | # See http://docs.djangoproject.com/en/dev/topics/logging for |
| 145 | # more details on how to customize your logging configuration. | 144 | # more details on how to customize your logging configuration. |
| 146 | LOGGING = { | 145 | LOGGING = { |
| 147 | 'version': 1, | 146 | 'version': 1, |
| 148 | 'disable_existing_loggers': False, | 147 | 'disable_existing_loggers': False, |
| 149 | 'filters': { | 148 | 'filters': { |
| 150 | 'require_debug_false': { | 149 | 'require_debug_false': { |
| 151 | '()': 'django.utils.log.RequireDebugFalse' | 150 | '()': 'django.utils.log.RequireDebugFalse' |
| 152 | } | 151 | } |
| 153 | }, | 152 | }, |
| 154 | 'handlers': { | 153 | 'handlers': { |
| 155 | 'mail_admins': { | 154 | 'mail_admins': { |
| 156 | 'level': 'ERROR', | 155 | 'level': 'ERROR', |
| 157 | 'filters': ['require_debug_false'], | 156 | 'filters': ['require_debug_false'], |
| 158 | 'class': 'django.utils.log.AdminEmailHandler' | 157 | 'class': 'django.utils.log.AdminEmailHandler' |
| 159 | }, | 158 | }, |
| 160 | 'console': { | 159 | 'console': { |
| 161 | 'level': 'DEBUG', | 160 | 'level': 'DEBUG', |
| 162 | 'class': 'logging.StreamHandler', | 161 | 'class': 'logging.StreamHandler', |
| 163 | }, | 162 | }, |
| 164 | }, | 163 | }, |
| 165 | 'loggers': { | 164 | 'loggers': { |
| 166 | 'django.request': { | 165 | 'django.request': { |
| 167 | 'handlers': ['mail_admins'], | 166 | 'handlers': ['mail_admins'], |
| 168 | 'level': 'ERROR', | 167 | 'level': 'ERROR', |
| 169 | 'propagate': True, | 168 | 'propagate': True, |
| 170 | }, | 169 | }, |
| 171 | 'django.db.backends': { | 170 | 'django.db.backends': { |
| 172 | 'level': 'DEBUG', | 171 | 'level': 'DEBUG', |
| 173 | 'handlers': ['console'], | 172 | 'handlers': ['console'], |
| 174 | }, | 173 | }, |
| 175 | } | 174 | } |
| 176 | } | 175 | } |
| 177 | # | 176 | # |
| 178 | # CACHES = { # memcached缓存设置 | 177 | # CACHES = { # memcached缓存设置 |
| 179 | # 'default': { | 178 | # 'default': { |
| 180 | # 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', | 179 | # 'BACKEND': 'django.core.cache.backends.memcached.MemcachedCache', |
| 181 | # 'LOCATION': '127.0.0.1:11211', | 180 | # 'LOCATION': '127.0.0.1:11211', |
| 182 | # } | 181 | # } |
| 183 | # } | 182 | # } |
| 184 | 183 | ||
| 185 | # SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 使用memcached存储session | 184 | # SESSION_ENGINE = 'django.contrib.sessions.backends.cache' # 使用memcached存储session |
| 186 | 185 | ||
| 187 | # 自定义User类 | 186 | # 自定义User类 |
| 188 | AUTH_USER_MODEL = 'forum.ForumUser' | 187 | AUTH_USER_MODEL = 'forum.ForumUser' |
| 189 | 188 | ||
| 190 | # 用户认证BackEnds | 189 | # 用户认证BackEnds |
| 191 | # AUTHENTICATION_BACKENDS = ('forum.backends.EmailAuthBackend',) | 190 | # AUTHENTICATION_BACKENDS = ('forum.backends.EmailAuthBackend',) |
| 192 | 191 | ||
| 193 | # 默认登陆uri | 192 | # 默认登陆uri |
| 194 | LOGIN_URL = '/login/' | 193 | LOGIN_URL = '/login/' |
| 195 | 194 | ||
| 196 | # 发送邮件设置 | 195 | # 发送邮件设置 |
| 197 | EMAIL_HOST = 'smtp.qq.com' | 196 | EMAIL_HOST = 'smtp.qq.com' |
| 198 | EMAIL_PORT = 25 | 197 | EMAIL_PORT = 25 |
| 199 | EMAIL_HOST_USER= '*********' | 198 | EMAIL_HOST_USER= '*********' |
| 200 | EMAIL_HOST_PASSWORD= '******' | 199 | EMAIL_HOST_PASSWORD= '******' |
| 201 | DEFAULT_FROM_EMAIL = '*********@qq.com' | 200 | DEFAULT_FROM_EMAIL = '*********@qq.com' |
| 202 | 201 | ||
| 203 | # 注册用户保留关键字,非Django设置 | 202 | # 注册用户保留关键字,非Django设置 |
| 204 | RESERVED = ["user", "topic", "home", "setting", "forgot", "login", "logout", "register", "admin"] | 203 | RESERVED = ["user", "topic", "home", "setting", "forgot", "login", "logout", "register", "admin"] |
| 205 | 204 |