From 54150a2c7c8609ad6f39d31dfc69b03da523eba7 Mon Sep 17 00:00:00 2001 From: Evgeny Fadeev Date: Sat, 21 Jul 2012 14:45:50 -0400 Subject: some PEP8 treatment to a couple of files --- askbot/__init__.py | 12 +- askbot/forms.py | 524 ++++++++++++++++++++++++++++++++++------------------- 2 files changed, 343 insertions(+), 193 deletions(-) diff --git a/askbot/__init__.py b/askbot/__init__.py index 859b2695..8e4f20ab 100644 --- a/askbot/__init__.py +++ b/askbot/__init__.py @@ -5,9 +5,6 @@ Functions in the askbot module perform various basic actions on behalf of the forum application """ import os -import smtplib -import sys -import logging VERSION = (0, 7, 43) @@ -43,17 +40,19 @@ try: from askbot.deployment.assertions import assert_package_compatibility assert_package_compatibility() patches.patch_django() - patches.patch_coffin()#must go after django + patches.patch_coffin() # must go after django except ImportError: pass + def get_install_directory(): """returns path to directory - where code of the askbot django application + where code of the askbot django application is installed """ return os.path.dirname(__file__) + def get_path_to(relative_path): """returns absolute path to a file relative to ``askbot`` directory @@ -72,10 +71,11 @@ def get_version(): """ return '.'.join([str(subversion) for subversion in VERSION]) + def get_database_engine_name(): """returns name of the database engine, independently of the version of django - - for django >=1.2 looks into ``settings.DATABASES['default']``, + - for django >=1.2 looks into ``settings.DATABASES['default']``, (i.e. assumes that askbot uses database named 'default') , and for django 1.1 and below returns settings.DATABASE_ENGINE """ diff --git a/askbot/forms.py b/askbot/forms.py index 81382a2c..1188ed59 100644 --- a/askbot/forms.py +++ b/askbot/forms.py @@ -1,3 +1,5 @@ +"""Forms, custom form fields and related utility functions +used in AskBot""" import re from django import forms from askbot import const @@ -5,7 +7,6 @@ from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ungettext_lazy, string_concat from django.utils.text import get_text_list from django.contrib.auth.models import User -from django.contrib.contenttypes.models import ContentType from django_countries import countries from askbot.utils.forms import NextUrlField, UserNameField from askbot.mail import extract_first_email_address @@ -13,6 +14,7 @@ from recaptcha_works.fields import RecaptchaField from askbot.conf import settings as askbot_settings import logging + def cleanup_dict(dictionary, key, empty_value): """deletes key from dictionary if it exists and the corresponding value equals the empty_value @@ -20,13 +22,27 @@ def cleanup_dict(dictionary, key, empty_value): if key in dictionary and dictionary[key] == empty_value: del dictionary[key] + def format_form_errors(form): + """Formats form errors in HTML + if there is only one error - returns a plain string + if more than one, returns an unordered list of errors + in HTML format. + If there are no errors, returns empty string + """ if form.errors: errors = form.errors.values() if len(errors) == 1: return errors[0] else: - return 'hahahahah' + result = '' + return result + else: + return '' + def clean_marked_tagnames(tagnames): """return two strings - one containing tagnames @@ -35,7 +51,7 @@ def clean_marked_tagnames(tagnames): wildcard tags are those that have an asterisk at the end the function does not verify that the tag names are valid """ - if askbot_settings.USE_WILDCARD_TAGS == False: + if askbot_settings.USE_WILDCARD_TAGS is False: return tagnames, list() pure_tags = list() @@ -53,7 +69,8 @@ def clean_marked_tagnames(tagnames): return pure_tags, wildcards -def filter_choices(remove_choices = None, from_choices = None): + +def filter_choices(remove_choices=None, from_choices=None): """a utility function that will remove choice tuples usable for the forms.ChoicesField from ``from_choices``, the removed ones will be those given @@ -73,12 +90,47 @@ def filter_choices(remove_choices = None, from_choices = None): if choice == choice_to_test[0]: remove = True break - if remove == False: - filtered_choices += ( choice_to_test, ) + if remove is False: + filtered_choices += (choice_to_test, ) return filtered_choices -COUNTRY_CHOICES = (('unknown',_('select country')),) + countries.COUNTRIES + +def need_mandatory_tags(): + """true, if list of mandatory tags is not empty""" + from askbot import models + return ( + askbot_settings.TAGS_ARE_REQUIRED + and len(models.tag.get_mandatory_tags()) > 0 + ) + + +def mandatory_tag_missing_in_list(tag_strings): + """true, if mandatory tag is not present in the list + of ``tag_strings``""" + from askbot import models + mandatory_tags = models.tag.get_mandatory_tags() + for mandatory_tag in mandatory_tags: + for tag_string in tag_strings: + if tag_strings_match(tag_string, mandatory_tag): + return False + return True + + +def tag_strings_match(tag_string, mandatory_tag): + """true if tag string matches the mandatory tag, + the comparison is not symmetric if tag_string ends with a + wildcard (asterisk) + """ + if mandatory_tag.endswith('*'): + return tag_string.startswith(mandatory_tag[:-1]) + else: + return tag_string == mandatory_tag + + + +COUNTRY_CHOICES = (('unknown', _('select country')),) + countries.COUNTRIES + class CountryField(forms.ChoiceField): """this is better placed into the django_coutries app""" @@ -100,10 +152,13 @@ class CountryField(forms.ChoiceField): return None return value + class CountedWordsField(forms.CharField): - + """a field where a number of words is expected + to be in a certain range""" + def __init__( - self, min_words = 0, max_words = 9999, field_name = None, + self, min_words=0, max_words=9999, field_name=None, *args, **kwargs ): self.min_words = min_words @@ -144,28 +199,38 @@ class CountedWordsField(forms.CharField): class DomainNameField(forms.CharField): + """Field for Internet Domain Names + todo: maybe there is a standard field for this? + """ def clean(self, value): #find a better regex, taking into account tlds domain_re = re.compile(r'[a-zA-Z\d]+(\.[a-zA-Z\d]+)+') if domain_re.match(value): return value else: - raise forms.ValidationError('%s is not a valid domain name' % value) + raise forms.ValidationError( + '%s is not a valid domain name' % value + ) class TitleField(forms.CharField): + """Fild receiving question title""" def __init__(self, *args, **kwargs): super(TitleField, self).__init__(*args, **kwargs) self.required = True self.widget = forms.TextInput( - attrs={'size' : 70, 'autocomplete' : 'off'} - ) + attrs={'size': 70, 'autocomplete': 'off'} + ) self.max_length = 255 - self.label = _('title') - self.help_text = _('please enter a descriptive title for your question') + self.label = _('title') + self.help_text = _( + 'please enter a descriptive title for your question' + ) self.initial = '' def clean(self, value): + """cleans the field for minimum and maximum length + also is supposed to work for unicode non-ascii characters""" if value is None: value = '' if len(value) < askbot_settings.MIN_TITLE_LENGTH: @@ -192,21 +257,22 @@ class TitleField(forms.CharField): ) % self.max_length ) - return value.strip() # TODO: test me + return value.strip() # TODO: test me + class EditorField(forms.CharField): - """EditorField is subclassed by the + """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 + min_length = 10 # sentinel default value def __init__(self, *args, **kwargs): super(EditorField, self).__init__(*args, **kwargs) self.required = True - self.widget = forms.Textarea(attrs={'id':'editor'}) - self.label = _('content') + self.widget = forms.Textarea(attrs={'id': 'editor'}) + self.label = _('content') self.help_text = u'' self.initial = '' @@ -218,32 +284,44 @@ class EditorField(forms.CharField): self.length_error_template_singular, self.length_error_template_plural, self.min_length - ) % self.min_length + ) % self.min_length raise forms.ValidationError(msg) return value + class QuestionEditorField(EditorField): + """Editor field for the questions""" + def __init__(self, *args, **kwargs): super(QuestionEditorField, self).__init__(*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.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 + class AnswerEditorField(EditorField): + """Editor field for answers""" + 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.min_length = askbot_settings.MIN_ANSWER_BODY_LENGTH + class TagNamesField(forms.CharField): + """field that receives AskBot tag names""" + def __init__(self, *args, **kwargs): super(TagNamesField, self).__init__(*args, **kwargs) self.required = askbot_settings.TAGS_ARE_REQUIRED - self.widget = forms.TextInput(attrs={'size' : 50, 'autocomplete' : 'off'}) + self.widget = forms.TextInput( + attrs={'size': 50, 'autocomplete': 'off'} + ) self.max_length = 255 self.label = _('tags') - #self.help_text = _('please use space to separate tags (this enables autocomplete feature)') self.help_text = ungettext_lazy( 'Tags are short keywords, with no spaces within. ' 'Up to %(max_tags)d tag can be used.', @@ -253,38 +331,16 @@ class TagNamesField(forms.CharField): ) % {'max_tags': askbot_settings.MAX_TAGS_PER_POST} self.initial = '' - def need_mandatory_tags(self): - """true, if list of mandatory tags is not empty""" - from askbot import models - return askbot_settings.TAGS_ARE_REQUIRED and len(models.tag.get_mandatory_tags()) > 0 - - def tag_string_matches(self, tag_string, mandatory_tag): - """true if tag string matches the mandatory tag""" - if mandatory_tag.endswith('*'): - return tag_string.startswith(mandatory_tag[:-1]) - else: - return tag_string == mandatory_tag - - def mandatory_tag_missing(self, tag_strings): - """true, if mandatory tag is not present in the list - of ``tag_strings``""" - from askbot import models - mandatory_tags = models.tag.get_mandatory_tags() - for mandatory_tag in mandatory_tags: - for tag_string in tag_strings: - if self.tag_string_matches(tag_string, mandatory_tag): - return False - return True - def clean(self, value): from askbot import models value = super(TagNamesField, self).clean(value) data = value.strip() if len(data) < 1: if askbot_settings.TAGS_ARE_REQUIRED: - raise forms.ValidationError(_('tags are required')) + raise forms.ValidationError(_('tags are required')) else: - return ''#don't test for required characters when tags is '' + #don't test for required characters when tags is '' + return '' split_re = re.compile(const.TAG_SPLIT_REGEX) tag_strings = split_re.split(data) entered_tags = [] @@ -294,11 +350,11 @@ class TagNamesField(forms.CharField): msg = ungettext_lazy( 'please use %(tag_count)d tag or less', 'please use %(tag_count)d tags or less', - tag_count) % {'tag_count':max_tags} + tag_count) % {'tag_count': max_tags} raise forms.ValidationError(msg) - if self.need_mandatory_tags(): - if self.mandatory_tag_missing(tag_strings): + if need_mandatory_tags(): + if mandatory_tag_missing_in_list(tag_strings): msg = _( 'At least one of the following tags is required : %(tags)s' ) % {'tags': get_text_list(models.tag.get_mandatory_tags())} @@ -307,18 +363,22 @@ class TagNamesField(forms.CharField): for tag in tag_strings: tag_length = len(tag) if tag_length > askbot_settings.MAX_TAG_LENGTH: - #singular form is odd in english, but required for pluralization - #in other languages - msg = ungettext_lazy('each tag must be shorter than %(max_chars)d character',#odd but added for completeness - 'each tag must be shorter than %(max_chars)d characters', - tag_length) % {'max_chars':tag_length} + #singular form is odd in english, but + #required for pluralization + #in other languages, odd but added for completeness + msg = ungettext_lazy( + 'each tag must be shorter than %(max_chars)d character', + 'each tag must be shorter than %(max_chars)d characters', + tag_length + ) % {'max_chars': tag_length} raise forms.ValidationError(msg) #todo - this needs to come from settings tagname_re = re.compile(const.TAG_REGEX, re.UNICODE) if not tagname_re.search(tag): raise forms.ValidationError(_( - 'In tags, please use letters, numbers and characters "-+.#"' + 'In tags, please use letters, ' + 'numbers and characters "-+.#"' )) #only keep unique tags if tag not in entered_tags: @@ -340,7 +400,7 @@ class TagNamesField(forms.CharField): #because we need tag name cases to be the same #as those stored in the database stored_tag = models.Tag.objects.get( - name__iexact = entered_tag + name__iexact=entered_tag ) if stored_tag.name not in cleaned_entered_tags: cleaned_entered_tags.append(stored_tag.name) @@ -349,30 +409,54 @@ class TagNamesField(forms.CharField): return u' '.join(cleaned_entered_tags) + class WikiField(forms.BooleanField): + """Rendered as checkbox turning post into + "community wiki" + """ + def __init__(self, *args, **kwargs): super(WikiField, self).__init__(*args, **kwargs) self.required = False self.initial = False - self.label = _('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') + self.label = _( + '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 + class EmailNotifyField(forms.BooleanField): + """Rendered as checkbox which turns on + email notifications on the post""" def __init__(self, *args, **kwargs): super(EmailNotifyField, self).__init__(*args, **kwargs) self.required = False self.widget.attrs['class'] = 'nomargin' + class SummaryField(forms.CharField): + def __init__(self, *args, **kwargs): super(SummaryField, self).__init__(*args, **kwargs) self.required = False - self.widget = forms.TextInput(attrs={'size' : 50, 'autocomplete' : 'off'}) + self.widget = forms.TextInput( + attrs={'size': 50, 'autocomplete': 'off'} + ) self.max_length = 300 - self.label = _('update summary:') - self.help_text = _('enter a brief summary of your revision (e.g. fixed spelling, grammar, improved style, this field is optional)') + self.label = _('update summary:') + self.help_text = _( + 'enter a brief summary of your revision (e.g. ' + 'fixed spelling, grammar, improved style, this ' + 'field is optional)' + ) class DumpUploadForm(forms.Form): @@ -382,6 +466,7 @@ class DumpUploadForm(forms.Form): """ dump_file = forms.FileField() + class ShowQuestionForm(forms.Form): """Cleans data necessary to access answers and comments by the respective comment or answer id - necessary @@ -389,10 +474,10 @@ class ShowQuestionForm(forms.Form): on the page other than the first page of answers to a question. Same for the answers that are shown on the later pages. """ - answer = forms.IntegerField(required = False) - comment = forms.IntegerField(required = False) - page = forms.IntegerField(required = False) - sort = forms.CharField(required = False) + answer = forms.IntegerField(required=False) + comment = forms.IntegerField(required=False) + page = forms.IntegerField(required=False) + sort = forms.CharField(required=False) def __init__(self, data, default_sort_method): super(ShowQuestionForm, self).__init__(data) @@ -436,6 +521,7 @@ class ShowQuestionForm(forms.Form): self.cleaned_data = out_data return out_data + class ChangeUserReputationForm(forms.Form): """Form that allows moderators and site administrators to adjust reputation of users. @@ -445,13 +531,15 @@ class ChangeUserReputationForm(forms.Form): """ user_reputation_delta = forms.IntegerField( - min_value = 1, - label = _('Enter number of points to add or subtract') - ) - comment = forms.CharField(max_length = 128) + min_value=1, + label=_( + 'Enter number of points to add or subtract' + ) + ) + comment = forms.CharField(max_length=128) def clean_comment(self): - if 'comment' in self.cleaned_data: + if 'comment' in self.cleaned_data: comment = self.cleaned_data['comment'].strip() if comment == '': del self.cleaned_data['comment'] @@ -485,9 +573,7 @@ class ChangeUserStatusForm(forms.Form): "moderation" tab """ - user_status = forms.ChoiceField( - label = _('Change status to'), - ) + user_status = forms.ChoiceField(label=_('Change status to')) def __init__(self, *arg, **kwarg): @@ -508,12 +594,12 @@ class ChangeUserStatusForm(forms.Form): #remove current status of the "subject" user from choices user_status_choices = filter_choices( - remove_choices = [subject.status, ], - from_choices = user_status_choices + remove_choices=[subject.status, ], + from_choices=user_status_choices ) #add prompt option - user_status_choices = ( ('select', _('which one?')), ) \ + user_status_choices = (('select', _('which one?')), ) \ + user_status_choices self.fields['user_status'].choices = user_status_choices @@ -561,41 +647,39 @@ class ChangeUserStatusForm(forms.Form): msg = _( 'If you wish to change %(username)s\'s status, ' 'please make a meaningful selection.' - ) % {'username': self.subject.username } + ) % {'username': self.subject.username} raise forms.ValidationError(msg) return self.cleaned_data + class SendMessageForm(forms.Form): subject_line = forms.CharField( - label = _('Subject line'), - max_length = 64, - widget = forms.TextInput( - attrs = {'size':64}, - ) - ) + label=_('Subject line'), + max_length=64, + widget=forms.TextInput(attrs={'size': 64}, ) + ) body_text = forms.CharField( - label = _('Message text'), - max_length = 1600, - widget = forms.Textarea( - attrs = {'cols':64} - ) + label=_('Message text'), + max_length=1600, + widget=forms.Textarea(attrs={'cols': 64}) ) class NotARobotForm(forms.Form): recaptcha = RecaptchaField( - private_key = askbot_settings.RECAPTCHA_SECRET, - public_key = askbot_settings.RECAPTCHA_KEY + 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}) + widget=forms.Textarea(attrs={'cols': 60}) ) no_email = forms.BooleanField( label=_("I don't want to give my email or receive a response:"), @@ -612,19 +696,21 @@ class FeedbackForm(forms.Form): def _add_recaptcha_field(self): self.fields['recaptcha'] = RecaptchaField( - private_key = askbot_settings.RECAPTCHA_SECRET, - public_key = askbot_settings.RECAPTCHA_KEY - ) + private_key=askbot_settings.RECAPTCHA_SECRET, + public_key=askbot_settings.RECAPTCHA_KEY + ) def clean(self): super(FeedbackForm, self).clean() if not self.is_auth: - if not self.cleaned_data['no_email'] and not self.cleaned_data['email']: + if not self.cleaned_data['no_email'] \ + and not self.cleaned_data['email']: msg = _('Please mark "I dont want to give my mail" field.') self._errors['email'] = self.error_class([msg]) return self.cleaned_data + class FormWithHideableFields(object): """allows to swap a field widget to HiddenInput() and back""" @@ -646,6 +732,7 @@ class FormWithHideableFields(object): if name in self.__hidden_fields: self.fields[name] = self.__hidden_fields.pop(name) + class AskForm(forms.Form, FormWithHideableFields): """the form used to askbot questions field ask_anonymously is shown to the user if the @@ -654,40 +741,51 @@ class AskForm(forms.Form, FormWithHideableFields): in the cleaned data, and will evaluate to False if the settings forbids anonymous asking """ - title = TitleField() - text = QuestionEditorField() - tags = TagNamesField() + title = TitleField() + text = QuestionEditorField() + tags = TagNamesField() wiki = WikiField() ask_anonymously = forms.BooleanField( - label = _('ask anonymously'), - help_text = _( + label=_('ask anonymously'), + help_text=_( 'Check if you do not want to reveal your name ' 'when asking this question' ), - required = False, + required=False, + ) + openid = forms.CharField( + required=False, max_length=255, + widget=forms.TextInput(attrs={'size': 40, 'class': 'openid-input'}) + ) + user = forms.CharField( + required=False, max_length=255, + widget=forms.TextInput(attrs={'size': 35}) + ) + email = forms.CharField( + required=False, max_length=255, + widget=forms.TextInput(attrs={'size': 35}) ) - openid = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 40, 'class':'openid-input'})) - user = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 35})) - email = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 35})) def __init__(self, *args, **kwargs): super(AskForm, self).__init__(*args, **kwargs) #hide ask_anonymously field - if askbot_settings.ALLOW_ASK_ANONYMOUSLY == False: + if askbot_settings.ALLOW_ASK_ANONYMOUSLY is False: self.hide_field('ask_anonymously') def clean_ask_anonymously(self): """returns false if anonymous asking is not allowed """ - if askbot_settings.ALLOW_ASK_ANONYMOUSLY == False: + if askbot_settings.ALLOW_ASK_ANONYMOUSLY is False: 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' ) + class AskByEmailForm(forms.Form): """:class:`~askbot.forms.AskByEmailForm` validates question data, where question was posted @@ -706,12 +804,13 @@ class AskByEmailForm(forms.Form): * ``email`` - email address * ``title`` - question title * ``tagnames`` - tag names all in one string - * ``body_text`` - body of question text - a pass-through, no extra validation + * ``body_text`` - body of question text - + a pass-through, no extra validation """ - sender = forms.CharField(max_length = 255) + sender = forms.CharField(max_length=255) subject = forms.CharField( - max_length = 255, - error_messages = { + max_length=255, + error_messages={ 'required': ASK_BY_EMAIL_SUBJECT_HELP } ) @@ -743,17 +842,19 @@ class AskByEmailForm(forms.Form): match = subject_re.match(raw_subject) if match: #make raw tags comma-separated - if match.group(1) is None:#no tags + if match.group(1) is None: # no tags self.cleaned_data['tagnames'] = '' else: - tagnames = match.group(1).replace(';',',') + tagnames = match.group(1).replace(';', ',') #pre-process tags tag_list = [tag.strip() for tag in tagnames.split(',')] tag_list = [re.sub(r'\s+', ' ', tag) for tag in tag_list] + if askbot_settings.REPLACE_SPACE_WITH_DASH_IN_EMAILED_TAGS: tag_list = [tag.replace(' ', '-') for tag in tag_list] - tagnames = ' '.join(tag_list)#todo: use tag separator char here + #todo: use tag separator char here + tagnames = ' '.join(tag_list) #clean tags - may raise ValidationError self.cleaned_data['tagnames'] = TagNamesField().clean(tagnames) @@ -765,22 +866,36 @@ class AskByEmailForm(forms.Form): raise forms.ValidationError(ASK_BY_EMAIL_SUBJECT_HELP) return self.cleaned_data['subject'] + class AnswerForm(forms.Form): - text = AnswerEditorField() - wiki = WikiField() - openid = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 40, 'class':'openid-input'})) - user = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 35})) - email = forms.CharField(required=False, max_length=255, widget=forms.TextInput(attrs={'size' : 35})) - email_notify = EmailNotifyField(initial = False) + text = AnswerEditorField() + wiki = WikiField() + openid = forms.CharField( + required=False, max_length=255, + widget=forms.TextInput(attrs={'size': 40, 'class': 'openid-input'}) + ) + user = forms.CharField( + required=False, max_length=255, + widget=forms.TextInput(attrs={'size': 35}) + ) + email = forms.CharField( + required=False, max_length=255, + widget=forms.TextInput(attrs={'size': 35}) + ) + email_notify = EmailNotifyField(initial=False) + def __init__(self, *args, **kwargs): super(AnswerForm, self).__init__(*args, **kwargs) - self.fields['email_notify'].widget.attrs['id'] = 'question-subscribe-updates' + self.fields['email_notify'].widget.attrs['id'] = \ + 'question-subscribe-updates' + class VoteForm(forms.Form): """form used in ajax vote view (only comment_upvote so far) """ post_id = forms.IntegerField() - cancel_vote = forms.CharField()#char because it is 'true' or 'false' as string + # char because it is 'true' or 'false' as string + cancel_vote = forms.CharField() def clean_cancel_vote(self): val = self.cleaned_data['cancel_vote'] @@ -790,7 +905,9 @@ class VoteForm(forms.Form): result = False else: del self.cleaned_data['cancel_vote'] - raise forms.ValidationError('either "true" or "false" strings expected') + raise forms.ValidationError( + 'either "true" or "false" strings expected' + ) self.cleaned_data['cancel_vote'] = result return self.cleaned_data['cancel_vote'] @@ -798,43 +915,57 @@ class VoteForm(forms.Form): class CloseForm(forms.Form): reason = forms.ChoiceField(choices=const.CLOSE_REASONS) + class RetagQuestionForm(forms.Form): tags = TagNamesField() - # initialize the default values + def __init__(self, question, *args, **kwargs): + """initialize the default values""" super(RetagQuestionForm, self).__init__(*args, **kwargs) self.fields['tags'].initial = question.thread.tagnames + class RevisionForm(forms.Form): """ Lists revisions of a Question or Answer """ - revision = forms.ChoiceField(widget=forms.Select(attrs={'style' : 'width:520px'})) + revision = forms.ChoiceField( + widget=forms.Select( + attrs={'style': 'width:520px'} + ) + ) def __init__(self, post, latest_revision, *args, **kwargs): super(RevisionForm, self).__init__(*args, **kwargs) revisions = post.revisions.values_list( - 'revision', 'author__username', 'revised_at', 'summary') + 'revision', 'author__username', 'revised_at', 'summary' + ) date_format = '%c' - self.fields['revision'].choices = [ - (r[0], u'%s - %s (%s) %s' % (r[0], r[1], r[2].strftime(date_format), r[3])) - for r in revisions] + rev_choices = list() + for r in revisions: + rev_details = u'%s - %s (%s) %s' % ( + r[0], r[1], r[2].strftime(date_format), r[3] + ) + rev_choices.append((r[0], rev_details)) + + self.fields['revision'].choices = rev_choices self.fields['revision'].initial = latest_revision.revision + class EditQuestionForm(forms.Form, FormWithHideableFields): - title = TitleField() - text = QuestionEditorField() - tags = TagNamesField() + title = TitleField() + text = QuestionEditorField() + tags = TagNamesField() summary = SummaryField() wiki = WikiField() reveal_identity = forms.BooleanField( - help_text = _( + help_text=_( 'You have asked this question anonymously, ' 'if you decide to reveal your identity, please check ' 'this box.' ), - label = _('reveal identity'), - required = False, + label=_('reveal identity'), + required=False, ) #todo: this is odd that this form takes question as an argument @@ -855,8 +986,8 @@ class EditQuestionForm(forms.Form, FormWithHideableFields): def can_stay_anonymous(self): """determines if the user cat keep editing the question anonymously""" - return (askbot_settings.ALLOW_ASK_ANONYMOUSLY \ - and self.question.is_anonymous \ + return (askbot_settings.ALLOW_ASK_ANONYMOUSLY + and self.question.is_anonymous and self.user.is_owner_of(self.question) ) @@ -882,7 +1013,7 @@ class EditQuestionForm(forms.Form, FormWithHideableFields): """ value = self.cleaned_data['reveal_identity'] if self.question.is_anonymous: - if value == True: + if value is True: if self.user.is_owner_of(self.question): #regardless of the ALLOW_ASK_ANONYMOUSLY return True @@ -900,7 +1031,7 @@ class EditQuestionForm(forms.Form, FormWithHideableFields): else: can_ask_anon = askbot_settings.ALLOW_ASK_ANONYMOUSLY is_owner = self.user.is_owner_of(self.question) - if can_ask_anon == False and is_owner: + if can_ask_anon is False and is_owner: self.show_field('reveal_identity') raise forms.ValidationError( _( @@ -924,11 +1055,12 @@ class EditQuestionForm(forms.Form, FormWithHideableFields): """ reveal_identity = self.cleaned_data.get('reveal_identity', False) stay_anonymous = False - if reveal_identity == False and self.can_stay_anonymous(): + if reveal_identity is False and self.can_stay_anonymous(): stay_anonymous = True self.cleaned_data['stay_anonymous'] = stay_anonymous return self.cleaned_data + class EditAnswerForm(forms.Form): text = AnswerEditorField() summary = SummaryField() @@ -939,40 +1071,42 @@ class EditAnswerForm(forms.Form): self.fields['text'].initial = revision.text self.fields['wiki'].initial = answer.wiki + class EditTagWikiForm(forms.Form): - text = forms.CharField(required = False) + text = forms.CharField(required=False) tag_id = forms.IntegerField() + class EditUserForm(forms.Form): email = forms.EmailField( label=u'Email', required=True, max_length=255, - widget=forms.TextInput(attrs={'size' : 35}) + widget=forms.TextInput(attrs={'size': 35}) ) realname = forms.CharField( label=_('Real name'), required=False, max_length=255, - widget=forms.TextInput(attrs={'size' : 35}) + widget=forms.TextInput(attrs={'size': 35}) ) website = forms.URLField( label=_('Website'), required=False, max_length=255, - widget=forms.TextInput(attrs={'size' : 35}) + widget=forms.TextInput(attrs={'size': 35}) ) city = forms.CharField( label=_('City'), required=False, max_length=255, - widget=forms.TextInput(attrs={'size' : 35}) + widget=forms.TextInput(attrs={'size': 35}) ) - country = CountryField(required = False) + country = CountryField(required=False) show_country = forms.BooleanField( label=_('Show country'), @@ -986,15 +1120,18 @@ class EditUserForm(forms.Form): birthday = forms.DateField( label=_('Date of birth'), - help_text=_('will not be shown, used to calculate age, format: YYYY-MM-DD'), + help_text=_( + 'will not be shown, used to calculate ' + 'age, format: YYYY-MM-DD' + ), required=False, - widget=forms.TextInput(attrs={'size' : 35}) + widget=forms.TextInput(attrs={'size': 35}) ) about = forms.CharField( label=_('Profile'), required=False, - widget=forms.Textarea(attrs={'cols' : 60}) + widget=forms.Textarea(attrs={'cols': 60}) ) def __init__(self, user, *args, **kwargs): @@ -1008,7 +1145,7 @@ class EditUserForm(forms.Form): self.fields['realname'].initial = user.real_name self.fields['website'].initial = user.website self.fields['city'].initial = user.location - if user.country == None: + if user.country is None: country = 'unknown' else: country = user.country @@ -1026,24 +1163,32 @@ class EditUserForm(forms.Form): """For security reason one unique email in database""" if self.user.email != self.cleaned_data['email']: #todo dry it, there is a similar thing in openidauth - if askbot_settings.EMAIL_UNIQUE == True: + if askbot_settings.EMAIL_UNIQUE is True: if 'email' in self.cleaned_data: try: - User.objects.get(email = self.cleaned_data['email']) + User.objects.get(email=self.cleaned_data['email']) except User.DoesNotExist: return self.cleaned_data['email'] except User.MultipleObjectsReturned: - raise forms.ValidationError(_('this email has already been registered, please use another one')) - raise forms.ValidationError(_('this email has already been registered, please use another one')) + raise forms.ValidationError(_( + 'this email has already been registered, ' + 'please use another one') + ) + raise forms.ValidationError(_( + 'this email has already been registered, ' + 'please use another one') + ) return self.cleaned_data['email'] + class TagFilterSelectionForm(forms.ModelForm): email_tag_filter_strategy = forms.ChoiceField( - choices = const.TAG_DISPLAY_FILTER_STRATEGY_CHOICES, - initial = const.EXCLUDE_IGNORED, - label = _('Choose email tag filter'), - widget = forms.RadioSelect + choices=const.TAG_DISPLAY_FILTER_STRATEGY_CHOICES, + initial=const.EXCLUDE_IGNORED, + label=_('Choose email tag filter'), + widget=forms.RadioSelect ) + class Meta: model = User fields = ('email_tag_filter_strategy',) @@ -1060,31 +1205,31 @@ class TagFilterSelectionForm(forms.ModelForm): class EmailFeedSettingField(forms.ChoiceField): def __init__(self, *arg, **kwarg): kwarg['choices'] = const.NOTIFICATION_DELIVERY_SCHEDULE_CHOICES - #kwarg['initial'] = askbot_settings.DEFAULT_NOTIFICATION_DELIVERY_SCHEDULE kwarg['widget'] = forms.RadioSelect super(EmailFeedSettingField, self).__init__(*arg, **kwarg) + class EditUserEmailFeedsForm(forms.Form): FORM_TO_MODEL_MAP = { - 'all_questions':'q_all', - 'asked_by_me':'q_ask', - 'answered_by_me':'q_ans', - 'individually_selected':'q_sel', - 'mentions_and_comments':'m_and_c', + 'all_questions': 'q_all', + 'asked_by_me': 'q_ask', + 'answered_by_me': 'q_ans', + 'individually_selected': 'q_sel', + 'mentions_and_comments': 'm_and_c', } NO_EMAIL_INITIAL = { - 'all_questions':'n', - 'asked_by_me':'n', - 'answered_by_me':'n', - 'individually_selected':'n', - 'mentions_and_comments':'n', + 'all_questions': 'n', + 'asked_by_me': 'n', + 'answered_by_me': 'n', + 'individually_selected': 'n', + 'mentions_and_comments': 'n', } INSTANT_EMAIL_INITIAL = { - 'all_questions':'i', - 'asked_by_me':'i', - 'answered_by_me':'i', - 'individually_selected':'i', - 'mentions_and_comments':'i', + 'all_questions': 'i', + 'asked_by_me': 'i', + 'answered_by_me': 'i', + 'individually_selected': 'i', + 'mentions_and_comments': 'i', } asked_by_me = EmailFeedSettingField( @@ -1107,7 +1252,7 @@ class EditUserEmailFeedsForm(forms.Form): def set_initial_values(self, user=None): from askbot import models KEY_MAP = dict([(v, k) for k, v in self.FORM_TO_MODEL_MAP.iteritems()]) - if user != None: + if user is not None: settings = models.EmailFeedSetting.objects.filter(subscriber=user) initial_values = {} for setting in settings: @@ -1137,7 +1282,7 @@ class EditUserEmailFeedsForm(forms.Form): """ return self.FORM_TO_MODEL_MAP.values() - def set_frequency(self, frequency = 'n'): + def set_frequency(self, frequency='n'): data = { 'all_questions': frequency, 'asked_by_me': frequency, @@ -1149,9 +1294,9 @@ class EditUserEmailFeedsForm(forms.Form): self.cleaned_data = data self.initial = data - def save(self,user,save_unbound=False): - """ - with save_unbound==True will bypass form validation and save initial values + def save(self, user, save_unbound=False): + """with save_unbound==True will bypass form + validation and save initial values """ from askbot import models changed = False @@ -1179,23 +1324,25 @@ class EditUserEmailFeedsForm(forms.Form): user.followed_threads.clear() return changed + class SubscribeForEmailUpdatesField(forms.ChoiceField): """a simple yes or no field to subscribe for email or not""" def __init__(self, **kwargs): kwargs['widget'] = forms.widgets.RadioSelect kwargs['error_messages'] = { - 'required':_('please choose one of the options above') + 'required': _('please choose one of the options above') } kwargs['choices'] = ( - ('y',_('okay, let\'s try!')), + ('y', _('okay, let\'s try!')), ( 'n', - _('no %(sitename)s email please, thanks') \ + _('no %(sitename)s email please, thanks') % {'sitename': askbot_settings.APP_SHORT_NAME} ) ) super(SubscribeForEmailUpdatesField, self).__init__(**kwargs) + class SimpleEmailSubscribeForm(forms.Form): subscribe = SubscribeForEmailUpdatesField() @@ -1211,11 +1358,13 @@ class SimpleEmailSubscribeForm(forms.Form): email_settings_form = EFF(initial=EFF.NO_EMAIL_INITIAL) email_settings_form.save(user, save_unbound=True) + class GroupLogoURLForm(forms.Form): """form for saving group logo url""" group_id = forms.IntegerField() image_url = forms.CharField() + class EditGroupMembershipForm(forms.Form): """a form for adding or removing users to and from user groups""" @@ -1231,11 +1380,12 @@ class EditGroupMembershipForm(forms.Form): raise forms.ValidationError('invalid action') return action + class EditRejectReasonForm(forms.Form): - reason_id = forms.IntegerField(required = False) + reason_id = forms.IntegerField(required=False) title = CountedWordsField( - min_words = 1, max_words = 4, field_name = _('Title') + min_words=1, max_words=4, field_name=_('Title') ) details = CountedWordsField( - min_words = 6, field_name = _('Description') + min_words=6, field_name=_('Description') ) -- cgit v1.2.3-1-g7c22