summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdolfo Fitoria <adolfo.fitoria@gmail.com>2012-11-01 06:02:17 -0600
committerAdolfo Fitoria <adolfo.fitoria@gmail.com>2012-11-01 06:02:17 -0600
commitdfd8e087cd734c5b01f2d5e3fe1b7f44b8ceef97 (patch)
tree21f89fb90c33230a43aef5042f14344769191c56
parent7726537fc9061cecc3a67c454c0dcb8eb7d579cd (diff)
parent991ba9083e23837d1224f267f2a0ef641d8cbe16 (diff)
downloadaskbot-dfd8e087cd734c5b01f2d5e3fe1b7f44b8ceef97.tar.gz
askbot-dfd8e087cd734c5b01f2d5e3fe1b7f44b8ceef97.tar.bz2
askbot-dfd8e087cd734c5b01f2d5e3fe1b7f44b8ceef97.zip
Merge branch 'master' of github.com:ASKBOT/askbot-devel
-rw-r--r--askbot/conf/minimum_reputation.py15
-rw-r--r--askbot/doc/source/changelog.rst1
-rw-r--r--askbot/forms.py55
-rw-r--r--askbot/mail/__init__.py30
-rw-r--r--askbot/migrations/0155_remove_unused_internal_tags.py387
-rw-r--r--askbot/models/__init__.py4
-rw-r--r--askbot/models/post.py11
-rw-r--r--askbot/models/question.py5
-rw-r--r--askbot/models/tag.py1
-rw-r--r--askbot/tasks.py1
-rw-r--r--askbot/templates/answer_edit.html5
-rw-r--r--askbot/templates/question/new_answer_form.html5
-rw-r--r--askbot/templates/question_edit.html5
-rw-r--r--askbot/templates/widgets/ask_form.html5
-rw-r--r--askbot/tests/email_parsing_tests.py8
-rw-r--r--askbot/tests/form_tests.py56
-rw-r--r--askbot/views/commands.py2
-rw-r--r--askbot/views/readers.py2
-rw-r--r--askbot/views/widgets.py12
-rw-r--r--askbot/views/writers.py45
20 files changed, 572 insertions, 83 deletions
diff --git a/askbot/conf/minimum_reputation.py b/askbot/conf/minimum_reputation.py
index 359855c9..fee880ac 100644
--- a/askbot/conf/minimum_reputation.py
+++ b/askbot/conf/minimum_reputation.py
@@ -108,8 +108,21 @@ settings.register(
livesettings.IntegerValue(
MIN_REP,
'MIN_REP_TO_INSERT_LINK',
+ default=30,
+ description=_('Insert clickable links')
+ )
+)
+
+settings.register(
+ livesettings.IntegerValue(
+ MIN_REP,
+ 'MIN_REP_TO_SUGGEST_LINK',
default=10,
- description=_('Insert links')
+ description=_('Insert link suggestions as plain text'),
+ help_text=_(
+ 'This value should be smaller than that for "insert clickable links". '
+ 'This setting should stop link-spamming by newly registered users.'
+ )
)
)
diff --git a/askbot/doc/source/changelog.rst b/askbot/doc/source/changelog.rst
index fcc85c21..f5714421 100644
--- a/askbot/doc/source/changelog.rst
+++ b/askbot/doc/source/changelog.rst
@@ -4,6 +4,7 @@ Changes in Askbot
Development version
-------------------
* Added minimum reputation to insert links and hotlinked images (Evgeny)
+* Added minimum reputation to suggest links as plain text (Evgeny)
* Added support of Haystack for search (Adolfo)
* Added minimum reputation setting to accept any answer as correct (Evgeny)
* Added "VIP" option to groups - if checked, all posts belong to the group and users of that group in the future will be able to moderate those posts. Moderation features for VIP group are in progress (Evgeny)
diff --git a/askbot/forms.py b/askbot/forms.py
index 1c5bc3d6..a4365776 100644
--- a/askbot/forms.py
+++ b/askbot/forms.py
@@ -11,6 +11,7 @@ from django.utils.text import get_text_list
from django.contrib.auth.models import User
from django_countries import countries
from askbot.utils.forms import NextUrlField, UserNameField
+from askbot.utils.markup import URL_RE
from askbot.mail import extract_first_email_address
from recaptcha_works.fields import RecaptchaField
from askbot.conf import settings as askbot_settings
@@ -273,6 +274,11 @@ class EditorField(forms.CharField):
min_length = 10 # sentinel default value
def __init__(self, *args, **kwargs):
+ user = kwargs.pop('user', None)
+ if user is None:
+ raise ValueError('user parameter is required')
+ self.user = user
+
editor_attrs = kwargs.pop('editor_attrs', {})
super(EditorField, self).__init__(*args, **kwargs)
self.required = True
@@ -295,6 +301,21 @@ class EditorField(forms.CharField):
self.min_length
) % self.min_length
raise forms.ValidationError(msg)
+
+ if re.search(URL_RE, value):
+ min_rep = askbot_settings.MIN_REP_TO_SUGGEST_LINK
+ if self.user.is_anonymous():
+ raise forms.ValidationError(
+ _('Links or images cannot be posted anonymously')
+ )
+ elif self.user.reputation < min_rep:
+ raise forms.ValidationError(
+ ungettext_lazy(
+ 'At at least %d karma point is required to post links',
+ 'At at least %d karma points are required to post links',
+ min_rep
+ ) % min_rep
+ )
return value
@@ -302,7 +323,10 @@ class QuestionEditorField(EditorField):
"""Editor field for the questions"""
def __init__(self, *args, **kwargs):
- super(QuestionEditorField, self).__init__(*args, **kwargs)
+ user = kwargs.pop('user', None)
+ super(QuestionEditorField, self).__init__(
+ user=user, *args, **kwargs
+ )
self.length_error_template_singular = \
'question body must be > %d character'
self.length_error_template_plural = \
@@ -477,10 +501,12 @@ class EditorForm(forms.Form):
the field must be created dynamically, so it's added
in the __init__() function"""
- def __init__(self, editor_attrs=None):
+ def __init__(self, user=None, editor_attrs=None):
super(EditorForm, self).__init__()
editor_attrs = editor_attrs or {}
- self.fields['editor'] = EditorField(editor_attrs=editor_attrs)
+ self.fields['editor'] = EditorField(
+ user=user, editor_attrs=editor_attrs
+ )
class DumpUploadForm(forms.Form):
@@ -775,6 +801,7 @@ class PostPrivatelyForm(forms.Form, FormWithHideableFields):
def allows_post_privately(self):
user = self._user
return (
+ askbot_settings.GROUPS_ENABLED and \
user and user.is_authenticated() and \
user.can_make_group_private_posts()
)
@@ -897,9 +924,10 @@ class AskForm(PostAsSomeoneForm, PostPrivatelyForm):
)
def __init__(self, *args, **kwargs):
+ user = kwargs.pop('user', None)
super(AskForm, self).__init__(*args, **kwargs)
#it's important that this field is set up dynamically
- self.fields['text'] = QuestionEditorField()
+ self.fields['text'] = QuestionEditorField(user=user)
#hide ask_anonymously field
if askbot_settings.ALLOW_ASK_ANONYMOUSLY is False:
self.hide_field('ask_anonymously')
@@ -932,11 +960,12 @@ class AskWidgetForm(forms.Form, FormWithHideableFields):
)
def __init__(self, include_text=True, *args, **kwargs):
+ user = kwargs.pop('user', None)
super(AskWidgetForm, self).__init__(*args, **kwargs)
#hide ask_anonymously field
if not askbot_settings.ALLOW_ASK_ANONYMOUSLY:
self.hide_field('ask_anonymously')
- self.fields['text'] = QuestionEditorField()
+ self.fields['text'] = QuestionEditorField(user=user)
if not include_text:
self.hide_field('text')
#hack to make it validate
@@ -1020,7 +1049,11 @@ class AskByEmailForm(forms.Form):
'required': ASK_BY_EMAIL_SUBJECT_HELP
}
)
- body_text = QuestionEditorField()
+
+ def __init__(self, *args, **kwargs):
+ user = kwargs.pop('user', None)
+ super(AskByEmailForm, self).__init__(*args, **kwargs)
+ self.fields['body_text'] = QuestionEditorField(user=user)
def clean_sender(self):
"""Cleans the :attr:`~askbot.forms.AskByEmail.sender` attribute
@@ -1074,7 +1107,6 @@ class AskByEmailForm(forms.Form):
class AnswerForm(PostAsSomeoneForm, PostPrivatelyForm):
- text = AnswerEditorField()
wiki = WikiField()
openid = forms.CharField(
required=False, max_length=255,
@@ -1084,7 +1116,7 @@ class AnswerForm(PostAsSomeoneForm, PostPrivatelyForm):
def __init__(self, *args, **kwargs):
super(AnswerForm, self).__init__(*args, **kwargs)
- self.fields['text'] = AnswerEditorField()
+ self.fields['text'] = AnswerEditorField(user=kwargs['user'])
self.fields['email_notify'].widget.attrs['id'] = \
'question-subscribe-updates'
@@ -1169,11 +1201,11 @@ class EditQuestionForm(PostAsSomeoneForm, PostPrivatelyForm):
def __init__(self, *args, **kwargs):
"""populate EditQuestionForm with initial data"""
self.question = kwargs.pop('question')
- self.user = kwargs['user']#preserve for superclass
+ self.user = kwargs.pop('user')#preserve for superclass
revision = kwargs.pop('revision')
super(EditQuestionForm, self).__init__(*args, **kwargs)
#it is important to add this field dynamically
- self.fields['text'] = QuestionEditorField()
+ self.fields['text'] = QuestionEditorField(user=self.user)
self.fields['title'].initial = revision.title
self.fields['text'].initial = revision.text
self.fields['tags'].initial = revision.tagnames
@@ -1275,9 +1307,10 @@ class EditAnswerForm(PostAsSomeoneForm, PostPrivatelyForm):
def __init__(self, answer, revision, *args, **kwargs):
self.answer = answer
+ user = kwargs.pop('user', None)
super(EditAnswerForm, self).__init__(*args, **kwargs)
#it is important to add this field dynamically
- self.fields['text'] = AnswerEditorField()
+ self.fields['text'] = AnswerEditorField(user=user)
self.fields['text'].initial = revision.text
self.fields['wiki'].initial = answer.wiki
diff --git a/askbot/mail/__init__.py b/askbot/mail/__init__.py
index 74aa27e9..c9c84f33 100644
--- a/askbot/mail/__init__.py
+++ b/askbot/mail/__init__.py
@@ -82,16 +82,15 @@ def thread_headers(post, orig_post, update):
return headers
def clean_html_email(email_body):
- '''needs more clenup might not work for other email templates
- that does not use table layout'''
-
- remove_linejump = lambda s: s.replace('\n', '')
-
+ """needs more clenup might not work for other email templates
+ that do not use table layout
+ """
soup = BeautifulSoup(email_body)
- table_tds = soup.find('body')
- phrases = map(lambda s: s.strip(),
- filter(bool, table_tds.get_text().split('\n')))
-
+ body_element = soup.find('body')
+ phrases = map(
+ lambda s: s.strip(),
+ filter(bool, body_element.get_text().split('\n'))
+ )
return '\n\n'.join(phrases)
def send_mail(
@@ -266,10 +265,15 @@ def bounce_email(
def extract_reply(text):
"""take the part above the separator
- and discard the last line above the separator"""
+ and discard the last line above the separator
+ """
if const.REPLY_SEPARATOR_REGEX.search(text):
text = const.REPLY_SEPARATOR_REGEX.split(text)[0]
- return '\n'.join(text.splitlines(True)[:-3])
+ text_lines = text.splitlines(False)
+ #log last 10 lines of text - to capture email responses
+ logging.debug('reply-border-separator|' + '|'.join(text_lines[-10:]))
+ #here we need code stripping the "On ... somebody wrote:"
+ return '\n'.join(text_lines[:-3])
else:
return text
@@ -362,10 +366,10 @@ def process_emailed_question(
'subject': subject,
'body_text': body_text
}
- form = AskByEmailForm(data)
+ user = User.objects.get(email__iexact = email_address)
+ form = AskByEmailForm(data, user=user)
if form.is_valid():
email_address = form.cleaned_data['email']
- user = User.objects.get(email__iexact = email_address)
if user.can_post_by_email() is False:
raise PermissionDenied(messages.insufficient_reputation(user))
diff --git a/askbot/migrations/0155_remove_unused_internal_tags.py b/askbot/migrations/0155_remove_unused_internal_tags.py
new file mode 100644
index 00000000..d4ef662f
--- /dev/null
+++ b/askbot/migrations/0155_remove_unused_internal_tags.py
@@ -0,0 +1,387 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import DataMigration
+from django.db import models
+
+class Migration(DataMigration):
+
+ def forwards(self, orm):
+ "Write your forwards methods here."
+ print 'Deleting unused tags added for internal bookkeeping...'
+ tags = orm['askbot.Tag'].objects.filter(name__startswith='_internal_')
+ count = tags.count()
+ if count > 0:
+ tags.delete()
+ print '%d tags formatted _internal_X' % count
+ else:
+ print 'None found'
+
+
+ def backwards(self, orm):
+ "Write your backwards methods here."
+
+
+ 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.askwidget': {
+ 'Meta': {'object_name': 'AskWidget'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Group']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'include_text_field': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'inner_style': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'outer_style': ('django.db.models.fields.TextField', [], {'blank': 'True'}),
+ 'tag': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Tag']", 'null': 'True', 'blank': 'True'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ '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.group': {
+ 'Meta': {'object_name': 'Group', '_ormbases': ['auth.Group']},
+ 'description': ('django.db.models.fields.related.OneToOneField', [], {'blank': 'True', 'related_name': "'described_group'", 'unique': 'True', 'null': 'True', 'to': "orm['askbot.Post']"}),
+ 'group_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.Group']", 'unique': 'True', 'primary_key': 'True'}),
+ 'is_vip': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'logo_url': ('django.db.models.fields.URLField', [], {'max_length': '200', 'null': 'True'}),
+ 'moderate_answers_to_enquirers': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ 'moderate_email': ('django.db.models.fields.BooleanField', [], {'default': 'True'}),
+ 'openness': ('django.db.models.fields.SmallIntegerField', [], {'default': '2'}),
+ '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.groupmembership': {
+ 'Meta': {'object_name': 'GroupMembership', '_ormbases': ['auth.AuthUserGroups']},
+ 'authusergroups_ptr': ('django.db.models.fields.related.OneToOneField', [], {'to': "orm['auth.AuthUserGroups']", 'unique': 'True', 'primary_key': 'True'}),
+ 'level': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'})
+ },
+ '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', 'through': "orm['askbot.PostToGroup']", 'to': "orm['askbot.Group']"}),
+ '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']"}),
+ 'points': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_column': "'score'"}),
+ 'post_type': ('django.db.models.fields.CharField', [], {'max_length': '255', 'db_index': 'True'}),
+ 'summary': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ '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.posttogroup': {
+ 'Meta': {'unique_together': "(('post', 'group'),)", 'object_name': 'PostToGroup', 'db_table': "'askbot_post_groups'"},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'post': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Post']"})
+ },
+ '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.questionwidget': {
+ 'Meta': {'object_name': 'QuestionWidget'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Group']", 'null': 'True', 'blank': 'True'}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'order_by': ('django.db.models.fields.CharField', [], {'default': "'-added_at'", 'max_length': '18'}),
+ 'question_number': ('django.db.models.fields.PositiveIntegerField', [], {'default': '7'}),
+ 'search_query': ('django.db.models.fields.CharField', [], {'default': "''", 'max_length': '50', 'null': 'True', 'blank': 'True'}),
+ 'style': ('django.db.models.fields.TextField', [], {'default': '"\\n@import url(\'http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz:300,400,700\');\\nbody {\\n overflow: hidden;\\n}\\n\\n#container {\\n width: 200px;\\n height: 350px;\\n}\\nul {\\n list-style: none;\\n padding: 5px;\\n margin: 5px;\\n}\\nli {\\n border-bottom: #CCC 1px solid;\\n padding-bottom: 5px;\\n padding-top: 5px;\\n}\\nli:last-child {\\n border: none;\\n}\\na {\\n text-decoration: none;\\n color: #464646;\\n font-family: \'Yanone Kaffeesatz\', sans-serif;\\n font-size: 15px;\\n}\\n"', 'blank': 'True'}),
+ 'tagnames': ('django.db.models.fields.CharField', [], {'max_length': '50'}),
+ 'title': ('django.db.models.fields.CharField', [], {'max_length': '100'})
+ },
+ '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', 'through': "orm['askbot.ThreadToGroup']", 'to': "orm['askbot.Group']"}),
+ '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']"}),
+ 'points': ('django.db.models.fields.IntegerField', [], {'default': '0', 'db_column': "'score'"}),
+ '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.threadtogroup': {
+ 'Meta': {'unique_together': "(('thread', 'group'),)", 'object_name': 'ThreadToGroup', 'db_table': "'askbot_thread_groups'"},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'thread': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['askbot.Thread']"}),
+ 'visibility': ('django.db.models.fields.SmallIntegerField', [], {'default': '1'})
+ },
+ '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.authusergroups': {
+ 'Meta': {'unique_together': "(('group', 'user'),)", 'object_name': 'AuthUserGroups', 'db_table': "'auth_user_groups'", 'managed': 'False'},
+ 'group': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.Group']"}),
+ 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['auth.User']"})
+ },
+ '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_fake': ('django.db.models.fields.BooleanField', [], {'default': 'False'}),
+ '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': '255'}),
+ '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']
+ symmetrical = True
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index ed687f86..4648748e 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -2490,8 +2490,8 @@ def user_fix_html_links(self, text):
result = replace_links_with_text(text)
if result != text:
message = ungettext(
- 'At least %d karma point is required to insert links',
- 'At least %d karma points is required to insert links',
+ 'At least %d karma point is required to post links',
+ 'At least %d karma points is required to post links',
askbot_settings.MIN_REP_TO_INSERT_LINK
) % askbot_settings.MIN_REP_TO_INSERT_LINK
self.message_set.create(message=message)
diff --git a/askbot/models/post.py b/askbot/models/post.py
index 4e841f13..da25f2fc 100644
--- a/askbot/models/post.py
+++ b/askbot/models/post.py
@@ -884,17 +884,6 @@ class Post(models.Model):
if parent_post is None:
break
quote_level += 1
- """
- output += '<p>'
- output += _(
- 'In reply to %(user)s %(post)s of %(date)s'
- ) % {
- 'user': parent_post.author.username,
- 'post': _(parent_post.post_type),
- 'date': parent_post.added_at.strftime(const.DATETIME_FORMAT)
- }
- output += '</p>'
- """
output += parent_post.format_for_email(
quote_level = quote_level,
format = 'parent_subthread'
diff --git a/askbot/models/question.py b/askbot/models/question.py
index 7faf589b..43844c82 100644
--- a/askbot/models/question.py
+++ b/askbot/models/question.py
@@ -702,7 +702,10 @@ class Thread(models.Model):
def format_for_email(self, user=None):
"""experimental function: output entire thread for email"""
- question, answers, junk, published_ans_ids = self.get_cached_post_data(user=user)
+
+ question, answers, junk, published_ans_ids = \
+ self.get_cached_post_data(user=user)
+
output = question.format_for_email_as_subthread()
if answers:
answer_heading = ungettext(
diff --git a/askbot/models/tag.py b/askbot/models/tag.py
index d7e91eb5..e4c4540a 100644
--- a/askbot/models/tag.py
+++ b/askbot/models/tag.py
@@ -1,5 +1,4 @@
import re
-import logging
from django.db import models
from django.contrib.auth.models import User
from django.utils.translation import ugettext as _
diff --git a/askbot/tasks.py b/askbot/tasks.py
index 505597d2..5cdd59b7 100644
--- a/askbot/tasks.py
+++ b/askbot/tasks.py
@@ -243,4 +243,3 @@ def send_instant_notifications_about_activity_in_post(
)
else:
logger.debug('success %s, logId=%s' % (user.email, log_id))
-
diff --git a/askbot/templates/answer_edit.html b/askbot/templates/answer_edit.html
index 8c3687f1..20c0684d 100644
--- a/askbot/templates/answer_edit.html
+++ b/askbot/templates/answer_edit.html
@@ -28,7 +28,10 @@
{% if settings.WIKI_ON and answer.wiki == False %}
{{ macros.checkbox_in_div(form.wiki) }}
{% endif %}
- {% if request.user.is_authenticated() and request.user.can_make_group_private_posts() %}
+ {% if settings.GROUPS_ENABLED and
+ request.user.is_authenticated() and
+ request.user.can_make_group_private_posts()
+ %}
{{ macros.checkbox_in_div(form.post_privately) }}
{% endif %}
<div class="after-editor">
diff --git a/askbot/templates/question/new_answer_form.html b/askbot/templates/question/new_answer_form.html
index 76772abf..bc51f44a 100644
--- a/askbot/templates/question/new_answer_form.html
+++ b/askbot/templates/question/new_answer_form.html
@@ -51,7 +51,10 @@
{% if settings.WIKI_ON %}
{{ macros.checkbox_in_div(answer.wiki) }}
{% endif %}
- {% if request.user.is_authenticated() and request.user.can_make_group_private_posts() %}
+ {% if settings.GROUPS_ENABLED and
+ request.user.is_authenticated() and
+ request.user.can_make_group_private_posts()
+ %}
{{ macros.checkbox_in_div(answer.post_privately) }}
{% endif %}
{% endif %}
diff --git a/askbot/templates/question_edit.html b/askbot/templates/question_edit.html
index f176b11d..8b049e55 100644
--- a/askbot/templates/question_edit.html
+++ b/askbot/templates/question_edit.html
@@ -38,7 +38,10 @@
{% if form.can_stay_anonymous() %}
{{ macros.checkbox_in_div(form.reveal_identity) }}
{% endif %}
- {% if request.user.is_authenticated() and request.user.can_make_group_private_posts() %}
+ {% if settings.GROUPS_ENABLED and
+ request.user.is_authenticated() and
+ request.user.can_make_group_private_posts()
+ %}
{{ macros.checkbox_in_div(form.post_privately) }}
{% endif %}
</div>
diff --git a/askbot/templates/widgets/ask_form.html b/askbot/templates/widgets/ask_form.html
index d528609f..0f851fee 100644
--- a/askbot/templates/widgets/ask_form.html
+++ b/askbot/templates/widgets/ask_form.html
@@ -39,7 +39,10 @@
{% if settings.ALLOW_ASK_ANONYMOUSLY %}
{{ macros.checkbox_in_div(form.ask_anonymously) }}
{% endif %}
- {% if request.user.is_authenticated() and request.user.can_make_group_private_posts() %}
+ {% if settings.GROUPS_ENABLED and
+ request.user.is_authenticated() and
+ request.user.can_make_group_private_posts()
+ %}
{{ macros.checkbox_in_div(form.post_privately) }}
{% endif %}
</div>
diff --git a/askbot/tests/email_parsing_tests.py b/askbot/tests/email_parsing_tests.py
index 905bff0a..6cc5e576 100644
--- a/askbot/tests/email_parsing_tests.py
+++ b/askbot/tests/email_parsing_tests.py
@@ -23,3 +23,11 @@ class EmailParseTests(utils.AskbotTestCase):
print cleaned_body
print "CLEANED BODY"
self.assertEquals(cleaned_body, self.expected_output)
+
+"""collection of quote separators separated with an empty line
+u'\n\nthis is my reply!\n\nOn Wed, Oct 31, 2012 at 1:45 AM, <kp@kp-dev.askbot.com> wrote:\n\n> **\n> '
+
+u'\n\nthis is my another reply!\n\nOn Wed, Oct 31, 2012 at 1:45 AM, <kp@kp-dev.askbot.com> wrote:\n>\n> '
+
+u'\n\nSending this from my yahoo mail account.\n\n\n\n________________________________\n From: "kp@kp-dev.askbot.com" <kp@kp-dev.askbot.com>\nTo: fadeev@rocketmail.com \nSent: Wednesday, October 31, 2012 2:41 AM\nSubject: "This is my test question"\n \n\n \n \n \n'
+"""
diff --git a/askbot/tests/form_tests.py b/askbot/tests/form_tests.py
index 90f4f4f2..fed38f87 100644
--- a/askbot/tests/form_tests.py
+++ b/askbot/tests/form_tests.py
@@ -1,5 +1,7 @@
from django import forms as django_forms
+from django.contrib.auth.models import AnonymousUser
from askbot.tests.utils import AskbotTestCase
+from askbot.tests.utils import with_settings
from askbot.conf import settings as askbot_settings
from askbot import forms
from askbot.utils import forms as util_forms
@@ -53,9 +55,10 @@ class AskByEmailFormTests(AskbotTestCase):
and makes sure that tags and title are parsed out"""
setting_backup = askbot_settings.TAGS_ARE_REQUIRED
askbot_settings.update('TAGS_ARE_REQUIRED', True)
+ user = AnonymousUser()
for test_case in SUBJECT_LINE_CASES:
self.data['subject'] = test_case[0]
- form = forms.AskByEmailForm(self.data)
+ form = forms.AskByEmailForm(self.data, user=user)
output = test_case[1]
if output is None:
self.assertFalse(form.is_valid())
@@ -75,10 +78,11 @@ class AskByEmailFormTests(AskbotTestCase):
"""loops through variants of the from field
in the emails and tests the email address
extractor"""
+ user = AnonymousUser()
for test_case in EMAIL_CASES:
self.data['sender'] = test_case[0]
expected_result = test_case[1]
- form = forms.AskByEmailForm(self.data)
+ form = forms.AskByEmailForm(self.data, user=user)
if expected_result is None:
self.assertFalse(form.is_valid())
else:
@@ -196,9 +200,9 @@ class EditQuestionAnonymouslyFormTests(AskbotTestCase):
data['reveal_identity'] = 'on'
self.form = forms.EditQuestionForm(
data,
- question = question,
- user = editor,
- revision = question.get_latest_revision(),
+ question=question,
+ user=editor,
+ revision=question.get_latest_revision(),
)
def test_reveal_identity_field(self):
@@ -230,7 +234,7 @@ class AskFormTests(AskbotTestCase):
}
if ask_anonymously == True:
data['ask_anonymously'] = 'on'
- self.form = forms.AskForm(data)
+ self.form = forms.AskForm(data, user=AnonymousUser())
self.form.full_clean()
def assert_anon_is(self, value):
@@ -317,7 +321,7 @@ class AnswerEditorFieldTests(AskbotTestCase):
def setUp(self):
self.old_min_length = askbot_settings.MIN_ANSWER_BODY_LENGTH
askbot_settings.update('MIN_ANSWER_BODY_LENGTH', 10)
- self.field = forms.AnswerEditorField()
+ self.field = forms.AnswerEditorField(user=AnonymousUser())
def tearDown(self):
askbot_settings.update('MIN_ANSWER_BODY_LENGTH', self.old_min_length)
@@ -364,8 +368,6 @@ class PostAsSomeoneFormTests(AskbotTestCase):
class AskWidgetFormTests(AskbotTestCase):
- form = forms.AskWidgetForm
-
def setUp(self):
self.good_data = {'title': "What's the price of a house in london?"}
self.good_data_anon = {'title': "What's the price of a house in london?",
@@ -374,12 +376,40 @@ class AskWidgetFormTests(AskbotTestCase):
self.bad_data = {'title': ''}
def test_valid_input(self):
- form_object = self.form(include_text=False, data=self.good_data)
- print form_object.errors
+ form_object = forms.AskWidgetForm(
+ include_text=False, data=self.good_data, user=AnonymousUser()
+ )
self.assertTrue(form_object.is_valid())
- form_object = self.form(include_text=False, data=self.good_data_anon)
+ form_object = forms.AskWidgetForm(
+ include_text=False, data=self.good_data_anon, user=AnonymousUser()
+ )
self.assertTrue(form_object.is_valid())
def test_invalid_input(self):
- form_object = self.form(False, data=self.bad_data)
+ form_object = forms.AskWidgetForm(
+ include_text=False, data=self.bad_data, user=AnonymousUser()
+ )
self.assertFalse(form_object.is_valid())
+
+
+TEXT_WITH_LINK = 'blah blah http://example.com/url/image.png'
+class EditorFieldTests(AskbotTestCase):
+
+ def setUp(self):
+ self.user = self.create_user('user')
+ self.user.reputation = 5
+ self.user.save()
+
+ @with_settings(EDITOR_TYPE='markdown', MIN_REP_TO_SUGGEST_LINK=10)
+ def test_low_rep_user_cannot_post_links_markdown(self):
+ field = forms.EditorField(user=self.user)
+ self.assertRaises(
+ django_forms.ValidationError, field.clean, TEXT_WITH_LINK
+ )
+
+ @with_settings(EDITOR_TYPE='tinymce', MIN_REP_TO_SUGGEST_LINK=10)
+ def test_low_rep_user_cannot_post_links_tinymce(self):
+ field = forms.EditorField(user=self.user)
+ self.assertRaises(
+ django_forms.ValidationError, field.clean, TEXT_WITH_LINK
+ )
diff --git a/askbot/views/commands.py b/askbot/views/commands.py
index 698bf2db..c072f7b8 100644
--- a/askbot/views/commands.py
+++ b/askbot/views/commands.py
@@ -1348,7 +1348,7 @@ def get_editor(request):
if 'config' not in request.GET:
return HttpResponseForbidden()
config = simplejson.loads(request.GET['config'])
- form = forms.EditorForm(editor_attrs=config)
+ form = forms.EditorForm(editor_attrs=config, user=request.user)
editor_html = render_text_into_skin(
'{{ form.media }} {{ form.editor }}',
{'form': form},
diff --git a/askbot/views/readers.py b/askbot/views/readers.py
index 5a3e378b..9801d5bc 100644
--- a/askbot/views/readers.py
+++ b/askbot/views/readers.py
@@ -549,7 +549,7 @@ def question(request, id):#refactor - long subroutine. display question body, an
if drafts.count() > 0:
initial['text'] = drafts[0].text
- answer_form = AnswerForm(initial)
+ answer_form = AnswerForm(initial, user=request.user)
user_can_post_comment = (
request.user.is_authenticated() and request.user.can_post_comment()
diff --git a/askbot/views/widgets.py b/askbot/views/widgets.py
index 8699cdf1..4401bbdc 100644
--- a/askbot/views/widgets.py
+++ b/askbot/views/widgets.py
@@ -61,8 +61,11 @@ def ask_widget(request, widget_id):
widget = get_object_or_404(models.AskWidget, id=widget_id)
if request.method == "POST":
- form = forms.AskWidgetForm(include_text=widget.include_text_field,
- data=request.POST)
+ form = forms.AskWidgetForm(
+ include_text=widget.include_text_field,
+ data=request.POST,
+ user=request.user
+ )
if form.is_valid():
ask_anonymously = form.cleaned_data['ask_anonymously']
title = form.cleaned_data['title']
@@ -116,7 +119,10 @@ def ask_widget(request, widget_id):
next_url = '%s?next=%s' % (reverse('widget_signin'), reverse('ask_by_widget'))
return redirect(next_url)
- form = forms.AskWidgetForm(include_text=widget.include_text_field)
+ form = forms.AskWidgetForm(
+ include_text=widget.include_text_field,
+ user=request.user
+ )
data = {
'form': form,
diff --git a/askbot/views/writers.py b/askbot/views/writers.py
index db7a24d2..d1504d23 100644
--- a/askbot/views/writers.py
+++ b/askbot/views/writers.py
@@ -211,7 +211,7 @@ def ask(request):#view used to ask a new question
user can start posting a question anonymously but then
must login/register in order for the question go be shown
"""
- form = forms.AskForm(request.REQUEST)
+ form = forms.AskForm(request.REQUEST, user=request.user)
if request.method == 'POST':
if form.is_valid():
timestamp = datetime.datetime.now()
@@ -264,7 +264,7 @@ def ask(request):#view used to ask a new question
return HttpResponseRedirect(url_utils.get_login_url())
if request.method == 'GET':
- form = forms.AskForm()
+ form = forms.AskForm(user=request.user)
draft_title = ''
draft_text = ''
@@ -386,24 +386,24 @@ def edit_question(request, id):
rev_id = revision_form.cleaned_data['revision']
revision = question.revisions.get(revision = rev_id)
form = forms.EditQuestionForm(
- question = question,
- user = request.user,
- revision = revision
+ question=question,
+ user=request.user,
+ revision=revision
)
else:
form = forms.EditQuestionForm(
request.POST,
- question = question,
- user = request.user,
- revision = revision
+ question=question,
+ user=quest.user,
+ revision=revision
)
else:#new content edit
# Always check modifications against the latest revision
form = forms.EditQuestionForm(
request.POST,
- question = question,
- revision = revision,
- user = request.user,
+ question=question,
+ revision=revision,
+ user=request.user,
)
revision_form = forms.RevisionForm(question, revision)
if form.is_valid():
@@ -437,10 +437,10 @@ def edit_question(request, id):
'wiki': question.wiki
}
form = forms.EditQuestionForm(
- question = question,
- revision = revision,
- user = request.user,
- initial = initial
+ question=question,
+ revision=revision,
+ user=request.user,
+ initial=initial
)
data = {
@@ -481,15 +481,20 @@ def edit_answer(request, id):
# Replace with those from the selected revision
rev = revision_form.cleaned_data['revision']
revision = answer.revisions.get(revision = rev)
- form = forms.EditAnswerForm(answer, revision)
+ form = forms.EditAnswerForm(
+ answer, revision, user=request.user
+ )
else:
form = forms.EditAnswerForm(
answer,
revision,
- request.POST
+ request.POST,
+ user=request.user
)
else:
- form = forms.EditAnswerForm(answer, revision, request.POST)
+ form = forms.EditAnswerForm(
+ answer, revision, request.POST, user=request.user
+ )
revision_form = forms.RevisionForm(answer, revision)
if form.is_valid():
@@ -506,7 +511,7 @@ def edit_answer(request, id):
return HttpResponseRedirect(answer.get_absolute_url())
else:
revision_form = forms.RevisionForm(answer, revision)
- form = forms.EditAnswerForm(answer, revision)
+ form = forms.EditAnswerForm(answer, revision, user=request.user)
if request.user.can_make_group_private_posts():
form.initial['post_privately'] = answer.is_private()
data = {
@@ -536,7 +541,7 @@ def answer(request, id):#process a new answer
"""
question = get_object_or_404(models.Post, post_type='question', id=id)
if request.method == "POST":
- form = forms.AnswerForm(request.POST)
+ form = forms.AnswerForm(request.POST, user=request.user)
if form.is_valid():
wiki = form.cleaned_data['wiki']
text = form.cleaned_data['text']