Skip to content

Commit

Permalink
Merge branch 'master' into refactoring
Browse files Browse the repository at this point in the history
Conflicts:
	apps/users/models.py
	locale/es/LC_MESSAGES/django.mo
	locale/es/LC_MESSAGES/django.po
	templates/mojo.html
	templates/projects/sidebar.html
  • Loading branch information
zuzelvp committed Jul 3, 2011
2 parents e4d351a + d1e15db commit 71850fb
Show file tree
Hide file tree
Showing 27 changed files with 678 additions and 165 deletions.
29 changes: 25 additions & 4 deletions apps/projects/templatetags/project_tags.py
Expand Up @@ -10,7 +10,7 @@
register = template.Library()


def sidebar(context):
def sidebar(context, max_people_count=64):
user = context['user']
project = context['project']
is_participating = is_following = is_organizing = False
Expand All @@ -26,9 +26,27 @@ def sidebar(context):
deleted=False, author=profile)
if answers.exists():
pending_signup = answers[0]
participants_count = project.non_organizer_participants().count()
followers_count = project.non_participant_followers().count()
organizers_count = project.organizers().count()

organizers = project.organizers()
organizers_count = organizers.count()
participants = project.non_organizer_participants()
participants_count = participants.count()
followers = project.non_participant_followers()
followers_count = followers.count()

# only display a subset of the participants and followers.
remaining = max_people_count
sidebar_organizers = organizers[:remaining]
sidebar_participants = []
sidebar_followers = []
remaining -= sidebar_organizers.count()
if remaining > 0:
sidebar_participants = participants[:remaining]
remaining -= sidebar_participants.count()
if remaining > 0:
sidebar_followers = followers[:remaining]
remaining -= sidebar_followers.count()

update_count = project.activities().count()
pending_applicants_count = len(project.pending_applicants())
content_pages = Page.objects.filter(project__pk=project.pk,
Expand All @@ -52,6 +70,9 @@ def sidebar(context):
'school': school,
'imported_from': imported_from,
'pending_signup': pending_signup,
'sidebar_organizers': sidebar_organizers,
'sidebar_participants': sidebar_participants,
'sidebar_followers': sidebar_followers,
})
return context

Expand Down
5 changes: 5 additions & 0 deletions apps/projects/urls.py
Expand Up @@ -26,6 +26,11 @@
name='projects_show'),
url(r'^(?P<slug>[\w-]+)/(?P<page>\d+)/$', 'projects.views.show',
name='projects_show'),
url(r'^(?P<slug>[\w-]+)/people/$', 'projects.views.user_list',
name='projects_user_list'),
url(r'^(?P<slug>[\w-]+)/people/' +
'(?P<participants_page>\d+)/(?P<followers_page>\d+)/$',
'projects.views.user_list', name='projects_user_list'),
url(r'^(?P<slug>[\w-]+)/contact_organizers/$',
'projects.views.contact_organizers',
name='projects_contact_organizers'),
Expand Down
41 changes: 41 additions & 0 deletions apps/projects/views.py
Expand Up @@ -605,3 +605,44 @@ def task_list(request, slug):
}
return render_to_response('projects/project_task_list.html', context,
context_instance=RequestContext(request))


def user_list(request, slug, participants_page=1, followers_page=1):
"""Display full list of users for the project."""
project = get_object_or_404(Project, slug=slug)

participants = project.non_organizer_participants()
participants_paginator = Paginator(participants, 24)
try:
participants_current_page = participants_paginator.page(
participants_page)
except EmptyPage:
raise http.Http404
participants = participants_current_page.object_list

followers = project.non_participant_followers()
followers_paginator = Paginator(followers, 24)
try:
followers_current_page = followers_paginator.page(followers_page)
except EmptyPage:
raise http.Http404
followers = followers_current_page.object_list

