diff options
Diffstat (limited to 'askbot/forms.py')
-rw-r--r-- | askbot/forms.py | 205 |
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() |