Skip to content

Commit 8d3d6e2

Browse files
committed
* askbot.models.user:
- Group.objects.get_or_create() - adds visibility parameter, returns tuple (group, created) to match the behavior of django.db.models.Manager.get_or_create() switch to this signature where this method is used - PEP8 cleanup * adds test case for askbot_create_per_email_domain_groups
1 parent 5f1a856 commit 8d3d6e2

12 files changed

+274
-236
lines changed
Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
"""A management command that creates groups for each email domain in the database."""
22
from django.core.management.base import BaseCommand
3-
from askbot.conf import settings
4-
from askbot.models import User
5-
from askbot.models.analytics import get_organization_domains
3+
from askbot.conf import settings as askbot_settings
4+
from askbot.models import Group, User
5+
from askbot.models.analytics import get_unique_user_email_domains_qs
66
from askbot.models.user import get_organization_name_from_domain
77
from askbot.utils.console import ProgressBar
88

@@ -14,14 +14,31 @@ def handle(self, *args, **options): # pylint: disable=missing-docstring, unused-
1414
Creates a group for each domain name, if such group does not exist.
1515
Group visibility is set to the value of settings.PER_EMAIL_DOMAIN_GROUP_DEFAULT_VISIBILITY.
1616
"""
17-
domains = get_organization_domains()
17+
domains = get_unique_user_email_domains_qs()
1818
count = len(domains)
19-
message = 'Initializing groups by the email address domain names'
20-
for domain in ProgressBar(domains, count, message):
21-
organization_name = get_organization_name_from_domain(domain)
22-
group = User.objects.get_or_create_group(
23-
organization_name,
24-
visibility=settings.PER_EMAIL_DOMAIN_GROUP_DEFAULT_VISIBILITY
19+
message = 'Creating groups by the email address domain names'
20+
created_groups = []
21+
unchanged_groups = []
22+
done_lowercased_domains = []
23+
for domain in ProgressBar(domains.iterator(), count, message):
24+
25+
domain_name = domain['domain']
26+
if domain_name.lower in done_lowercased_domains:
27+
continue
28+
else:
29+
done_lowercased_domains.append(domain_name.lower())
30+
31+
organization_name = get_organization_name_from_domain(domain_name)
32+
group, created = Group.objects.get_or_create(
33+
name=organization_name,
34+
visibility=askbot_settings.PER_EMAIL_DOMAIN_GROUP_DEFAULT_VISIBILITY
2535
)
26-
print('Group {0} created.'.format(group.name))
36+
users = User.objects.filter(email__endswith='@' + domain_name)
37+
for user in users.iterator():
38+
user.join_group(group, force=True)
39+
40+
if created:
41+
created_groups.append(group)
42+
else:
43+
unchanged_groups.append(group)
2744

askbot/media/js/utils/lang_nav.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ LangNav.prototype.translateUrl = function(url, lang) {
1313
type: 'GET',
1414
url: askbot['urls']['translateUrl'],
1515
data: {'url': url, 'language': lang },
16-
async: false,
16+
async: false, //important!
1717
cache: false,
1818
dataType: 'json',
1919
success: function(data) {

askbot/models/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2946,7 +2946,7 @@ def user_join_default_groups(self):
29462946
group = Group.objects.get_global_group()
29472947
self.join_group(group, force=True)
29482948
group_name = format_personal_group_name(self)
2949-
group = Group.objects.get_or_create(name=group_name, user=self)
2949+
group, _ = Group.objects.get_or_create(name=group_name, user=self)
29502950
self.join_group(group, force=True)
29512951

29522952
def user_get_personal_group(self):

askbot/models/analytics.py

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ def get_non_admins_count():
9090
return non_admins.count()
9191

9292

93-
def get_organization_domains():
93+
def get_unique_user_email_domains_qs():
9494
"""Returns the query set of organization domain names"""
9595
domain_annotation = Substr('email', StrIndex('email', Value('@')) + 1)
9696
return User.objects.annotate(domain=domain_annotation).values('domain').distinct()
@@ -102,7 +102,12 @@ def get_organizations_count():
102102
"""
103103
if not django_settings.ASKBOT_ANALYTICS_EMAIL_DOMAIN_ORGANIZATIONS_ENABLED:
104104
return 0
105-
return get_organization_domains().count()
105+
return get_unique_user_email_domains_qs().count()
106+
107+
108+
def get_unique_user_email_domains():
109+
"""Returns a list of unique email domain names"""
110+
return list(get_user_organization_domains_qs().values_list('domain', flat=True))
106111

107112

108113
class Session(models.Model):

askbot/models/user.py

