def post_action_merge(self, ids): users = [] posts = [] for post in self.posts: if post.pk in ids: posts.append(post) if not post.user_id in users: users.append(post.user_id) if len(users) > 1: raise forms.ValidationError( _("You cannot merge replies made by different members!" )) if len(posts) < 2: raise forms.ValidationError( _("You have to select two or more posts you want to merge.")) new_post = posts[0] for post in posts[1:]: post.merge_with(new_post) post.delete() md, new_post.post_preparsed = post_markdown(new_post.post) new_post.sync_attachments() new_post.save(force_update=True) self.thread.sync() self.thread.save(force_update=True) self.forum.sync() self.forum.save(force_update=True) messages.success( self.request, _('Selected posts have been merged into one message.'), 'threads')
def dispatch(self, request, **kwargs): if ((not self.change.thread_name_old or self.thread.name == self.change.thread_name_old) and (self.change.post_content == self.post.post)): request.messages.set_flash(Message(_("No changes to revert.")), 'error', 'changelog') return redirect(reverse('changelog_diff', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug, 'post': self.post.pk, 'change': self.change.pk})) if self.change.thread_name_old and self.change.thread_name_old != self.thread.name: self.thread.name = self.change.thread_name_old self.thread.slug = slugify(self.change.thread_name_old) self.thread.save(force_update=True) if self.forum.last_thread_id == self.thread.pk: self.forum.last_thread_name = self.change.thread_name_old self.forum.last_thread_slug = slugify(self.change.thread_name_old) self.forum.save(force_update=True) if self.change.post_content != self.post.post: self.post.post = self.change.post_content md, self.post.post_preparsed = post_markdown(request, self.change.post_content) self.post.save(force_update=True) from misago.template.templatetags.django2jinja import reldate request.messages.set_flash(Message(_("Post has been reverted to state from %(date)s.") % {'date': reldate(self.change.date).lower()}), 'success', 'threads_%s' % self.post.pk) pagination = make_pagination(0, request.acl.threads.filter_posts(self.request, self.thread, self.thread.post_set).filter(id__lte=self.post.pk).count(), self.request.settings.posts_per_page) if pagination['total'] > 1: return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug, 'page': pagination['total']}) + ('#post-%s' % self.post.pk)) return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}) + ('#post-%s' % self.post.pk))
def post_form(self, form): old_post = self.post.post changed_thread = False changed_post = old_post != form.cleaned_data['post'] if self.thread.last_post_id == self.post.pk: self.thread.last_post == self.post if 'close_thread' in form.cleaned_data and form.cleaned_data['close_thread']: self.thread.closed = not self.thread.closed changed_thread = True if self.thread.closed: self.thread.set_checkpoint(self.request, 'closed') else: self.thread.set_checkpoint(self.request, 'opened') if ('thread_weight' in form.cleaned_data and form.cleaned_data['thread_weight'] != self.thread.weight): self.thread.weight = form.cleaned_data['thread_weight'] changed_thread = True if changed_thread: self.thread.save(force_update=True) if changed_post: self.post.post = form.cleaned_data['post'] self.md, self.post.post_preparsed = post_markdown(form.cleaned_data['post']) self.post.save(force_update=True) self.record_edit(form, self.thread.name, old_post)
def handle(self, *args, **options): count = 0 total = Post.objects.count() last = 0 self.stdout.write('\nReparsing posts...') for post in Post.objects.iterator(): md, post.post_preparsed = post_markdown(post.post) post.save(force_update=True) count += 1 progress = (count * 100 / total) if not progress % 10 and progress > last and progress < 100: self.stdout.write('Reparsed %s out of %s posts...' % (count, total)) last = progress self.stdout.write('\n%s posts have been reparsed.\n' % count)
def dispatch(self, request, **kwargs): if ((not self.change.thread_name_old or self.thread.name == self.change.thread_name_old) and (self.change.post_content == self.post.post)): messages.error(request, _("No changes to revert."), 'changelog') return redirect(reverse('%s_changelog_diff' % self.type_prefix, kwargs={'thread': self.thread.pk, 'slug': self.thread.slug, 'post': self.post.pk, 'change': self.change.pk})) self.post.edits += 1 self.post.edit_user = self.request.user self.post.edit_user_name = self.request.user.username self.post.edit_user_slug = self.request.user.username_slug self.post.change_set.create( forum=self.forum, thread=self.thread, post=self.post, user=request.user, user_name=request.user.username, user_slug=request.user.username_slug, date=timezone.now(), ip=request.session.get_ip(self.request), agent=request.META.get('HTTP_USER_AGENT'), reason=_("Reverted to the state before %(date)s.") % {'date': reldate(self.change.date).lower()}, size=len(self.change.post_content), change=len(self.change.post_content) - len(self.post.post), thread_name_old=self.thread.name if self.change.thread_name_old != self.thread.name and self.change.thread_name_old != None else None, thread_name_new=self.change.thread_name_old if self.change.thread_name_old != self.thread.name else None, post_content=self.post.post, ) if self.change.thread_name_old and self.change.thread_name_old != self.thread.name: self.thread.name = self.change.thread_name_old self.thread.slug = slugify(self.change.thread_name_old) self.thread.save(force_update=True) if self.forum.last_thread_id == self.thread.pk: self.forum.last_thread_name = self.change.thread_name_old self.forum.last_thread_slug = slugify(self.change.thread_name_old) self.forum.save(force_update=True) if self.change.post_content != self.post.post: self.post.post = self.change.post_content md, self.post.post_preparsed = post_markdown(self.change.post_content) self.post.save(force_update=True) messages.success(request, _("Post has been reverted to the state before %(date)s.") % {'date': reldate(self.change.date).lower()}, 'threads_%s' % self.post.pk) return self.redirect_to_post(self.post)
def post_form(self, form): now = timezone.now() old_name = self.thread.name old_post = self.post.post changed_thread = old_name != form.cleaned_data['thread_name'] changed_post = old_post != form.cleaned_data['post'] if self.thread.last_post_id == self.post.pk: self.thread.last_post == self.post if 'close_thread' in form.cleaned_data and form.cleaned_data['close_thread']: self.thread.closed = not self.thread.closed changed_thread = True if self.thread.closed: self.thread.last_post.set_checkpoint(self.request, 'closed') else: self.thread.last_post.set_checkpoint(self.request, 'opened') if self.thread.last_post_id != self.post.pk or not changed_post: self.thread.last_post.save(force_update=True) if ('thread_weight' in form.cleaned_data and form.cleaned_data['thread_weight'] != self.thread.weight): self.thread.weight = form.cleaned_data['thread_weight'] changed_thread = True if changed_thread: self.thread.name = form.cleaned_data['thread_name'] self.thread.slug = slugify(form.cleaned_data['thread_name']) self.thread.save(force_update=True) if changed_post: self.post.post = form.cleaned_data['post'] self.md, self.post.post_preparsed = post_markdown(self.request, form.cleaned_data['post']) self.post.edits += 1 self.post.edit_date = now self.post.edit_user = self.request.user self.post.edit_user_name = self.request.user.username self.post.edit_user_slug = self.request.user.username_slug self.post.save(force_update=True) if changed_thread or changed_post: self.record_edit(form, old_name, old_post)
def dispatch(self, request, **kwargs): if ((not self.change.thread_name_old or self.thread.name == self.change.thread_name_old) and (self.change.post_content == self.post.post)): request.messages.set_flash(Message(_("No changes to revert.")), 'error', 'changelog') return redirect( reverse('%s_changelog_diff' % self.type_prefix, kwargs={ 'thread': self.thread.pk, 'slug': self.thread.slug, 'post': self.post.pk, 'change': self.change.pk })) if self.change.thread_name_old and self.change.thread_name_old != self.thread.name: self.thread.name = self.change.thread_name_old self.thread.slug = slugify(self.change.thread_name_old) self.thread.save(force_update=True) if self.forum.last_thread_id == self.thread.pk: self.forum.last_thread_name = self.change.thread_name_old self.forum.last_thread_slug = slugify( self.change.thread_name_old) self.forum.save(force_update=True) if self.change.post_content != self.post.post: self.post.post = self.change.post_content md, self.post.post_preparsed = post_markdown( self.change.post_content) self.post.save(force_update=True) request.messages.set_flash( Message( _("Post has been reverted to state from %(date)s.") % {'date': reldate(self.change.date).lower()}), 'success', 'threads_%s' % self.post.pk) return self.redirect_to_post(self.post)
def post_action_merge(self, ids): users = [] posts = [] for post in self.posts: if post.pk in ids: posts.append(post) if not post.user_id in users: users.append(post.user_id) if len(users) > 1: raise forms.ValidationError(_("You cannot merge replies made by different members!")) if len(posts) < 2: raise forms.ValidationError(_("You have to select two or more posts you want to merge.")) new_post = posts[0] for post in posts[1:]: post.merge_with(new_post) post.delete() md, new_post.post_preparsed = post_markdown(new_post.post) new_post.save(force_update=True) self.thread.sync() self.thread.save(force_update=True) self.forum.sync() self.forum.save(force_update=True) self.request.messages.set_flash(Message(_('Selected posts have been merged into one message.')), 'success', 'threads')
def dispatch(self, request, **kwargs): if ((not self.change.thread_name_old or self.thread.name == self.change.thread_name_old) and (self.change.post_content == self.post.post)): request.messages.set_flash(Message(_("No changes to revert.")), 'error', 'changelog') return redirect(reverse('%s_changelog_diff' % self.type_prefix, kwargs={'thread': self.thread.pk, 'slug': self.thread.slug, 'post': self.post.pk, 'change': self.change.pk})) if self.change.thread_name_old and self.change.thread_name_old != self.thread.name: self.thread.name = self.change.thread_name_old self.thread.slug = slugify(self.change.thread_name_old) self.thread.save(force_update=True) if self.forum.last_thread_id == self.thread.pk: self.forum.last_thread_name = self.change.thread_name_old self.forum.last_thread_slug = slugify(self.change.thread_name_old) self.forum.save(force_update=True) if self.change.post_content != self.post.post: self.post.post = self.change.post_content md, self.post.post_preparsed = post_markdown(request, self.change.post_content) self.post.save(force_update=True) request.messages.set_flash(Message(_("Post has been reverted to state from %(date)s.") % {'date': reldate(self.change.date).lower()}), 'success', 'threads_%s' % self.post.pk) return self.redirect_to_post(self.post)
def view(request): report = None made_report = False if self.post.reported: report = self.post.live_report() if report and report.start_poster_id != request.user.pk: # Append our q.q to existing report? try: report.checkpoint_set.get(user=request.user, action="reported") except Checkpoint.DoesNotExist: report.set_checkpoint(self.request, "reported", user) made_report = True if not report: # File up new report now = timezone.now() reason_post = _( """ Member @%(reporter)s has reported following post by @%(reported)s: %(quote)s **Post link:** <%(post)s> """ ) reason_post = reason_post.strip() % { "reporter": request.user.username, "reported": self.post.user_name, "post": settings.BOARD_ADDRESS + self.redirect_to_post(self.post)["Location"], "quote": self.post.quote(), } md, reason_post_preparsed = post_markdown(reason_post) reports = Forum.objects.special_model("reports") report = Thread.objects.create( forum=reports, weight=2, name=self.thread.name, slug=slugify(self.thread.slug), start=now, start_poster=request.user, start_poster_name=request.user.username, start_poster_slug=request.user.username_slug, start_poster_style=request.user.rank.style, last=now, last_poster=request.user, last_poster_name=request.user.username, last_poster_slug=request.user.username_slug, last_poster_style=request.user.rank.style, report_for=self.post, ) reason = Post.objects.create( forum=reports, thread=report, user=request.user, user_name=request.user.username, ip=request.session.get_ip(self.request), agent=request.META.get("HTTP_USER_AGENT"), post=reason_post, post_preparsed=reason_post_preparsed, date=now, ) report.start_post = reason report.last_post = reason report.save(force_update=True) for m in self.post.mentions.all(): reason.mentions.add(m) self.post.reported = True self.post.save(force_update=True) self.thread.replies_reported += 1 self.thread.save(force_update=True) request.monitor.increase("reported_posts") made_report = True if made_report: if request.is_ajax(): return json_response( request, message=_("Selected post has been reported and will receive moderator attention. Thank you."), ) self.request.messages.set_flash( Message(_("Selected post has been reported and will receive moderator attention. Thank you.")), "info", "threads_%s" % self.post.pk, ) else: if request.is_ajax(): return json_response( request, message=_( "You have already reported this post. One of moderators will handle it as soon as it is possible. Thank you for your patience." ), ) self.request.messages.set_flash( Message( _( "You have already reported this post. One of moderators will handle it as soon as it is possible. Thank you for your patience." ) ), "info", "threads_%s" % self.post.pk, ) return self.redirect_to_post(self.post)
def post_form(self, form): now = timezone.now() moderation = (not self.request.acl.threads.acl[self.forum.pk]['can_approve'] and self.request.acl.threads.acl[self.forum.pk]['can_start_threads'] == 1) self.thread.previous_last = self.thread.last_post self.md, post_preparsed = post_markdown(self.request, form.cleaned_data['post']) # Count merge diff and see if we are merging merge_diff = (now - self.thread.last) merge_diff = (merge_diff.days * 86400) + merge_diff.seconds if (self.request.settings.post_merge_time and merge_diff < (self.request.settings.post_merge_time * 60) and self.thread.last_poster_id == self.request.user.id and self.thread.last_post.moderated == moderation): merged = True self.post = self.thread.last_post self.post.date = now self.post.post = '%s\n\n- - -\n**%s**\n%s' % (self.post.post, _("Added on %(date)s:") % {'date': date(now, 'SHORT_DATETIME_FORMAT')}, form.cleaned_data['post']) self.md, self.post.post_preparsed = post_markdown(self.request, self.post.post) self.post.save(force_update=True) else: # Create new post merged = False self.post = Post.objects.create( forum=self.forum, thread=self.thread, user=self.request.user, user_name=self.request.user.username, ip=self.request.session.get_ip(self.request), agent=self.request.META.get('HTTP_USER_AGENT'), post=form.cleaned_data['post'], post_preparsed=post_preparsed, date=now, merge=self.thread.merges, moderated=moderation, ) # Update thread data and score? if not moderation: self.thread.new_last_post(self.post) if not merged: if not moderation: self.thread.replies += 1 else: self.thread.replies_moderated += 1 # Increase thread score if self.thread.last_poster_id != self.request.user.pk: self.thread.score += self.request.settings['thread_ranking_reply_score'] # Save updated thread self.thread.save(force_update=True) # Update forum and monitor if not moderation and not merged: self.request.monitor['posts'] = int(self.request.monitor['posts']) + 1 self.forum.posts += 1 self.forum.new_last_thread(self.thread) self.forum.save(force_update=True) # Reward user for posting new reply? if not moderation and not merged and (not self.request.user.last_post or self.request.user.last_post < timezone.now() - timedelta(seconds=self.request.settings['score_reward_new_post_cooldown'])): self.request.user.score += self.request.settings['score_reward_new_post'] # Update user if not moderation and not merged: self.request.user.threads += 1 self.request.user.posts += 1 self.request.user.last_post = now self.request.user.save(force_update=True) # Set thread weight if 'thread_weight' in form.cleaned_data: self.thread.weight = form.cleaned_data['thread_weight'] # Set "closed" checkpoint, either due to thread limit or posters wish if (self.request.settings.thread_length > 0 and not merged and not moderation and not self.thread.closed and self.thread.replies >= self.request.settings.thread_length): self.thread.closed = True self.post.set_checkpoint(self.request, 'limit') self.post.save(force_update=True) self.thread.save(force_update=True) elif 'close_thread' in form.cleaned_data and form.cleaned_data['close_thread']: self.thread.closed = not self.thread.closed if merged: checkpoint_post = self.post else: checkpoint_post = self.thread.previous_last if self.thread.closed: checkpoint_post.set_checkpoint(self.request, 'closed') else: checkpoint_post.set_checkpoint(self.request, 'opened') checkpoint_post.save(force_update=True) self.thread.save(force_update=True) # Notify user we quoted? if (self.quote and self.quote.user_id and not merged and self.quote.user_id != self.request.user.pk and not self.quote.user.is_ignoring(self.request.user)): alert = self.quote.user.alert(ugettext_lazy("%(username)s has replied to your post in thread %(thread)s").message) alert.profile('username', self.request.user) alert.post('thread', self.type_prefix, self.thread, self.post) alert.save_all() # E-mail users about new response self.thread.email_watchers(self.request, self.type_prefix, self.post)
def __call__(self, request, **kwargs): self.request = request self.kwargs = kwargs self.forum = None self.thread = None self.quote = None self.post = None self.parents = [] self.message = request.messages.get_message('threads') post_preview = '' form = None try: self._type_available() self._set_context() self.check_forum_type() self._check_permissions() request.block_flood_requests = self.block_flood_requests self.make_attachments_token() self.fetch_attachments() if request.method == 'POST': # Create correct form instance if self.allow_quick_reply and 'quick_reply' in request.POST: form = QuickReplyForm(request.POST, request=request) if not form or 'preview' in request.POST or not form.is_valid(): # Override "quick reply" form with full one try: form = self.form_type(request.POST, request.FILES, request=request, forum=self.forum, thread=self.thread) except AttributeError: form = self.form_type(request.POST, request=request, forum=self.forum, thread=self.thread) # Handle specific submit if list(set(request.POST.keys()) & set(('preview', 'upload', 'remove_attachment', 'restore_attachment'))): form.empty_errors() if form['post'].value(): md, post_preview = post_markdown(form['post'].value()) else: md, post_preview = None, None if 'upload' in request.POST: try: uploaded_file = form['new_file'].value() except KeyError: uploaded_file = None self._upload_file(uploaded_file) if 'remove_attachment' in request.POST: try: self.remove_attachment(int(request.POST.get('remove_attachment'))) except ValueError: self.message = Message(_("Requested attachment could not be found."), messages.ERROR) if 'restore_attachment' in request.POST: try: self.restore_attachment(int(request.POST.get('restore_attachment'))) except ValueError: self.message = Message(_("Requested attachment could not be found."), messages.ERROR) else: if form.is_valid(): self.post_form(form) self.watch_thread() self.after_form(form) self.finalize_attachments() self.notify_users() return self.response() else: self.message = Message(form.non_field_errors()[0], messages.ERROR) else: form = self.form_type(request=request, forum=self.forum, thread=self.thread, initial=self.form_initial_data()) except (Forum.DoesNotExist, Thread.DoesNotExist, Post.DoesNotExist): return error404(request) except ACLError403 as e: return error403(request, unicode(e)) except ACLError404 as e: return error404(request, unicode(e)) return render_to_response('%ss/posting.html' % self.type_prefix, self._template_vars({ 'action': self.action, 'attachments': self.attachments, 'attachments_types': AttachmentType.objects.all_types(), 'attachments_removed': self.attachments_removed, 'attachments_number': self.user_attachments, 'message': self.message, 'forum': self.forum, 'thread': self.thread, 'quote': self.quote, 'post': self.post, 'parents': self.parents, 'preview': post_preview, 'form': form, 'emojis': emojis(), }), context_instance=RequestContext(request));
def view(request): report = None made_report = False if self.post.reported: report = self.post.live_report() if report and report.start_poster_id != request.user.pk: # Append our q.q to existing report? try: report.checkpoint_set.get(user=request.user, action="reported") except Checkpoint.DoesNotExist: report.set_checkpoint(self.request, 'reported', user) made_report = True if not report: # File up new report now = timezone.now() reason_post = _(''' Member @%(reporter)s has reported following post by @%(reported)s: %(quote)s **Post link:** <%(post)s> ''') reason_post = reason_post.strip() % { 'reporter': request.user.username, 'reported': self.post.user_name, 'post': settings.BOARD_ADDRESS + self.redirect_to_post(self.post)['Location'], 'quote': self.post.quote(), } md, reason_post_preparsed = post_markdown(reason_post) reports = Forum.objects.special_model('reports') report = Thread.objects.create( forum=reports, weight=2, name=self.thread.name, slug=slugify(self.thread.slug), start=now, start_poster=request.user, start_poster_name=request.user.username, start_poster_slug=request.user.username_slug, start_poster_style=request.user.rank.style, last=now, last_poster=request.user, last_poster_name=request.user.username, last_poster_slug=request.user.username_slug, last_poster_style=request.user.rank.style, report_for=self.post, ) reason = Post.objects.create( forum=reports, thread=report, user=request.user, user_name=request.user.username, ip=request.session.get_ip(self.request), agent=request.META.get('HTTP_USER_AGENT'), post=reason_post, post_preparsed=reason_post_preparsed, date=now, ) report.start_post = reason report.last_post = reason report.save(force_update=True) for m in self.post.mentions.all(): reason.mentions.add(m) self.post.reported = True self.post.save(force_update=True) self.thread.replies_reported += 1 self.thread.save(force_update=True) request.monitor.increase('reported_posts') made_report = True if made_report: if request.is_ajax(): return json_response( request, message= _("Selected post has been reported and will receive moderator attention. Thank you." )) self.request.messages.set_flash( Message( _("Selected post has been reported and will receive moderator attention. Thank you." )), 'info', 'threads_%s' % self.post.pk) else: if request.is_ajax(): return json_response( request, message= _("You have already reported this post. One of moderators will handle it as soon as it is possible. Thank you for your patience." )) self.request.messages.set_flash( Message( _("You have already reported this post. One of moderators will handle it as soon as it is possible. Thank you for your patience." )), 'info', 'threads_%s' % self.post.pk) return self.redirect_to_post(self.post)
def post_form(self, form): now = timezone.now() if self.force_moderation(): moderation = True else: moderation = ( not self.request.acl.threads.acl[self.forum.pk]['can_approve'] and self.request.acl.threads.acl[ self.forum.pk]['can_start_threads'] == 1) self.thread.previous_last = self.thread.last_post self.md, post_preparsed = post_markdown(form.cleaned_data['post']) # Count merge diff and see if we are merging merge_diff = (now - self.thread.last) merge_diff = (merge_diff.days * 86400) + merge_diff.seconds if (settings.post_merge_time and merge_diff < (settings.post_merge_time * 60) and self.thread.last_poster_id == self.request.user.id and self.thread.last_post.moderated == moderation and (not self.thread.last_post.deleted or self.thread.last_post_id == self.thread.start_post_id)): merged = True self.post = self.thread.last_post self.post.date = now self.post.post = '%s\n\n%s' % (self.post.post, form.cleaned_data['post']) self.md, self.post.post_preparsed = post_markdown(self.post.post) self.post.save(force_update=True) else: # Create new post merged = False self.post = Post.objects.create( forum=self.forum, thread=self.thread, user=self.request.user, user_name=self.request.user.username, ip=self.request.session.get_ip(self.request), agent=self.request.META.get('HTTP_USER_AGENT'), post=form.cleaned_data['post'], post_preparsed=post_preparsed, date=now, moderated=moderation, ) # Update thread data and score? if not moderation: self.thread.new_last_post(self.post) if not merged: if not moderation: self.thread.replies += 1 else: self.thread.replies_moderated += 1 # Increase thread score if self.thread.last_poster_id != self.request.user.pk: self.thread.score += settings.thread_ranking_reply_score # Update forum and monitor if not moderation and not merged: with UpdatingMonitor() as cm: monitor.increase('posts') self.forum.posts += 1 self.forum.new_last_thread(self.thread) self.forum.save(force_update=True) # Reward user for posting new reply? if not moderation and not merged and ( not self.request.user.last_post or self.request.user.last_post < timezone.now() - timedelta(seconds=settings.score_reward_new_post_cooldown)): self.request.user.score += settings.score_reward_new_post # Update user if not moderation and not merged: self.request.user.posts += 1 self.request.user.last_post = now self.request.user.save(force_update=True) # Set thread weight if 'thread_weight' in form.cleaned_data: self.thread.weight = form.cleaned_data['thread_weight'] # Set "closed" checkpoint, either due to thread limit or posters wish if (settings.thread_length > 0 and not merged and not moderation and not self.thread.closed and self.thread.replies >= settings.thread_length): self.thread.closed = True self.thread.set_checkpoint(self.request, 'limit') elif 'close_thread' in form.cleaned_data and form.cleaned_data[ 'close_thread']: self.thread.closed = not self.thread.closed if self.thread.closed: self.thread.set_checkpoint(self.request, 'closed') else: self.thread.set_checkpoint(self.request, 'opened') # Save updated thread self.thread.save(force_update=True) # Mute quoted user? if not (self.quote and self.quote.user_id and not merged and self.quote.user_id != self.request.user.pk and not self.quote.user.is_ignoring(self.request.user)): self.quote = None
def post_form(self, form): now = timezone.now() moderation = ( not self.request.acl.threads.acl[self.forum.pk]['can_approve'] and self.request.acl.threads.acl[self.forum.pk]['can_start_threads'] == 1) # Create empty thread self.thread = Thread.objects.create( forum=self.forum, name=form.cleaned_data['thread_name'], slug=slugify(form.cleaned_data['thread_name']), start=now, last=now, moderated=moderation, score=self.request.settings['thread_ranking_initial_score'], ) # Create our post self.md, post_preparsed = post_markdown(form.cleaned_data['post']) self.post = Post.objects.create( forum=self.forum, thread=self.thread, user=self.request.user, user_name=self.request.user.username, ip=self.request.session.get_ip(self.request), agent=self.request.META.get('HTTP_USER_AGENT'), post=form.cleaned_data['post'], post_preparsed=post_preparsed, date=now, moderated=moderation, ) # Update thread stats to contain this post self.thread.new_start_post(self.post) self.thread.new_last_post(self.post) # Set thread status if 'close_thread' in form.cleaned_data: self.thread.closed = form.cleaned_data['close_thread'] if 'thread_weight' in form.cleaned_data: self.thread.weight = form.cleaned_data['thread_weight'] # Finally save complete thread self.thread.save(force_update=True) # Update forum monitor if not moderation: self.request.monitor.increase('threads') self.request.monitor.increase('posts') self.forum.threads += 1 self.forum.posts += 1 self.forum.new_last_thread(self.thread) self.forum.save(force_update=True) # Reward user for posting new thread? if not moderation and ( not self.request.user.last_post or self.request.user.last_post < timezone.now() - timedelta(seconds=self.request. settings['score_reward_new_post_cooldown'])): self.request.user.score += self.request.settings[ 'score_reward_new_thread'] # Update user if not moderation: self.request.user.threads += 1 self.request.user.posts += 1 self.request.user.last_post = now self.request.user.save(force_update=True)
def __call__(self, request, **kwargs): self.request = request self.forum = None self.thread = None self.quote = None self.post = None self.parents = None self.mode = kwargs.get('mode') if self.request.POST.get('quick_reply') and self.mode == 'new_post': self.mode = 'new_post_quick' try: self.fetch_target(kwargs) if not request.user.is_authenticated(): raise ACLError403(_("Guest, you have to sign-in in order to post replies.")) except (Forum.DoesNotExist, Thread.DoesNotExist, Post.DoesNotExist): return error404(self.request) except ACLError403 as e: return error403(request, e.message) except ACLError404 as e: return error404(request, e.message) message = request.messages.get_message('threads') if request.method == 'POST': form = self.get_form(True) # Show message preview if 'preview' in request.POST: if form['post'].value(): md, preparsed = post_markdown(request, form['post'].value()) else: md, preparsed = None, None form.empty_errors() return request.theme.render_to_response('threads/posting.html', { 'mode': self.mode, 'forum': self.forum, 'thread': self.thread, 'post': self.post, 'quote': self.quote, 'parents': self.parents, 'message': message, 'preview': preparsed, 'form': FormLayout(form), }, context_instance=RequestContext(request)); # Commit form to database if form.is_valid(): # Record original vars if user is editing if self.mode in ['edit_thread', 'edit_post']: old_name = self.thread.name old_post = self.post.post # If there is no change, throw user back changed_name = (old_name != form.cleaned_data['thread_name']) if self.mode == 'edit_thread' else False changed_post = old_post != form.cleaned_data['post'] changed_anything = changed_name or changed_post # Some extra initialisation now = timezone.now() md = None moderation = False if not request.acl.threads.acl[self.forum.pk]['can_approve']: if self.mode == 'new_thread' and request.acl.threads.acl[self.forum.pk]['can_start_threads'] == 1: moderation = True if self.mode in ['new_post', 'new_post_quick'] and request.acl.threads.acl[self.forum.pk]['can_write_posts'] == 1: moderation = True # Get or create new thread if self.mode == 'new_thread': thread = Thread.objects.create( forum=self.forum, name=form.cleaned_data['thread_name'], slug=slugify(form.cleaned_data['thread_name']), start=now, last=now, moderated=moderation, score=request.settings['thread_ranking_initial_score'], ) if moderation: thread.replies_moderated += 1 else: thread = self.thread if self.mode == 'edit_thread': thread.name = form.cleaned_data['thread_name'] thread.slug = slugify(form.cleaned_data['thread_name']) thread.previous_last = thread.last # Create new message if self.mode in ['new_thread', 'new_post', 'new_post_quick']: # Use last post instead? if self.mode in ['new_post', 'new_post_quick']: merge_diff = (now - self.thread.last) merge_diff = (merge_diff.days * 86400) + merge_diff.seconds if (self.mode in ['new_post', 'new_post_quick'] and request.settings.post_merge_time and merge_diff < (request.settings.post_merge_time * 60) and self.thread.last_poster_id == request.user.id): # Overtake posting post = self.thread.last_post post.appended = True post.moderated = moderation post.date = now post.post = '%s\n\n- - -\n**%s**\n%s' % (post.post, _("Added on %(date)s:") % {'date': date(now, 'SHORT_DATETIME_FORMAT')}, form.cleaned_data['post']) md, post.post_preparsed = post_markdown(request, post.post) post.save(force_update=True) thread.last = now thread.save(force_update=True) self.forum.last = now self.forum.save(force_update=True) # Ignore rest of posting action request.messages.set_flash(Message(_("Your reply has been added to previous one.")), 'success', 'threads_%s' % post.pk) return self.redirect_to_post(post) else: md, post_preparsed = post_markdown(request, form.cleaned_data['post']) post = Post.objects.create( forum=self.forum, thread=thread, merge=thread.merges, user=request.user, user_name=request.user.username, ip=request.session.get_ip(request), agent=request.META.get('HTTP_USER_AGENT'), post=form.cleaned_data['post'], post_preparsed=post_preparsed, date=now, moderated=moderation, ) post.appended = False elif changed_post: # Change message post = self.post post.post = form.cleaned_data['post'] md, post.post_preparsed = post_markdown(request, form.cleaned_data['post']) post.edits += 1 post.edit_date = now post.edit_user = request.user post.edit_user_name = request.user.username post.edit_user_slug = request.user.username_slug post.save(force_update=True) # Record this edit in changelog? if self.mode in ['edit_thread', 'edit_post'] and changed_anything: self.post.change_set.create( forum=self.forum, thread=self.thread, post=self.post, user=request.user, user_name=request.user.username, user_slug=request.user.username_slug, date=now, ip=request.session.get_ip(request), agent=request.META.get('HTTP_USER_AGENT'), reason=form.cleaned_data['edit_reason'], size=len(self.post.post), change=len(self.post.post) - len(old_post), thread_name_old=old_name if self.mode == 'edit_thread' and form.cleaned_data['thread_name'] != old_name else None, thread_name_new=self.thread.name if self.mode == 'edit_thread' and form.cleaned_data['thread_name'] != old_name else None, post_content=old_post, ) # Set thread start post and author data if self.mode == 'new_thread': thread.start_post = post thread.start_poster = request.user thread.start_poster_name = request.user.username thread.start_poster_slug = request.user.username_slug if request.user.rank and request.user.rank.style: thread.start_poster_style = request.user.rank.style # Reward user for posting new thread? if not request.user.last_post or request.user.last_post < timezone.now() - timedelta(seconds=request.settings['score_reward_new_post_cooldown']): request.user.score += request.settings['score_reward_new_thread'] # New post - increase post counters, thread score # Notify quoted post author and close thread if it has hit limit if self.mode in ['new_post', 'new_post_quick']: if moderation: thread.replies_moderated += 1 else: thread.replies += 1 if thread.last_poster_id != request.user.pk: thread.score += request.settings['thread_ranking_reply_score'] # Notify quoted poster of reply? if self.quote and self.quote.user_id and self.quote.user_id != request.user.pk and not self.quote.user.is_ignoring(request.user): alert = self.quote.user.alert(ugettext_lazy("%(username)s has replied to your post in thread %(thread)s").message) alert.profile('username', request.user) alert.post('thread', self.thread, post) alert.save_all() if (self.request.settings.thread_length > 0 and not thread.closed and thread.replies >= self.request.settings.thread_length): thread.closed = True post.set_checkpoint(self.request, 'limit') # Reward user for posting new post? if not post.appended and (not request.user.last_post or request.user.last_post < timezone.now() - timedelta(seconds=request.settings['score_reward_new_post_cooldown'])): request.user.score += request.settings['score_reward_new_post'] # Update last poster data if not moderation and self.mode not in ['edit_thread', 'edit_post']: thread.last = now thread.last_post = post thread.last_poster = request.user thread.last_poster_name = request.user.username thread.last_poster_slug = request.user.username_slug thread.last_poster_style = request.user.rank.style # Final update of thread entry if self.mode != 'edit_post': thread.save(force_update=True) # Update forum and monitor if not moderation: if self.mode == 'new_thread': self.request.monitor['threads'] = int(self.request.monitor['threads']) + 1 self.forum.threads += 1 if self.mode in ['new_thread', 'new_post', 'new_post_quick']: self.request.monitor['posts'] = int(self.request.monitor['posts']) + 1 self.forum.posts += 1 if self.mode in ['new_thread', 'new_post', 'new_post_quick'] or ( self.mode == 'edit_thread' and self.forum.last_thread_id == thread.pk and self.forum.last_thread_name != thread.name): self.forum.last_thread = thread self.forum.last_thread_name = thread.name self.forum.last_thread_slug = thread.slug self.forum.last_thread_date = thread.last if self.mode in ['new_thread', 'new_post', 'new_post_quick']: self.forum.last_poster = thread.last_poster self.forum.last_poster_name = thread.last_poster_name self.forum.last_poster_slug = thread.last_poster_slug self.forum.last_poster_style = thread.last_poster_style if self.mode != 'edit_post': self.forum.save(force_update=True) # Update user if not moderation: if self.mode == 'new_thread': request.user.threads += 1 request.user.posts += 1 if self.mode in ['new_thread', 'new_post', 'new_post_quick']: request.user.last_post = thread.last request.user.save(force_update=True) # Notify users about post if md: try: if self.quote and self.quote.user_id: del md.mentions[self.quote.user.username_slug] except KeyError: pass if md.mentions: post.notify_mentioned(request, md.mentions) post.save(force_update=True) # Set thread watch status if self.mode == 'new_thread' and request.user.subscribe_start: ThreadWatch.objects.create( user=request.user, forum=self.forum, thread=thread, last_read=now, email=(request.user.subscribe_start == 2), ) if self.mode in ['new_post', 'new_post_quick'] and request.user.subscribe_reply: try: watcher = ThreadWatch.objects.get(user=request.user, thread=self.thread) except ThreadWatch.DoesNotExist: ThreadWatch.objects.create( user=request.user, forum=self.forum, thread=thread, last_read=now, email=(request.user.subscribe_reply == 2), ) # Set flash and redirect user to his post if self.mode == 'new_thread': if moderation: request.messages.set_flash(Message(_("New thread has been posted. It will be hidden from other members until moderator reviews it.")), 'success', 'threads') else: request.messages.set_flash(Message(_("New thread has been posted.")), 'success', 'threads') return redirect(reverse('thread', kwargs={'thread': thread.pk, 'slug': thread.slug}) + ('#post-%s' % post.pk)) if self.mode in ['new_post', 'new_post_quick']: thread.email_watchers(request, post) if moderation: request.messages.set_flash(Message(_("Your reply has been posted. It will be hidden from other members until moderator reviews it.")), 'success', 'threads_%s' % post.pk) else: request.messages.set_flash(Message(_("Your reply has been posted.")), 'success', 'threads_%s' % post.pk) return self.redirect_to_post(post) if self.mode == 'edit_thread': request.messages.set_flash(Message(_("Your thread has been edited.")), 'success', 'threads_%s' % self.post.pk) if self.mode == 'edit_post': request.messages.set_flash(Message(_("Your reply has been edited.")), 'success', 'threads_%s' % self.post.pk) return self.redirect_to_post(self.post) return redirect(reverse('thread', kwargs={'thread': self.thread.pk, 'slug': self.thread.slug}) + ('#post-%s' % self.post.pk)) message = Message(form.non_field_errors()[0], 'error') else: form = self.get_form() # Merge proxy into forum self.forum.closed = self.proxy.closed return request.theme.render_to_response('threads/posting.html', { 'mode': self.mode, 'forum': self.forum, 'thread': self.thread, 'post': self.post, 'quote': self.quote, 'parents': self.parents, 'message': message, 'form': FormLayout(form), }, context_instance=RequestContext(request));
def __call__(self, request, **kwargs): self.request = request self.kwargs = kwargs self.forum = None self.thread = None self.quote = None self.post = None self.parents = [] self.message = request.messages.get_message('threads') post_preview = '' form = None try: self._type_available() self._set_context() self.check_forum_type() self._check_permissions() request.block_flood_requests = self.block_flood_requests self.make_attachments_token() self.fetch_attachments() if request.method == 'POST': # Create correct form instance if self.allow_quick_reply and 'quick_reply' in request.POST: form = QuickReplyForm(request.POST, request=request) if not form or 'preview' in request.POST or not form.is_valid( ): # Override "quick reply" form with full one try: form = self.form_type(request.POST, request.FILES, request=request, forum=self.forum, thread=self.thread) except AttributeError: form = self.form_type(request.POST, request=request, forum=self.forum, thread=self.thread) # Handle specific submit if list( set(request.POST.keys()) & set(('preview', 'upload', 'remove_attachment', 'restore_attachment'))): form.empty_errors() if form['post'].value(): md, post_preview = post_markdown(form['post'].value()) else: md, post_preview = None, None if 'upload' in request.POST: try: uploaded_file = form['new_file'].value() except KeyError: uploaded_file = None self._upload_file(uploaded_file) if 'remove_attachment' in request.POST: try: self.remove_attachment( int(request.POST.get('remove_attachment'))) except ValueError: self.message = Message( _("Requested attachment could not be found."), messages.ERROR) if 'restore_attachment' in request.POST: try: self.restore_attachment( int(request.POST.get('restore_attachment'))) except ValueError: self.message = Message( _("Requested attachment could not be found."), messages.ERROR) else: if form.is_valid(): self.post_form(form) self.watch_thread() self.after_form(form) self.finalize_attachments() self.notify_users() return self.response() else: self.message = Message(form.non_field_errors()[0], messages.ERROR) else: form = self.form_type(request=request, forum=self.forum, thread=self.thread, initial=self.form_initial_data()) except (Forum.DoesNotExist, Thread.DoesNotExist, Post.DoesNotExist): return error404(request) except ACLError403 as e: return error403(request, unicode(e)) except ACLError404 as e: return error404(request, unicode(e)) return render_to_response('%ss/posting.html' % self.type_prefix, self._template_vars({ 'action': self.action, 'attachments': self.attachments, 'attachments_types': AttachmentType.objects.all_types(), 'attachments_removed': self.attachments_removed, 'attachments_number': self.user_attachments, 'message': self.message, 'forum': self.forum, 'thread': self.thread, 'quote': self.quote, 'post': self.post, 'parents': self.parents, 'preview': post_preview, 'form': form, 'emojis': emojis(), }), context_instance=RequestContext(request))
def __call__(self, request, **kwargs): self.request = request self.kwargs = kwargs self.forum = None self.thread = None self.quote = None self.post = None self.parents = [] self.message = request.messages.get_message('threads') post_preview = '' form = None try: self._type_available() self._set_context() self.check_forum_type() self._check_permissions() if request.method == 'POST': # Create correct form instance if self.allow_quick_reply and 'quick_reply' in request.POST: form = QuickReplyForm(request.POST, request=request) if not form or 'preview' in request.POST or not form.is_valid(): # Override "quick reply" form with full one try: form = self.form_type(request.POST, request.FILE, request=request, forum=self.forum, thread=self.thread) except AttributeError: form = self.form_type(request.POST, request=request, forum=self.forum, thread=self.thread) # Handle specific submit if 'preview' in request.POST: form.empty_errors() if form['post'].value(): md, post_preview = post_markdown(request, form['post'].value()) else: md, post_preview = None, None else: if form.is_valid(): self.post_form(form) self.watch_thread() self.after_form(form) self.notify_users() return self.response() else: self.message = Message(form.non_field_errors()[0], 'error') else: form = self.form_type(request=request, forum=self.forum, thread=self.thread, initial=self.form_initial_data()) except (Forum.DoesNotExist, Thread.DoesNotExist, Post.DoesNotExist): return error404(request) except ACLError403 as e: return error403(request, unicode(e)) except ACLError404 as e: return error404(request, unicode(e)) return request.theme.render_to_response(('%ss/posting.html' % self.type_prefix), self.template_vars({ 'type_prefix': self.type_prefix, 'action': self.action, 'message': self.message, 'forum': self.forum, 'thread': self.thread, 'quote': self.quote, 'post': self.post, 'parents': self.parents, 'preview': post_preview, 'form': FormLayout(form), }), context_instance=RequestContext(request));
def dispatch(self, request, **kwargs): if ((not self.change.thread_name_old or self.thread.name == self.change.thread_name_old) and (self.change.post_content == self.post.post)): messages.error(request, _("No changes to revert."), 'changelog') return redirect( reverse('%s_changelog_diff' % self.type_prefix, kwargs={ 'thread': self.thread.pk, 'slug': self.thread.slug, 'post': self.post.pk, 'change': self.change.pk })) self.post.edits += 1 self.post.edit_user = self.request.user self.post.edit_user_name = self.request.user.username self.post.edit_user_slug = self.request.user.username_slug self.post.change_set.create( forum=self.forum, thread=self.thread, post=self.post, user=request.user, user_name=request.user.username, user_slug=request.user.username_slug, date=timezone.now(), ip=request.session.get_ip(self.request), agent=request.META.get('HTTP_USER_AGENT'), reason=_("Reverted to the state before %(date)s.") % {'date': reldate(self.change.date).lower()}, size=len(self.change.post_content), change=len(self.change.post_content) - len(self.post.post), thread_name_old=self.thread.name if self.change.thread_name_old != self.thread.name and self.change.thread_name_old != None else None, thread_name_new=self.change.thread_name_old if self.change.thread_name_old != self.thread.name else None, post_content=self.post.post, ) if self.change.thread_name_old and self.change.thread_name_old != self.thread.name: self.thread.name = self.change.thread_name_old self.thread.slug = slugify(self.change.thread_name_old) self.thread.save(force_update=True) if self.forum.last_thread_id == self.thread.pk: self.forum.last_thread_name = self.change.thread_name_old self.forum.last_thread_slug = slugify( self.change.thread_name_old) self.forum.save(force_update=True) if self.change.post_content != self.post.post: self.post.post = self.change.post_content md, self.post.post_preparsed = post_markdown( self.change.post_content) self.post.save(force_update=True) messages.success( request, _("Post has been reverted to the state before %(date)s.") % {'date': reldate(self.change.date).lower()}, 'threads_%s' % self.post.pk) return self.redirect_to_post(self.post)
def post_form(self, form): now = timezone.now() moderation = (not self.request.acl.threads.acl[self.forum.pk]['can_approve'] and self.request.acl.threads.acl[self.forum.pk]['can_start_threads'] == 1) self.thread.previous_last = self.thread.last_post self.md, post_preparsed = post_markdown(form.cleaned_data['post']) # Count merge diff and see if we are merging merge_diff = (now - self.thread.last) merge_diff = (merge_diff.days * 86400) + merge_diff.seconds if (settings.post_merge_time and merge_diff < (settings.post_merge_time * 60) and self.thread.last_poster_id == self.request.user.id and self.thread.last_post.moderated == moderation and (not self.thread.last_post.deleted or self.thread.last_post_id == self.thread.start_post_id)): merged = True self.post = self.thread.last_post self.post.date = now self.post.post = '%s\n\n%s' % (self.post.post, form.cleaned_data['post']) self.md, self.post.post_preparsed = post_markdown(self.post.post) self.post.save(force_update=True) else: # Create new post merged = False self.post = Post.objects.create( forum=self.forum, thread=self.thread, user=self.request.user, user_name=self.request.user.username, ip=self.request.session.get_ip(self.request), agent=self.request.META.get('HTTP_USER_AGENT'), post=form.cleaned_data['post'], post_preparsed=post_preparsed, date=now, moderated=moderation, ) # Update thread data and score? if not moderation: self.thread.new_last_post(self.post) if not merged: if not moderation: self.thread.replies += 1 else: self.thread.replies_moderated += 1 # Increase thread score if self.thread.last_poster_id != self.request.user.pk: self.thread.score += settings.thread_ranking_reply_score # Update forum and monitor if not moderation and not merged: with UpdatingMonitor() as cm: monitor.increase('posts') self.forum.posts += 1 self.forum.new_last_thread(self.thread) self.forum.save(force_update=True) # Reward user for posting new reply? if not moderation and not merged and (not self.request.user.last_post or self.request.user.last_post < timezone.now() - timedelta(seconds=settings.score_reward_new_post_cooldown)): self.request.user.score += settings.score_reward_new_post # Update user if not moderation and not merged: self.request.user.posts += 1 self.request.user.last_post = now self.request.user.save(force_update=True) # Set thread weight if 'thread_weight' in form.cleaned_data: self.thread.weight = form.cleaned_data['thread_weight'] # Set "closed" checkpoint, either due to thread limit or posters wish if (settings.thread_length > 0 and not merged and not moderation and not self.thread.closed and self.thread.replies >= settings.thread_length): self.thread.closed = True self.thread.set_checkpoint(self.request, 'limit') elif 'close_thread' in form.cleaned_data and form.cleaned_data['close_thread']: self.thread.closed = not self.thread.closed if self.thread.closed: self.thread.set_checkpoint(self.request, 'closed') else: self.thread.set_checkpoint(self.request, 'opened') # Save updated thread self.thread.save(force_update=True) # Mute quoted user? if not (self.quote and self.quote.user_id and not merged and self.quote.user_id != self.request.user.pk and not self.quote.user.is_ignoring(self.request.user)): self.quote = None
def __call__(self, request, **kwargs): self.request = request self.kwargs = kwargs self.forum = None self.thread = None self.quote = None self.post = None self.parents = [] self.message = request.messages.get_message('threads') post_preview = '' form = None try: self._type_available() self._set_context() self.check_forum_type() self._check_permissions() request.block_flood_requests = self.block_flood_requests if request.method == 'POST': # Create correct form instance if self.allow_quick_reply and 'quick_reply' in request.POST: form = QuickReplyForm(request.POST, request=request) if not form or 'preview' in request.POST or not form.is_valid( ): # Override "quick reply" form with full one try: form = self.form_type(request.POST, request.FILE, request=request, forum=self.forum, thread=self.thread) except AttributeError: form = self.form_type(request.POST, request=request, forum=self.forum, thread=self.thread) # Handle specific submit if 'preview' in request.POST: form.empty_errors() if form['post'].value(): md, post_preview = post_markdown(form['post'].value()) else: md, post_preview = None, None else: if form.is_valid(): self.post_form(form) self.watch_thread() self.after_form(form) self.notify_users() return self.response() else: self.message = Message(form.non_field_errors()[0], 'error') else: form = self.form_type(request=request, forum=self.forum, thread=self.thread, initial=self.form_initial_data()) except (Forum.DoesNotExist, Thread.DoesNotExist, Post.DoesNotExist): return error404(request) except ACLError403 as e: return error403(request, unicode(e)) except ACLError404 as e: return error404(request, unicode(e)) return request.theme.render_to_response( ('%ss/posting.html' % self.type_prefix), self.template_vars({ 'type_prefix': self.type_prefix, 'action': self.action, 'message': self.message, 'forum': self.forum, 'thread': self.thread, 'quote': self.quote, 'post': self.post, 'parents': self.parents, 'preview': post_preview, 'form': FormLayout(form), 'emojis': emojis(), }), context_instance=RequestContext(request))
def post_form(self, form): now = timezone.now() if self.force_moderation(): moderation = True else: moderation = (not self.request.acl.threads.acl[self.forum.pk]['can_approve'] and self.request.acl.threads.acl[self.forum.pk]['can_start_threads'] == 1) # Create empty thread self.thread = Thread.objects.create( forum=self.forum, name=form.cleaned_data['thread_name'], slug=slugify(form.cleaned_data['thread_name']), start=now, last=now, moderated=moderation, score=settings.thread_ranking_initial_score, ) # Create our post self.md, post_preparsed = post_markdown(form.cleaned_data['post']) self.post = Post.objects.create( forum=self.forum, thread=self.thread, user=self.request.user, user_name=self.request.user.username, ip=self.request.session.get_ip(self.request), agent=self.request.META.get('HTTP_USER_AGENT'), post=form.cleaned_data['post'], post_preparsed=post_preparsed, date=now, moderated=moderation, ) # Update thread stats to contain this post self.thread.new_start_post(self.post) self.thread.new_last_post(self.post) # Set thread status if 'close_thread' in form.cleaned_data: self.thread.closed = form.cleaned_data['close_thread'] if 'thread_weight' in form.cleaned_data: self.thread.weight = form.cleaned_data['thread_weight'] # Finally save complete thread self.thread.save(force_update=True) # Update forum monitor if not moderation: with UpdatingMonitor() as cm: monitor.increase('threads') monitor.increase('posts') self.forum.threads += 1 self.forum.posts += 1 self.forum.new_last_thread(self.thread) self.forum.save(force_update=True) # Reward user for posting new thread? if not moderation and (not self.request.user.last_post or self.request.user.last_post < timezone.now() - timedelta(seconds=settings.score_reward_new_post_cooldown)): self.request.user.score += settings.score_reward_new_thread # Update user if not moderation: self.request.user.threads += 1 self.request.user.posts += 1 self.request.user.last_post = now self.request.user.save(force_update=True)