diff options
author | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2012-05-08 11:51:01 -0400 |
---|---|---|
committer | Evgeny Fadeev <evgeny.fadeev@gmail.com> | 2012-05-08 11:51:01 -0400 |
commit | 7ca0c514c2d1fabdcf3d12b0a371d56584f0cb8e (patch) | |
tree | 2930f757fcfe037e7d37bf2cc0e57939377694a8 | |
parent | 0c46a9b987373e5a791cf1c5bd731a682aa652c6 (diff) | |
download | askbot-7ca0c514c2d1fabdcf3d12b0a371d56584f0cb8e.tar.gz askbot-7ca0c514c2d1fabdcf3d12b0a371d56584f0cb8e.tar.bz2 askbot-7ca0c514c2d1fabdcf3d12b0a371d56584f0cb8e.zip |
preapproved emails and email domains work for the groups
-rw-r--r-- | askbot/forms.py | 17 | ||||
-rw-r--r-- | askbot/models/user.py | 41 | ||||
-rw-r--r-- | askbot/skins/common/media/jquery-openid/openid.css | 2 | ||||
-rw-r--r-- | askbot/skins/common/media/js/utils.js | 21 | ||||
-rw-r--r-- | askbot/skins/default/media/style/style.less | 4 | ||||
-rw-r--r-- | askbot/utils/decorators.py | 16 | ||||
-rw-r--r-- | askbot/utils/functions.py | 19 | ||||
-rw-r--r-- | askbot/views/commands.py | 9 |
8 files changed, 103 insertions, 26 deletions
diff --git a/askbot/forms.py b/askbot/forms.py index c5b72365..f1d8ce55 100644 --- a/askbot/forms.py +++ b/askbot/forms.py @@ -1,6 +1,5 @@ import re from django import forms -from askbot import models from askbot import const from django.utils.translation import ugettext_lazy as _ from django.utils.translation import ungettext_lazy, string_concat @@ -143,6 +142,17 @@ class CountedWordsField(forms.CharField): ) return value + +class DomainNameField(forms.CharField): + 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) + + class TitleField(forms.CharField): def __init__(self, *args, **kwargs): super(TitleField, self).__init__(*args, **kwargs) @@ -245,6 +255,7 @@ class TagNamesField(forms.CharField): 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): @@ -257,6 +268,7 @@ class TagNamesField(forms.CharField): 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: @@ -265,6 +277,7 @@ class TagNamesField(forms.CharField): return True def clean(self, value): + from askbot import models value = super(TagNamesField, self).clean(value) data = value.strip() if len(data) < 1: @@ -1086,6 +1099,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: settings = models.EmailFeedSetting.objects.filter(subscriber=user) @@ -1133,6 +1147,7 @@ class EditUserEmailFeedsForm(forms.Form): """ with save_unbound==True will bypass form validation and save initial values """ + from askbot import models changed = False for form_field, feed_type in self.FORM_TO_MODEL_MAP.items(): s, created = models.EmailFeedSetting.objects.get_or_create( diff --git a/askbot/models/user.py b/askbot/models/user.py index e6bd6e1d..2e4bbda5 100644 --- a/askbot/models/user.py +++ b/askbot/models/user.py @@ -1,15 +1,19 @@ import datetime import logging +import re from django.db import models from django.db.backends.dummy.base import IntegrityError from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes import generic from django.contrib.auth.models import User +from django.core import exceptions +from django.forms import EmailField, URLField from django.utils.translation import ugettext as _ from django.utils.html import strip_tags from askbot import const from askbot.utils import functions from askbot.models.tag import Tag +from askbot.forms import DomainNameField class ResponseAndMentionActivityManager(models.Manager): def get_query_set(self): @@ -359,9 +363,9 @@ class GroupProfile(models.Model): is_open = models.BooleanField(default = False) #preapproved email addresses and domain names to auto-join groups #trick - the field is padded with space and all tokens are space separated - preapproved_emails = models.TextField(null = True) + preapproved_emails = models.TextField(null = True, blank = True) #only domains - without the '@' or anything before them - preapproved_email_domains = models.TextField(null = True) + preapproved_email_domains = models.TextField(null = True, blank = True) class Meta: app_label = 'askbot' @@ -378,8 +382,37 @@ class GroupProfile(models.Model): return True #relying on a specific method of storage - if (' %s ' % user.email) in self.preapproved_emails: + email_match_re = re.compile(r'\s%s\s' % user.email) + if email_match_re.search(self.preapproved_emails): return True email_domain = user.email.split('@')[1] - return (' %s ' % email_domain) in self.preapproved_email_domains + domain_match_re = re.compile(r'\s%s\s' % email_domain) + return domain_match_re.search(self.preapproved_email_domains) + + def clean(self): + """called in `save()` + """ + emails = functions.split_list(self.preapproved_emails) + email_field = EmailField() + try: + map(lambda v: email_field.clean(v), emails) + except exceptions.ValidationError: + raise exceptions.ValidationError( + _('Please give a list of valid email addresses.') + ) + self.preapproved_emails = ' ' + '\n'.join(emails) + ' ' + + domains = functions.split_list(self.preapproved_email_domains) + domain_field = DomainNameField() + try: + map(lambda v: domain_field.clean(v), domains) + except exceptions.ValidationError: + raise exceptions.ValidationError( + _('Please give a list of valid email domain names.') + ) + self.preapproved_email_domains = ' ' + '\n'.join(domains) + ' ' + + def save(self, *args, **kwargs): + self.clean() + super(GroupProfile, self).save(*args, **kwargs) diff --git a/askbot/skins/common/media/jquery-openid/openid.css b/askbot/skins/common/media/jquery-openid/openid.css index f9430108..ec93881d 100644 --- a/askbot/skins/common/media/jquery-openid/openid.css +++ b/askbot/skins/common/media/jquery-openid/openid.css @@ -2,7 +2,7 @@ div#login-icons {padding:20px 0 0 0;} ul.login-icons {width: 450px; margin:0;padding:0;text-align:left; list-style-type:none; display:block;} ul.login-icons li {display:inline;} ul.large input {height: 40px; width: 90px;border:1px solid #ccc;margin:0 5px 5px 0;} -.openid-signin h1 {margin-top: -15px; padding-bottom: 10px;} +.openid-signin h1 {padding-bottom: 10px;} .openid-signin h2 {margin-top:15px;} .openid-signin h2#account-recovery-heading {margin-bottom:2px;} #account-recovery-form p.hint a {color:#1b79bd; text-decoration: none;} diff --git a/askbot/skins/common/media/js/utils.js b/askbot/skins/common/media/js/utils.js index f01f5bcf..c82913a8 100644 --- a/askbot/skins/common/media/js/utils.js +++ b/askbot/skins/common/media/js/utils.js @@ -588,26 +588,23 @@ TextPropertyEditor.prototype.clearMessages = function(){ }; TextPropertyEditor.prototype.getAlert = function(){ - if (this._alert) { - return this._alert; - } else { - var box = new AlertBox(); - this._alert = box; - this._editor.find('.modal-body').prepend(box.getElement()); - return box; - } + var box = new AlertBox(); + var modal_body = this._editor.find('.modal-body'); + modal_body.prepend(box.getElement()); + return box; }; TextPropertyEditor.prototype.showAlert = function(text){ + this.clearMessages(); var box = this.getAlert(); - box.setError(false); box.setText(text); + return box; }; TextPropertyEditor.prototype.showError = function(text){ - var box = this.getAlert(); + var box = this.showAlert(text); box.setError(true); - box.setText(text); + return box; }; TextPropertyEditor.prototype.setText = function(text){ @@ -633,7 +630,7 @@ TextPropertyEditor.prototype.startOpeningEditor = function(){ success: function(data){ if (data['success']) { me.makeEditor(); - me.setText(data['text']); + me.setText($.trim(data['text'])); me.openEditor(); } else { showMessage(me.getElement(), data['message']); diff --git a/askbot/skins/default/media/style/style.less b/askbot/skins/default/media/style/style.less index 27424871..5bb0bb11 100644 --- a/askbot/skins/default/media/style/style.less +++ b/askbot/skins/default/media/style/style.less @@ -3537,3 +3537,7 @@ textarea.tipped-input { .modal p { font-size: 14px; } +.modal-body > textarea { + width: 515px; + margin-bottom: 0px; +} diff --git a/askbot/utils/decorators.py b/askbot/utils/decorators.py index cfdc0a5d..940c3654 100644 --- a/askbot/utils/decorators.py +++ b/askbot/utils/decorators.py @@ -87,7 +87,17 @@ def ajax_only(view_func): if data is None: data = {} except Exception, e: - message = unicode(e) + if isinstance(e, Exception): + if len(e.messages) > 1: + message = u'<ul>' + \ + u''.join( + map(lambda v: u'<li>%s</li>' % v, e.messages) + ) + \ + u'</ul>' + else: + message = e.messages[0] + else: + message = unicode(e) if message == '': message = _('Oops, apologies - there was some error') logging.debug(message) @@ -225,9 +235,9 @@ def admins_only(view_func): @functools.wraps(view_func) def decorator(request, *args, **kwargs): if request.user.is_anonymous(): - raise exceptions.PermissionDenied() + raise django_exceptions.PermissionDenied() if not request.user.is_administrator_or_moderator(): - raise exceptions.PermissionDenied( + raise django_exceptions.PermissionDenied( _('This function is limited to moderators and administrators') ) return view_func(request, *args, **kwargs) diff --git a/askbot/utils/functions.py b/askbot/utils/functions.py index 6042414c..f9d36534 100644 --- a/askbot/utils/functions.py +++ b/askbot/utils/functions.py @@ -18,6 +18,25 @@ def enumerate_string_list(strings): numbered_strings = enumerate(strings, start = 1) return [ '%d) %s' % item for item in numbered_strings ] +def pad_string(text): + """Inserts one space between words, + including one space before the first word + and after the last word. + String without words is collapsed to '' + """ + words = text.strip().split() + if len(words) > 0: + return ' ' + ' '.join(words) + ' ' + else: + return '' + +def split_list(text): + """Takes text, representing a loosely formatted + list (comma, semicolon, empty space separated + words) and returns a list() of words. + """ + text = text.replace(',', ' ').replace(';', ' ') + return text.strip().split() def is_iterable(thing): if hasattr(thing, '__iter__'): diff --git a/askbot/views/commands.py b/askbot/views/commands.py index 62db014f..59589b62 100644 --- a/askbot/views/commands.py +++ b/askbot/views/commands.py @@ -839,14 +839,13 @@ def edit_object_property_text(request): if (model_name, property_name) not in accessible_fields: raise exceptions.PermissionDenied() - query_set = models.get_model(model_name).objects.filter(id=object_id) + obj = models.get_model(model_name).objects.get(id=object_id) if request.method == 'POST': text = CharField().clean(request.POST['text']) - params = dict() - params[str(property_name)] = text #dammit str() - query_set.update(**params) + setattr(obj, property_name, text) + obj.save() elif request.method == 'GET': - return {'text': getattr(query_set[0], property_name)} + return {'text': getattr(obj, property_name)} else: raise exceptions.PermissionDenied() |