summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-05-08 11:51:01 -0400
committerEvgeny Fadeev <evgeny.fadeev@gmail.com>2012-05-08 11:51:01 -0400
commit7ca0c514c2d1fabdcf3d12b0a371d56584f0cb8e (patch)
tree2930f757fcfe037e7d37bf2cc0e57939377694a8
parent0c46a9b987373e5a791cf1c5bd731a682aa652c6 (diff)
downloadaskbot-7ca0c514c2d1fabdcf3d12b0a371d56584f0cb8e.tar.gz
askbot-7ca0c514c2d1fabdcf3d12b0a371d56584f0cb8e.tar.bz2
askbot-7ca0c514c2d1fabdcf3d12b0a371d56584f0cb8e.zip
preapproved emails and email domains work for the groups
-rw-r--r--askbot/forms.py17
-rw-r--r--askbot/models/user.py41
-rw-r--r--askbot/skins/common/media/jquery-openid/openid.css2
-rw-r--r--askbot/skins/common/media/js/utils.js21
-rw-r--r--askbot/skins/default/media/style/style.less4
-rw-r--r--askbot/utils/decorators.py16
-rw-r--r--askbot/utils/functions.py19
-rw-r--r--askbot/views/commands.py9
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()