app/soc/views/site/user/profile.py
changeset 170 1fadf6e0348d
parent 141 e120c24b89e2
child 171 b62f1cf5e878
--- a/app/soc/views/site/user/profile.py	Fri Sep 19 05:12:35 2008 +0000
+++ b/app/soc/views/site/user/profile.py	Fri Sep 19 05:15:20 2008 +0000
@@ -21,13 +21,12 @@
   '"Todd Larsen" <tlarsen@google.com>',
   ]
 
-import re
-import logging
 
 from google.appengine.api import users
+
 from django import http
-from django import shortcuts
 from django import newforms as forms
+from django.utils.translation import ugettext_lazy
 
 from soc.logic import out_of_band
 from soc.logic.site import id_user
@@ -35,15 +34,29 @@
 from soc.views.helpers import forms_helpers
 from soc.views.helpers import response_helpers
 from soc.views.helpers import template_helpers
+from soc.views.user import profile
 
 import soc.models.user
 
 
 class LookupForm(forms_helpers.DbModelForm):
   """Django form displayed for a Developer to look up a User.
+  
+  This form is manually specified, instead of using
+    model = soc.models.user.User
+  in the Meta class, because the form behavior is unusual and normally
+  required Properties of the User model need to sometimes be omitted.
+  
+  Also, this form only permits entry and editing  of some of the User entity
+  Properties, not all of them.
   """
-  id = forms.EmailField(required=False)
-  link_name = forms.CharField(required=False)
+  id = forms.EmailField(required=False,
+      label=soc.models.user.User.id.verbose_name,
+      help_text=soc.models.user.User.id.help_text)
+
+  link_name = forms.CharField(required=False,
+      label=soc.models.user.User.link_name.verbose_name,
+      help_text=soc.models.user.User.link_name.help_text)
 
   class Meta:
     model = None
@@ -90,25 +103,15 @@
   # create default template context for use with any templates
   context = response_helpers.getUniversalContext(request)
 
-  logged_in_id = users.get_current_user()
-
-  alt_response = simple.getAltResponseIfNotDeveloper(request, context, 
-                                                        id = logged_in_id)
+  alt_response = simple.getAltResponseIfNotDeveloper(request,
+                                                     context=context)
   if alt_response:
-    # not a developer
-    return alt_response
-  
-  alt_response = simple.getAltResponseIfNotLoggedIn(request, context, 
-                                                        id = logged_in_id)
-  if alt_response:
-    # not logged in
     return alt_response
 
   user = None  # assume that no User entity will be found
   form = None  # assume blank form needs to be displayed
-  lookup_message = 'Enter information to look up a User.'
-  lookup_error = None  # assume no look-up errors
-  edit_link = None  # assume no User entity found to be edited
+  lookup_message = ugettext_lazy('Enter information to look up a User.')
+  email_error = None  # assume no email look-up errors
 
   if request.method == 'POST':
     form = LookupForm(request.POST)
@@ -121,9 +124,9 @@
         user = id_user.getUserFromId(form_id)
 
         if user:
-          lookup_message = 'User found by email.'
+          lookup_message = ugettext_lazy('User found by email.')
         else:
-          lookup_error = 'User with that email not found.'
+          email_error = ugettext_lazy('User with that email not found.')
 
       if not user:
         # user not found yet, so see if link name was provided
@@ -134,15 +137,11 @@
           user = id_user.getUserFromLinkName(linkname)
         
           if user:
-            lookup_message = 'User found by link name.'
-            lookup_error = None  # clear previous error, now that User was found
+            lookup_message = ugettext_lazy('User found by link name.')
+            email_error = None  # clear previous error, since User was found
           else:
-            if form_id:
-              # email was provided, so look up failure is due to both            
-              lookup_error = 'User with that email or link name not found.'            
-            else:
-              # email was not provided, so look up failure is due to link name            
-              lookup_error = 'User with that link name not found.'            
+            context['linkname_error'] = ugettext_lazy(
+                'User with that link name not found.')            
     # else: form was not valid
   # else:  # method == 'GET'
 
@@ -154,17 +153,149 @@
 
     if request.path.endswith('lookup'):
       # convert /lookup path into /profile/link_name path
-      edit_link = '%sprofile/%s' % (request.path[:-len('lookup')],
-                                    user.link_name) 
+      context['edit_link'] = response_helpers.replaceSuffix(
+          request.path, 'lookup', 'profile/%s' % user.link_name)
     # else: URL is not one that was expected, so do not display edit link
   elif not form:
     # no pre-populated form was constructed, so show the empty look-up form
     form = LookupForm()
 
   context.update({'form': form,
-                  'edit_link': edit_link,
                   'found_user': user,
-                  'lookup_error': lookup_error,
+                  'email_error': email_error,
                   'lookup_message': lookup_message})
 
   return response_helpers.respond(request, template, context)
