Revision a4233484
b/snf-astakos-app/astakos/im/forms.py | ||
---|---|---|
572 | 572 |
model = AstakosGroup |
573 | 573 |
fields = ('homepage', 'desc') |
574 | 574 |
|
575 |
class AddGroupMembersForm(forms.Form): |
|
576 |
q = forms.CharField(max_length=800, widget=forms.Textarea, label=_('Search users'), |
|
577 |
help_text=_('Add comma separated user emails'), |
|
578 |
required=True) |
|
579 |
|
|
580 |
def clean(self): |
|
581 |
q = self.cleaned_data.get('q') or '' |
|
582 |
users = q.split(',') |
|
583 |
users = list(u.strip() for u in users if u) |
|
584 |
db_entries = AstakosUser.objects.filter(email__in=users) |
|
585 |
unknown = list(set(users) - set(u.email for u in db_entries)) |
|
586 |
if unknown: |
|
587 |
raise forms.ValidationError( |
|
588 |
_('Unknown users: %s' % unknown)) |
|
589 |
self.valid_users = db_entries |
|
590 |
return self.cleaned_data |
|
591 |
|
|
592 |
def get_valid_users(self): |
|
593 |
"""Should be called after form cleaning""" |
|
594 |
try: |
|
595 |
return self.valid_users |
|
596 |
except: |
|
597 |
return () |
|
598 |
|
|
599 |
|
|
575 | 600 |
class AstakosGroupSearchForm(forms.Form): |
576 | 601 |
q = forms.CharField(max_length=200, label='Search group') |
b/snf-astakos-app/astakos/im/templates/im/astakosgroup_detail.html | ||
---|---|---|
129 | 129 |
</div> |
130 | 130 |
|
131 | 131 |
|
132 |
{% if user in object.owner.all and more_policies %}
|
|
132 |
{% if user in object.owner.all %} |
|
133 | 133 |
<div class="full-dotted"> |
134 |
<form action="{% url group_policies_add object.id %}" method="post" class="withlabels">{% csrf_token %} |
|
135 |
<h2>NEW POLICY</h2> |
|
136 |
{% include "im/form_render.html" %} |
|
134 |
<form action="{% url add_members object.id %}" method="post" class="withlabels">{% csrf_token %} |
|
135 |
<h2>Enroll more members</h2> |
|
136 |
{% with search_form as form %} |
|
137 |
{% include "im/form_render.html" %} |
|
138 |
{% endwith %} |
|
137 | 139 |
<div class="form-row submit"> |
138 |
<input type="submit" class="submit altcol" value="ADD POLICY" />
|
|
140 |
<input type="submit" class="submit altcol" value="ADD MEMBERS" />
|
|
139 | 141 |
</div> |
140 | 142 |
</form> |
141 | 143 |
</div> |
b/snf-astakos-app/astakos/im/urls.py | ||
---|---|---|
42 | 42 |
url(r'^profile/?$', |
43 | 43 |
'edit_profile', {}, name='edit_profile'), |
44 | 44 |
url(r'^feedback/?$', 'feedback', {}, name='feedback'), |
45 |
url( |
|
46 |
r'^signup/?$', 'signup', {'on_success': 'im/login.html', |
|
47 |
'extra_context': {'login_form': LoginForm()}}, name='signup'), |
|
48 |
url( |
|
49 |
r'^logout/?$', 'logout', {'template': 'im/login.html', |
|
50 |
'extra_context': {'login_form': LoginForm()}}, name='logout'), |
|
45 |
url(r'^signup/?$', 'signup', |
|
46 |
{'on_success': 'im/login.html', |
|
47 |
'extra_context': {'login_form': LoginForm()}}, |
|
48 |
name='signup'), |
|
49 |
url(r'^logout/?$', 'logout', |
|
50 |
{'template': 'im/login.html', |
|
51 |
'extra_context': {'login_form': LoginForm()}}, |
|
52 |
name='logout'), |
|
51 | 53 |
url(r'^activate/?$', 'activate', {}, name='activate'), |
52 | 54 |
url(r'^approval_terms/?$', |
53 | 55 |
'approval_terms', {}, name='latest_terms'), |
... | ... | |
62 | 64 |
'group_add', {}, name='group_add'), |
63 | 65 |
url(r'^group/list/?$', |
64 | 66 |
'group_list', {}, name='group_list'), |
65 |
url(r'^group/(?P<group_id>\d+)/?$', 'group_detail', {},
|
|
66 |
name='group_detail'), |
|
67 |
url(r'^group/(?P<group_id>\d+)/?$', 'group_detail', |
|
68 |
{}, name='group_detail'),
|
|
67 | 69 |
url(r'^group/update/(?P<group_id>\d+)/?$', |
68 | 70 |
'group_update', {}, name='group_update'), |
69 | 71 |
url(r'^group/search/?$', |
70 | 72 |
'group_search', {}, name='group_search'), |
71 | 73 |
url(r'^group/all/?$', |
72 | 74 |
'group_all', {}, name='group_all'), |
73 |
url(r'^group/(?P<group_id>\d+)/join/?$', 'group_join', { |
|
74 |
},name='group_join'), |
|
75 |
url( |
|
76 |
r'^group/(?P<group_id>\d+)/leave/?$', 'group_leave', {}, |
|
77 |
name='group_leave'), |
|
78 |
url( |
|
79 |
r'^group/(?P<group_id>\d+)/(?P<user_id>\d+)/approve/?$', |
|
80 |
'approve_member', {}, name='approve_member'), |
|
81 |
url( |
|
82 |
r'^group/(?P<group_id>\d+)/(?P<user_id>\d+)/disapprove/?$', |
|
83 |
'disapprove_member', {}, name='disapprove_member'), |
|
75 |
url(r'^group/(?P<group_id>\d+)/join/?$', 'group_join', |
|
76 |
{}, name='group_join'), |
|
77 |
url(r'^group/(?P<group_id>\d+)/leave/?$', 'group_leave', |
|
78 |
{}, name='group_leave'), |
|
79 |
url(r'^group/(?P<group_id>\d+)/(?P<user_id>\d+)/approve/?$', |
|
80 |
'approve_member', {}, name='approve_member'), |
|
81 |
url(r'^group/(?P<group_id>\d+)/(?P<user_id>\d+)/disapprove/?$', |
|
82 |
'disapprove_member', {}, name='disapprove_member'), |
|
83 |
url(r'^group/(?P<group_id>\d+)/add/?$', |
|
84 |
'add_members', {}, name='add_members'), |
|
84 | 85 |
url(r'^group/create/?$', 'group_create_list', {}, |
85 | 86 |
name='group_create_list'), |
86 | 87 |
) |
b/snf-astakos-app/astakos/im/views.py | ||
---|---|---|
67 | 67 |
FeedbackForm, SignApprovalTermsForm, |
68 | 68 |
ExtendedPasswordChangeForm, EmailChangeForm, |
69 | 69 |
AstakosGroupCreationForm, AstakosGroupSearchForm, |
70 |
AstakosGroupUpdateForm) |
|
70 |
AstakosGroupUpdateForm, AddGroupMembersForm)
|
|
71 | 71 |
from astakos.im.functions import (send_feedback, SendMailError, |
72 | 72 |
invite as invite_func, logout as auth_logout, |
73 | 73 |
activate as activate_func, |
... | ... | |
733 | 733 |
except AstakosGroup.DoesNotExist: |
734 | 734 |
return HttpResponseBadRequest(_('Invalid group.')) |
735 | 735 |
form = AstakosGroupUpdateForm(instance=group) |
736 |
search_form = AddGroupMembersForm() |
|
736 | 737 |
return object_detail(request, |
737 | 738 |
AstakosGroup.objects.all(), |
738 | 739 |
object_id=group_id, |
739 | 740 |
extra_context={'quota': group.quota, |
740 |
'form': form} |
|
741 |
'form': form, |
|
742 |
'search_form': search_form} |
|
741 | 743 |
) |
742 | 744 |
|
743 | 745 |
|
... | ... | |
753 | 755 |
form = AstakosGroupUpdateForm(request.POST, instance=group) |
754 | 756 |
if form.is_valid(): |
755 | 757 |
form.save() |
758 |
search_form = AddGroupMembersForm() |
|
756 | 759 |
return object_detail(request, |
757 | 760 |
AstakosGroup.objects.all(), |
758 | 761 |
object_id=group_id, |
759 | 762 |
extra_context={'quota': group.quota, |
760 |
'form': form}) |
|
763 |
'form': form, |
|
764 |
'search_form': search_form}) |
|
761 | 765 |
|
762 | 766 |
@signed_terms_required |
763 | 767 |
@login_required |
... | ... | |
896 | 900 |
messages.error(request, msg) |
897 | 901 |
|
898 | 902 |
|
903 |
|
|
904 |
|
|
905 |
@signed_terms_required |
|
906 |
@login_required |
|
907 |
def add_members(request, group_id): |
|
908 |
if request.method != 'POST': |
|
909 |
return HttpResponseBadRequest(_('Bad method')) |
|
910 |
try: |
|
911 |
group = AstakosGroup.objects.select_related().get(id=group_id) |
|
912 |
except AstakosGroup.DoesNotExist: |
|
913 |
return HttpResponseBadRequest(_('Invalid group.')) |
|
914 |
search_form = AddGroupMembersForm(request.POST) |
|
915 |
if search_form.is_valid(): |
|
916 |
users = search_form.get_valid_users() |
|
917 |
map(group.approve_member, users) |
|
918 |
search_form = AddGroupMembersForm() |
|
919 |
form = AstakosGroupUpdateForm(instance=group) |
|
920 |
return object_detail(request, |
|
921 |
AstakosGroup.objects.all(), |
|
922 |
object_id=group_id, |
|
923 |
extra_context={'quota': group.quota, |
|
924 |
'form': form, |
|
925 |
'search_form' : search_form} |
|
926 |
) |
|
927 |
|
|
928 |
|
|
899 | 929 |
@signed_terms_required |
900 | 930 |
@login_required |
901 | 931 |
def resource_list(request): |
Also available in: Unified diff