diff --git a/forms.py b/forms.py index ac0e2d0..1b557e9 100644 --- a/forms.py +++ b/forms.py @@ -605,13 +605,13 @@ class Login(FieldsetForm): """Form fields to let the user log in. """ - address = forms.EmailField( + addr = forms.EmailField( label = _('Email address'), error_messages = {'required': _('Please enter an email address.'), 'invalid': _('Please enter a valid email address.')}, required = True, ) - password = forms.CharField( + psw = forms.CharField( label = _('Password'), widget = forms.PasswordInput, error_messages = {'required': _('Please enter your password.'), @@ -624,7 +624,7 @@ Class to define the name of the fieldsets and what should be included in each. """ - layout = [["Login", "address", "password"],] + layout = [["Login", "addr", "psw"],] class ListMassSubscription(FieldsetForm): """Form fields to masssubscribe users to a list. @@ -673,8 +673,10 @@ required = False, choices = ( ("", _("Please choose")), - ("delivery_mode", "some mode..."), # this must later be - # changed to what modes are available + ("delivery_mode", "some mode..."), # TODO: this must later + # be dynalically changed to what modes the list offers + # (see the address field in __init__ in UserSettings for + # how to do this) ), label = _('Delivery mode'), ) @@ -686,16 +688,13 @@ required = False, choices = ( ("", _("Please choose")), - ("delivery_status", "some status..."), # this must later be - # changed to what statuses are available + ("delivery_status", "some status..."), # TODO: this must + # later be dynalically changed to what statuses the list + # offers (see the address field in __init__ in UserSettings + # for how to do this) ), label = _('Delivery status'), ) - name = forms.CharField( - label = "", - widget = forms.HiddenInput(), - initial = "membership", - ) class Meta: """ @@ -704,11 +703,23 @@ """ layout = [["Membership Settings", "acknowledge_posts", "hide_address", "receive_list_copy", "receive_own_postings", - "delivery_mode", "delivery_status", "name"],] + "delivery_mode", "delivery_status"],] class UserSettings(FieldsetForm): """Form handling the user settings. """ + def __init__(self, address_choices, *args, **kwargs): + """ + Initialize the user settings with a field 'address' where + the values are set dynamically in the view. + """ + super(UserSettings, self).__init__(*args, **kwargs) + self.fields['address'] = forms.ChoiceField(choices=(address_choices), + widget = forms.Select(), + error_messages = {'required': _("Please choose an address."),}, + required = True, + label = _('Default email address'),) + id = forms.IntegerField( # this should probably not be # changeable... label = _('ID'), @@ -724,19 +735,6 @@ widget = forms.HiddenInput(), required = False, ) - address = forms.ChoiceField( - widget = forms.Select(), - error_messages = { - 'required': _("Please choose an address."), - }, - required = True, - choices = ( - ("", _("Please choose")), - ("address", "address@example.com"), # this must later be - # changed to what addresses are available - ), - label = _('Default email address'), - ) real_name =forms.CharField( label = _('Real name'), required = False, @@ -750,8 +748,9 @@ required = False, choices = ( ("", _("Please choose")), - ("English (USA)", "English (USA)"), # this must later be - # changed to what languages the list offers + ("English (USA)", "English (USA)"), # TODO: this must later + # be dynalically changed to what languages the list offers + # (see the address field in __init__ for how to do this) ) ) password = forms.CharField( @@ -768,15 +767,11 @@ error_messages = {'required': _('Please enter your password.'), 'invalid': _('Please enter a valid password.')}, ) - name = forms.CharField( - label = "", - widget = forms.HiddenInput(), - initial = "user", - ) + class Meta: """ Class to define the name of the fieldsets and what should be included in each. """ layout = [["User settings", "real_name", "password", - "conf_password", "preferred_language", "address", "name"],] + "conf_password", "preferred_language", "address"],] diff --git a/mailman_rest_client.py b/mailman_rest_client.py index f87a422..91178b8 100644 --- a/mailman_rest_client.py +++ b/mailman_rest_client.py @@ -32,7 +32,7 @@ import json from httplib2 import Http -from mailmanclient import mockdata +from mailman_django import mockdata from operator import itemgetter from urllib import urlencode from urllib2 import HTTPError diff --git a/mockdata.py b/mockdata.py index 3c72223..dbed039 100644 --- a/mockdata.py +++ b/mockdata.py @@ -178,8 +178,8 @@ self.info['preferred_language'] = 'Preferred language lorem ipsum dolor sit' self.info['receive_list_copy'] = True self.info['receive_own_postings'] = True - self.info['delivery_mode'] = 'Delivery mode lorem ipsum dolor sit' - self.info['delivery_status'] = 'Delivery status lorem ipsum dolor sit' + #self.info['delivery_mode'] = 'Delivery mode lorem ipsum dolor sit' + #self.info['delivery_status'] = 'Delivery status lorem ipsum dolor sit' self.info['real_name'] = 'Real name lorem ipsum dolor sit' self.info['password'] = 'Password lorem ipsum dolor sit' self.info['preferences_id'] = 9 diff --git a/templates/mailman-django/lists/user_settings.html b/templates/mailman-django/lists/user_settings.html index 79f18ac..f6ed9b3 100644 --- a/templates/mailman-django/lists/user_settings.html +++ b/templates/mailman-django/lists/user_settings.html @@ -3,14 +3,16 @@ {% block content %} - -

{{ settings_type }}{% trans "Settings" %}

- -
+{% ifequal tab "membership"%} +

{% trans "Membership Settings" %} {% if listname %}{% trans "for"%}{% endif %} {{ listname }}

+{% else %} +

{% trans "User Settings" %}

+{% endifequal %} +

Logout

@@ -22,26 +24,22 @@

{{ message }}

{% endif %} -
+ +{% if form %}
-{{ user_form.as_div }} -
+
    + {{ form.as_ul }} +
  • -
+ +
-
- -
-{% for form in membership_forms %} -
-{{ form.as_div }} -
- -
-
+{% else %} +
- -
+ +{% endif %} {% endblock %} \ No newline at end of file diff --git a/urls.py b/urls.py index e10a1f5..2d9671e 100644 --- a/urls.py +++ b/urls.py @@ -9,7 +9,8 @@ url(r'^lists/logout/$', 'logout', name = 'logout'), url(r'^lists/(?P.+)/$', 'list_info', name = 'list_info'), url(r'^delete_list/(?P[^/]+)/$', 'list_delete', name = 'list_delete'), - url(r'^user_settings/(?P[^/]+)/$', 'user_settings', name = 'user_settings'), + url(r'^user_settings/(?P[^/]+)/$', 'user_settings', kwargs={"tab": "user"}, name = 'user_settings'), + url(r'^membership_settings/(?P[^/]+)/$', 'user_settings', kwargs={"tab": "membership"}, name = 'membership_settings'), url(r'^settings/(?P[^/]+)/$', 'list_settings', name = 'list_settings'), url(r'^settings/(?P[^/]+)/mass_subscribe/$', 'mass_subscribe', name = 'mass_subscribe'), # to override the default templates specifiy your own: diff --git a/views.py b/views.py index b008c03..199714b 100644 --- a/views.py +++ b/views.py @@ -16,7 +16,7 @@ user to be logged in. The function requiring login will automatically be added as an argument in the call. """ - def _login_decorator(*request, **kwargs): + def _login_decorator(*args, **kwargs): """ Inner decorator to require a user to login. This inner function gets access to the arguments of the function demanding @@ -26,9 +26,10 @@ redirected to the original function. """ # If the user is already logged in, let them continue directly. + request = args[0] try: - if request[0].session['member_id']: - return fn(request[0], **kwargs) + if request.session['member_id']: + return fn(*args, **kwargs) except: pass template = 'mailman-django/lists/login.html' @@ -39,16 +40,16 @@ valid_users = {"james@example.com": "james", "katie@example.com": "katie", "kevin@example.com": "kevin"} - if request[0].method == 'POST': - form = Login(request[0].POST) + if request.method == 'POST': + form = Login(request.POST) if form.is_valid(): - if request[0].POST["address"] in valid_users.keys(): - if request[0].POST["password"] == valid_users[request[0].POST["address"]]: + if request.POST["addr"] in valid_users.keys(): + if request.POST["psw"] == valid_users[request.POST["addr"]]: # TODO: change this to a better id when possible - request[0].session['member_id'] = request[0].POST["address"] + request.session['member_id'] = request.POST["addr"] # make sure to "reset" the method before continuing - request[0].method = 'GET' - return fn(request[0], **kwargs) + request.method = 'GET' + return fn(*args, **kwargs) message = "Your username and password didn't match." else: message = "" @@ -273,54 +274,77 @@ return render_to_response(template, {'form': form, 'message': message, 'fqdn_listname': the_list.info['fqdn_listname']}) + @login_required -def user_settings(request, member = None, +def user_settings(request, member = None, tab = "user", template = 'mailman-django/lists/user_settings.html'): """ Change the user or the membership settings. The user must be logged in to be allowed to change any settings. - TODO: * deal with the actual member and updating the list - * add CSS to display tabs - * create a function returning all membership lists for a user + TODO: * add CSS to display tabs + * add missing functionality in REST server and client and + change to the correct calls here """ message = "" - settings_type = "User " - membership_forms = [] - # TODO: call function to append all membership lists for a user + membership_lists = [] + listname = "" + try: + c = MailmanRESTClient('localhost:8001') + user_object = c.get_user(member) + # address_choices for the 'address' field must be a list of + # tuples of length 2 + address_choices = [[addr, addr] for addr in user_object.get_email_addresses()] + except Exception, e: + return HttpResponse(e) if request.method == 'POST': # The form enables both user and member settings. As a result # we must find out which was the case. - tab_type = request.POST.get('name', '') - if tab_type == "membership": - membership_forms.append(MembershipSettings(request.POST)) - user_form = UserSettings() - settings_type = "Membership " - # TODO: make sure the correct form is evaluated, this is - # just a temporary solution with one membership list - if membership_forms[0].is_valid(): - # TODO: add a call to an update function of the member - # settings HERE, once the member class is created + if tab == "membership": + form = MembershipSettings(request.POST) + if form.is_valid(): + member_object = c.get_member(member, request.GET["list"]) + member_object.update(request.POST) message = "The membership settings have been updated." else: - user_form = UserSettings(request.POST) - membership_forms.append(MembershipSettings()) - if user_form.is_valid(): - # TODO: add a call to an update function of the user - # settings HERE, once the member class is created + # the post request came from the user tab + # the 'address' field need choices as a tuple of length 2 + addr_choices = [[request.POST["address"], request.POST["address"]]] + form = UserSettings(addr_choices, request.POST) + if form.is_valid(): + user_object.update(request.POST) + # to get the full list of addresses we need to + # reinstantiate the form with all the addresses + # TODO: should return the correct settings from the DB, + # not just the address_choices (add mock data to _User + # class and make the call with 'user_object.info') + form = UserSettings(address_choices) message = "The user settings have been updated." else: - tab_type = "user" - user_form = UserSettings() - # TODO: add a call to a function adding all membership forms, - # this is just a temporary solution until we know what lists - # the user is subscribed to - membership_forms.append(MembershipSettings()) - - return render_to_response(template, {'user_form': user_form, - 'membership_forms': membership_forms, - 'settings_type': settings_type, - 'tab_type': tab_type, + if tab == "membership": + listname = request.GET.get("list", "") + if listname: + member_object = c.get_member(member, listname) + # TODO: add delivery_mode and deliver_status from a + # list of tuples at one point, currently we hard code + # them in forms.py + # instantiate the form with the correct member info + form = MembershipSettings(member_object.info) + else: + form = None + membership_lists = user_object.get_lists() + else: + # TODO: should return the correct settings from the DB, + # not just the address_choices (add mock data to _User + # class and make the call with 'user_object.info') The 'language' + # field must also be added as a list of tuples with correct + # values (is currently hard coded in forms.py). + form = UserSettings(address_choices) + + return render_to_response(template, {'form': form, + 'tab': tab, + 'listname': listname, + 'membership_lists': membership_lists, 'message': message, 'member': member})