Lines changed: 28 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -89,7 +89,7 @@ def remove_email_from_invited_moderators(email):
8989
"""Update the `INVITED_MODERATORS` setting by removing
9090
the matching email entry"""
9191
lines = askbot_settings.INVITED_MODERATORS.strip().split('\n')
92-
clean_lines = list()
92+
clean_lines = []
9393
prefix = email + ' '
9494
for line in lines:
9595
if not line.startswith(prefix):
@@ -157,15 +157,15 @@ def fetch_content_objects_dict(self):
157157
"""return a dictionary where keys are activity ids
158158
and values - content objects"""
159159
content_object_ids = defaultdict(list)# lists of c.object ids by c.types
160-
activity_type_ids = dict()#links c.objects back to activity objects
160+
activity_type_ids = {} #links c.objects back to activity objects
161161
for act in self:
162162
content_type_id = act.content_type_id
163163
object_id = act.object_id
164164
content_object_ids[content_type_id].append(object_id)
165165
activity_type_ids[(content_type_id, object_id)] = act.id
166166

167167
#3) get links from activity objects to content objects
168-
objects_by_activity = dict()
168+
objects_by_activity = {}
169169
for content_type_id, object_id_list in list(content_object_ids.items()):
170170
content_type = ContentType.objects.get_for_id(content_type_id)
171171
model_class = content_type.model_class()
@@ -193,7 +193,7 @@ def create_new_mention(
193193
):
194194

195195
#todo: automate this using python inspect module
196-
kwargs = dict()
196+
kwargs = {}
197197

198198
kwargs['activity_type'] = const.TYPE_ACTIVITY_MENTION
199199

