summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAdolfo Fitoria <adolfo.fitoria@gmail.com>2012-08-29 09:30:33 -0600
committerAdolfo Fitoria <adolfo.fitoria@gmail.com>2012-08-29 09:30:33 -0600
commitf39380e089ac30845589756f44b49e4e059fcf78 (patch)
tree020accb3f25df5890d0dd2552635be094f4de2f3
parentcac82a75d32938bd2c598e3b0c415bb269985e0a (diff)
parent8278bbeffc5346800ee12c7fae41c1c2d3fd14f7 (diff)
downloadaskbot-f39380e089ac30845589756f44b49e4e059fcf78.tar.gz
askbot-f39380e089ac30845589756f44b49e4e059fcf78.tar.bz2
askbot-f39380e089ac30845589756f44b49e4e059fcf78.zip
Merge branch 'user-groups' of github.com:ASKBOT/askbot-devel into user-groups
Conflicts: askbot/context.py askbot/models/post.py askbot/models/tag.py askbot/tests/db_api_tests.py askbot/views/users.py
-rw-r--r--askbot/context.py7
-rw-r--r--askbot/mail/lamson_handlers.py11
-rw-r--r--askbot/migrations/0137_migrate_data_to_internal_group_models.py20
-rw-r--r--askbot/migrations/0138_del__old_group_models.py69
-rw-r--r--askbot/models/__init__.py23
-rw-r--r--askbot/models/post.py36
-rw-r--r--askbot/models/question.py22
-rw-r--r--askbot/models/tag.py83
-rw-r--r--askbot/models/user.py86
-rw-r--r--askbot/skins/default/templates/widgets/group_info.html18
-rw-r--r--askbot/tests/db_api_tests.py22
-rw-r--r--askbot/tests/page_load_tests.py4
-rw-r--r--askbot/tests/thread_model_tests.py4
-rw-r--r--askbot/tests/user_model_tests.py6
-rw-r--r--askbot/tests/utils.py5
-rw-r--r--askbot/views/commands.py42
-rw-r--r--askbot/views/users.py20
17 files changed, 259 insertions, 219 deletions
diff --git a/askbot/context.py b/askbot/context.py
index 30718972..2dace3eb 100644
--- a/askbot/context.py
+++ b/askbot/context.py
@@ -59,10 +59,9 @@ def application_settings(request):
}
if askbot_settings.GROUPS_ENABLED:
- groups = models.Tag.group_tags.get_all().filter(
- deleted=False
- ).exclude(
- name__startswith='_internal_').values('id', 'name')
+ groups = models.Group.objects.exclude(
+ name__startswith='_internal_'
+ ).values('id', 'name')
group_list = []
for group in groups:
group_slug = slugify(group['name'])
diff --git a/askbot/mail/lamson_handlers.py b/askbot/mail/lamson_handlers.py
index 6bafbc3f..59d707c7 100644
--- a/askbot/mail/lamson_handlers.py
+++ b/askbot/mail/lamson_handlers.py
@@ -6,7 +6,7 @@ from django.template import Context
from django.utils.translation import ugettext as _
from lamson.routing import route, stateless
from lamson.server import Relay
-from askbot.models import ReplyAddress, Tag
+from askbot.models import ReplyAddress, Group, Tag
from askbot import mail
from askbot.conf import settings as askbot_settings
from askbot.skins.loaders import get_template
@@ -199,15 +199,12 @@ def ASK(message, host = None, addr = None):
if askbot_settings.GROUP_EMAIL_ADDRESSES_ENABLED == False:
return
try:
- group_tag = Tag.group_tags.get(
- deleted = False,
- name__iexact = addr
- )
+ group = Group.objects.get(name__iexact=addr)
mail.process_emailed_question(
from_address, subject, body_text, stored_files,
- group_id = group_tag.id
+ group_id = group.id
)
- except Tag.DoesNotExist:
+ except Group.DoesNotExist:
#do nothing because this handler will match all emails
return
except Tag.MultipleObjectsReturned:
diff --git a/askbot/migrations/0137_migrate_data_to_internal_group_models.py b/askbot/migrations/0137_migrate_data_to_internal_group_models.py
index 92fb72d6..0f18846e 100644
--- a/askbot/migrations/0137_migrate_data_to_internal_group_models.py
+++ b/askbot/migrations/0137_migrate_data_to_internal_group_models.py
@@ -3,6 +3,7 @@ import datetime
from south.db import db
from south.v2 import DataMigration
from django.db import models
+from askbot.utils.console import ProgressBar
class Migration(DataMigration):
@@ -10,14 +11,12 @@ class Migration(DataMigration):
"Write your forwards methods here."
profiles = orm['askbot.GroupProfile'].objects.all()
- print 'Transfering group information from Tag to Group model'
- for profile in profiles.iterator():
+ items = profiles.iterator()
+ count = profiles.count()
+ message = 'Transfering group information from Tag to Group model'
+ for profile in ProgressBar(items, count, message):
group_tag = profile.group_tag
group_name = group_tag.name.replace('-', ' ')
- if group_name.startswith('_internal_'):
- group_name = group_name.replace('_internal_', '', 1)
- print 'Group: %s' % group_name
-
group = orm['askbot.Group']()
group.name = group_name
group.logo_url = profile.logo_url
@@ -30,31 +29,28 @@ class Migration(DataMigration):
#see if such group is already there
auth_group = orm['auth.Group'].objects.get(name=group_name)
group.group_ptr = auth_group
- print 'merging with Django group'
except orm['auth.Group'].DoesNotExist:
pass
group.save()
- print 'moving users'
memberships = group_tag.user_memberships.iterator()
for old_membership in memberships:
old_membership.user.groups.add(group)
- print 'moving threads'
threads = orm['askbot.Thread'].objects.filter(groups=group_tag)
for thread in threads:
thread.new_groups.add(group)
thread.groups.remove(group_tag)
- print 'moving posts'
posts = orm['askbot.Post'].objects.filter(groups=group_tag)
for post in posts:
post.new_groups.add(group)
post.groups.remove(group_tag)
- print 'Deleting old group information'
- for profile in profiles.iterator():
+ message = 'Deleting old group information'
+ items = profiles.iterator()
+ for profile in ProgressBar(items, count, message):
group_tag = profile.group_tag
group_tag.user_memberships.all().delete()
profile.delete()
diff --git a/askbot/migrations/0138_del__old_group_models.py b/askbot/migrations/0138_del__old_group_models.py
new file mode 100644
index 00000000..a91eccb1
--- /dev/null
+++ b/askbot/migrations/0138_del__old_group_models.py
@@ -0,0 +1,69 @@
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Removing unique constraint on 'GroupMembership', fields ['group', 'user']
+ db.delete_unique('askbot_groupmembership', ['group_id', 'user_id'])
+
+ # Removing unique constraint on 'PostToGroup', fields ['post', 'tag']
+ db.delete_unique('askbot_post_groups_old', ['post_id', 'tag_id'])
+ # Removing M2M table for field groups on 'Post'
+ db.delete_table('askbot_post_groups_old')
+
+ # Deleting model 'GroupProfile'
+ db.delete_table('askbot_groupprofile')
+
+ # Deleting model 'GroupMembership'
+ db.delete_table('askbot_groupmembership')
+
+ # Removing M2M table for field new_groups on 'Thread'
+ db.delete_unique('askbot_thread_groups_old', ['thread_id', 'tag_id'])
+ db.delete_table('askbot_thread_groups_old')
+
+ def backwards(self, orm):
+ # Adding model 'GroupProfile'
+ db.create_table('askbot_groupprofile', (
+ ('preapproved_emails', self.gf('django.db.models.fields.TextField')(default='', null=True, blank=True)),
+ ('is_open', self.gf('django.db.models.fields.BooleanField')(default=False)),
+ ('preapproved_email_domains', self.gf('django.db.models.fields.TextField')(default='', null=True, blank=True)),
+ ('moderate_email', self.gf('django.db.models.fields.BooleanField')(default=True)),
+ ('logo_url', self.gf('django.db.models.fields.URLField')(max_length=200, null=True)),
+ ('group_tag', self.gf('django.db.models.fields.related.OneToOneField')(related_name='group_profile', unique=True, to=orm['askbot.Tag'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ))
+ db.send_create_signal('askbot', ['GroupProfile'])
+
+ # Adding model 'GroupMembership'
+ db.create_table('askbot_groupmembership', (
+ ('group', self.gf('django.db.models.fields.related.ForeignKey')(related_name='user_memberships', to=orm['askbot.Tag'])),
+ ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
+ ('user', self.gf('django.db.models.fields.related.ForeignKey')(related_name='group_memberships', to=orm['auth.User'])),
+ ))
+ db.send_create_signal('askbot', ['GroupMembership'])
+
+ # Adding unique constraint on 'GroupMembership', fields ['group', 'user']
+ db.create_unique('askbot_groupmembership', ['group_id', 'user_id'])
+
+ # Adding M2M table for field groups on 'Post'
+ db.create_table('askbot_post_groups_old', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('post', models.ForeignKey(orm['askbot.post'], null=False)),
+ ('tag', models.ForeignKey(orm['askbot.tag'], null=False))
+ ))
+ db.create_unique('askbot_post_groups_old', ['post_id', 'tag_id'])
+
+ # Adding M2M table for field new_groups on 'Thread'
+ db.create_table('askbot_thread_groups_old', (
+ ('id', models.AutoField(verbose_name='ID', primary_key=True, auto_created=True)),
+ ('thread', models.ForeignKey(orm['askbot.thread'], null=False)),
+ ('group', models.ForeignKey(orm['auth.group'], null=False))
+ ))
+ db.create_unique('askbot_thread_groups_old', ['thread_id', 'group_id'])
+
+ complete_apps = ['askbot']
diff --git a/askbot/models/__init__.py b/askbot/models/__init__.py
index adf7fb90..17dc727a 100644
--- a/askbot/models/__init__.py
+++ b/askbot/models/__init__.py
@@ -41,7 +41,8 @@ from askbot.models.tag import Tag, MarkedTag
from askbot.models.tag import format_personal_group_name
from askbot.models.group import get_groups, get_global_group
from askbot.models.user import EmailFeedSetting, ActivityAuditStatus, Activity
-from askbot.models.user import GroupMembership, GroupProfile
+from askbot.models.user import AuthUserGroups as GroupMembership
+from askbot.models.user import Group
from askbot.models.post import Post, PostRevision
from askbot.models.post import PostFlagReason, AnonymousAnswer
from askbot.models.post import PostToGroup
@@ -2204,11 +2205,11 @@ def get_profile_link(self):
def user_get_groups(self, private=False):
"""returns a query set of groups to which user belongs"""
#todo: maybe cache this query
- return Tag.group_tags.get_for_user(self, private=private)
+ return Group.objects.get_for_user(self, private=private)
def user_get_personal_group(self):
group_name = format_personal_group_name(self)
- return Tag.group_tags.get(name=group_name)
+ return Group.objects.get(name=group_name)
def user_get_foreign_groups(self):
"""returns a query set of groups to which user does not belong"""
@@ -2240,8 +2241,6 @@ def user_get_groups_membership_info(self, groups):
``groups`` is a group tag query set
"""
- groups = groups.select_related('group_profile')
-
group_ids = groups.values_list('id', flat = True)
memberships = GroupMembership.objects.filter(
user__id = self.id,
@@ -2255,7 +2254,7 @@ def user_get_groups_membership_info(self, groups):
info[membership.group_id]['is_member'] = True
for group in groups:
- info[group.id]['can_join'] = group.group_profile.can_accept_user(self)
+ info[group.id]['can_join'] = group.can_accept_user(self)
return info
@@ -2631,8 +2630,12 @@ def user_join_group(self, group):
def user_leave_group(self, group):
self.edit_group_membership(group=group, user=self, action='remove')
-def user_is_group_member(self, group = None):
- return self.group_memberships.filter(group = group).count() == 1
+def user_is_group_member(self, group=None):
+ import pdb
+ pdb.set_trace()
+ return GroupMembership.objects.filter(
+ user=self, group=group
+ ).count() == 1
User.add_to_class(
'add_missing_askbot_subscriptions',
@@ -3367,7 +3370,7 @@ def add_user_to_personal_group(sender, instance, created, **kwargs):
#in theore here we may have two users that will have
#identical group names!!!
group_name = format_personal_group_name(instance)
- group = Tag.group_tags.get_or_create(
+ group = Group.objects.get_or_create(
group_name=group_name, user=instance
)
instance.edit_group_membership(
@@ -3528,7 +3531,7 @@ __all__ = [
'ActivityAuditStatus',
'EmailFeedSetting',
'GroupMembership',
- 'GroupProfile',
+ 'Group',
'User',
diff --git a/askbot/models/post.py b/askbot/models/post.py
index 72a64fa7..3f979059 100644
--- a/askbot/models/post.py
+++ b/askbot/models/post.py
@@ -9,7 +9,6 @@ from django.contrib.sitemaps import ping_google
from django.utils import html
from django.conf import settings
from django.contrib.auth.models import User
-from django.contrib.auth.models import Group
from django.core import urlresolvers
from django.db import models
from django.utils import html as html_utils
@@ -27,7 +26,8 @@ from askbot.utils.slug import slugify
from askbot import const
from askbot.models.user import Activity
from askbot.models.user import EmailFeedSetting
-from askbot.models.user import GroupMembership
+from askbot.models.user import Group
+from askbot.models.user import AuthUserGroups as GroupMembership
from askbot.models.tag import Tag, MarkedTag
from askbot.models.tag import tags_match_some_wildcard
from askbot.models.group import get_groups, get_global_group
@@ -43,25 +43,13 @@ from askbot.utils import mysql
class PostToGroup(models.Model):
- """the "trough" table for the
- relation of groups to posts
- """
- post = models.ForeignKey('Post')
- tag = models.ForeignKey('Tag')
-
- class Meta:
- unique_together = ('post', 'tag')
- db_table = 'askbot_post_groups'
- app_label = 'askbot'
-
-
-class PostToGroup2(models.Model):
post = models.ForeignKey('Post')
group = models.ForeignKey(Group)
class Meta:
unique_together = ('post', 'group')
app_label = 'askbot'
+ db_table = 'askbot_post_groups'
class PostQuerySet(models.query.QuerySet):
@@ -333,8 +321,7 @@ class Post(models.Model):
parent = models.ForeignKey('Post', blank=True, null=True, related_name='comments') # Answer or Question for Comment
thread = models.ForeignKey('Thread', blank=True, null=True, default = None, related_name='posts')
- groups = models.ManyToManyField('Tag', through='PostToGroup', related_name = 'group_posts')#used for group-private posts
- new_groups = models.ManyToManyField(Group, through='PostToGroup2')
+ groups = models.ManyToManyField(Group, through='PostToGroup')
author = models.ForeignKey(User, related_name='posts')
added_at = models.DateTimeField(default=datetime.datetime.now)
@@ -572,21 +559,20 @@ class Post(models.Model):
def add_to_groups(self, groups):
#todo: use bulk-creation
for group in groups:
- PostToGroup.objects.get_or_create(post=self, tag=group)
+ PostToGroup.objects.get_or_create(post=self, group=group)
if self.is_answer() or self.is_question():
comments = self.comments.all()
for group in groups:
for comment in comments:
- PostToGroup.objects.get_or_create(post=comment, tag=group)
-
+ PostToGroup.objects.get_or_create(post=comment, group=group)
def remove_from_groups(self, groups):
- PostToGroup.objects.filter(post=self, tag__in=groups).delete()
+ PostToGroup.objects.filter(post=self, group__in=groups).delete()
if self.is_answer() or self.is_question():
comment_ids = self.comments.all().values_list('id', flat=True)
PostToGroup.objects.filter(
post__id__in=comment_ids,
- tag__in=groups
+ group__in=groups
).delete()
@@ -664,7 +650,7 @@ class Post(models.Model):
todo: this is a copy-paste in thread and post
"""
if group_id:
- group = Tag.group_tags.get(id=group_id)
+ group = Group.objects.get(id=group_id)
groups = [group]
self.add_to_groups(groups)
@@ -1979,9 +1965,9 @@ class PostRevision(models.Model):
if self.by_email and self.email_address:
group_name = self.email_address.split('@')[0]
try:
- group = Tag.objects.get(name = group_name, deleted = False)
+ group = Group.objects.get(name = group_name, deleted = False)
return group.group.profile.moderate_email
- except Tag.DoesNotExist:
+ except Group.DoesNotExist:
pass
return True
return False
diff --git a/askbot/models/question.py b/askbot/models/question.py
index a3704107..6261cb17 100644
--- a/askbot/models/question.py
+++ b/askbot/models/question.py
@@ -4,7 +4,7 @@ import re
from django.conf import settings
from django.db import models
-from django.contrib.auth.models import User, Group
+from django.contrib.auth.models import User
from django.core import cache # import cache, not from cache import cache, to be able to monkey-patch cache.cache in test cases
from django.core.urlresolvers import reverse
from django.utils.hashcompat import md5_constructor
@@ -25,6 +25,7 @@ from askbot.models.base import DraftContent, BaseQuerySetManager
from askbot.models.tag import Tag
from askbot.models.post import Post, PostRevision
from askbot.models.post import PostToGroup
+from askbot.models.user import Group
from askbot.models import signals
from askbot import const
from askbot.utils.lists import LazyList
@@ -442,8 +443,7 @@ class Thread(models.Model):
title = models.CharField(max_length=300)
tags = models.ManyToManyField('Tag', related_name='threads')
- groups = models.ManyToManyField('Tag', related_name='group_threads')
- new_groups = models.ManyToManyField(Group, db_table='askbot_thread_groups')
+ groups = models.ManyToManyField(Group, db_table='askbot_thread_groups')
# Denormalised data, transplanted from Question
tagnames = models.CharField(max_length=125)
@@ -534,11 +534,19 @@ class Thread(models.Model):
groups = self.groups.filter(name__startswith='_internal_')
if exclude_user:
- groups = groups.exclude(created_by__id=exclude_user.id)
+ exclude_user_group = exclude_user.get_personal_group()
+ groups = groups.exclude(name=exclude_user_group.name)
- user_ids = groups.values_list('created_by__id', flat=True)
if max_count:
- user_ids = user_ids[:max_count]
+ groups = groups[:max_count]
+
+ from askbot.models import GroupMembership
+ user_ids = GroupMembership.objects.filter(
+ group__in=groups
+ ).values_list(
+ 'user__id', flat=True
+ )
+
return User.objects.filter(id__in=user_ids)
def get_groups_shared_with(self, max_count=None):
@@ -904,7 +912,7 @@ class Thread(models.Model):
The add by ID now only works if user belongs to that group
"""
if group_id:
- group = Tag.group_tags.get(id=group_id)
+ group = Group.objects.get(id=group_id)
groups = [group]
self.add_to_groups(groups)
diff --git a/askbot/models/tag.py b/askbot/models/tag.py
index 2c6e5e67..2f2cf1fd 100644
--- a/askbot/models/tag.py
+++ b/askbot/models/tag.py
@@ -8,6 +8,21 @@ from askbot import const
from askbot.conf import settings as askbot_settings
from askbot.utils import category_tree
+def get_global_group():
+ """Returns the global group,
+ if necessary, creates one
+ """
+ #todo: when groups are disconnected from tags,
+ #find comment as shown below in the test cases and
+ #revert the values
+ #todo: change groups to django groups
+ group_name = askbot_settings.GLOBAL_GROUP_NAME
+ from askbot.models import Group
+ try:
+ return Group.objects.get(name=group_name)
+ except Group.DoesNotExist:
+ return Group.objects.create(name=group_name, is_open=False)
+
def delete_tags(tags):
"""deletes tags in the list"""
tag_ids = [tag.id for tag in tags]
@@ -173,11 +188,7 @@ class TagManager(BaseQuerySetManager):
def get_content_tags(self):
"""temporary function that filters out the group tags"""
- return self.annotate(
- member_count = models.Count('user_memberships')
- ).filter(
- member_count = 0
- )
+ return self.all()
def create(self, name = None, created_by = None, **kwargs):
"""Creates a new tag"""
@@ -267,55 +278,12 @@ class TagManager(BaseQuerySetManager):
return created_tags
-class GroupTagQuerySet(TagQuerySet):
- """Custom query set for the group"""
-
- def get_for_user(self, user=None, private=False):
- if private:
- from askbot.models.group import get_global_group
- global_group = get_global_group()
- return self.filter(
- user_memberships__user=user
- ).exclude(id=global_group.id)
- else:
- return self.filter(user_memberships__user = user)
-
- def get_all(self):
- return self.annotate(
- member_count = models.Count('user_memberships')
- ).filter(
- member_count__gt = 0
- )
-
- def get_by_name(self, group_name = None):
- from askbot.models.group import clean_group_name
- return self.get(name = clean_group_name(group_name))
-
+def clean_group_name(name):
+ """group names allow spaces,
+ tag names do not, so we use this method
+ to replace spaces with dashes"""
+ return re.sub('\s+', '-', name.strip())
-class GroupTagManager(BaseQuerySetManager):
- """manager for group tags"""
-
- def get_query_set(self):
- return GroupTagQuerySet(self.model)
-
- def get_or_create(self, group_name = None, user = None, is_open=True):
- """creates a group tag or finds one, if exists"""
- #todo: here we might fill out the group profile
-
- #replace spaces with dashes
- from askbot.models.group import clean_group_name
- group_name = clean_group_name(group_name)
- try:
- #iexact is important!!! b/c we don't want case variants
- #of tags
- tag = self.get(name__iexact = group_name)
- except self.model.DoesNotExist:
- tag = self.model(name = group_name, created_by = user)
- tag.save()
- from askbot.models.user import GroupProfile
- group_profile = GroupProfile(group_tag = tag, is_open=is_open)
- group_profile.save()
- return tag
class Tag(models.Model):
#a couple of status constants
@@ -346,7 +314,6 @@ class Tag(models.Model):
)
objects = TagManager()
- group_tags = GroupTagManager()
class Meta:
app_label = 'askbot'
@@ -368,3 +335,11 @@ class MarkedTag(models.Model):
class Meta:
app_label = 'askbot'
+
+def get_groups():
+ from askbot.models import Group
+ return Group.objects.all()
+
+def get_group_names():
+ #todo: cache me
+ return get_groups().values_list('name', flat = True)
diff --git a/askbot/models/user.py b/askbot/models/user.py
index a6ff72a2..0eb48f6f 100644
--- a/askbot/models/user.py
+++ b/askbot/models/user.py
@@ -14,7 +14,9 @@ from django.utils.html import strip_tags
from askbot import const
from askbot.conf import settings as askbot_settings
from askbot.utils import functions
-from askbot.models.tag import Tag
+from askbot.models.base import BaseQuerySetManager
+from askbot.models.tag import Tag, get_global_group
+from askbot.models.tag import clean_group_name#todo - delete this
from askbot.forms import DomainNameField
from askbot.utils.forms import email_is_allowed
@@ -344,7 +346,6 @@ class EmailFeedSetting(models.Model):
class AuthUserGroups(models.Model):
"""explicit model for the auth_user_groups bridge table.
- Should not be used directly, but via a subclass
"""
group = models.ForeignKey(AuthGroup)
user = models.ForeignKey(User)
@@ -356,46 +357,51 @@ class AuthUserGroups(models.Model):
managed = False
-class GroupMembership(models.Model):
- """an explicit model to link users and the groups
- that by being recorded with this relation automatically
- become group tags
- """
- group = models.ForeignKey(Tag, related_name = 'user_memberships')
- user = models.ForeignKey(User, related_name = 'group_memberships')
+class GroupQuerySet(models.query.QuerySet):
+ """Custom query set for the group"""
- class Meta:
- app_label = 'askbot'
- unique_together = ('group', 'user')
+ def get_for_user(self, user=None, private=False):
+ if private:
+ global_group = get_global_group()
+ return self.filter(
+ user=user
+ ).exclude(id=global_group.id)
+ else:
+ return self.filter(user = user)
+ def get_by_name(self, group_name = None):
+ return self.get(name = clean_group_name(group_name))
-class Group(AuthGroup):
- """group profile for askbot"""
- logo_url = models.URLField(null = True)
- moderate_email = models.BooleanField(default = True)
- 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, blank = True, default = ''
- )
- #only domains - without the '@' or anything before them
- preapproved_email_domains = models.TextField(
- null = True, blank = True, default = ''
- )
- class Meta:
- app_label = 'askbot'
- db_table = 'askbot_group'
+class GroupManager(BaseQuerySetManager):
+ """model manager for askbot groups"""
+
+ def get_query_set(self):
+ return GroupQuerySet(self.model)
+
+ def create(self, **kwargs):
+ name = kwargs['name']
+ try:
+ group_ptr = AuthGroup.objects.get(name=name)
+ kwargs['group_ptr'] = group_ptr
+ except AuthGroup.DoesNotExist:
+ pass
+ return super(GroupManager, self).create(**kwargs)
+
+ def get_or_create(self, group_name = None, user = None, is_open=True):
+ """creates a group tag or finds one, if exists"""
+ #todo: here we might fill out the group profile
+ try:
+ #iexact is important!!! b/c we don't want case variants
+ #of tags
+ group = self.get(name__iexact = group_name)
+ except self.model.DoesNotExist:
+ group = self.create(name=group_name, is_open=is_open)
+ return group
-class GroupProfile(models.Model):
- """stores group profile data"""
- group_tag = models.OneToOneField(
- Tag,
- unique = True,
- related_name = 'group_profile'
- )
+class Group(AuthGroup):
+ """group profile for askbot"""
logo_url = models.URLField(null = True)
moderate_email = models.BooleanField(default = True)
is_open = models.BooleanField(default = False)
@@ -409,9 +415,11 @@ class GroupProfile(models.Model):
null = True, blank = True, default = ''
)
+ objects = GroupManager()
+
class Meta:
- #added to make account merges work properly
app_label = 'askbot'
+ db_table = 'askbot_group'
def can_accept_user(self, user):
"""True if user is preapproved to join the group"""
@@ -419,7 +427,7 @@ class GroupProfile(models.Model):
return False
#a special case - automatic global group cannot be joined or left
- if self.group_tag.name == askbot_settings.GLOBAL_GROUP_NAME:
+ if self.name == askbot_settings.GLOBAL_GROUP_NAME:
return False
if self.is_open:
@@ -462,4 +470,4 @@ class GroupProfile(models.Model):
def save(self, *args, **kwargs):
self.clean()
- super(GroupProfile, self).save(*args, **kwargs)
+ super(Group, self).save(*args, **kwargs)
diff --git a/askbot/skins/default/templates/widgets/group_info.html b/askbot/skins/default/templates/widgets/group_info.html
index 5d3a4c7f..85fcd693 100644
--- a/askbot/skins/default/templates/widgets/group_info.html
+++ b/askbot/skins/default/templates/widgets/group_info.html
@@ -2,8 +2,8 @@
<div id="group-wiki-{{group.id}}" class="box group-wiki">
<h2>{% trans %}Group info{% endtrans %}</h2>
<img class="group-logo"
- {% if group.group_profile.logo_url %}
- src="{{ group.group_profile.logo_url }}"
+ {% if group.logo_url %}
+ src="{{ group.logo_url }}"
{% else %}
style="display:none"
{% endif %}
@@ -24,7 +24,7 @@
<div class="controls">
<a class="edit-description"
>{% trans %}edit description{% endtrans %}</a>
- {% if group.group_profile.logo_url %}
+ {% if group.logo_url %}
<span>|</span>
<a class="change-logo"
>{% trans %}change logo{% endtrans %}</a>
@@ -39,7 +39,7 @@
{% if group_email_moderation_enabled %}
<input type="checkbox"
id="moderate-email"
- {% if group.group_profile.moderate_email %}checked="checked"{% endif %}
+ {% if group.moderate_email %}checked="checked"{% endif %}
data-toggle-url="{% url toggle_group_profile_property %}"
/>
<label for="moderate-email">
@@ -49,7 +49,7 @@
{% endif %}
<input type="checkbox"
id="open-or-close-group"
- {% if group.group_profile.is_open %}checked="checked"{% endif %}
+ {% if group.is_open %}checked="checked"{% endif %}
data-toggle-url="{% url toggle_group_profile_property %}"
/>
<label for="open-or-close-group">
@@ -59,8 +59,8 @@
<a
id="preapproved-emails"
title="{% trans %}list of email addresses of pre-approved users{% endtrans %}"
- data-object-id="{{group.group_profile.id}}"
- data-model-name="GroupProfile"
+ data-object-id="{{group.group_ptr_id}}"
+ data-model-name="Group"
data-property-name="preapproved_emails"
data-url="{% url edit_object_property_text %}"
data-editor-heading="{% trans %}List of preapproved email addresses{% endtrans %}"
@@ -70,8 +70,8 @@
<a
id="preapproved-email-domains"
title="{% trans %}list of preapproved email address domain names{% endtrans %}"
- data-object-id="{{group.group_profile.id}}"
- data-model-name="GroupProfile"
+ data-object-id="{{group.group_ptr_id}}"
+ data-model-name="Group"
data-property-name="preapproved_email_domains"
data-url="{% url edit_object_property_text %}"
data-editor-heading="{% trans %}List of preapproved email domain names{% endtrans %}"
diff --git a/askbot/tests/db_api_tests.py b/askbot/tests/db_api_tests.py
index 32c4ebb3..fa78c140 100644
--- a/askbot/tests/db_api_tests.py
+++ b/askbot/tests/db_api_tests.py
@@ -431,13 +431,6 @@ class TagAndGroupTests(AskbotTestCase):
'answer_comment': answer_comment
}
- def test_group_cannot_create_case_variant_tag(self):
- self.post_question(user = self.u1, tags = 'one two three')
- models.Tag.group_tags.get_or_create(user = self.u1, group_name = 'One')
- tag_one = models.Tag.objects.filter(name__iexact = 'one')
- self.assertEqual(tag_one.count(), 1)
- self.assertEqual(tag_one[0].name, 'one')
-
def test_posts_added_to_global_group(self):
q = self.post_question(user=self.u1)
group_name = askbot_settings.GLOBAL_GROUP_NAME
@@ -579,3 +572,18 @@ class TagAndGroupTests(AskbotTestCase):
visible_threads = models.Thread.objects.get_visible(AnonymousUser())
self.assertEqual(visible_threads.count(), 0)
+
+class GroupTests(AskbotTestCase):
+
+ def setUp(self):
+ self.u1 = self.create_user('user1')
+
+ def test_join_group(self):
+ #create group
+ group = models.Group(name='somegroup')
+ group.save()
+ #join
+ self.u1.join_group(group)
+ #assert membership of askbot group object
+ found_count = self.u1.get_groups().filter(name='somegroup').count()
+ self.assertEqual(found_count, 1)
diff --git a/askbot/tests/page_load_tests.py b/askbot/tests/page_load_tests.py
index f3e10c1e..a3f36e80 100644
--- a/askbot/tests/page_load_tests.py
+++ b/askbot/tests/page_load_tests.py
@@ -520,9 +520,9 @@ class PageLoadTestCase(AskbotTestCase):
)
def test_user_page_with_groups_enabled(self):
- askbot_settings.GROUPS_ENABLED = True
+ askbot_settings.update('GROUPS_ENABLED', True)
self.try_url('users', status_code=302)
- askbot_settings.GROUPS_ENABLED = False
+ askbot_settings.update('GROUPS_ENABLED', False)
self.try_url('users', status_code=200)
class AvatarTests(AskbotTestCase):
diff --git a/askbot/tests/thread_model_tests.py b/askbot/tests/thread_model_tests.py
index 3f313ff3..45a704c0 100644
--- a/askbot/tests/thread_model_tests.py
+++ b/askbot/tests/thread_model_tests.py
@@ -19,9 +19,7 @@ class ThreadModelTestsWithGroupsEnabled(AskbotTestCase):
'm_and_c': 'i'
}
)
- self.group = models.Tag.group_tags.get_or_create(
- group_name = 'jockeys', user = self.admin
- )
+ self.group = models.Group.objects.get_or_create(group_name = 'jockeys')
self.admin.edit_group_membership(
group = self.group,
user = self.admin,
diff --git a/askbot/tests/user_model_tests.py b/askbot/tests/user_model_tests.py
index 7a8fd9f2..df4974dd 100644
--- a/askbot/tests/user_model_tests.py
+++ b/askbot/tests/user_model_tests.py
@@ -9,12 +9,8 @@ class UserModelTests(AskbotTestCase):
def test_new_user_has_personal_group(self):
user = User.objects.create_user('somebody', 'somebody@example.com')
group_name = format_personal_group_name(user)
- group = models.Tag.objects.filter(name=group_name)
+ group = models.Group.objects.filter(name=group_name)
self.assertEqual(group.count(), 1)
-
- group_profile = models.GroupProfile.objects.filter(group_tag=group)
- self.assertEqual(group_profile.count(), 1)
-
memberships = models.GroupMembership.objects.filter(
group=group, user=user
)
diff --git a/askbot/tests/utils.py b/askbot/tests/utils.py
index 99f43677..eea9b96b 100644
--- a/askbot/tests/utils.py
+++ b/askbot/tests/utils.py
@@ -252,10 +252,7 @@ class AskbotTestCase(TestCase):
return tag
def create_group(self, group_name=None, user=None):
- return models.Tag.group_tags.get_or_create(
- group_name='private',
- user=self.u1
- )
+ return models.Group.objects.get_or_create(group_name='private')
def post_comment(
self,
diff --git a/askbot/views/commands.py b/askbot/views/commands.py
index 75ae3ca4..8914530f 100644
--- a/askbot/views/commands.py
+++ b/askbot/views/commands.py
@@ -657,12 +657,12 @@ def get_groups_list(request):
"""returns names of group tags
for the autocomplete function"""
global_group = get_global_group()
- group_names = models.Tag.group_tags.get_all().filter(
+ group_names = models.Group.objects.all().filter(
deleted = False
).exclude(
- name=global_group.name
- ).exclude(
name__startswith='_internal_'
+ ).exclude(
+ name=global_group.name
).values_list(
'name', flat = True
)
@@ -898,7 +898,7 @@ def edit_group_membership(request):
#warning: possible race condition
if action == 'add':
group_params = {'group_name': group_name, 'user': user}
- group = models.Tag.group_tags.get_or_create(**group_params)
+ group = models.Group.objects.get_or_create(**group_params)
request.user.edit_group_membership(user, group, 'add')
template = get_template('widgets/group_snippet.html')
return {
@@ -908,9 +908,9 @@ def edit_group_membership(request):
}
elif action == 'remove':
try:
- group = models.Tag.group_tags.get_by_name(group_name = group_name)
+ group = models.Group.objects.get(group_name = group_name)
request.user.edit_group_membership(user, group, 'remove')
- except models.Tag.DoesNotExist:
+ except models.Group.DoesNotExist:
raise exceptions.PermissionDenied()
else:
raise exceptions.PermissionDenied()
@@ -928,9 +928,9 @@ def save_group_logo_url(request):
if form.is_valid():
group_id = form.cleaned_data['group_id']
image_url = form.cleaned_data['image_url']
- group = models.Tag.group_tags.get(id = group_id)
- group.group_profile.logo_url = image_url
- group.group_profile.save()
+ group = models.Group.objects.get(id = group_id)
+ group.logo_url = image_url
+ group.save()
else:
raise ValueError('invalid data found when saving group logo')
@@ -958,9 +958,9 @@ def add_group(request):
@decorators.admins_only
def delete_group_logo(request):
group_id = IntegerField().clean(int(request.POST['group_id']))
- group = models.Tag.group_tags.get(id = group_id)
- group.group_profile.logo_url = None
- group.group_profile.save()
+ group = models.Group.objects.get(id = group_id)
+ group.logo_url = None
+ group.save()
@csrf.csrf_exempt
@@ -983,10 +983,10 @@ def toggle_group_profile_property(request):
property_name = CharField().clean(request.POST['property_name'])
assert property_name in ('is_open', 'moderate_email')
- group = models.Tag.objects.get(id = group_id)
- new_value = not getattr(group.group_profile, property_name)
- setattr(group.group_profile, property_name, new_value)
- group.group_profile.save()
+ group = models.Group.objects.get(id = group_id)
+ new_value = not getattr(group, property_name)
+ setattr(group, property_name, new_value)
+ group.save()
return {'is_enabled': new_value}
@@ -999,8 +999,8 @@ def edit_object_property_text(request):
property_name = CharField().clean(request.REQUEST['property_name'])
accessible_fields = (
- ('GroupProfile', 'preapproved_emails'),
- ('GroupProfile', 'preapproved_email_domains')
+ ('Group', 'preapproved_emails'),
+ ('Group', 'preapproved_email_domains')
)
if (model_name, property_name) not in accessible_fields:
@@ -1026,7 +1026,7 @@ def join_or_leave_group(request):
raise exceptions.PermissionDenied()
group_id = IntegerField().clean(request.POST['group_id'])
- group = models.Tag.objects.get(id = group_id)
+ group = models.Group.objects.get(id = group_id)
if request.user.is_group_member(group):
action = 'remove'
@@ -1089,7 +1089,7 @@ def moderate_suggested_tag(request):
thread_id = form.cleaned_data.get('thread_id', None)
try:
- tag = models.Tag.objects.get(id = tag_id)#can tag not exist?
+ tag = models.Tag.objects.get(id=tag_id)#can tag not exist?
except models.Tag.DoesNotExist:
return
@@ -1227,7 +1227,7 @@ def share_question_with_group(request):
if group_name == askbot_settings.GLOBAL_GROUP_NAME:
thread.make_public(recursive=True)
else:
- group = models.Tag.group_tags.get(name=group_name)
+ group = models.Group.objects.get(name=group_name)
thread.add_to_groups((group,), recursive=True)
#get notif sets after
diff --git a/askbot/views/users.py b/askbot/views/users.py
index ddb60f13..6a335d2f 100644
--- a/askbot/views/users.py
+++ b/askbot/views/users.py
@@ -81,18 +81,17 @@ def show_users(request, by_group=False, group_id=None, group_slug=None):
return HttpResponseRedirect('groups')
else:
try:
- group = get_group_manager().get(id = group_id)
+ group = models.Group.objects.get(id = group_id)
group_email_moderation_enabled = \
(
askbot_settings.GROUP_EMAIL_ADDRESSES_ENABLED \
and askbot_settings.ENABLE_CONTENT_MODERATION
)
- user_can_join_group = group.group_profile.can_accept_user(request.user)
- except models.Tag.DoesNotExist:
+ user_can_join_group = group.can_accept_user(request.user)
+ except models.Group.DoesNotExist:
raise Http404
if group_slug == slugify(group.name):
- users = users.filter(
- group_memberships__group__id = group_id
+ users = users.filter(groups__id = group_id
)
if request.user.is_authenticated():
user_is_group_member = bool(
@@ -462,7 +461,7 @@ def user_stats(request, user, context):
badges = badges_dict.items()
badges.sort(key=operator.itemgetter(1), reverse=True)
- user_groups = get_group_manager().get_for_user(user = user)
+ user_groups = models.Group.objects.get_for_user(user = user)
user_groups = user_groups.exclude(name__startswith='_internal_')
global_group = get_global_group()
user_groups = user_groups.exclude(name=global_group.name)
@@ -1011,13 +1010,14 @@ def groups(request, id = None, slug = None):
scope = 'all-groups'
if scope == 'all-groups':
- groups = get_groups()
+ groups = models.Group.objects.all()
else:
- groups = get_group_manager().get_for_user(user=request.user)
+ groups = models.Group.objects.get_for_user(
+ user=request.user
+ )
groups = groups.exclude(name__startswith='_internal_')
- groups = groups.annotate(users_count=Count('user_memberships'))
- groups = groups.select_related('group_profile')
+ groups = groups.annotate(users_count=Count('user'))
user_can_add_groups = request.user.is_authenticated() and \
request.user.is_administrator_or_moderator()