def question_revisions(request, question_id): """Revision history for a Question.""" question = get_object_or_404(Question, id=question_id) revisions = list(question.revisions.all()) populate_foreign_key_caches(User, ((revisions, ('author', )), ), fields=('username', 'gravatar', 'reputation', 'gold', 'silver', 'bronze')) for i, revision in enumerate(revisions): revision.html = QUESTION_REVISION_TEMPLATE % { 'title': revision.title, 'html': sanitize_html(markdowner.convert(revision.text)), 'tags': ' '.join([ '<a class="tag">%s</a>' % tag for tag in revision.tagnames.split(' ') ]), } if i > 0: revisions[i - 1].diff = htmldiff(revision.html, revisions[i - 1].html) return render_to_response('question_revisions.html', { 'title': u'Question Revisions', 'question': question, 'revisions': revisions, }, context_instance=RequestContext(request))
def add_answer(request, question_id): """ Adds an Answer to a Question. Once a certain number of Answers have been added, a Question and all its Answers will enter wiki mode and all subsequent Answers will be in wiki mode. """ question = get_object_or_404(Question, id=question_id) preview = None if request.method == 'POST': form = AddAnswerForm(request.POST) if form.is_valid(): html = sanitize_html(markdowner.convert(form.cleaned_data['text'])) if 'preview' in request.POST: # The user submitted the form to preview the formatted answer preview = mark_safe(html) elif 'submit' in request.POST: added_at = datetime.datetime.now() # Create the Answer answer = Answer( question = question, author = request.user, added_at = added_at, wiki = (form.cleaned_data['wiki'] or question.answer_count >= AUTO_WIKI_ANSWER_COUNT), html = html ) if answer.wiki: answer.wikified_at = added_at # When in wiki mode, we always display the last edit answer.last_edited_at = added_at answer.last_edited_by = request.user answer.save() # Create the initial revision AnswerRevision.objects.create( answer = answer, revision = 1, author = request.user, revised_at = added_at, summary = u'added answer', text = form.cleaned_data['text'] ) Question.objects.update_answer_count(question) # TODO Badges related to answering Questions # TODO If this is answer 30, put question and all answers into # wiki mode. # TODO Redirect needs to handle paging return HttpResponseRedirect(question.get_absolute_url()) else: form = AddAnswerForm() return render_to_response('add_answer.html', { 'title': u'Post an Answer', 'question': question, 'form': form, 'preview': preview, }, context_instance=RequestContext(request))
def add_answer(request, question_id): """ Adds an Answer to a Question. Once a certain number of Answers have been added, a Question and all its Answers will enter wiki mode and all subsequent Answers will be in wiki mode. """ question = get_object_or_404(Question, id=question_id) preview = None if request.method == 'POST': form = AddAnswerForm(request.POST) if form.is_valid(): html = sanitize_html(markdowner.convert(form.cleaned_data['text'])) if 'preview' in request.POST: # The user submitted the form to preview the formatted answer preview = mark_safe(html) elif 'submit' in request.POST: added_at = datetime.datetime.now() # Create the Answer answer = Answer( question=question, author=request.user, added_at=added_at, wiki=(form.cleaned_data['wiki'] or question.answer_count >= AUTO_WIKI_ANSWER_COUNT), html=html) if answer.wiki: answer.wikified_at = added_at # When in wiki mode, we always display the last edit answer.last_edited_at = added_at answer.last_edited_by = request.user answer.save() # Create the initial revision AnswerRevision.objects.create(answer=answer, revision=1, author=request.user, revised_at=added_at, summary=u'added answer', text=form.cleaned_data['text']) Question.objects.update_answer_count(question) # TODO Badges related to answering Questions # TODO If this is answer 30, put question and all answers into # wiki mode. # TODO Redirect needs to handle paging return HttpResponseRedirect(question.get_absolute_url()) else: form = AddAnswerForm() return render_to_response('add_answer.html', { 'title': u'Post an Answer', 'question': question, 'form': form, 'preview': preview, }, context_instance=RequestContext(request))
def ask_question(request): """Adds a Question.""" preview = None if request.method == 'POST': form = AskQuestionForm(request.POST) if form.is_valid(): html = sanitize_html(markdowner.convert(form.cleaned_data['text'])) if 'preview' in request.POST: # The user submitted the form to preview the formatted question preview = mark_safe(html) elif 'submit' in request.POST: added_at = datetime.datetime.now() # Create the Question question = Question( title = form.cleaned_data['title'], author = request.user, added_at = added_at, wiki = form.cleaned_data['wiki'], last_activity_at = added_at, last_activity_by = request.user, tagnames = form.cleaned_data['tags'], html = html, summary = strip_tags(html)[:180] ) if question.wiki: question.wikified_at = added_at # When in wiki mode, we always display the last edit question.last_edited_at = added_at question.last_edited_by = request.user question.save() # Create the initial revision QuestionRevision.objects.create( question = question, revision = 1, title = question.title, author = request.user, revised_at = added_at, tagnames = question.tagnames, summary = u'asked question', text = form.cleaned_data['text'] ) # TODO Badges related to Tag usage # TODO Badges related to asking Questions return HttpResponseRedirect(question.get_absolute_url()) else: form = AskQuestionForm() return render_to_response('ask_question.html', { 'title': u'Ask a Question', 'form': form, 'preview': preview, }, context_instance=RequestContext(request))
def ask_question(request): """Adds a Question.""" preview = None if request.method == 'POST': form = AskQuestionForm(request.POST) if form.is_valid(): html = sanitize_html(markdowner.convert(form.cleaned_data['text'])) if 'preview' in request.POST: # The user submitted the form to preview the formatted question preview = mark_safe(html) elif 'submit' in request.POST: added_at = datetime.datetime.now() # Create the Question question = Question(title=form.cleaned_data['title'], author=request.user, added_at=added_at, wiki=form.cleaned_data['wiki'], last_activity_at=added_at, last_activity_by=request.user, tagnames=form.cleaned_data['tags'], html=html, summary=strip_tags(html)[:180]) if question.wiki: question.wikified_at = added_at # When in wiki mode, we always display the last edit question.last_edited_at = added_at question.last_edited_by = request.user question.save() # Create the initial revision QuestionRevision.objects.create(question=question, revision=1, title=question.title, author=request.user, revised_at=added_at, tagnames=question.tagnames, summary=u'asked question', text=form.cleaned_data['text']) # TODO Badges related to Tag usage # TODO Badges related to asking Questions return HttpResponseRedirect(question.get_absolute_url()) else: form = AskQuestionForm() return render_to_response('ask_question.html', { 'title': u'Ask a Question', 'form': form, 'preview': preview, }, context_instance=RequestContext(request))
def answer_revisions(request, answer_id): """Revision history for an Answer.""" answer = get_object_or_404(Answer, id=answer_id) revisions = list(answer.revisions.all()) populate_foreign_key_caches(User, ((revisions, ('author',)),), fields=('username', 'gravatar', 'reputation', 'gold', 'silver', 'bronze')) for i, revision in enumerate(revisions): revision.html = QUESTION_REVISION_TEMPLATE % { 'html': sanitize_html(markdowner.convert(revision.text)), } if i > 0: revisions[i - 1].diff = htmldiff(revision.html, revisions[i - 1].html) return render_to_response('answer_revisions.html', { 'title': u'Answer Revisions', 'answer': answer, 'revisions': revisions, }, context_instance=RequestContext(request))
def answer_revisions(request, answer_id): """Revision history for an Answer.""" answer = get_object_or_404(Answer, id=answer_id) revisions = list(answer.revisions.all()) populate_foreign_key_caches(User, ((revisions, ('author', )), ), fields=('username', 'gravatar', 'reputation', 'gold', 'silver', 'bronze')) for i, revision in enumerate(revisions): revision.html = QUESTION_REVISION_TEMPLATE % { 'html': sanitize_html(markdowner.convert(revision.text)), } if i > 0: revisions[i - 1].diff = htmldiff(revision.html, revisions[i - 1].html) return render_to_response('answer_revisions.html', { 'title': u'Answer Revisions', 'answer': answer, 'revisions': revisions, }, context_instance=RequestContext(request))
def question_revisions(request, question_id): """Revision history for a Question.""" question = get_object_or_404(Question, id=question_id) revisions = list(question.revisions.all()) populate_foreign_key_caches(User, ((revisions, ('author',)),), fields=('username', 'gravatar', 'reputation', 'gold', 'silver', 'bronze')) for i, revision in enumerate(revisions): revision.html = QUESTION_REVISION_TEMPLATE % { 'title': revision.title, 'html': sanitize_html(markdowner.convert(revision.text)), 'tags': ' '.join(['<a class="tag">%s</a>' % tag for tag in revision.tagnames.split(' ')]), } if i > 0: revisions[i - 1].diff = htmldiff(revision.html, revisions[i - 1].html) return render_to_response('question_revisions.html', { 'title': u'Question Revisions', 'question': question, 'revisions': revisions, }, context_instance=RequestContext(request))
def edit_answer(request, answer_id): """Edits an Answer.""" answer = get_object_or_404(Answer, id=answer_id) if not auth.can_edit_post(request.user, answer): raise Http404 latest_revision = answer.get_latest_revision() preview = None revision_form = None if request.method == 'POST': if 'select_revision' in request.POST: # The user submitted to change the revision to start editing from revision_form = RevisionForm(answer, latest_revision, request.POST) if revision_form.is_valid(): # Replace Question details with those from the selected revision form = EditAnswerForm( answer, AnswerRevision.objects.get( answer=answer, revision=revision_form.cleaned_data['revision'])) else: # Make sure we keep a hold of the user's other input, even # though they appear to be messing about. form = EditAnswerForm(answer, latest_revision, request.POST) else: # Always check modifications against the latest revision form = EditAnswerForm(answer, latest_revision, request.POST) if form.is_valid(): html = sanitize_html( markdowner.convert(form.cleaned_data['text'])) if 'preview' in request.POST: # The user submitted to preview the formatted question preview = mark_safe(html) elif 'submit' in request.POST: if form.has_changed(): edited_at = datetime.datetime.now() # Update the Answer itself updated_fields = { 'last_edited_at': edited_at, 'last_edited_by': request.user, 'html': html, } if ('wiki' in form.cleaned_data and form.cleaned_data['wiki']): updated_fields['wiki'] = True updated_fields['wikified_at'] = edited_at Answer.objects.filter(id=answer.id).update( **updated_fields) # Create a new revision revision = AnswerRevision( answer=answer, author=request.user, revised_at=edited_at, text=form.cleaned_data['text']) if form.cleaned_data['summary']: revision.summary = form.cleaned_data['summary'] else: revision.summary = \ diff.generate_answer_revision_summary( latest_revision, revision, ('wiki' in updated_fields)) revision.save() # TODO 5 body edits by the asker = automatic wiki mode # TODO 4 individual editors = automatic wiki mode # TODO Badges related to editing Answers return HttpResponseRedirect(answer.get_absolute_url()) else: revision_form = RevisionForm(answer, latest_revision) form = EditAnswerForm(answer, latest_revision) if revision_form is None: # We're about to redisplay after a POST where we didn't care which # revision was selected - make sure the revision the user started from # is still selected on redisplay. revision_form = RevisionForm(answer, latest_revision, request.POST) return render_to_response('edit_answer.html', { 'title': u'Edit Answer', 'question': answer.question, 'answer': answer, 'revision_form': revision_form, 'form': form, 'preview': preview, }, context_instance=RequestContext(request))
def _edit_question(request, question): """ Allows the user to edit a Question's title, text and tags. If the Question is not already in wiki mode, the user can put it in wiki mode, or it will automatically be put in wiki mode if the question has been edited five times by the person who asked it, or has been edited by four different users. """ latest_revision = question.get_latest_revision() preview = None revision_form = None if request.method == 'POST': if 'select_revision' in request.POST: # The user submitted to change the revision to start editing from revision_form = RevisionForm(question, latest_revision, request.POST) if revision_form.is_valid(): # Replace Question details with those from the selected revision form = EditQuestionForm( question, QuestionRevision.objects.get( question=question, revision=revision_form.cleaned_data['revision'])) else: # Make sure we keep a hold of the user's other input, even # though they appear to be messing about. form = EditQuestionForm(question, latest_revision, request.POST) else: # Always check modifications against the latest revision form = EditQuestionForm(question, latest_revision, request.POST) if form.is_valid(): html = sanitize_html( markdowner.convert(form.cleaned_data['text'])) if 'preview' in request.POST: # The user submitted to preview the formatted question preview = mark_safe(html) elif 'submit' in request.POST: if form.has_changed(): edited_at = datetime.datetime.now() tags_changed = (latest_revision.tagnames != form.cleaned_data['tags']) tags_updated = False # Update the Question itself updated_fields = { 'title': form.cleaned_data['title'], 'last_edited_at': edited_at, 'last_edited_by': request.user, 'last_activity_at': edited_at, 'last_activity_by': request.user, 'tagnames': form.cleaned_data['tags'], 'summary': strip_tags(html)[:180], 'html': html, } if ('wiki' in form.cleaned_data and form.cleaned_data['wiki']): updated_fields['wiki'] = True updated_fields['wikified_at'] = edited_at Question.objects.filter(id=question.id).update( **updated_fields) # Update the Question's tag associations if tags_changed: tags_updated = Question.objects.update_tags( question, question.tagnames, request.user) # Create a new revision revision = QuestionRevision( question=question, title=form.cleaned_data['title'], author=request.user, revised_at=edited_at, tagnames=form.cleaned_data['tags'], text=form.cleaned_data['text']) if form.cleaned_data['summary']: revision.summary = form.cleaned_data['summary'] else: revision.summary = \ diff.generate_question_revision_summary( latest_revision, revision, ('wiki' in updated_fields)) revision.save() # TODO 5 body edits by the author = automatic wiki mode # TODO 4 individual editors = automatic wiki mode # TODO Badges related to Tag usage # TODO Badges related to editing Questions return HttpResponseRedirect(question.get_absolute_url()) else: if 'revision' in request.GET: revision_form = RevisionForm(question, latest_revision, request.GET) if revision_form.is_valid(): # Replace Question details with those from the selected revision form = EditQuestionForm( question, QuestionRevision.objects.get( question=question, revision=revision_form.cleaned_data['revision'])) else: revision_form = RevisionForm(question, latest_revision) form = EditQuestionForm(question, latest_revision) if revision_form is None: # We're about to redisplay after a POST where we didn't care which # revision was selected - make sure the revision the user started from # is still selected on redisplay. revision_form = RevisionForm(question, latest_revision, request.POST) return render_to_response('edit_question.html', { 'title': u'Edit Question', 'question': question, 'revision_form': revision_form, 'form': form, 'preview': preview, }, context_instance=RequestContext(request))
def edit_answer(request, answer_id): """Edits an Answer.""" answer = get_object_or_404(Answer, id=answer_id) if not auth.can_edit_post(request.user, answer): raise Http404 latest_revision = answer.get_latest_revision() preview = None revision_form = None if request.method == 'POST': if 'select_revision' in request.POST: # The user submitted to change the revision to start editing from revision_form = RevisionForm(answer, latest_revision, request.POST) if revision_form.is_valid(): # Replace Question details with those from the selected revision form = EditAnswerForm(answer, AnswerRevision.objects.get(answer=answer, revision=revision_form.cleaned_data['revision'])) else: # Make sure we keep a hold of the user's other input, even # though they appear to be messing about. form = EditAnswerForm(answer, latest_revision, request.POST) else: # Always check modifications against the latest revision form = EditAnswerForm(answer, latest_revision, request.POST) if form.is_valid(): html = sanitize_html( markdowner.convert(form.cleaned_data['text'])) if 'preview' in request.POST: # The user submitted to preview the formatted question preview = mark_safe(html) elif 'submit' in request.POST: if form.has_changed(): edited_at = datetime.datetime.now() # Update the Answer itself updated_fields = { 'last_edited_at': edited_at, 'last_edited_by': request.user, 'html': html, } if ('wiki' in form.cleaned_data and form.cleaned_data['wiki']): updated_fields['wiki'] = True updated_fields['wikified_at'] = edited_at Answer.objects.filter( id=answer.id).update(**updated_fields) # Create a new revision revision = AnswerRevision( answer = answer, author = request.user, revised_at = edited_at, text = form.cleaned_data['text'] ) if form.cleaned_data['summary']: revision.summary = form.cleaned_data['summary'] else: revision.summary = \ diff.generate_answer_revision_summary( latest_revision, revision, ('wiki' in updated_fields)) revision.save() # TODO 5 body edits by the asker = automatic wiki mode # TODO 4 individual editors = automatic wiki mode # TODO Badges related to editing Answers return HttpResponseRedirect(answer.get_absolute_url()) else: revision_form = RevisionForm(answer, latest_revision) form = EditAnswerForm(answer, latest_revision) if revision_form is None: # We're about to redisplay after a POST where we didn't care which # revision was selected - make sure the revision the user started from # is still selected on redisplay. revision_form = RevisionForm(answer, latest_revision, request.POST) return render_to_response('edit_answer.html', { 'title': u'Edit Answer', 'question': answer.question, 'answer': answer, 'revision_form': revision_form, 'form': form, 'preview': preview, }, context_instance=RequestContext(request))
def _edit_question(request, question): """ Allows the user to edit a Question's title, text and tags. If the Question is not already in wiki mode, the user can put it in wiki mode, or it will automatically be put in wiki mode if the question has been edited five times by the person who asked it, or has been edited by four different users. """ latest_revision = question.get_latest_revision() preview = None revision_form = None if request.method == 'POST': if 'select_revision' in request.POST: # The user submitted to change the revision to start editing from revision_form = RevisionForm(question, latest_revision, request.POST) if revision_form.is_valid(): # Replace Question details with those from the selected revision form = EditQuestionForm(question, QuestionRevision.objects.get(question=question, revision=revision_form.cleaned_data['revision'])) else: # Make sure we keep a hold of the user's other input, even # though they appear to be messing about. form = EditQuestionForm(question, latest_revision, request.POST) else: # Always check modifications against the latest revision form = EditQuestionForm(question, latest_revision, request.POST) if form.is_valid(): html = sanitize_html( markdowner.convert(form.cleaned_data['text'])) if 'preview' in request.POST: # The user submitted to preview the formatted question preview = mark_safe(html) elif 'submit' in request.POST: if form.has_changed(): edited_at = datetime.datetime.now() tags_changed = (latest_revision.tagnames != form.cleaned_data['tags']) tags_updated = False # Update the Question itself updated_fields = { 'title': form.cleaned_data['title'], 'last_edited_at': edited_at, 'last_edited_by': request.user, 'last_activity_at': edited_at, 'last_activity_by': request.user, 'tagnames': form.cleaned_data['tags'], 'summary': strip_tags(html)[:180], 'html': html, } if ('wiki' in form.cleaned_data and form.cleaned_data['wiki']): updated_fields['wiki'] = True updated_fields['wikified_at'] = edited_at Question.objects.filter( id=question.id).update(**updated_fields) # Update the Question's tag associations if tags_changed: tags_updated = Question.objects.update_tags( question, question.tagnames, request.user) # Create a new revision revision = QuestionRevision( question = question, title = form.cleaned_data['title'], author = request.user, revised_at = edited_at, tagnames = form.cleaned_data['tags'], text = form.cleaned_data['text'] ) if form.cleaned_data['summary']: revision.summary = form.cleaned_data['summary'] else: revision.summary = \ diff.generate_question_revision_summary( latest_revision, revision, ('wiki' in updated_fields)) revision.save() # TODO 5 body edits by the author = automatic wiki mode # TODO 4 individual editors = automatic wiki mode # TODO Badges related to Tag usage # TODO Badges related to editing Questions return HttpResponseRedirect(question.get_absolute_url()) else: if 'revision' in request.GET: revision_form = RevisionForm(question, latest_revision, request.GET) if revision_form.is_valid(): # Replace Question details with those from the selected revision form = EditQuestionForm(question, QuestionRevision.objects.get(question=question, revision=revision_form.cleaned_data['revision'])) else: revision_form = RevisionForm(question, latest_revision) form = EditQuestionForm(question, latest_revision) if revision_form is None: # We're about to redisplay after a POST where we didn't care which # revision was selected - make sure the revision the user started from # is still selected on redisplay. revision_form = RevisionForm(question, latest_revision, request.POST) return render_to_response('edit_question.html', { 'title': u'Edit Question', 'question': question, 'revision_form': revision_form, 'form': form, 'preview': preview, }, context_instance=RequestContext(request))