@@ -241,7 +241,7 @@ def get_mentions(
241241
todo: implement better rich field lookups
242242
"""
243243

244-
kwargs = dict()
244+
kwargs = {}
245245

246246
kwargs['activity_type'] = const.TYPE_ACTIVITY_MENTION
247247

@@ -571,28 +571,34 @@ def create(self, **kwargs):
571571
kwargs['group_ptr'] = group_ptr
572572
except AuthGroup.DoesNotExist:
573573
pass
574-
return super(GroupManager, self).create(**kwargs)
574+
return super().create(**kwargs)
575575

576-
def get_or_create(self, name=None, user=None, openness=None):
576+
def get_or_create(self, name=None, user=None, openness=None, visibility=None):
577577
"""creates a group tag or finds one, if exists"""
578578
#todo: here we might fill out the group profile
579579
try:
580-
#iexact is important!!! b/c we don't want case variants
581-
#of tags
580+
#iexact is important!!! b/c we don't want case variants of groups
582581
group = self.get(name__iexact = name)
582+
created = False
583583
except self.model.DoesNotExist:
584+
default_visibility = askbot_settings.PER_EMAIL_DOMAIN_GROUP_DEFAULT_VISIBILITY
585+
if visibility is None:
586+
visibility = default_visibility
587+
584588
if openness is None:
585-
group = self.create(name=name)
586-
else:
587-
group = self.create(name=name, openness=openness)
588-
return group
589+
openness = self.model.DEFAULT_OPENNESS
590+
591+
group = self.create(name=name, openness=openness, visibility=visibility)
592+
created = True
593+
return group, created
589594

590595

591596
class Group(AuthGroup):
592597
"""group profile for askbot"""
593598
OPEN = 0
594599
MODERATED = 1
595600
CLOSED = 2
601+
DEFAULT_OPENNESS = CLOSED
596602
OPENNESS_CHOICES = (
597603
(OPEN, 'open'),
598604
(MODERATED, 'moderated'),
@@ -610,7 +616,7 @@ class Group(AuthGroup):
610616
can_upload_attachments = models.BooleanField(default=False)
611617
can_upload_images = models.BooleanField(default=False)
612618

613-
openness = models.SmallIntegerField(default=CLOSED, choices=OPENNESS_CHOICES)
619+
openness = models.SmallIntegerField(default=DEFAULT_OPENNESS, choices=OPENNESS_CHOICES)
614620
visibility = models.SmallIntegerField(default=const.GROUP_VISIBILITY_PUBLIC,
615621
choices=const.GROUP_VISIBILITY_CHOICES)
616622

@@ -695,27 +701,27 @@ def clean(self):
695701
emails = functions.split_list(self.preapproved_emails)
696702
email_field = EmailField()
697703
try:
698-
list(map(lambda v: email_field.clean(v), emails))
699-
except exceptions.ValidationError:
704+
list(map(email_field.clean, emails))
705+
except exceptions.ValidationError as exc:
700706
raise exceptions.ValidationError(
701707
_('Please give a list of valid email addresses.')
702-
)
708+
) from exc
703709
self.preapproved_emails = ' ' + '\n'.join(emails) + ' '
704710

705711
domains = functions.split_list(self.preapproved_email_domains)
706712
from askbot.forms import DomainNameField
707713
domain_field = DomainNameField()
708714
try:
709-
list(map(lambda v: domain_field.clean(v), domains))
710-
except exceptions.ValidationError:
715+
list(map(domain_field.clean, domains))
716+
except exceptions.ValidationError as exc:
711717
raise exceptions.ValidationError(
712718
_('Please give a list of valid email domain names.')
713-
)
719+
) from exc
714720
self.preapproved_email_domains = ' ' + '\n'.join(domains) + ' '
715721

716722
def save(self, *args, **kwargs):
717723
self.clean()
718-
super(Group, self).save(*args, **kwargs)
724+
super().save(*args, **kwargs)
719725

720726

721727
class BulkTagSubscriptionManager(BaseQuerySetManager): # pylint: disable=too-few-public-methods
@@ -735,7 +741,7 @@ def create(
735741
user_list = user_list or []
736742
group_list = group_list or []
737743

738-
new_object = super(BulkTagSubscriptionManager, self).create(**kwargs)
744+
new_object = super().create(**kwargs)
739745
tag_name_list = []
740746

741747
if tag_names:

askbot/tests/test_management_commands.py

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -376,3 +376,15 @@ def test_askbot_send_moderation_alerts1(self):
376376
#command sends alerts to three moderators at a time
377377
self.assertEqual(len(mail.outbox), 2)
378378
self.assertTrue('moderation' in mail.outbox[0].subject)
379+
380+
381+
def test_askbot_create_per_email_domain_groups(self):
382+
user1 = self.create_user('org1', '[email protected]')
383+
user2 = self.create_user('org2', '[email protected]')
384+
count = models.Group.objects.filter(name__in=('Org1', 'Org2')).count()
385+
self.assertEqual(count, 0)
386+
management.call_command('askbot_create_per_email_domain_groups')
387+
count = models.Group.objects.filter(name__in=('Org1', 'Org2')).count()
388+
self.assertEqual(count, 2)
389+
390+

askbot/tests/test_markup.py

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -130,7 +130,5 @@ def test_convert_mixed_text(self):
130130
"""
131131
"""<a href="http://example.com"><div>http://example.com</div></a>
132132
"""
133-
import pdb
134-
pdb.set_trace()
135133
converted = self.conv(text)
136134
self.assertHTMLEqual(converted, expected)

askbot/tests/test_thread_model.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def setUp(self):
2929
self.user.new_response_count = 0
3030
self.user.seen_response_count = 0
3131
self.user.save()
32-
self.group = models.Group.objects.get_or_create(name='jockeys')
32+
self.group = models.Group.objects.get_or_create(name='jockeys')[0]
3333
self.group.can_post_questions = True
3434
self.group.can_post_answers = True
3535
self.group.can_post_comments = True

askbot/tests/utils.py

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -316,9 +316,7 @@ def create_tag(self, tag_name, user = None):
316316
return tag
317317

318318
def create_group(self, group_name=None, openness=models.Group.OPEN):
319-
return models.Group.objects.get_or_create(
320-
name='private', openness=openness
321-
)
319+
return models.Group.objects.get_or_create(name='private', openness=openness)[0]
322320

323321
def post_comment(
324322
self,

askbot/utils/decorators.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@ def wrapper(request, *args, **kwargs):
8787
data = view_func(request, *args, **kwargs)
8888
if data is None:
8989
data = {}
90-
except Exception as e:
90+
except Exception as e: # pylint: disable=broad-except
9191
#todo: also check field called "message"
9292
if hasattr(e, 'messages'):
9393
if len(e.messages) > 1:

askbot/utils/http.py

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,25 @@
11
"""http-related utilities for askbot
22
"""
33
from copy import copy
4+
from askbot.conf import settings as askbot_settings
45

56
def is_ajax(request):
67
"""Returns `True` if request is ajax"""
78
return request.META.get('HTTP_X_REQUESTED_WITH') == 'XMLHttpRequest'
89

910

11+
def can_save_draft(request):
12+
"""Returns `True` if the user is allowed to save drafts"""
13+
return not any((
14+
request.user.is_anonymous,
15+
request.user.is_read_only(),
16+
not request.user.is_active,
17+
request.user.is_blocked(),
18+
request.user.is_suspended(),
19+
askbot_settings.READ_ONLY_MODE_ENABLED,
20+
))
21+
22+
1023
def hide_passwords(data):
1124
"""replaces content of values that may contain passsword
1225
with XXXXXX for better security"""

0 commit comments

Comments
 (0)