return render_to_response('projects/project_user_list.html', {
'project': project,
'organizers': project.organizers(),
'participants': participants,
'followers': followers,
'participants_paginator': participants_paginator,
'participants_page_num': participants_page,
'participants_next_page': int(participants_page) + 1,
'participants_prev_page': int(participants_page) - 1,
'participants_num_pages': participants_paginator.num_pages,
'participants_page': participants_current_page,
'followers_paginator': followers_paginator,
'followers_page_num': followers_page,
'followers_next_page': int(followers_page) + 1,
'followers_prev_page': int(followers_page) - 1,
'followers_num_pages': followers_paginator.num_pages,
'followers_page': followers_current_page,
}, context_instance=RequestContext(request))
17 changes: 11 additions & 6 deletions apps/relationships/views.py
@@ -1,7 +1,7 @@
import logging

from django.db.utils import IntegrityError
from django.http import HttpResponseRedirect, Http404, HttpResponseForbidden
from django.http import HttpResponseRedirect, Http404
from django.views.decorators.http import require_http_methods
from django.shortcuts import get_object_or_404
from django.utils.translation import ugettext as _
Expand All @@ -26,9 +26,11 @@ def follow(request, object_type, slug):
if object_type == PROJECT:
project = get_object_or_404(Project, slug=slug)
relationship = Relationship(source=profile, target_project=project)
url = project.get_absolute_url()
elif object_type == USER:
user = get_object_or_404(UserProfile, username=slug)
relationship = Relationship(source=profile, target_user=user)
url = user.get_absolute_url()
else:
raise Http404
try:
Expand All @@ -41,7 +43,7 @@ def follow(request, object_type, slug):
messages.error(request, _('You are already following this user'))
log.warn("Attempt to create duplicate relationship: %s" % (
relationship,))
return HttpResponseRedirect(request.META['HTTP_REFERER'])
return HttpResponseRedirect(url)


@login_required
Expand All @@ -52,13 +54,16 @@ def unfollow(request, object_type, slug):
project = get_object_or_404(Project, slug=slug)
# project.participants() includes project.organizers()
if project.participants().filter(user=profile).exists():
return HttpResponseForbidden(_("You can't unfollow"))
Relationship.objects.filter(
source=profile, target_project=project).delete()
messages.error(request, _("You can't unfollow"))
else:
Relationship.objects.filter(
source=profile, target_project=project).delete()
url = project.get_absolute_url()
elif object_type == USER:
user = get_object_or_404(UserProfile, username=slug)
Relationship.objects.filter(
source=profile, target_user=user).delete()
url = user.get_absolute_url()
else:
raise Http404
return HttpResponseRedirect(request.META['HTTP_REFERER'])
return HttpResponseRedirect(url)
7 changes: 6 additions & 1 deletion apps/users/admin.py
@@ -1,5 +1,5 @@
from django.contrib import admin
from users.models import UserProfile
from users.models import UserProfile, TaggedProfile


class UserProfileAdmin(admin.ModelAdmin):
Expand All @@ -9,4 +9,9 @@ class UserProfileAdmin(admin.ModelAdmin):
list_filter = list_display[5:]
search_fields = list_display[:5]


class TaggedProfileAdmin(admin.ModelAdmin):
list_display = ('id', 'tag')

admin.site.register(UserProfile, UserProfileAdmin)
admin.site.register(TaggedProfile, TaggedProfileAdmin)
60 changes: 54 additions & 6 deletions apps/users/forms.py
Expand Up @@ -10,9 +10,11 @@
from drumbeat.utils import CKEditorWidget

from captcha import fields as captcha_fields
from taggit.forms import TagField
from taggit.utils import edit_string_for_tags

from users.blacklist import passwords as blacklisted_passwords
from users.models import UserProfile
from users.models import UserProfile, TaggedProfile
from users.fields import UsernameField
from users import drupal
from links.models import Link
Expand Down Expand Up @@ -45,7 +47,6 @@ def check_password_complexity(password):


class SetPasswordForm(auth_forms.SetPasswordForm):

def __init__(self, *args, **kwargs):
super(SetPasswordForm, self).__init__(*args, **kwargs)

Expand Down Expand Up @@ -171,13 +172,63 @@ def clean(self):
return data


class CategoryTagWidget(forms.TextInput):
def __init__(self, *args, **kwargs):
self.category = kwargs.pop('category', None)
super(CategoryTagWidget, self).__init__(*args, **kwargs)

def render(self, name, value, attrs=None):
if value is not None and not isinstance(value, basestring):
objs = value.select_related("tag").filter(
tag__category=self.category)
value = edit_string_for_tags([o.tag for o in objs])
return super(CategoryTagWidget, self).render(name, value, attrs)


