summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-07-26 11:00:48 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-07-26 11:00:48 -0400
commit6849a323ef40a1a4b261fdcf0905fc13334d3c6d (patch)
treef1e40f8aebfa5bd0345c7a63e497e4007444aeb4
parentfc0dff78e5d1b0337d9649e6316dfb92a9cccdc8 (diff)
downloadaskbot-6849a323ef40a1a4b261fdcf0905fc13334d3c6d.tar.gz
askbot-6849a323ef40a1a4b261fdcf0905fc13334d3c6d.tar.bz2
askbot-6849a323ef40a1a4b261fdcf0905fc13334d3c6d.zip
draft saving starts working, incomplete for answers
-rw-r--r--askbot/forms.py17
-rw-r--r--askbot/migrations/0131_auto__add_draftquestion__add_draftanswer.py356
-rw-r--r--askbot/models/__init__.py4
-rw-r--r--askbot/models/post.py14
-rw-r--r--askbot/models/question.py13
-rw-r--r--askbot/skins/common/media/js/post.js136
-rw-r--r--askbot/skins/common/media/js/utils.js14
-rw-r--r--askbot/skins/default/templates/ask.html12
-rw-r--r--askbot/skins/default/templates/meta/html_head_javascript.html1
-rw-r--r--askbot/skins/default/templates/question.html2
-rw-r--r--askbot/skins/default/templates/question/javascript.html7
-rw-r--r--askbot/skins/default/templates/widgets/ask_form.html1
-rw-r--r--askbot/urls.py10
-rw-r--r--askbot/views/commands.py60
-rw-r--r--askbot/views/writers.py22
15 files changed, 660 insertions, 9 deletions
diff --git a/askbot/forms.py b/askbot/forms.py
index 9fc66f45..fe65cd02 100644
--- a/askbot/forms.py
+++ b/askbot/forms.py
@@ -218,7 +218,7 @@ class TitleField(forms.CharField):
"""Fild receiving question title"""
def __init__(self, *args, **kwargs):
super(TitleField, self).__init__(*args, **kwargs)
- self.required = True
+ self.required = kwargs.get('required', True)
self.widget = forms.TextInput(
attrs={'size': 70, 'autocomplete': 'off'}
)
@@ -271,7 +271,7 @@ class EditorField(forms.CharField):
def __init__(self, *args, **kwargs):
super(EditorField, self).__init__(*args, **kwargs)
- self.required = True
+ self.required = kwargs.get('required', True)
self.widget = forms.Textarea(attrs={'id': 'editor'})
self.label = _('content')
self.help_text = u''
@@ -756,6 +756,19 @@ class PostPrivatelyForm(forms.Form, FormWithHideableFields):
return self.cleaned_data['post_privately']
+class DraftQuestionForm(forms.Form):
+ """No real validation required for this form"""
+ title = forms.CharField(required=False)
+ text = forms.CharField(required=False)
+ tagnames = forms.CharField(required=False)
+
+
+class DraftAnswerForm(forms.Form):
+ """Only thread_id is required"""
+ thread_id = forms.IntegerField()
+ text = forms.CharField(required=False)
+
+
class AskForm(PostPrivatelyForm):
"""the form used to askbot questions
field ask_anonymously is shown to the user if the
diff --git a/askbot/migrations/0131_auto__add_draftquestion__add_draftanswer.py b/askbot/migrations/0131_auto__add_draftquestion__add_draftanswer.py
new file mode 100644
index 00000000..bceca754
--- /dev/null
+++ b/askbot/migrations/0131_auto__add_draftquestion__add_draftanswer.py
@@ -0,0 +1,356 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding model 'DraftQuestion'
+ db.create_table('askbot_draftquestion', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('author', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['auth.User'])),
+ ('title', self.gf('django.db.models.fields.CharField')(max_length=300, null=True)),
+ ('text', self.gf('django.db.models.fields.TextField')(null=True)),
+ ('tagnames', self.gf('django.db.models.fields.CharField')(max_length=125, null=True)),
+ ))
+ db.send_create_signal('askbot', ['DraftQuestion'])
+
+ # Adding model 'DraftAnswer'
+ db.create_table('askbot_draftanswer', (
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('thread', self.gf('django.db.models.fields.related.ForeignKey')(related_name='draft_answers', to=orm['askbot.Thread'])),
+ ('author', self.gf('django.db.models.fields.related.ForeignKey')(related_name='draft_answers', to=orm['auth.User'])),
+ ('text', self.gf('django.db.models.fields.TextField')(null=True)),
+ ))
+ db.send_create_signal('askbot', ['DraftAnswer'])
+
+ def backwards(self, orm):
+ # Deleting model 'DraftQuestion'
+ db.delete_table('askbot_draftquestion')
+
+ # Deleting model 'DraftAnswer'
+ db.delete_table('askbot_draftanswer')
+
+ models = {
+ 'askbot.activity': {
+ 'Meta': {'object_name': 'Activity', 'db_table': "u'activity'"},
+ 'active_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'activity_type': ('django.db.models.fields.SmallIntegerField', [], {}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_auditted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Post']", 'null': 'True'}),
+ 'receiving_users': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'received_activity'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
+ 'recipients': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'incoming_activity'", 'symmetrical': 'False', 'through': "orm['askbot.ActivityAuditStatus']", 'to': "orm['auth.User']"}),
+ 'summary': ('django.db.models.fields.TextField', [], {'default': "''"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'askbot.activityauditstatus': {
+ 'Meta': {'unique_together': "(('user', 'activity'),)", 'object_name': 'ActivityAuditStatus'},
+ 'activity': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Activity']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'askbot.anonymousanswer': {
+ 'Meta': {'object_name': 'AnonymousAnswer'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ip_addr': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'anonymous_answers'", 'to': "orm['askbot.Post']"}),
+ 'session_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}),
+ 'text': ('django.db.models.fields.TextField', [], {}),
+ 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'askbot.anonymousquestion': {
+ 'Meta': {'object_name': 'AnonymousQuestion'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ip_addr': ('django.db.models.fields.IPAddressField', [], {'max_length': '15'}),
+ 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'session_key': ('django.db.models.fields.CharField', [], {'max_length': '40'}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'text': ('django.db.models.fields.TextField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'})
+ },
+ 'askbot.award': {
+ 'Meta': {'object_name': 'Award', 'db_table': "u'award'"},
+ 'awarded_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'badge': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_badge'", 'to': "orm['askbot.BadgeData']"}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'notified': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'object_id': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'award_user'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.badgedata': {
+ 'Meta': {'ordering': "('slug',)", 'object_name': 'BadgeData'},
+ 'awarded_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'awarded_to': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'badges'", 'symmetrical': 'False', 'through': "orm['askbot.Award']", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'slug': ('django.db.models.fields.SlugField', [], {'unique': 'True', 'max_length': '50'})
+ },
+ 'askbot.draftanswer': {
+ 'Meta': {'object_name': 'DraftAnswer'},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'draft_answers'", 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'thread': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'draft_answers'", 'to': "orm['askbot.Thread']"})
+ },
+ 'askbot.draftquestion': {
+ 'Meta': {'object_name': 'DraftQuestion'},
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125', 'null': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True'})
+ },
+ 'askbot.emailfeedsetting': {
+ 'Meta': {'unique_together': "(('subscriber', 'feed_type'),)", 'object_name': 'EmailFeedSetting'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'feed_type': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
+ 'frequency': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '8'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'reported_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}),
+ 'subscriber': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'notification_subscriptions'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.favoritequestion': {
+ 'Meta': {'object_name': 'FavoriteQuestion', 'db_table': "u'favorite_question'"},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'thread': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Thread']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_favorite_questions'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.groupmembership': {
+ 'Meta': {'unique_together': "(('group', 'user'),)", 'object_name': 'GroupMembership'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_memberships'", 'to': "orm['askbot.Tag']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'group_memberships'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.groupprofile': {
+ 'Meta': {'object_name': 'GroupProfile'},
+ 'group_tag': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'group_profile'", 'unique': 'True', 'to': "orm['askbot.Tag']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_open': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
+ 'moderate_email': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'preapproved_email_domains': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'}),
+ 'preapproved_emails': ('django.db.models.fields.TextField', [], {'default': "''", 'null': 'True', 'blank': 'True'})
+ },
+ 'askbot.markedtag': {
+ 'Meta': {'object_name': 'MarkedTag'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'reason': ('django.db.models.fields.CharField', [], {'max_length': '16'}),
+ 'tag': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'user_selections'", 'to': "orm['askbot.Tag']"}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'tag_selections'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.post': {
+ 'Meta': {'object_name': 'Post'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'posts'", 'to': "orm['auth.User']"}),
+ 'comment_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
+ 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_posts'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'group_posts'", 'symmetrical': 'False', 'to': "orm['askbot.Tag']"}),
+ 'html': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_edited_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'last_edited_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'last_edited_posts'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'locked': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'locked_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'locked_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'locked_posts'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'offensive_flag_count': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'old_answer_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+ 'old_comment_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+ 'old_question_id': ('django.db.models.fields.PositiveIntegerField', [], {'default': 'None', 'unique': 'True', 'null': 'True', 'blank': 'True'}),
+ 'parent': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'comments'", 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'post_type': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '180'}),
+ 'text': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'thread': ('django.db.models.fields.related.ForeignKey', [], {'default': 'None', 'related_name': "'posts'", 'null': 'True', 'blank': 'True', 'to': "orm['askbot.Thread']"}),
+ 'vote_down_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'vote_up_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'wiki': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'wikified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'})
+ },
+ 'askbot.postflagreason': {
+ 'Meta': {'object_name': 'PostFlagReason'},
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"}),
+ 'details': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'post_reject_reasons'", 'to': "orm['askbot.Post']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '128'})
+ },
+ 'askbot.postrevision': {
+ 'Meta': {'ordering': "('-revision',)", 'unique_together': "(('post', 'revision'),)", 'object_name': 'PostRevision'},
+ 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'False', 'db_index': 'True'}),
+ 'approved_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'approved_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+ 'author': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'postrevisions'", 'to': "orm['auth.User']"}),
+ 'by_email': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'email_address': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'is_anonymous': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'post': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'revisions'", 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'revised_at': ('django.db.models.fields.DateTimeField', [], {}),
+ 'revision': ('django.db.models.fields.PositiveIntegerField', [], {}),
+ 'summary': ('django.db.models.fields.CharField', [], {'max_length': '300', 'blank': 'True'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '125', 'blank': 'True'}),
+ 'text': ('django.db.models.fields.TextField', [], {}),
+ 'title': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '300', 'blank': 'True'})
+ },
+ 'askbot.questionview': {
+ 'Meta': {'object_name': 'QuestionView'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'viewed'", 'to': "orm['askbot.Post']"}),
+ 'when': ('django.db.models.fields.DateTimeField', [], {}),
+ 'who': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'question_views'", 'to': "orm['auth.User']"})
+ },
+ 'askbot.replyaddress': {
+ 'Meta': {'object_name': 'ReplyAddress'},
+ 'address': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '25'}),
+ 'allowed_from_email': ('django.db.models.fields.EmailField', [], {'max_length': '150'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'reply_addresses'", 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'reply_action': ('django.db.models.fields.CharField', [], {'default': "'auto_answer_or_comment'", 'max_length': '32'}),
+ 'response_post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'edit_addresses'", 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'used_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'askbot.repute': {
+ 'Meta': {'object_name': 'Repute', 'db_table': "u'repute'"},
+ 'comment': ('django.db.models.fields.CharField', [], {'max_length': '128', 'null': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'negative': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'positive': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'question': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Post']", 'null': 'True', 'blank': 'True'}),
+ 'reputation': ('django.db.models.fields.IntegerField', [], {'default': '1'}),
+ 'reputation_type': ('django.db.models.fields.SmallIntegerField', [], {}),
+ 'reputed_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ 'askbot.tag': {
+ 'Meta': {'ordering': "('-used_count', 'name')", 'object_name': 'Tag', 'db_table': "u'tag'"},
+ 'created_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'created_tags'", 'to': "orm['auth.User']"}),
+ 'deleted': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'deleted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'deleted_by': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'deleted_tags'", 'null': 'True', 'to': "orm['auth.User']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '255'}),
+ 'status': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
+ 'suggested_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'suggested_tags'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
+ 'tag_wiki': ('django.db.models.fields.related.OneToOneField', [], {'related_name': "'described_tag'", 'unique': 'True', 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'used_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
+ },
+ 'askbot.thread': {
+ 'Meta': {'object_name': 'Thread'},
+ 'accepted_answer': ('django.db.models.fields.related.ForeignKey', [], {'blank': 'True', 'related_name': "'+'", 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'added_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'answer_accepted_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'answer_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'approved': ('django.db.models.fields.BooleanField', [], {'default': 'True', 'db_index': 'True'}),
+ 'close_reason': ('django.db.models.fields.SmallIntegerField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'closed_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True', 'blank': 'True'}),
+ 'closed_by': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']", 'null': 'True', 'blank': 'True'}),
+ 'favorited_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'unused_favorite_threads'", 'symmetrical': 'False', 'through': "orm['askbot.FavoriteQuestion']", 'to': "orm['auth.User']"}),
+ 'favourite_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'}),
+ 'followed_by': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'followed_threads'", 'symmetrical': 'False', 'to': "orm['auth.User']"}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'group_threads'", 'symmetrical': 'False', 'to': "orm['askbot.Tag']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'last_activity_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_activity_by': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'unused_last_active_in_threads'", 'to': "orm['auth.User']"}),
+ 'score': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '125'}),
+ 'tags': ('django.db.models.fields.related.ManyToManyField', [], {'related_name': "'threads'", 'symmetrical': 'False', 'to': "orm['askbot.Tag']"}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '300'}),
+ 'view_count': ('django.db.models.fields.PositiveIntegerField', [], {'default': '0'})
+ },
+ 'askbot.vote': {
+ 'Meta': {'unique_together': "(('user', 'voted_post'),)", 'object_name': 'Vote', 'db_table': "u'vote'"},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['auth.User']"}),
+ 'vote': ('django.db.models.fields.SmallIntegerField', [], {}),
+ 'voted_at': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'voted_post': ('django.db.models.fields.related.ForeignKey', [], {'related_name': "'votes'", 'to': "orm['askbot.Post']"})
+ },
+ 'auth.group': {
+ 'Meta': {'object_name': 'Group'},
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '80'}),
+ 'permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'})
+ },
+ 'auth.permission': {
+ 'Meta': {'ordering': "('content_type__app_label', 'content_type__model', 'codename')", 'unique_together': "(('content_type', 'codename'),)", 'object_name': 'Permission'},
+ 'codename': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'content_type': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['contenttypes.ContentType']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '50'})
+ },
+ 'auth.user': {
+ 'Meta': {'object_name': 'User'},
+ 'about': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'avatar_type': ('django.db.models.fields.CharField', [], {'default': "'n'", 'max_length': '1'}),
+ 'bronze': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'consecutive_days_visit_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'country': ('django_countries.fields.CountryField', [], {'max_length': '2', 'blank': 'True'}),
+ 'date_joined': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'date_of_birth': ('django.db.models.fields.DateField', [], {'null': 'True', 'blank': 'True'}),
+ 'display_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'blank': 'True'}),
+ 'email_isvalid': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'email_key': ('django.db.models.fields.CharField', [], {'max_length': '32', 'null': 'True'}),
+ 'email_signature': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'email_tag_filter_strategy': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'}),
+ 'first_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'gold': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'gravatar': ('django.db.models.fields.CharField', [], {'max_length': '32'}),
+ 'groups': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Group']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'ignored_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'interesting_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'is_active': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'is_staff': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'is_superuser': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'last_login': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'last_name': ('django.db.models.fields.CharField', [], {'max_length': '30', 'blank': 'True'}),
+ 'last_seen': ('django.db.models.fields.DateTimeField', [], {'default': 'datetime.datetime.now'}),
+ 'location': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+ 'new_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'password': ('django.db.models.fields.CharField', [], {'max_length': '128'}),
+ 'questions_per_page': ('django.db.models.fields.SmallIntegerField', [], {'default': '10'}),
+ 'real_name': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}),
+ 'reputation': ('django.db.models.fields.PositiveIntegerField', [], {'default': '1'}),
+ 'seen_response_count': ('django.db.models.fields.IntegerField', [], {'default': '0'}),
+ 'show_country': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'show_marked_tags': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'silver': ('django.db.models.fields.SmallIntegerField', [], {'default': '0'}),
+ 'status': ('django.db.models.fields.CharField', [], {'default': "'w'", 'max_length': '2'}),
+ 'subscribed_tags': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'user_permissions': ('django.db.models.fields.related.ManyToManyField', [], {'to': "orm['auth.Permission']", 'symmetrical': 'False', 'blank': 'True'}),
+ 'username': ('django.db.models.fields.CharField', [], {'unique': 'True', 'max_length': '30'}),
+ 'website': ('django.db.models.fields.URLField', [], {'max_length': '200', 'blank': 'True'})
+ },
+ 'contenttypes.contenttype': {
+ 'Meta': {'ordering': "('name',)", 'unique_together': "(('app_label', 'model'),)", 'object_name': 'ContentType', 'db_table': "'django_content_type'"},
+ 'app_label': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'model': ('django.db.models.fields.CharField', [], {'max_length': '100'}),
+ 'name': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ }
+ }
+
+ complete_apps = ['askbot'] \ No newline at end of file
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index d5c13a0f..4fbabe9d 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -28,12 +28,14 @@ from askbot.models.question import Thread
from askbot.skins import utils as skin_utils
from askbot.mail import messages
from askbot.models.question import QuestionView, AnonymousQuestion
+from askbot.models.question import DraftQuestion
from askbot.models.question import FavoriteQuestion
from askbot.models.tag import Tag, MarkedTag
from askbot.models.tag import get_group_names, get_groups
from askbot.models.user import EmailFeedSetting, ActivityAuditStatus, Activity
from askbot.models.user import GroupMembership, GroupProfile
from askbot.models.post import Post, PostRevision, PostFlagReason, AnonymousAnswer
+from askbot.models.post import DraftAnswer
from askbot.models.reply_by_email import ReplyAddress
from askbot.models import signals
from askbot.models.badges import award_badges_signal, get_badge, BadgeData
@@ -3394,8 +3396,10 @@ __all__ = [
'QuestionView',
'FavoriteQuestion',
'AnonymousQuestion',
+ 'DraftQuestion',
'AnonymousAnswer',
+ 'DraftAnswer',
'Post',
'PostRevision',
diff --git a/askbot/models/post.py b/askbot/models/post.py
index e7624b1e..0ec6927a 100644
--- a/askbot/models/post.py
+++ b/askbot/models/post.py
@@ -1998,7 +1998,21 @@ class PostFlagReason(models.Model):
app_label = 'askbot'
+class DraftAnswer(models.Model):
+ """Provides space for draft answers,
+ note that unlike ``AnonymousAnswer`` the foreign key
+ is going to ``Thread`` as it should.
+ """
+ thread = models.ForeignKey('Thread', related_name='draft_answers')
+ author = models.ForeignKey(User, related_name='draft_answers')
+ text = models.TextField(null=True)
+
+ class Meta:
+ app_label = 'askbot'
+
+
class AnonymousAnswer(DraftContent):
+ """Todo: re-route the foreign key to ``Thread``"""
question = models.ForeignKey(Post, related_name='anonymous_answers')
def publish(self, user):
diff --git a/askbot/models/question.py b/askbot/models/question.py
index d10b2c8f..7063b843 100644
--- a/askbot/models/question.py
+++ b/askbot/models/question.py
@@ -1068,6 +1068,19 @@ class FavoriteQuestion(models.Model):
return '[%s] favorited at %s' %(self.user, self.added_at)
+class DraftQuestion(models.Model):
+ """Provides space to solve unpublished draft
+ questions. Contents is used to populate the Ask form.
+ """
+ author = models.ForeignKey(User)
+ title = models.CharField(max_length=300, null=True)
+ text = models.TextField(null=True)
+ tagnames = models.CharField(max_length=125, null=True)
+
+ class Meta:
+ app_label = 'askbot'
+
+
class AnonymousQuestion(DraftContent):
"""question that was asked before logging in
maybe the name is a little misleading, the user still
diff --git a/askbot/skins/common/media/js/post.js b/askbot/skins/common/media/js/post.js
index 5b30b2bc..e8d521ed 100644
--- a/askbot/skins/common/media/js/post.js
+++ b/askbot/skins/common/media/js/post.js
@@ -206,6 +206,142 @@ var CPValidator = function(){
/**
* @constructor
+ */
+var DraftPost = function() {
+ WrappedElement.call(this);
+};
+inherits(DraftPost, WrappedElement);
+
+/**
+ * @return {string}
+ */
+DraftPost.prototype.getUrl = function() {
+ throw 'Not Implemented';
+};
+
+/**
+ * @return {boolean}
+ */
+DraftPost.prototype.shouldSave = function() {
+ throw 'Not Implemented';
+};
+
+/**
+ * @return {object} data dict
+ */
+DraftPost.prototype.getData = function() {
+ throw 'Not Implemented';
+};
+
+DraftPost.prototype.backupData = function() {
+ this._old_data = this.getData();
+};
+
+
+DraftPost.prototype.getSaveHandler = function() {
+ var me = this;
+ return function(save_synchronously) {
+ if (me.shouldSave()) {
+ $.ajax({
+ type: 'POST',
+ cache: false,
+ dataType: 'json',
+ async: save_synchronously ? false : true,
+ url: me.getUrl(),
+ data: me.getData(),
+ success: function(data) {
+ if (data['success'] && !save_synchronously) {
+ notify.show(gettext('Draft saved'), true);
+ }
+ me.backupData();
+ }
+ });
+ }
+ };
+};
+
+DraftPost.prototype.decorate = function(element) {
+ this._element = element;
+ this.assignContentElements();
+ this.backupData();
+ setInterval(this.getSaveHandler(), 5000);
+ var me = this;
+ window.onbeforeunload = function() {
+ var saveHandler = me.getSaveHandler();
+ saveHandler(true);
+ var msg = gettext("%s, we've saved your draft, but...");
+ return interpolate(msg, [askbot['data']['userName']]);
+ };
+};
+
+
+/**
+ * @contstructor
+ */
+var DraftQuestion = function() {
+ DraftPost.call(this);
+};
+inherits(DraftQuestion, DraftPost);
+
+DraftQuestion.prototype.getUrl = function() {
+ return askbot['urls']['saveDraftQuestion'];
+};
+
+DraftQuestion.prototype.shouldSave = function() {
+ var newd = this.getData();
+ var oldd = this._old_data;
+ return (
+ newd['title'] !== oldd['title'] ||
+ newd['text'] !== oldd['text'] ||
+ newd['tagnames'] !== oldd['tagnames']
+ );
+};
+
+DraftQuestion.prototype.getData = function() {
+ return {
+ 'title': this._title_element.val(),
+ 'text': this._text_element.val(),
+ 'tagnames': this._tagnames_element.val()
+ };
+};
+
+DraftQuestion.prototype.assignContentElements = function() {
+ this._title_element = $('#id_title');
+ this._text_element = $('#editor');
+ this._tagnames_element = $('#id_tags');
+};
+
+var DraftAnswer = function() {
+ DraftPost.call(this);
+};
+inherits(DraftAnswer, DraftPost);
+
+DraftAnswer.prototype.setThreadId = function(id) {
+ this._threadId = id;
+};
+
+DraftAnswer.prototype.getUrl = function() {
+ return askbot['urls']['saveDraftAnswer'];
+};
+
+DraftAnswer.prototype.shouldSave = function() {
+ return this.getData()['text'] !== this._old_data['text'];
+};
+
+DraftAnswer.prototype.getData = function() {
+ return {
+ 'text': this._textElement.val(),
+ 'thread_id': this._threadId
+ };
+};
+
+DraftAnswer.prototype.assignContentElements = function() {
+ this._textElement = $('#editor');
+};
+
+
+/**
+ * @constructor
* @extends {SimpleControl}
* @param {Comment} comment to upvote
*/
diff --git a/askbot/skins/common/media/js/utils.js b/askbot/skins/common/media/js/utils.js
index da0e029b..30d2a64e 100644
--- a/askbot/skins/common/media/js/utils.js
+++ b/askbot/skins/common/media/js/utils.js
@@ -114,7 +114,7 @@ var setCheckBoxesIn = function(selector, value){
var notify = function() {
var visible = false;
return {
- show: function(html) {
+ show: function(html, autohide) {
if (html) {
$("body").addClass('user-messages');
var par = $('<p class="notification"></p>');
@@ -123,7 +123,19 @@ var notify = function() {
}
$(".notify").fadeIn("slow");
visible = true;
+ if (autohide) {
+ setTimeout(
+ function() {
+ notify.close(false);
+ notify.clear();
+ },
+ 3000
+ );
+ }
},
+ clear: function() {
+ $('.notify').empty();
+ },
close: function(doPostback) {
if (doPostback) {
$.post(
diff --git a/askbot/skins/default/templates/ask.html b/askbot/skins/default/templates/ask.html
index f0dae0ce..7826923b 100644
--- a/askbot/skins/default/templates/ask.html
+++ b/askbot/skins/default/templates/ask.html
@@ -36,6 +36,7 @@
{% endif %}
<script type='text/javascript'>
askbot['urls']['api_get_questions'] = '{% url api_get_questions %}';
+ askbot['urls']['saveDraftQuestion'] = '{% url save_draft_question %}';
{% if settings.ENABLE_MATHJAX or settings.MARKUP_CODE_FRIENDLY %}
var codeFriendlyMarkdown = true;
{% else %}
@@ -66,6 +67,17 @@
setupFormValidation($("#fmask"), CPValidator.getQuestionFormRules(), CPValidator.getQuestionFormMessages());
lanai.highlightSyntax();
+
+ if (askbot['data']['userIsAuthenticated']) {
+ var draftHandler = new DraftQuestion();
+ draftHandler.decorate($(document));
+ window.onbeforeunload = function() {
+ var saveHandler = draftHandler.getSaveHandler();
+ saveHandler(true);
+ var msg = gettext("%s, we've saved your draft, but...");
+ return interpolate(msg, [askbot['data']['userName']]);
+ };
+ }
});
</script>
{% endblock %}
diff --git a/askbot/skins/default/templates/meta/html_head_javascript.html b/askbot/skins/default/templates/meta/html_head_javascript.html
index 6e480f8b..881244ed 100644
--- a/askbot/skins/default/templates/meta/html_head_javascript.html
+++ b/askbot/skins/default/templates/meta/html_head_javascript.html
@@ -5,6 +5,7 @@
{% if request.user.is_authenticated() %}
askbot['data']['userIsAuthenticated'] = true;
askbot['data']['userId'] = {{request.user.id}};
+ askbot['data']['userName'] = '{{ request.user.username }}';
askbot['data']['userIsAdminOrMod'] = {% if
request.user.is_administrator()
or request.user.is_moderator()
diff --git a/askbot/skins/default/templates/question.html b/askbot/skins/default/templates/question.html
index 511c5086..c810aecb 100644
--- a/askbot/skins/default/templates/question.html
+++ b/askbot/skins/default/templates/question.html
@@ -94,7 +94,7 @@
{% if user_can_post_comment %}
can_add = true;
{% else %}
- if (post_id in data['user_posts']){
+ if (data['user_posts'] && post_id in data['user_posts']){
can_add = true;
}
{% endif %}
diff --git a/askbot/skins/default/templates/question/javascript.html b/askbot/skins/default/templates/question/javascript.html
index e76849c9..003d7f70 100644
--- a/askbot/skins/default/templates/question/javascript.html
+++ b/askbot/skins/default/templates/question/javascript.html
@@ -10,6 +10,7 @@
askbot['urls']['editComment'] = '{% url edit_comment %}';
askbot['urls']['deleteComment'] = '{% url delete_comment %}';
askbot['urls']['getComment'] = '{% url get_comment %}';
+ askbot['urls']['saveDraftAnswer'] = '{% url save_draft_answer %}';
askbot['urls']['question_url_template'] = scriptUrl + '{{ 'question/'|transurl }}{{ "{{QuestionID}}/{{questionSlug}}" }}';{# yes it needs to be that whacky #}
askbot['urls']['vote_url_template'] = scriptUrl + '{{ 'questions/'|transurl }}{{ "{{QuestionID}}/" }}{{ 'vote/'|transurl }}';
askbot['urls']['user_signin'] = '{{ settings.LOGIN_URL }}';
@@ -63,6 +64,12 @@
$("#fmanswer_button").hide();
});
{%endif%}
+
+ if (askbot['data']['userIsAuthenticated']) {
+ var draftHandler = new DraftAnswer();
+ draftHandler.setThreadId({{ thread.id }});
+ draftHandler.decorate($(document));
+ }
});
$(window).bind('hashchange', animate_hashes);
diff --git a/askbot/skins/default/templates/widgets/ask_form.html b/askbot/skins/default/templates/widgets/ask_form.html
index 38613a3c..eaa3e154 100644
--- a/askbot/skins/default/templates/widgets/ask_form.html
+++ b/askbot/skins/default/templates/widgets/ask_form.html
@@ -3,7 +3,6 @@
<div class="form-item">
<div id="askFormBar">
{% if not request.user.is_authenticated() %}
- <p>{% trans %}login to post question info{% endtrans %}</p>
<p>{% trans %}<span class=\"strong big\">You are welcome to start submitting your question anonymously</span>. When you submit the post, you will be redirected to the login/signup page. Your question will be saved in the current session and will be published after you log in. Login/signup process is very simple. Login takes about 30 seconds, initial signup takes a minute or less.{% endtrans %}</p>
{% else %}
{% if settings.EMAIL_VALIDATION %}
diff --git a/askbot/urls.py b/askbot/urls.py
index 726722ff..c7c9c9f8 100644
--- a/askbot/urls.py
+++ b/askbot/urls.py
@@ -79,6 +79,16 @@ urlpatterns = patterns('',
name = 'api_get_questions'
),
url(
+ r'^save-draft-question/',
+ views.commands.save_draft_question,
+ name = 'save_draft_question'
+ ),
+ url(
+ r'^save-draft-answer/',
+ views.commands.save_draft_answer,
+ name = 'save_draft_answer'
+ ),
+ url(
r'^%s%s$' % (_('questions/'), _('ask/')),
views.writers.ask,
name='ask'
diff --git a/askbot/views/commands.py b/askbot/views/commands.py
index 56848267..d4e7304e 100644
--- a/askbot/views/commands.py
+++ b/askbot/views/commands.py
@@ -1056,3 +1056,63 @@ def moderate_suggested_tag(request):
tag.delete()
else:
raise Exception(forms.format_form_errors(form))
+
+
+@csrf.csrf_exempt
+@decorators.ajax_only
+@decorators.post_only
+def save_draft_question(request):
+ """saves draft questions"""
+ #todo: allow drafts for anonymous users
+ if request.user.is_anonymous():
+ return
+
+ form = forms.DraftQuestionForm(request.POST)
+ if form.is_valid():
+ title = form.cleaned_data.get('title', '')
+ text = form.cleaned_data.get('text', '')
+ tagnames = form.cleaned_data.get('tagnames', '')
+ if title or text or tagnames:
+ try:
+ draft = models.DraftQuestion.objects.get(author=request.user)
+ except models.DraftQuestion.DoesNotExist:
+ draft = models.DraftQuestion()
+
+ draft.title = title
+ draft.text = text
+ draft.tagnames = tagnames
+ draft.author = request.user
+ draft.save()
+
+
+@csrf.csrf_exempt
+@decorators.ajax_only
+@decorators.post_only
+def save_draft_answer(request):
+ """saves draft answers"""
+ #todo: allow drafts for anonymous users
+ if request.user.is_anonymous():
+ return
+
+ import pdb
+ pdb.set_trace()
+
+ form = forms.DraftAnswerForm(request.POST)
+ if form.is_valid():
+ thread_id = form.cleaned_data['thread_id']
+ try:
+ thread = models.Thread.objects.get(id=thread_id)
+ except models.Thread.DoesNotExist:
+ return
+ try:
+ draft = models.DraftAnswer.objects.get(
+ thread=thread,
+ author=request.user
+ )
+ except models.DraftAnswer.DoesNotExist:
+ draft = models.DraftAnswer()
+
+ draft.author = request.user
+ draft.thread = thread
+ draft.text = form.cleaned_data.get('text', '')
+ draft.save()
diff --git a/askbot/views/writers.py b/askbot/views/writers.py
index 2791557e..b4c58547 100644
--- a/askbot/views/writers.py
+++ b/askbot/views/writers.py
@@ -222,6 +222,10 @@ def ask(request):#view used to ask a new question
group_id = form.cleaned_data.get('group_id', None)
if request.user.is_authenticated():
+ drafts = models.DraftQuestion.objects.filter(
+ author=request.user
+ )
+ drafts.delete()
try:
question = request.user.post_question(
title = title,
@@ -258,11 +262,21 @@ def ask(request):#view used to ask a new question
if request.method == 'GET':
form = forms.AskForm()
+ draft_title = ''
+ draft_text = ''
+ draft_tagnames = ''
+ if request.user.is_authenticated():
+ drafts = models.DraftQuestion.objects.filter(author=request.user)
+ if len(drafts) > 0:
+ draft = drafts[0]
+ draft_title = draft.title
+ draft_text = draft.text
+ draft_tagnames = draft.tagnames
form.initial = {
- 'title': request.REQUEST.get('title', ''),
- 'text': request.REQUEST.get('text', ''),
- 'tags': request.REQUEST.get('tags', ''),
+ 'title': request.REQUEST.get('title', draft_title),
+ 'text': request.REQUEST.get('text', draft_text),
+ 'tags': request.REQUEST.get('tags', draft_tagnames),
'wiki': request.REQUEST.get('wiki', False),
'ask_anonymously': request.REQUEST.get('ask_anonymousy', False),
'post_privately': request.REQUEST.get('post_privately', False)
@@ -271,7 +285,7 @@ def ask(request):#view used to ask a new question
try:
group_id = int(request.GET.get('group_id', None))
form.initial['group_id'] = group_id
- except Exeption:
+ except Exception:
pass
data = {