summaryrefslogtreecommitdiffstats
path: root/askbot/forms.py
diff options
context:
space:
mode:
Diffstat (limited to 'askbot/forms.py')
-rw-r--r--askbot/forms.py205
1 files changed, 106 insertions, 99 deletions
diff --git a/askbot/forms.py b/askbot/forms.py
index ce27ebc8..e3c6c253 100644
--- a/askbot/forms.py
+++ b/askbot/forms.py
@@ -9,8 +9,10 @@ from django.conf import settings as django_settings
from django.core.exceptions import PermissionDenied
from django.forms.util import ErrorList
from django.utils.html import strip_tags
+from django.utils.datastructures import SortedDict
from django.utils.translation import ugettext_lazy as _
from django.utils.translation import ungettext_lazy, string_concat
+from django.utils.translation import get_language
from django.utils.text import get_text_list
from django.contrib.auth.models import User
from django_countries import countries
@@ -22,6 +24,10 @@ from askbot.conf import get_tag_display_filter_strategy_choices
from tinymce.widgets import TinyMCE
import logging
+def should_use_recaptcha(user):
+ """True if user must use recaptcha"""
+ return askbot_settings.USE_RECAPTCHA and (user.is_anonymous() or user.is_watched())
+
def cleanup_dict(dictionary, key, empty_value):
"""deletes key from dictionary if it exists
@@ -68,12 +74,14 @@ def clean_marked_tagnames(tagnames):
if tagname == '':
continue
if tagname.endswith('*'):
- if tagname.count('*') > 1:
+ if tagname.count('*') > 1 or len(tagname) == 1:
continue
else:
- wildcards.append(tagname)
+ base_tag = tagname[:-1]
+ cleaned_base_tag = clean_tag(base_tag, look_in_db=False)
+ wildcards.append(cleaned_base_tag + '*')
else:
- pure_tags.append(tagname)
+ pure_tags.append(clean_tag(tagname))
return pure_tags, wildcards
@@ -206,6 +214,14 @@ class CountedWordsField(forms.CharField):
return value
+class AskbotRecaptchaField(RecaptchaField):
+ """A recaptcha field with preset keys from the livesettings"""
+ def __init__(self, *args, **kwargs):
+ kwargs.setdefault('private_key', askbot_settings.RECAPTCHA_SECRET)
+ kwargs.setdefault('public_key', askbot_settings.RECAPTCHA_KEY)
+ super(AskbotRecaptchaField, self).__init__(*args, **kwargs)
+
+
class LanguageField(forms.ChoiceField):
def __init__(self, *args, **kwargs):
@@ -245,9 +261,7 @@ class TitleField(forms.CharField):
)
self.max_length = 255
self.label = _('title')
- self.help_text = _(
- 'Please enter your question'
- )
+ self.help_text = askbot_settings.WORDS_PLEASE_ENTER_YOUR_QUESTION
self.initial = ''
def clean(self, value):
@@ -263,20 +277,21 @@ class TitleField(forms.CharField):
) % askbot_settings.MIN_TITLE_LENGTH
raise forms.ValidationError(msg)
encoded_value = value.encode('utf-8')
+ question_term = askbot_settings.WORDS_QUESTION_SINGULAR
if len(value) == len(encoded_value):
if len(value) > self.max_length:
raise forms.ValidationError(
_(
- 'The question is too long, maximum allowed size is '
- '%d characters'
- ) % self.max_length
+ 'The %(question)s is too long, maximum allowed size is '
+ '%(length)d characters'
+ ) % {'question': question_term, 'length': self.max_length}
)
elif len(encoded_value) > self.max_length:
raise forms.ValidationError(
_(
- 'The question is too long, maximum allowed size is '
- '%d bytes'
- ) % self.max_length
+ 'The %(question)s is too long, maximum allowed size is '
+ '%(length)d bytes'
+ ) % {'question': question_term, 'length': self.max_length}
)
return value.strip() # TODO: test me
@@ -286,9 +301,6 @@ class EditorField(forms.CharField):
"""EditorField is subclassed by the
:class:`QuestionEditorField` and :class:`AnswerEditorField`
"""
- length_error_template_singular = 'post content must be > %d character',
- length_error_template_plural = 'post content must be > %d characters',
- min_length = 10 # sentinel default value
def __init__(self, *args, **kwargs):
user = kwargs.pop('user', None)
@@ -309,16 +321,18 @@ class EditorField(forms.CharField):
self.label = _('content')
self.help_text = u''
self.initial = ''
+ self.min_length = 10
+ self.post_term_name = _('post')
def clean(self, value):
if value is None:
value = ''
if len(value) < self.min_length:
msg = ungettext_lazy(
- self.length_error_template_singular,
- self.length_error_template_plural,
+ '%(post)s content must be > %(count)d character',
+ '%(post)s content must be > %(count)d characters',
self.min_length
- ) % self.min_length
+ ) % {'post': unicode(self.post_term_name), 'count': self.min_length}
raise forms.ValidationError(msg)
if self.user.is_anonymous():
@@ -342,11 +356,8 @@ class QuestionEditorField(EditorField):
super(QuestionEditorField, self).__init__(
user=user, *args, **kwargs
)
- self.length_error_template_singular = \
- 'question body must be > %d character'
- self.length_error_template_plural = \
- 'question body must be > %d characters'
self.min_length = askbot_settings.MIN_QUESTION_BODY_LENGTH
+ self.post_term_name = askbot_settings.WORDS_QUESTION_SINGULAR
class AnswerEditorField(EditorField):
@@ -354,12 +365,11 @@ class AnswerEditorField(EditorField):
def __init__(self, *args, **kwargs):
super(AnswerEditorField, self).__init__(*args, **kwargs)
- self.length_error_template_singular = 'answer must be > %d character'
- self.length_error_template_plural = 'answer must be > %d characters'
+ self.post_term_name = askbot_settings.WORDS_ANSWER_SINGULAR
self.min_length = askbot_settings.MIN_ANSWER_BODY_LENGTH
-def clean_tag(tag_name):
+def clean_tag(tag_name, look_in_db=True):
"""a function that cleans a single tag name"""
tag_length = len(tag_name)
if tag_length > askbot_settings.MAX_TAG_LENGTH:
@@ -376,16 +386,26 @@ def clean_tag(tag_name):
#todo - this needs to come from settings
tagname_re = re.compile(const.TAG_REGEX, re.UNICODE)
if not tagname_re.search(tag_name):
- raise forms.ValidationError(
- _(message_keys.TAG_WRONG_CHARS_MESSAGE)
- )
+ if tag_name[0] in const.TAG_FORBIDDEN_FIRST_CHARS:
+ raise forms.ValidationError(
+ _(message_keys.TAG_WRONG_FIRST_CHAR_MESSAGE)
+ )
+ else:
+ raise forms.ValidationError(
+ _(message_keys.TAG_WRONG_CHARS_MESSAGE)
+ )
if askbot_settings.FORCE_LOWERCASE_TAGS:
#a simpler way to handle tags - just lowercase thew all
return tag_name.lower()
+ elif look_in_db == False:
+ return tag_name
else:
from askbot import models
- matching_tags = models.Tag.objects.filter(name__iexact=tag_name)
+ matching_tags = models.Tag.objects.filter(
+ name__iexact=tag_name,
+ language_code=get_language()
+ )
if len(matching_tags) > 0:
return matching_tags[0].name
else:
@@ -420,7 +440,7 @@ class TagNamesField(forms.CharField):
def clean(self, value):
from askbot import models
value = super(TagNamesField, self).clean(value)
- data = value.strip()
+ data = value.strip(const.TAG_STRIP_CHARS)
if len(data) < 1:
if askbot_settings.TAGS_ARE_REQUIRED:
raise forms.ValidationError(
@@ -475,11 +495,6 @@ class WikiField(forms.BooleanField):
'community wiki (karma is not awarded & '
'many others can edit wiki post)'
)
- self.help_text = _(
- 'if you choose community wiki option, the question '
- 'and answer do not generate points and name of '
- 'author will not be shown'
- )
def clean(self, value):
return value and askbot_settings.WIKI_ON
@@ -718,19 +733,11 @@ class SendMessageForm(forms.Form):
)
-class NotARobotForm(forms.Form):
- recaptcha = RecaptchaField(
- private_key=askbot_settings.RECAPTCHA_SECRET,
- public_key=askbot_settings.RECAPTCHA_KEY
- )
-
-
class FeedbackForm(forms.Form):
name = forms.CharField(label=_('Your name (optional):'), required=False)
email = forms.EmailField(label=_('Email:'), required=False)
message = forms.CharField(
label=_('Your message:'),
- max_length=800,
widget=forms.Textarea(attrs={'cols': 60})
)
no_email = forms.BooleanField(
@@ -739,22 +746,21 @@ class FeedbackForm(forms.Form):
)
next = NextUrlField()
- def __init__(self, is_auth=False, *args, **kwargs):
+ def __init__(self, user=None, *args, **kwargs):
super(FeedbackForm, self).__init__(*args, **kwargs)
- self.is_auth = is_auth
- if not is_auth:
- if askbot_settings.USE_RECAPTCHA:
- self._add_recaptcha_field()
-
- def _add_recaptcha_field(self):
- self.fields['recaptcha'] = RecaptchaField(
- private_key=askbot_settings.RECAPTCHA_SECRET,
- public_key=askbot_settings.RECAPTCHA_KEY
- )
+ self.user = user
+ if should_use_recaptcha(user):
+ self.fields['recaptcha'] = AskbotRecaptchaField()
+
+ def clean_message(self):
+ message = self.cleaned_data.get('message', '').strip()
+ if not message:
+ raise forms.ValidationError(_('Message is required'))
+ return message
def clean(self):
super(FeedbackForm, self).clean()
- if not self.is_auth:
+ if self.user and self.user.is_anonymous():
if not self.cleaned_data['no_email'] \
and not self.cleaned_data['email']:
msg = _('Please mark "I dont want to give my mail" field.')
@@ -908,18 +914,9 @@ class AskForm(PostAsSomeoneForm, PostPrivatelyForm):
in the cleaned data, and will evaluate to False if the
settings forbids anonymous asking
"""
- title = TitleField()
tags = TagNamesField()
wiki = WikiField()
group_id = forms.IntegerField(required = False, widget = forms.HiddenInput)
- ask_anonymously = forms.BooleanField(
- label=_('ask anonymously'),
- help_text=_(
- 'Check if you do not want to reveal your name '
- 'when asking this question'
- ),
- required=False,
- )
openid = forms.CharField(
required=False, max_length=255,
widget=forms.TextInput(attrs={'size': 40, 'class': 'openid-input'})
@@ -929,13 +926,22 @@ class AskForm(PostAsSomeoneForm, PostPrivatelyForm):
user = kwargs.pop('user', None)
super(AskForm, self).__init__(*args, **kwargs)
#it's important that this field is set up dynamically
+ self.fields['title'] = TitleField()
self.fields['text'] = QuestionEditorField(user=user)
- #hide ask_anonymously field
+
+ self.fields['ask_anonymously'] = forms.BooleanField(
+ label=_('post anonymously'),
+ required=False
+ )
+
+ if user.is_anonymous() or not askbot_settings.ALLOW_ASK_ANONYMOUSLY:
+ self.hide_field('ask_anonymously')
+
if getattr(django_settings, 'ASKBOT_MULTILINGUAL', False):
self.fields['language'] = LanguageField()
- if askbot_settings.ALLOW_ASK_ANONYMOUSLY is False:
- self.hide_field('ask_anonymously')
+ if should_use_recaptcha(user):
+ self.fields['recaptcha'] = AskbotRecaptchaField()
def clean_ask_anonymously(self):
"""returns false if anonymous asking is not allowed
@@ -944,7 +950,6 @@ class AskForm(PostAsSomeoneForm, PostPrivatelyForm):
self.cleaned_data['ask_anonymously'] = False
return self.cleaned_data['ask_anonymously']
-
ASK_BY_EMAIL_SUBJECT_HELP = _(
'Subject line is expected in the format: '
'[tag1, tag2, tag3,...] question title'
@@ -954,21 +959,17 @@ ASK_BY_EMAIL_SUBJECT_HELP = _(
class AskWidgetForm(forms.Form, FormWithHideableFields):
'''Simple form with just the title to ask a question'''
- title = TitleField()
ask_anonymously = forms.BooleanField(
label=_('ask anonymously'),
- help_text=_(
- 'Check if you do not want to reveal your name '
- 'when asking this question'
- ),
required=False,
)
def __init__(self, include_text=True, *args, **kwargs):
user = kwargs.pop('user', None)
super(AskWidgetForm, self).__init__(*args, **kwargs)
+ self.fields['title'] = TitleField()
#hide ask_anonymously field
- if not askbot_settings.ALLOW_ASK_ANONYMOUSLY:
+ if user.is_anonymous() or not askbot_settings.ALLOW_ASK_ANONYMOUSLY:
self.hide_field('ask_anonymously')
self.fields['text'] = QuestionEditorField(user=user)
if not include_text:
@@ -977,6 +978,9 @@ class AskWidgetForm(forms.Form, FormWithHideableFields):
self.fields['text'].required = False
self.fields['text'].min_length = 0
+ if should_use_recaptcha(user):
+ self.fields['recaptcha'] = AskbotRecaptchaField()
+
class CreateAskWidgetForm(forms.Form, FormWithHideableFields):
title = forms.CharField(max_length=100)
include_text_field = forms.BooleanField(required=False)
@@ -1120,7 +1124,11 @@ class AnswerForm(PostAsSomeoneForm, PostPrivatelyForm):
def __init__(self, *args, **kwargs):
super(AnswerForm, self).__init__(*args, **kwargs)
- self.fields['text'] = AnswerEditorField(user=kwargs['user'])
+ user = kwargs['user']
+ self.fields['text'] = AnswerEditorField(user=user)
+
+ if should_use_recaptcha(user):
+ self.fields['recaptcha'] = AskbotRecaptchaField()
def has_data(self):
"""True if form is bound or has inital data"""
@@ -1206,16 +1214,10 @@ class RevisionForm(forms.Form):
self.fields['revision'].initial = latest_revision.revision
class EditQuestionForm(PostAsSomeoneForm, PostPrivatelyForm):
- title = TitleField()
tags = TagNamesField()
summary = SummaryField()
wiki = WikiField()
reveal_identity = forms.BooleanField(
- help_text=_(
- 'You have asked this question anonymously, '
- 'if you decide to reveal your identity, please check '
- 'this box.'
- ),
label=_('reveal identity'),
required=False,
)
@@ -1230,6 +1232,7 @@ class EditQuestionForm(PostAsSomeoneForm, PostPrivatelyForm):
super(EditQuestionForm, self).__init__(*args, **kwargs)
#it is important to add this field dynamically
self.fields['text'] = QuestionEditorField(user=self.user)
+ self.fields['title'] = TitleField()
self.fields['title'].initial = revision.title
self.fields['text'].initial = revision.text
self.fields['tags'].initial = revision.tagnames
@@ -1241,6 +1244,9 @@ class EditQuestionForm(PostAsSomeoneForm, PostPrivatelyForm):
if getattr(django_settings, 'ASKBOT_MULTILINGUAL', False):
self.fields['language'] = LanguageField()
+ if should_use_recaptcha(self.user):
+ self.fields['recaptcha'] = AskbotRecaptchaField()
+
def has_changed(self):
if super(EditQuestionForm, self).has_changed():
return True
@@ -1348,6 +1354,9 @@ class EditAnswerForm(PostAsSomeoneForm, PostPrivatelyForm):
self.fields['text'].initial = revision.text
self.fields['wiki'].initial = answer.wiki
+ if should_use_recaptcha(user):
+ self.fields['recaptcha'] = AskbotRecaptchaField()
+
def has_changed(self):
#todo: this function is almost copy/paste of EditQuestionForm.has_changed()
if super(EditAnswerForm, self).has_changed():
@@ -1520,22 +1529,15 @@ class EditUserEmailFeedsForm(forms.Form):
'mentions_and_comments': 'i',
}
- asked_by_me = EmailFeedSettingField(
- label=_('Asked by me')
- )
- answered_by_me = EmailFeedSettingField(
- label=_('Answered by me')
- )
- individually_selected = EmailFeedSettingField(
- label=_('Individually selected')
- )
- all_questions = EmailFeedSettingField(
- label=_('Entire forum (tag filtered)'),
- )
-
- mentions_and_comments = EmailFeedSettingField(
- label=_('Comments and posts mentioning me'),
- )
+ def __init__(self, *args, **kwargs):
+ super(EditUserEmailFeedsForm, self).__init__(*args, **kwargs)
+ self.fields = SortedDict((
+ ('asked_by_me', EmailFeedSettingField(label=askbot_settings.WORDS_ASKED_BY_ME)),
+ ('answered_by_me', EmailFeedSettingField(label=askbot_settings.WORDS_ANSWERED_BY_ME)),
+ ('individually_selected', EmailFeedSettingField(label=_('Individually selected'))),
+ ('all_questions', EmailFeedSettingField(label=_('Entire forum (tag filtered)'))),
+ ('mentions_and_comments', EmailFeedSettingField(label=_('Comments and posts mentioning me')))
+ ))
def set_initial_values(self, user=None):
from askbot import models
@@ -1703,9 +1705,14 @@ class BulkTagSubscriptionForm(forms.Form):
if askbot_settings.GROUPS_ENABLED:
self.fields['groups'] = forms.ModelMultipleChoiceField(queryset=Group.objects.exclude_personal())
-class GetCommentsForPostForm(forms.Form):
+class GetDataForPostForm(forms.Form):
post_id = forms.IntegerField()
+class GetUserItemsForm(forms.Form):
+ page_size = forms.IntegerField(required=False)
+ page_number = forms.IntegerField(min_value=1)
+ user_id = forms.IntegerField()
+
class NewCommentForm(forms.Form):
comment = forms.CharField()
post_id = forms.IntegerField()
@@ -1716,5 +1723,5 @@ class EditCommentForm(forms.Form):
suppress_email = SuppressEmailField()
-class DeleteCommentForm(forms.Form):
+class ProcessCommentForm(forms.Form):
comment_id = forms.IntegerField()