class CategoryTagField(TagField):
def __init__(self, **kwargs):
category = kwargs.pop('category', None)
self.widget = CategoryTagWidget(category=category)
super(CategoryTagField, self).__init__(**kwargs)

def clean(self, value):
value = super(CategoryTagField, self).clean(value)
value = [i.lower() for i in value]
return value


class ProfileEditForm(forms.ModelForm):
interest = CategoryTagField(category='interest', required=False)
skill = CategoryTagField(category='skill', required=False)
desired_topic = CategoryTagField(category='desired_topic', required=False)

def __init__(self, *args, **kwargs):
super(ProfileEditForm, self).__init__(*args, **kwargs)

if kwargs.has_key('instance'):
instance = kwargs['instance']
self.initial['interest'] = TaggedProfile.objects.filter(
object_id=instance.id)
self.initial['skill'] = TaggedProfile.objects.filter(
object_id=instance.id)
self.initial['desired_topic'] = TaggedProfile.objects.filter(
object_id=instance.id)

def save(self, commit=True):
model = super(ProfileEditForm, self).save(commit=False)
model.tags.set('interest', *self.cleaned_data['interest'])
model.tags.set('skill', *self.cleaned_data['skill'])
model.tags.set('desired_topic', *self.cleaned_data['desired_topic'])
if commit:
model.save()
return model

class Meta:
model = UserProfile
fields = ('full_name', 'location', 'bio', 'preflang',)
fields = ('full_name', 'location', 'bio', 'preflang', 'interest')
widgets = {
'bio': CKEditorWidget(config_name='reduced'),
'interest': CategoryTagWidget(category='interest')
}

def clean(self):
Expand All @@ -189,7 +240,6 @@ def clean(self):


class ProfileImageForm(forms.ModelForm):

class Meta:
model = UserProfile
fields = ('image',)
Expand All @@ -206,14 +256,12 @@ def clean_image(self):


class ProfileLinksForm(forms.ModelForm):

class Meta:
model = Link
fields = ('name', 'url', 'subscribe',)


class PasswordResetForm(auth_forms.PasswordResetForm):

def clean_email(self):
email = self.cleaned_data["email"]
self.users_cache = User.objects.filter(
Expand Down
59 changes: 59 additions & 0 deletions apps/users/managers.py
@@ -0,0 +1,59 @@
from taggit.utils import require_instance_manager
from taggit.managers import TaggableManager, _TaggableManager


class CategoryTaggableManager(TaggableManager):
def formfield(self, *args, **kwargs):
return None

def __get__(self, instance, model):
"""Override ___get___ to return a slightly tweaked manager class"""
if instance is not None and instance.pk is None:
raise ValueError("%s objects need to have a primary key value "
"before you can access their tags." % model.__name__)
manager = _CategoryTaggableManager(
through=self.through, model=model, instance=instance
)
return manager


class _CategoryTaggableManager(_TaggableManager):
@require_instance_manager
def add(self, category, *tags):
"""This is the same as the _TaggableManager add, except it accepts a
category parameter."""
str_tags = set([
t
for t in tags
if not isinstance(t, self.through.tag_model())
])
tag_objs = set(tags) - str_tags
# If str_tags has 0 elements Django actually optimizes that to not do a
# query. Malcolm is very smart.
existing = self.through.tag_model().objects.filter(
name__in=str_tags, category=category
)
tag_objs.update(existing)

for new_tag in str_tags - set(t.name for t in existing):
tag_objs.add(self.through.tag_model().objects.
create(name=new_tag, category=category))

for tag in tag_objs:
self.through.objects.get_or_create(
tag=tag, **self._lookup_kwargs())

@require_instance_manager
def set(self, category, *tags):
self.clear(category)
self.add(category, *tags)

@require_instance_manager
def remove(self, category, *tags):
self.through.objects.filter(**self._lookup_kwargs()).filter(
tag__name__in=tags, tag__category=category).delete()

@require_instance_manager
def clear(self, category):
self.through.objects.filter(**self._lookup_kwargs()).filter(
tag__category=category).delete()

0 comments on commit 71850fb

Please sign in to comment.