from astakos.im.functions import (send_verification, send_activation,
send_account_creation_notification,
send_group_creation_notification, activate)
-from astakos.im.settings import INVITATIONS_ENABLED, MODERATION_ENABLED, SITENAME, RE_USER_EMAIL_PATTERNS
+from astakos.im.settings import (INVITATIONS_ENABLED, MODERATION_ENABLED,
+ SITENAME, RE_USER_EMAIL_PATTERNS
+)
+from astakos.im.messages import as astakos_messages
import logging
import re
class VerificationSent(ActivationResult):
def __init__(self):
- message = _('Verification sent.')
+ message = _(astakos_messages.VERIFICATION_SENT)
super(VerificationSent, self).__init__(message)
class SwitchAccountsVerificationSent(ActivationResult):
def __init__(self, email):
- message = _('This email is already associated with another \
- local account. To change this account to a shibboleth \
- one follow the link in the verification email sent \
- to %s. Otherwise just ignore it.' % email)
+ message = _(astakos_messages.SWITCH_ACCOUNT_LINK_SENT)
super(SwitchAccountsVerificationSent, self).__init__(message)
class NotificationSent(ActivationResult):
def __init__(self):
- message = _('Your request for an account was successfully received and is now pending \
- approval. You will be notified by email in the next few days. Thanks for \
- your interest in ~okeanos! The GRNET team.')
+ message = _(astakos_messages.NOTIFACATION_SENT)
super(NotificationSent, self).__init__(message)
class RegistationCompleted(ActivationResult):
def __init__(self):
- message = _('Registration completed. You can now login.')
+ message = _(astakos_messages.REGISTRATION_COMPLETED)
super(RegistationCompleted, self).__init__(message)
ENTITY_KEY = '1'
+inf = float('inf')
+
logger = logging.getLogger(__name__)
+inf = float('inf')
def call(func_name):
"""Decorator function for QuotaholderHTTP client calls."""
for resource, uplimit in user.quota.iteritems():
key = ENTITY_KEY
quantity = None
- capacity = uplimit
+ capacity = uplimit if uplimit != inf else None
import_limit = None
export_limit = None
flags = 0
from astakos.im.util import reserved_email, get_query
+import astakos.im.messages as astakos_messages
+
import logging
import hashlib
import recaptcha.client.captcha as captcha
def clean_email(self):
email = self.cleaned_data['email']
if not email:
- raise forms.ValidationError(_("This field is required"))
+ raise forms.ValidationError(_(astakos_messages.REQUIRED_FIELD))
if reserved_email(email):
- raise forms.ValidationError(_("This email is already used"))
+ raise forms.ValidationError(_(astakos_messages.EMAIL_USED))
return email
def clean_has_signed_terms(self):
has_signed_terms = self.cleaned_data['has_signed_terms']
if not has_signed_terms:
- raise forms.ValidationError(_('You have to agree with the terms'))
+ raise forms.ValidationError(_(astakos_messages.SIGN_TERMS))
return has_signed_terms
def clean_recaptcha_response_field(self):
rrf = self.cleaned_data['recaptcha_response_field']
check = captcha.submit(rcf, rrf, RECAPTCHA_PRIVATE_KEY, self.ip)
if not check.is_valid:
- raise forms.ValidationError(
- _('You have not entered the correct words'))
+ raise forms.ValidationError(_(astakos_messages.CAPTCHA_VALIDATION_ERR))
def save(self, commit=True):
"""
def clean_email(self):
email = self.cleaned_data['email']
if not email:
- raise forms.ValidationError(_("This field is required"))
+ raise forms.ValidationError(_(astakos_messages.REQUIRED_FIELD))
return email
def clean_has_signed_terms(self):
has_signed_terms = self.cleaned_data['has_signed_terms']
if not has_signed_terms:
- raise forms.ValidationError(_('You have to agree with the terms'))
+ raise forms.ValidationError(_(astakos_messages.SIGN_TERMS))
return has_signed_terms
def save(self, commit=True):
email = self.cleaned_data['email']
for user in AstakosUser.objects.filter(email=email):
if user.provider == 'shibboleth':
- raise forms.ValidationError(_("This email is already associated with another shibboleth account."))
+ raise forms.ValidationError(_(astakos_messages.SHIBBOLETH_EMAIL_USED))
elif not user.is_active:
- raise forms.ValidationError(_("This email is already associated with an inactive account. \
- You need to wait to be activated before being able to switch to a shibboleth account."))
+ raise forms.ValidationError(_(astakos_messages.SHIBBOLETH_INACTIVE_ACC))
super(ShibbolethUserCreationForm, self).clean_email()
return email
rrf = self.cleaned_data['recaptcha_response_field']
check = captcha.submit(rcf, rrf, RECAPTCHA_PRIVATE_KEY, self.ip)
if not check.is_valid:
- raise forms.ValidationError(
- _('You have not entered the correct words'))
+ raise forms.ValidationError(_(astakos_messages.CAPTCHA_VALIDATION_ERR))
def clean(self):
super(LoginForm, self).clean()
if self.user_cache and self.user_cache.provider not in ('local', ''):
- raise forms.ValidationError(_('Local login is not the current authentication method for this account.'))
+ raise forms.ValidationError(_(astakos_messages.SUSPENDED_LOCAL_ACC))
return self.cleaned_data
try:
user = AstakosUser.objects.get(email=email, is_active=True)
if not user.has_usable_password():
- raise forms.ValidationError(
- _("This account has not a usable password."))
+ raise forms.ValidationError(_(astakos_messages.UNUSABLE_PASSWORD))
except AstakosUser.DoesNotExist:
- raise forms.ValidationError(_('That e-mail address doesn\'t have an associated user account. Are you sure you\'ve registered?'))
+ raise forms.ValidationError(_(astakos_messages.EMAIL_UNKNOWN))
return email
def save(
def clean_new_email_address(self):
addr = self.cleaned_data['new_email_address']
if AstakosUser.objects.filter(email__iexact=addr):
- raise forms.ValidationError(_(u'This email address is already in use. Please supply a different email address.'))
+ raise forms.ValidationError(_(astakos_messages.EMAIL_USED))
return addr
def save(self, email_template_name, request, commit=True):
def clean_has_signed_terms(self):
has_signed_terms = self.cleaned_data['has_signed_terms']
if not has_signed_terms:
- raise forms.ValidationError(_('You have to agree with the terms'))
+ raise forms.ValidationError(_(astakos_messages.SIGN_TERMS))
return has_signed_terms
username = self.cleaned_data['username']
try:
Invitation.objects.get(username=username)
- raise forms.ValidationError(
- _('There is already invitation for this email.'))
+ raise forms.ValidationError(_(astakos_messages.INVITATION_EMAIL_EXISTS))
except Invitation.DoesNotExist:
pass
return username
class AddGroupMembersForm(forms.Form):
q = forms.CharField(
max_length=800, widget=forms.Textarea, label=_('Add users'),
- help_text=_('Add comma separated user emails, eg. user1@user.com, user2@user.com'),
+ help_text=_(astakos_messages.ADD_GROUP_MEMBERS_Q_HELP),
required=True)
def clean(self):
db_entries = AstakosUser.objects.filter(email__in=users)
unknown = list(set(users) - set(u.email for u in db_entries))
if unknown:
- raise forms.ValidationError(
- _('Unknown users: %s' % ','.join(unknown)))
+ raise forms.ValidationError(_(astakos_messages.UNKNOWN_USERS) % ','.join(unknown))
self.valid_users = db_entries
return self.cleaned_data
FEEDBACK_EMAIL_SUBJECT,
EMAIL_CHANGE_EMAIL_SUBJECT)
import astakos.im.models
+import astakos.im.messages as astakos_messages
logger = logging.getLogger(__name__)
class SendAdminNotificationError(SendMailError):
def __init__(self):
- self.message = _('Failed to send notification')
+ self.message = _(astakos_messages.ADMIN_NOTIFICATION_SEND_ERR)
super(SendAdminNotificationError, self).__init__()
class SendVerificationError(SendMailError):
def __init__(self):
- self.message = _('Failed to send verification')
+ self.message = _(astakos_messages.VERIFICATION_SEND_ERR)
super(SendVerificationError, self).__init__()
class SendInvitationError(SendMailError):
def __init__(self):
- self.message = _('Failed to send invitation')
+ self.message = _(astakos_messages.INVITATION_SEND_ERR)
super(SendInvitationError, self).__init__()
class SendGreetingError(SendMailError):
def __init__(self):
- self.message = _('Failed to send greeting')
+ self.message = _(astakos_messages.GREETING_SEND_ERR)
super(SendGreetingError, self).__init__()
class SendFeedbackError(SendMailError):
def __init__(self):
- self.message = _('Failed to send feedback')
+ self.message = _(astakos_messages.FEEDBACK_SEND_ERR)
super(SendFeedbackError, self).__init__()
class ChangeEmailError(SendMailError):
def __init__(self):
- self.message = _('Failed to send change email')
+ self.message = self.message = _(astakos_messages.CHANGE_EMAIL_SEND_ERR)
super(ChangeEmailError, self).__init__()
class SendNotificationError(SendMailError):
def __init__(self):
- self.message = _('Failed to send notification email')
+ self.message = _(astakos_messages.NOTIFICATION_SEND_ERR)
super(SendNotificationError, self).__init__()
--- /dev/null
+# Copyright 2011-2012 GRNET S.A. All rights reserved.
+#
+# Redistribution and use in source and binary forms, with or
+# without modification, are permitted provided that the following
+# conditions are met:
+#
+# 1. Redistributions of source code must retain the above
+# copyright notice, this list of conditions and the following
+# disclaimer.
+#
+# 2. Redistributions in binary form must reproduce the above
+# copyright notice, this list of conditions and the following
+# disclaimer in the documentation and/or other materials
+# provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS
+# OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+# WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR
+# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
+# USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION HOWEVER CAUSED
+# AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE ARISING IN
+# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+# POSSIBILITY OF SUCH DAMAGE.
+#
+# The views and conclusions contained in the software and
+# documentation are those of the authors and should not be
+# interpreted as representing official policies, either expressed
+# or implied, of GRNET S.A.
+
+ACCOUNT_AUTHENTICATION_FAILED = 'Cannot authenticate account.'
+ACCOUNT_INACTIVE = 'Inactive account.'
+ACCOUNT_ALREADY_ACTIVE = 'Account is already active.'
+TOKEN_UNKNOWN = 'There is no user matching this token.'
+
+INVITATION_SENT = 'Invitation sent to %(emails.'
+PROFILE_UPDATED = 'Profile has been updated successfully.'
+FEEDBACK_SENT = 'Feedback successfully sent.'
+EMAIL_CHANGED = 'Account email has been changed successfully.'
+EMAIL_CHANGE_REGISTERED = 'Change email request has been registered succefully. \
+ You are going to receive a verification email in the new address.'
+
+OBJECT_CREATED = 'The %(verbose_names was created successfully.'
+MEMBER_JOINED_GROUP = '%(realnames has been successfully joined the group.'
+MEMBER_REMOVED = '%(realnames has been successfully removed from the group.'
+BILLING_ERROR = 'Service response status: %(status)d'
+LOGOUT_SUCCESS = 'You have successfully logged out.'
+
+GENERIC_ERROR = 'Something wrong has happened. \
+ Please contact the administrators for more details.'
+
+MAX_INVITATION_NUMBER_REACHED = 'There are no invitations left.'
+GROUP_MAX_PARTICIPANT_NUMBER_REACHED = 'Group maximum participant number has been reached.'
+NO_APPROVAL_TERMS = 'There are no approval terms.'
+PENDING_EMAIL_CHANGE_REQUEST = 'There is already a pending change email request.'
+OBJECT_CREATED_FAILED = 'The %(verbose_names creation failed: %(reasons.'
+GROUP_JOIN_FAILURE = 'Failed to join group.'
+GROUPKIND_UNKNOWN = 'There is no such a group kind'
+NOT_MEMBER = 'User is not member of the group.'
+NOT_OWNER = 'User is not a group owner.'
+OWNER_CANNOT_LEAVE_GROUP = 'Owner cannot leave the group.'
+
+# Field validation fields
+REQUIRED_FIELD = 'This field is required.'
+EMAIL_USED = 'This email address is already in use. Please supply a different email address.'
+SHIBBOLETH_EMAIL_USED = 'This email is already associated with another shibboleth account.'
+SHIBBOLETH_INACTIVE_ACC = 'This email is already associated with an inactive account. \
+ You need to wait to be activated before being able to switch to a shibboleth account.'
+
+SIGN_TERMS = 'You have to agree with the terms.'
+CAPTCHA_VALIDATION_ERR = 'You have not entered the correct words.'
+SUSPENDED_LOCAL_ACC = 'Local login is not the current authentication method for this account.'
+UNUSABLE_PASSWORD = 'This account has not a usable password.'
+EMAIL_UNKNOWN = 'That e-mail address doesn\'t have an associated user account. \
+ Are you sure you\'ve registered?'
+INVITATION_EMAIL_EXISTS = 'There is already invitation for this email.'
+INVITATION_CONSUMED_ERR = 'Invitation is used.'
+UNKNOWN_USERS = 'Unknown users: %s'
+UNIQUE_EMAIL_IS_ACTIVE_CONSTRAIN_ERR = 'Another account with the same email & is_active combination found.'
+INVALID_ACTIVATION_KEY = 'Invalid activation key.'
+NEW_EMAIL_ADDR_RESERVED = 'The new email address is reserved.'
+EMAIL_RESERVED = 'Email: %(email)s is reserved'
+
+# Field help text
+ADD_GROUP_MEMBERS_Q_HELP = 'Add comma separated user emails, eg. user1@user.com, user2@user.com'
+ASTAKOSUSER_GROUPS_HELP = 'In addition to the permissions manually assigned, \
+ this user will also get all permissions granted to each group he/she is in.'
+EMAIL_CHANGE_NEW_ADDR_HELP = 'Your old email address will be used until you verify your new one.'
+
+EMAIL_SEND_ERR = 'Failed to send %s.'
+ADMIN_NOTIFICATION_SEND_ERR = EMAIL_SEND_ERR % 'admin notification'
+VERIFICATION_SEND_ERR = EMAIL_SEND_ERR % 'verification'
+INVITATION_SEND_ERR = EMAIL_SEND_ERR % 'invitation'
+GREETING_SEND_ERR = EMAIL_SEND_ERR % 'greeting'
+FEEDBACK_SEND_ERR = EMAIL_SEND_ERR % 'feedback'
+CHANGE_EMAIL_SEND_ERR = EMAIL_SEND_ERR % 'feedback'
+NOTIFICATION_SEND_ERR = EMAIL_SEND_ERR % 'notification'
+
+
+MISSING_NEXT_PARAMETER = 'No next parameter'
+
+VERIFICATION_SENT = 'Verification sent.'
+
+SWITCH_ACCOUNT_LINK_SENT = 'This email is already associated with another local account. \
+ To change this account to a shibboleth one follow the link in the verification email sent to %(emails. \
+ Otherwise just ignore it.'
+NOTIFACATION_SENT = 'Your request for an account was successfully received and is now pending approval. \
+ You will be notified by email in the next few days. \
+ Thanks for your interest in ~okeanos! The GRNET team.'
+REGISTRATION_COMPLETED = 'Registration completed. You can now login.'
\ No newline at end of file
from django.db import models, IntegrityError
from django.contrib.auth.models import User, UserManager, Group, Permission
from django.utils.translation import ugettext as _
+from django.db import transaction
from django.core.exceptions import ValidationError
from django.db import transaction
from django.db.models.signals import (pre_save, post_save, post_syncdb,
from astakos.im.tasks import propagate_groupmembers_quota
from astakos.im.functions import send_invitation
+import astakos.im.messages as astakos_messages
+
logger = logging.getLogger(__name__)
DEFAULT_CONTENT_TYPE = None
self.save()
quota_disturbed.send(sender=self, users=self.approved_members)
+ @transaction.commit_manually
def approve_member(self, person):
m, created = self.membership_set.get_or_create(person=person)
# update date_joined in any case
- m.date_joined = datetime.now()
- m.save()
+ try:
+ m.approve()
+ except:
+ transaction.rollback()
+ raise
+ else:
+ transaction.commit()
- def disapprove_member(self, person):
- self.membership_set.remove(person=person)
+# def disapprove_member(self, person):
+# self.membership_set.remove(person=person)
@property
def members(self):
astakos_groups = models.ManyToManyField(
AstakosGroup, verbose_name=_('agroups'), blank=True,
- help_text=_("""In addition to the permissions manually assigned, this
- user will also get all permissions granted to each group
- he/she is in."""),
+ help_text=_(astakos_messages.ASTAKOSUSER_GROUPS_HELP),
through='Membership')
__has_signed_terms = False
q = q.filter(email=self.email)
q = q.filter(is_active=self.is_active)
if q.count() != 0:
- raise ValidationError({'__all__': [_('Another account with the same email & is_active combination found.')]})
+ raise ValidationError({'__all__': [_(astakos_messages.UNIQUE_EMAIL_IS_ACTIVE_CONSTRAIN_ERR)]})
@property
def signed_terms(self):
return False
def approve(self):
+ if self.group.max_participants:
+ assert len(self.group.approved_members) + 1 <= self.group.max_participants
self.date_joined = datetime.now()
self.save()
quota_disturbed.send(sender=self, users=(self.person,))
except AstakosUser.DoesNotExist:
pass
else:
- raise ValueError(_('The new email address is reserved.'))
+ raise ValueError(_(astakos_messages.NEW_EMAIL_ADDR_RESERVED))
# update user
user = AstakosUser.objects.get(pk=email_change.user_id)
user.email = email_change.new_email_address
email_change.delete()
return user
except EmailChange.DoesNotExist:
- raise ValueError(_('Invalid activation key'))
+ raise ValueError(_(astakos_messages.INVALID_ACTIVATION_KEY))
class EmailChange(models.Model):
new_email_address = models.EmailField(_(u'new e-mail address'),
- help_text=_(u'Your old email address will be used until you verify your new one.'))
+ help_text=_(astakos_messages.EMAIL_CHANGE_NEW_ADDR_HELP))
user = models.ForeignKey(
AstakosUser, unique=True, related_name='emailchange_user')
requested_at = models.DateTimeField(default=datetime.now())
post_save.connect(send_quota_disturbed, sender=AstakosUserQuota)
post_delete.connect(send_quota_disturbed, sender=AstakosUserQuota)
post_save.connect(send_quota_disturbed, sender=AstakosGroupQuota)
-post_delete.connect(send_quota_disturbed, sender=AstakosGroupQuota)
+post_delete.connect(send_quota_disturbed, sender=AstakosGroupQuota)
\ No newline at end of file
from astakos.im.forms import LoginForm
from astakos.im.settings import RATELIMIT_RETRIES_ALLOWED
+import astakos.im.messages as astakos_messages
+
from ratelimit.decorators import ratelimit
retries = RATELIMIT_RETRIES_ALLOWED - 1
message = None
if not user:
- message = _('Cannot authenticate account')
+ message = _(astakos_messages.ACCOUNT_AUTHENTICATION_FAILED)
elif not user.is_active:
- message = _('Inactive account')
+ message = _(astakos_messages.ACCOUNT_INACTIVE)
if message:
messages.error(request, message)
return render_to_response(on_failure,
from astakos.im.util import set_cookie
from astakos.im.functions import login as auth_login, logout
+import astakos.im.messages as astakos_messages
+
import logging
logger = logging.getLogger(__name__)
"""
next = request.GET.get('next')
if not next:
- return HttpResponseBadRequest(_('No next parameter'))
+ return HttpResponseBadRequest(_(astakos_messages.MISSING_NEXT_PARAMETER))
force = request.GET.get('force', None)
response = HttpResponse()
if force == '':
from astakos.im.forms import LoginForm
from astakos.im.activation_backends import get_backend, SimpleBackend
+import astakos.im.messages as astakos_messages
class Tokens:
# these are mapped by the Shibboleth SP software
request.GET.get('next'),
'renew' in request.GET)
else:
- message = _('Inactive account')
+ message = _(astakos_messages.ACCOUNT_INACTIVE)
messages.error(request, message)
return render_response(on_login_template,
login_form=LoginForm(request=request),
{% endif %}
{% endfor %}
</dd>
+ <dt>Max participants</dt>
+ <dd>{% if object.max_participants%}{{object.max_participants}}{% else %} {% endif %}</dd>
</dl>
</div>
{% extends "im/account_base.html" %}
+{% load filters %}
+{% block headjs %}
+ {{ block.super }}
+ <script src="{{ IM_STATIC_URL }}js/quotas.js"></script>
+{% endblock %}
{% block page.body %}
-<div class="projects">
- <div class="maincol {% block innerpage.class %}{% endblock %}">
- <form action="" method="post"
- class="withlabels">{% csrf_token %}
- <h2><span>CREATE {{ kind|upper }}</span></h2>
- {% include "im/form_render.html" %}
- <div class="form-row submit">
- <input type="submit" class="submit altcol" value="SUBMIT" />
- </div>
- </form>
+
+
+<form action="" method="post" class="withlabels quotas-form">{% csrf_token %}
+
+ <fieldset class="with-info">
+ <legend>
+ 1. CREATE GROUP
+ <span class="info">
+ <em>more info</em>
+ <span>Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text</span>
+ </span>
+ </legend>
+
+ {% include "im/form_render.html" %}
+
+<!--
+ <div class="double-checks">
+ <label>Max users per group</label>
+ <div class="form-row">
+ <p class="clearfix">
+ <label for="members_unlimited">Unlimited</label>
+ <input type="checkbox" id="members_unlimited" name="members_unlimited" class="unlimited" checked="checked">
+ <span class="info">
+ <em>more info</em>
+ <span>Help Text Help Text Help Text Text Help Text Help Text</span>
+ </span>
+ </p>
+ </div>
+ <div class="form-row">
+ <p class="clearfix">
+ <label for="members_limited">Limited</label>
+ <input type="checkbox" id="members_limited" name="members_limited" class="limited">
+ <input type="text" id="members_uplimit" name="members_uplimit" />
+
+ </p>
+
+ </div>
+
+ </div>
+ -->
+ </fieldset>
+
+ <fieldset id="icons">
+ <legend>
+ 2. CHOOSE RESOURCES
+ <span class="info">
+ <em>more info</em>
+ <span>Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text Help Text</span>
+ </span>
+ </legend>
+
+ {% with resource_catalog|lookup:'resources' as resources %}
+ {% with resource_catalog|lookup:'groups' as groups %}
+ <ul class="clearfix">
+ {% for g, rs in groups.items %}
+ {% with resource_presentation|lookup:g as group_info %}
+ <li>
+ <a href="#{{ g }}" id="{{'group_'|add:g}}"><img src="/static/im/images/create-{{ g }}.png" alt="vm"/></a>
+ <input type="hidden" name="{{ 'is_selected_'|add:g }}" id="{{ 'id_is_selected_'|add:g }}" value="0">
+ <p class="msg">{{ group_info.help_text }}</p>
+ </li>
+ {% endwith %}
+ {% endfor %}
+ </ul>
+
+ </fieldset>
+
+ <div class="foo">
+
+ </div>
+ <div class="not-foo">
+ {% for g, rs in groups.items %}
+
+ <div class="group {{'group_'|add:g}}" id="{{ g }}">
+ <a href="#icons" class="delete">X remove resource</a>
+ {% for r in rs %}
+ {% with resource_presentation|lookup:r as resource_info %}
+ {% with resources|lookup:r as resource%}
+ <fieldset class="quota storage">
+ <legend>
+ {% if resource_info.is_abbreviation %}
+ {{ r|get_value_after_dot|upper }}
+ {% else %}
+ {{ r|get_value_after_dot|capfirst }}
+ {% endif %}
+ <span class="info">
+ <em>more info</em>
+ <span>{{ resource_info.help_text }}</span>
+ </span>
+ </legend>
+<!-- <div class="form-row">
+ <p class="clearfix">
+ <label for="num_storage">Total storage</label>
+ <input type="text" name="num_storage">
+ <span class="extra-img"> </span>
+ <span class="info"><em>more info</em><span>Help Text</span></span>
+ </p>
+ </div>-->
+ <div class="double-checks">
+ <label>
+ Max {% if resource_info.is_abbreviation %}{{ r|get_value_after_dot|upper }}{% else %}{{ r|get_value_after_dot }}{% endif %}{% if not resource.unit %}s {% endif %} per user
+ {% if resource.unit %}
+ ({{ resource.unit }})
+ {% endif %}
+ </label>
+ <div class="form-row">
+ <p class="clearfix">
+ <label for="{{r|add:'_unlimited'}}">Unlimited</label>
+ <input type="checkbox" id="{{'id_'|add:r|add:'_unlimited'}}" name="{{r|add:'_unlimited'}}" class="unlimited radio" checked="checked">
+ </p>
+ </div>
+ <div class="form-row">
+ <p class="clearfix">
+ <label for="{{r|add:'_limited'}}">Limited</label>
+ <input type="checkbox" id="id_storage_per_user_limited" name="{{r|add:'_limited'}}" class="radio limited">
+ <input type="text" id="{{'id_'|add:r|add:'_uplimit'}}" name="{{r|add:'_uplimit'}}"/>
+ </p>
+ </div>
+
+ </div>
+ </fieldset>
+ {% endwith %}
+ {% endwith %}
+ {% endfor %}
+ </div>
+
+ {% endfor %}
</div>
-</div>
-{% endblock %}
+ {% endwith %}
+ {% endwith %}
+
+ <div class="form-row submit">
+ <input type="submit" value="SUBMIT" class="submit altcol" autocomplete="off">
+ </div>
+</form>
+
+<script>
+
+</script>
+
+{% endblock %}
\ No newline at end of file
from django.core.urlresolvers import reverse
from django.core.exceptions import ValidationError, ObjectDoesNotExist
from django.db.models.fields import Field
+from django.utils.translation import ugettext as _
+
from astakos.im.models import AstakosUser, Invitation
from astakos.im.settings import COOKIE_NAME, \
COOKIE_DOMAIN, COOKIE_SECURE, FORCE_PROFILE_UPDATE, LOGGING_LEVEL
from astakos.im.functions import login
+import astakos.im.messages as astakos_messages
+
logger = logging.getLogger(__name__)
return
invitation = Invitation.objects.get(code=code)
if invitation.is_consumed:
- raise ValueError(_('Invitation is used'))
+ raise ValueError(_(astakos_messages.INVITATION_CONSUMED_ERR))
if reserved_email(invitation.username):
- raise ValueError(_('Email: %s is reserved' % invitation.username))
+ email = invitation.username
+ raise ValueError(_(astakos_messages.EMAIL_RESRVED) % locals()))
return invitation
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)
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,
try:
kind = GroupKind.objects.get(name=kind_name)
except:
- return HttpResponseBadRequest(_('No such group kind'))
+ return HttpResponseBadRequest(_(astakos_messages.GROUPKIND_UNKNOWN))
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()
)
return HttpResponse(t.render(c))
-@require_http_methods(["POST"])
+#@require_http_methods(["POST"])
+@require_http_methods(["GET", "POST"])
@signed_terms_required
@login_required
def group_add_complete(request):
result = callpoint.create_groups((d,)).next()
if result.is_success:
new_object = result.data[0]
- msg = _("The %(verbose_name)s was created successfully.") %\
+ msg = _(astakos_messages.OBJECT_CREATED) %\
{"verbose_name": model._meta.verbose_name}
messages.success(request, msg, fail_silently=True)
post_save_redirect = '/im/group/%(id)s/'
return HttpResponseRedirect(post_save_redirect % new_object)
else:
- msg = _("The %(verbose_name)s creation failed: %(reason)s.") %\
+ msg = _(astakos_messages.OBJECT_CREATED_FAILED) %\
{"verbose_name": model._meta.verbose_name,
"reason":result.reason}
messages.error(request, msg, fail_silently=True)
form=form)
-@require_http_methods(["GET"])
+#@require_http_methods(["GET"])
+@require_http_methods(["GET", "POST"])
@signed_terms_required
@login_required
def group_list(request):
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" % (
sorting=sorting))
-@require_http_methods(["POST"])
+@require_http_methods(["GET", "POST"])
@signed_terms_required
@login_required
def group_all(request, extra_context=None, **kwargs):
sorting=sorting))
-@require_http_methods(["POST"])
+#@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)
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"])
+@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(["GET"])
+@require_http_methods(["POST", "GET"])
@signed_terms_required
@login_required
def resource_list(request):
context_instance=get_context(request),)
-@require_http_methods(["GET"])
+#@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(["GET"])
+@require_http_methods(["POST", "GET"])
@signed_terms_required
@login_required
def timeline(request):