Resource, EmailChange, GroupKind, Membership,
AstakosGroupQuota, RESOURCE_SEPARATOR)
from django.views.decorators.http import require_http_methods
+from django.db.models.query import QuerySet
from astakos.im.activation_backends import get_backend, SimpleBackend
from astakos.im.util import get_context, prepare_response, set_cookie, get_query
AstakosGroupCreationForm, AstakosGroupSearchForm,
AstakosGroupUpdateForm, AddGroupMembersForm,
AstakosGroupSortForm, MembersSortForm,
- TimelineForm, PickResourceForm)
+ TimelineForm, PickResourceForm,
+ AstakosGroupCreationSummaryForm)
from astakos.im.functions import (send_feedback, SendMailError,
logout as auth_logout,
activate as activate_func,
switch_account_to_shibboleth,
send_group_creation_notification,
SendNotificationError)
-from astakos.im.endpoints.quotaholder import timeline_charge
+from astakos.im.endpoints.qh import timeline_charge
from astakos.im.settings import (COOKIE_NAME, COOKIE_DOMAIN, LOGOUT_NEXT,
LOGGING_LEVEL, PAGINATE_BY)
from astakos.im.tasks import request_billing
from astakos.im.api.callpoint import AstakosCallpoint
+import astakos.im.messages as astakos_messages
+
logger = logging.getLogger(__name__)
email = form.cleaned_data.get('username')
realname = form.cleaned_data.get('realname')
inviter.invite(email, realname)
- message = _('Invitation sent to %s' % email)
+ message = _(astakos_messages.INVITATION_SENT) % locals()
messages.success(request, message)
except SendMailError, e:
message = e.message
messages.error(request, message)
transaction.rollback()
except BaseException, e:
- message = _('Something went wrong.')
+ message = _(astakos_messages.GENERIC_ERROR)
messages.error(request, message)
logger.exception(e)
transaction.rollback()
else:
transaction.commit()
else:
- message = _('No invitations left')
+ message = _(astakos_messages.MAX_INVITATION_NUMBER_REACHED)
messages.error(request, message)
sent = [{'email': inv.username,
next = request.POST.get('next')
if next:
return redirect(next)
- msg = _('Profile has been updated successfully')
+ msg = _(astakos_messages.PROFILE_UPDATED)
messages.success(request, msg)
except ValueError, ve:
messages.success(request, ve)
logger.log(LOGGING_LEVEL, msg)
if user and user.is_active:
next = request.POST.get('next', '')
+ response = prepare_response(request, user, next=next)
transaction.commit()
- return prepare_response(request, user, next=next)
+ return response
messages.add_message(request, status, message)
transaction.commit()
return render_response(on_success,
messages.error(request, message)
transaction.rollback()
except BaseException, e:
- message = _('Something went wrong.')
+ message = _(astakos_messages.GENERIC_ERROR)
messages.error(request, message)
logger.exception(e)
transaction.rollback()
except SendMailError, e:
messages.error(request, message)
else:
- message = _('Feedback successfully sent')
+ message = _(astakos_messages.FEEDBACK_SENT)
messages.success(request, message)
return render_response(template_name,
feedback_form=form,
response['Location'] = LOGOUT_NEXT
response.status_code = 301
return response
- messages.success(request, _('You have successfully logged out.'))
+ messages.success(request, _(astakos_messages.LOGOUT_SUCCESS))
context = get_context(request, extra_context)
response.write(
template_loader.render_to_string(template, context_instance=context))
try:
user = AstakosUser.objects.get(auth_token=token)
except AstakosUser.DoesNotExist:
- return HttpResponseBadRequest(_('No such user'))
+ return HttpResponseBadRequest(_(astakos_messages.ACCOUNT_UNKNOWN))
if user.is_active:
- message = _('Account already active.')
+ message = _(astakos_messages.ACCOUNT_ALREADY_ACTIVE)
messages.error(request, message)
return index(request)
transaction.rollback()
return index(request)
except BaseException, e:
- message = _('Something went wrong.')
+ message = _(astakos_messages.GENERIC_ERROR)
messages.error(request, message)
logger.exception(e)
transaction.rollback()
transaction.rollback()
return index(request)
except BaseException, e:
- message = _('Something went wrong.')
+ message = _(astakos_messages.GENERIC_ERROR)
messages.error(request, message)
logger.exception(e)
transaction.rollback()
pass
if not term:
- messages.error(request, 'There are no approval terms.')
+ messages.error(request, _(astakos_messages.NO_APPROVAL_TERMS))
return HttpResponseRedirect(reverse('index'))
f = open(term.location, 'r')
terms = f.read()
try:
user = EmailChange.objects.change_email(activation_key)
if request.user.is_authenticated() and request.user == user:
- msg = _('Email changed successfully.')
+ msg = _(astakos_messages.EMAIL_CHANGED)
messages.success(request, msg)
auth_logout(request)
response = prepare_response(request, user)
messages.error(request, msg)
transaction.rollback()
except IntegrityError, e:
- msg = _('There is already a pending change email request.')
+ msg = _(astakos_messages.PENDING_EMAIL_CHANGE_REQUEST)
messages.error(request, msg)
else:
- msg = _('Change email request has been registered succefully.\
- You are going to receive a verification email in the new address.')
+ msg = _(astakos_messages.EMAIL_CHANGE_REGISTERED)
messages.success(request, msg)
transaction.commit()
return render_response(form_template_name,
extra_context))
+
+resource_presentation = {
+ 'compute': {
+ 'help_text':'group compute help text',
+ 'is_abbreviation':False,
+ 'report_desc':''
+ },
+ 'storage': {
+ 'help_text':'group storage help text',
+ 'is_abbreviation':False,
+ 'report_desc':''
+ },
+ 'pithos+.diskspace': {
+ 'help_text':'resource pithos+.diskspace help text',
+ 'is_abbreviation':False,
+ 'report_desc':'Pithos+ Diskspace',
+ 'placeholder':'eg. 10GB'
+ },
+ 'cyclades.vm': {
+ 'help_text':'resource cyclades.vm help text resource cyclades.vm help text resource cyclades.vm help text resource cyclades.vm help text',
+ 'is_abbreviation':True,
+ 'report_desc':'Virtual Machines',
+ 'placeholder':'eg. 2'
+ },
+ 'cyclades.disksize': {
+ 'help_text':'resource cyclades.disksize help text',
+ 'is_abbreviation':False,
+ 'report_desc':'Disksize',
+ 'placeholder':'eg. 5GB, 2GB etc'
+ },
+ 'cyclades.disk': {
+ 'help_text':'resource cyclades.disk help text',
+ 'is_abbreviation':False,
+ 'report_desc':'Disk',
+ 'placeholder':'eg. 5GB, 2GB etc'
+ },
+ 'cyclades.ram': {
+ 'help_text':'resource cyclades.ram help text',
+ 'is_abbreviation':True,
+ 'report_desc':'RAM',
+ 'placeholder':'eg. 4GB'
+ },
+ 'cyclades.cpu': {
+ 'help_text':'resource cyclades.cpu help text',
+ 'is_abbreviation':True,
+ 'report_desc':'CPUs',
+ 'placeholder':'eg. 1'
+ },
+ 'cyclades.network.private': {
+ 'help_text':'resource cyclades.network.private help text',
+ 'is_abbreviation':False,
+ 'report_desc':'Network',
+ 'placeholder':'eg. 1'
+ }
+ }
+
+@require_http_methods(["GET", "POST"])
@signed_terms_required
@login_required
def group_add(request, kind_name='default'):
result = callpoint.list_resources()
+ print '###', result
resource_catalog = {'resources':defaultdict(defaultdict),
'groups':defaultdict(list)}
if result.is_success:
try:
kind = GroupKind.objects.get(name=kind_name)
except:
- return HttpResponseBadRequest(_('No such group kind'))
+ return HttpResponseBadRequest(_(astakos_messages.GROUPKIND_UNKNOWN))
+
- resource_presentation = {
- 'compute': {
- 'help_text':'group compute help text',
- },
- 'storage': {
- 'help_text':'group storage help text',
- },
- 'pithos+.diskspace': {
- 'help_text':'resource pithos+.diskspace help text',
- },
- 'cyclades.vm': {
- 'help_text':'resource cyclades.vm help text resource cyclades.vm help text resource cyclades.vm help text resource cyclades.vm help text',
- },
- 'cyclades.disksize': {
- 'help_text':'resource cyclades.disksize help text',
- },
- 'cyclades.ram': {
- 'help_text':'resource cyclades.ram help text',
- }
- }
post_save_redirect = '/im/group/%(id)s/'
context_processors = None
form_class=AstakosGroupCreationForm
)
+ resources = resource_catalog['resources']
+
+
if request.method == 'POST':
form = form_class(request.POST, request.FILES)
if form.is_valid():
- d = form.cleaned_data.copy()
- d['owners'] = [request.user]
- result = callpoint.create_groups((d,)).next()
- if result.is_success:
- new_object = result.data[0]
- msg = _("The %(verbose_name)s was created successfully.") %\
- {"verbose_name": model._meta.verbose_name}
- messages.success(request, msg, fail_silently=True)
-
-# # send notification
-# try:
-# send_group_creation_notification(
-# template_name='im/group_creation_notification.txt',
-# dictionary={
-# 'group': new_object,
-# 'owner': request.user,
-# 'policies': list(form.cleaned_data['policies']),
-# }
-# )
-# except SendNotificationError, e:
-# messages.error(request, e, fail_silently=True)
- return HttpResponseRedirect(post_save_redirect % new_object)
- else:
- msg = _("The %(verbose_name)s creation failed: %(reason)s.") %\
- {"verbose_name": model._meta.verbose_name,
- "reason":result.reason}
- messages.error(request, msg, fail_silently=True)
+ return render_response(
+ template='im/astakosgroup_form_summary.html',
+ context_instance=get_context(request),
+ form = AstakosGroupCreationSummaryForm(form.cleaned_data),
+ policies = form.policies(),
+ resource_presentation=resource_presentation,
+ resource_catalog= resource_catalog,
+ resources = resources,
+
+ )
else:
now = datetime.now()
data = {
- 'kind': kind
+ 'kind': kind,
}
+ for group, resources in resource_catalog['groups'].iteritems():
+ data['is_selected_%s' % group] = False
+ for resource in resources:
+ data['%s_uplimit' % resource] = ''
+
form = form_class(data)
# Create the template, context, response
- template_name = "%s/%s_form_demo.html" % (
+ template_name = "%s/%s_form.html" % (
model._meta.app_label,
model._meta.object_name.lower()
)
}, context_processors)
return HttpResponse(t.render(c))
+
+#@require_http_methods(["POST"])
+@require_http_methods(["GET", "POST"])
+@signed_terms_required
+@login_required
+def group_add_complete(request):
+ model = AstakosGroup
+ form = AstakosGroupCreationSummaryForm(request.POST)
+ if form.is_valid():
+ d = form.cleaned_data
+ d['owners'] = [request.user]
+ result = callpoint.create_groups((d,)).next()
+ if result.is_success:
+ new_object = result.data[0]
+ msg = _(astakos_messages.OBJECT_CREATED) %\
+ {"verbose_name": model._meta.verbose_name}
+ messages.success(request, msg, fail_silently=True)
+
+ # send notification
+ try:
+ send_group_creation_notification(
+ template_name='im/group_creation_notification.txt',
+ dictionary={
+ 'group': new_object,
+ 'owner': request.user,
+ 'policies': d.get('policies', [])
+ }
+ )
+ except SendNotificationError, e:
+ messages.error(request, e, fail_silently=True)
+ post_save_redirect = '/im/group/%(id)s/'
+ return HttpResponseRedirect(post_save_redirect % new_object)
+ else:
+ msg = _(astakos_messages.OBJECT_CREATED_FAILED) %\
+ {"verbose_name": model._meta.verbose_name,
+ "reason":result.reason}
+ messages.error(request, msg, fail_silently=True)
+ return render_response(
+ template='im/astakosgroup_form_summary.html',
+ context_instance=get_context(request),
+ form=form)
+
+
+#@require_http_methods(["GET"])
+@require_http_methods(["GET", "POST"])
@signed_terms_required
@login_required
def group_list(request):
none = request.user.astakos_groups.none()
+ sorting = request.GET.get('sorting')
q = AstakosGroup.objects.raw("""
SELECT auth_group.id,
%s AS groupname,
im_astakosuser_owner.astakosuser_id = owner.id)
WHERE im_membership.person_id = %s
""" % (DB_REPLACE_GROUP_SCHEME, request.user.id, request.user.id))
- d = defaultdict(list)
- for g in q:
- if request.user.email == g.groupowner:
- d['own'].append(g)
- else:
- d['other'].append(g)
- # validate sorting
- fields = ('own', 'other')
- for f in fields:
- v = globals()['%s_sorting' % f] = request.GET.get('%s_sorting' % f)
- if v:
- form = AstakosGroupSortForm({'sort_by': v})
- if not form.is_valid():
- globals()['%s_sorting' % f] = form.cleaned_data.get('sort_by')
- return object_list(request, queryset=none,
- extra_context={'is_search': False,
- 'mine': d['own'],
- 'other': d['other'],
- 'own_sorting': own_sorting,
- 'other_sorting': other_sorting,
- 'own_page': request.GET.get('own_page', 1),
- 'other_page': request.GET.get('other_page', 1)
- })
+
+ # Create the template, context, response
+ template_name = "%s/%s_list.html" % (
+ q.model._meta.app_label,
+ q.model._meta.object_name.lower()
+ )
+ extra_context = dict(
+ is_search=False,
+ q=q,
+ sorting=request.GET.get('sorting'),
+ page=request.GET.get('page', 1)
+ )
+ return render_response(template_name,
+ context_instance=get_context(request, extra_context)
+ )
+@require_http_methods(["GET", "POST"])
@signed_terms_required
@login_required
def group_detail(request, group_id):
if update_form.is_valid():
update_form.save()
if addmembers_form.is_valid():
- map(obj.approve_member, addmembers_form.valid_users)
+ try:
+ map(obj.approve_member, addmembers_form.valid_users)
+ except AssertionError:
+ msg = _(astakos_messages.GROUP_MAX_PARTICIPANT_NUMBER_REACHED)
+ messages.error(request, msg)
addmembers_form = AddGroupMembersForm()
template_name = "%s/%s_detail.html" % (
if form.is_valid():
sorting = form.cleaned_data.get('sort_by')
+ result = callpoint.list_resources()
+ resource_catalog = {'resources':defaultdict(defaultdict),
+ 'groups':defaultdict(list)}
+ if result.is_success:
+ for r in result.data:
+ service = r.get('service', '')
+ name = r.get('name', '')
+ group = r.get('group', '')
+ unit = r.get('unit', '')
+ fullname = '%s%s%s' % (service, RESOURCE_SEPARATOR, name)
+ resource_catalog['resources'][fullname] = dict(unit=unit, name=name)
+ resource_catalog['groups'][group].append(fullname)
+
+ resource_catalog = dict(resource_catalog)
+ for k, v in resource_catalog.iteritems():
+ resource_catalog[k] = dict(v)
+
+ print '####', resource_catalog, obj.quota
extra_context = {'update_form': update_form,
'addmembers_form': addmembers_form,
'page': request.GET.get('page', 1),
- 'sorting': sorting}
+ 'sorting': sorting,
+ 'resource_catalog':resource_catalog,
+ 'resource_presentation':resource_presentation,}
for key, value in extra_context.items():
if callable(value):
c[key] = value()
return response
+@require_http_methods(["GET", "POST"])
@signed_terms_required
@login_required
def group_search(request, extra_context=None, **kwargs):
+ print '###', request
q = request.GET.get('q')
sorting = request.GET.get('sorting')
if request.method == 'GET':
SELECT id FROM im_astakosuser_owner
WHERE astakosgroup_id = im_astakosgroup.group_ptr_id
AND astakosuser_id = %s)
- THEN 1 ELSE 0 END""" % request.user.id})
+ THEN 1 ELSE 0 END""" % request.user.id,
+ 'is_owner': """SELECT CASE WHEN EXISTS(
+ SELECT id FROM im_astakosuser_owner
+ WHERE astakosgroup_id = im_astakosgroup.group_ptr_id
+ AND astakosuser_id = %s)
+ THEN 1 ELSE 0 END""" % request.user.id,
+ })
if sorting:
# TODO check sorting value
queryset = queryset.order_by(sorting)
sorting=sorting))
+@require_http_methods(["GET", "POST"])
@signed_terms_required
@login_required
def group_all(request, extra_context=None, **kwargs):
SELECT date_joined FROM im_membership
WHERE group_id = im_astakosgroup.group_ptr_id
AND person_id = %s)
- THEN 1 ELSE 0 END""" % request.user.id})
+ THEN 1 ELSE 0 END""" % request.user.id,
+ 'is_owner': """SELECT CASE WHEN EXISTS(
+ SELECT id FROM im_astakosuser_owner
+ WHERE astakosgroup_id = im_astakosgroup.group_ptr_id
+ AND astakosuser_id = %s)
+ THEN 1 ELSE 0 END""" % request.user.id, })
sorting = request.GET.get('sorting')
if sorting:
# TODO check sorting value
sorting=sorting))
+#@require_http_methods(["POST"])
+@require_http_methods(["POST", "GET"])
@signed_terms_required
@login_required
def group_join(request, group_id):
return HttpResponseRedirect(post_save_redirect)
except IntegrityError, e:
logger.exception(e)
- msg = _('Failed to join group.')
+ msg = _(astakos_messages.GROUP_JOIN_FAILURE)
messages.error(request, msg)
return group_search(request)
+@require_http_methods(["POST"])
@signed_terms_required
@login_required
def group_leave(request, group_id):
group__id=group_id,
person=request.user)
except Membership.DoesNotExist:
- return HttpResponseBadRequest(_('Invalid membership.'))
+ return HttpResponseBadRequest(_(astakos_messages.NOT_A_MEMBER))
if request.user in m.group.owner.all():
- return HttpResponseForbidden(_('Owner can not leave the group.'))
+ return HttpResponseForbidden(_(astakos_messages.OWNER_CANNOT_LEAVE_GROUP))
return delete_object(
request,
model=Membership,
group__id=group_id,
person__id=user_id)
except Membership.DoesNotExist:
- return HttpResponseBadRequest(_('Invalid membership.'))
+ return HttpResponseBadRequest(_(astakos_messages.NOT_MEMBER))
else:
if request.user not in m.group.owner.all():
- return HttpResponseForbidden(_('User is not a group owner.'))
+ return HttpResponseForbidden(_(astakos_messages.NOT_OWNER))
func(request, m)
return group_detail(request, group_id)
return wrapper
+#@require_http_methods(["POST"])
+@require_http_methods(["POST", "GET"])
@signed_terms_required
@login_required
@handle_membership
try:
membership.approve()
realname = membership.person.realname
- msg = _('%s has been successfully joined the group.' % realname)
+ msg = _(astakos_messages.MEMBER_JOINED_GROUP) % locals()
messages.success(request, msg)
+ except AssertionError:
+ msg = _(astakos_messages.GROUP_MAX_PARTICIPANT_NUMBER_REACHED)
+ messages.error(request, msg)
except BaseException, e:
logger.exception(e)
realname = membership.person.realname
- msg = _('Something went wrong during %s\'s approval.' % realname)
+ msg = _(astakos_messages.GENERIC_ERROR)
messages.error(request, msg)
try:
membership.disapprove()
realname = membership.person.realname
- msg = _('%s has been successfully removed from the group.' % realname)
+ msg = MEMBER_REMOVED % realname
messages.success(request, msg)
except BaseException, e:
logger.exception(e)
- msg = _('Something went wrong during %s\'s disapproval.' % realname)
+ msg = _(astakos_messages.GENERIC_ERROR)
messages.error(request, msg)
+#@require_http_methods(["GET"])
+@require_http_methods(["POST", "GET"])
@signed_terms_required
@login_required
def resource_list(request):
entry['load_class'] = 'red'
max_value = float(entry['maxValue'])
curr_value = float(entry['currValue'])
- entry['ratio'] = (curr_value / max_value) * 100
+ if max_value > 0 :
+ entry['ratio'] = (curr_value / max_value) * 100
+ else:
+ entry['ratio'] = 0
if entry['ratio'] < 66:
entry['load_class'] = 'yellow'
if entry['ratio'] < 33:
messages.error(request, result.reason)
return render_response('im/resource_list.html',
data=data,
+ resource_presentation=resource_presentation,
context_instance=get_context(request))
context_instance=get_context(request),)
+#@require_http_methods(["GET"])
+@require_http_methods(["POST", "GET"])
@signed_terms_required
@login_required
def billing(request):
status, data = r.result
data = _clear_billing_data(data)
if status != 200:
- messages.error(request, _('Service response status: %d' % status))
+ messages.error(request, _(astakos_messages.BILLING_ERROR) % status)
except:
messages.error(request, r.result)
return data
+#@require_http_methods(["GET"])
+@require_http_methods(["POST", "GET"])
@signed_terms_required
@login_required
def timeline(request):
form=form,
timeline_header=timeline_header,
timeline_body=timeline_body)
- return data
+ return data