+
+
+class EditForm(forms_helpers.DbModelForm):
+  """Django form displayed when Developer creates or edits a User.
+  
+  This form is manually specified, instead of using
+    model = soc.models.user.User
+  in the Meta class, because the form behavior is unusual and normally
+  required Properties of the User model need to sometimes be omitted.
+  """
+  id = forms.EmailField(
+      label=soc.models.user.User.id.verbose_name,
+      help_text=soc.models.user.User.id.help_text)
+
+  link_name = forms.CharField(
+      label=soc.models.user.User.link_name.verbose_name,
+      help_text=soc.models.user.User.link_name.help_text)
+
+  nick_name = forms.CharField(
+      label=soc.models.user.User.nick_name.verbose_name)
+
+  is_developer = forms.BooleanField(required=False,
+      label=soc.models.user.User.is_developer.verbose_name,
+      help_text=soc.models.user.User.is_developer.help_text)
+
+  class Meta:
+    model = None
+ 
+  def clean_link_name(self):
+    link_name = self.cleaned_data.get('link_name')
+    if not id_user.isLinkNameFormatValid(link_name):
+      raise forms.ValidationError("This link name is in wrong format.")
+    else:
+      if not id_user.isLinkNameAvailableForId(
+          link_name, id=self.cleaned_data.get('id')):
+        raise forms.ValidationError("This link name is already in use.")
+    return link_name
+
+  def clean_id(self):
+    try:
+      return users.User(email=self.cleaned_data.get('id'))
+    except users.UserNotFoundError:
+      raise forms.ValidationError('Account not found.')
+    
+
+DEF_SITE_USER_PROFILE_EDIT_TMPL = 'soc/site/user/profile/edit.html'
+
+def edit(request, linkname=None, template=DEF_SITE_USER_PROFILE_EDIT_TMPL):
+  """View for a Developer to modify the properties of a User Model entity.
+
+  Args:
+    request: the standard django request object
+    linkname: the User's site-unique "linkname" extracted from the URL
+    template: the "sibling" template (or a search list of such templates)
+      from which to construct the public.html template name (or names)
+
+  Returns:
+    A subclass of django.http.HttpResponse which either contains the form to
+    be filled out, or a redirect to the correct view in the interface.
+  """
+  # create default template context for use with any templates
+  context = response_helpers.getUniversalContext(request)
+
+  alt_response = simple.getAltResponseIfNotDeveloper(request,
+                                                     context=context)
+  if alt_response:
+    return alt_response
+
+  user = None  # assume that no User entity will be found
+
+  if request.method == 'POST':
+    form = EditForm(request.POST)
+
+    if form.is_valid():
+      form_id = form.cleaned_data.get('id')
+      new_linkname = form.cleaned_data.get('link_name')
+      nickname = form.cleaned_data.get('nick_name')
+      is_developer = form.cleaned_data.get('is_developer')
+      
+      user = id_user.updateOrCreateUserFromId(
+        form_id, link_name=new_linkname, nick_name=nickname,
+        is_developer=is_developer)
+
+      # redirect to new /site/user/profile/new_linkname&s=0
+      # (causes 'Profile saved' message to be displayed)
+      return response_helpers.redirectToChangedSuffix(
+          request, linkname, new_linkname,
+          params=profile.SUBMIT_PROFILE_SAVED_PARAMS)
+  else: # method == 'GET':
+    # try to fetch User entity corresponding to link name if one exists
+    if linkname:
+      user = id_user.getUserFromLinkName(linkname)
+
+      if user:
+        # is 'Profile saved' parameter present, but referrer was not ourself?
+        # (e.g. someone bookmarked the GET that followed the POST submit) 
+        if (request.GET.get(profile.SUBMIT_MSG_PARAM_NAME)
+            and (not response_helpers.isReferrerSelf(request,
+                                                    suffix=linkname))):
+          # redirect to aggressively remove 'Profile saved' query parameter
+          return http.HttpResponseRedirect(request.path)
+    
+        # referrer was us, so select which submit message to display
+        # (may display no message if ?s=0 parameter is not present)
+        context['submit_message'] = (
+            template_helpers.getSingleIndexedParamValue(
+                request, profile.SUBMIT_MSG_PARAM_NAME,
+                values=profile.SUBMIT_MESSAGES))
+
+        # populate form with the existing User entity
+        form = EditForm(initial={
+            'id': user.id, 'link_name': user.link_name,
+            'nick_name': user.nick_name, 'is_developer': user.is_developer})       
+      else:
+        if request.GET.get(profile.SUBMIT_MSG_PARAM_NAME):
+          # redirect to aggressively remove 'Profile saved' query parameter
+          return http.HttpResponseRedirect(request.path)
+          
+        context['lookup_error'] = ugettext_lazy(
+            'User with that link name not found.')
+        form = EditForm(initial={'link_name': linkname})
+    else:  # no link name specified in the URL
+      if request.GET.get(profile.SUBMIT_MSG_PARAM_NAME):
+        # redirect to aggressively remove 'Profile saved' query parameter
+        return http.HttpResponseRedirect(request.path)
+
+      # no link name specified, so start with an empty form
+      form = EditForm()
+
+  context.update({'form': form,
+                  'existing_user': user})
+
+  return response_helpers.respond(request, template, context)