app/soc/views/user/profile.py
changeset 124 051afb721c22
parent 118 d2e61a490969
child 131 3db97cf7f2c7
equal deleted inserted replaced
123:45d10b6af158 124:051afb721c22
    26 from google.appengine.api import users
    26 from google.appengine.api import users
    27 from django import http
    27 from django import http
    28 from django import shortcuts
    28 from django import shortcuts
    29 from django import newforms as forms
    29 from django import newforms as forms
    30 
    30 
       
    31 from soc.logic import out_of_band
    31 from soc.logic.site import id_user
    32 from soc.logic.site import id_user
       
    33 from soc.views import simple
    32 from soc.views.helpers import forms_helpers
    34 from soc.views.helpers import forms_helpers
    33 from soc.views.helpers import response_helpers
    35 from soc.views.helpers import response_helpers
       
    36 from soc.views.helpers import template_helpers
    34 
    37 
    35 import soc.models.user
    38 import soc.models.user
    36 
    39 
    37 
    40 
    38 class UserForm(forms_helpers.DbModelForm):
    41 class UserForm(forms_helpers.DbModelForm):
    68     elif not self.LINKNAME_REGEX.match(linkname):
    71     elif not self.LINKNAME_REGEX.match(linkname):
    69       raise forms.ValidationError("This link name is in wrong format.")
    72       raise forms.ValidationError("This link name is in wrong format.")
    70     return linkname
    73     return linkname
    71 
    74 
    72 
    75 
    73 def edit(request, linkname=None, template='soc/user/profile/edit.html'):
    76 DEF_USER_PROFILE_EDIT_TMPL = 'soc/user/profile/edit.html'
    74   """View for a User to modify the properties of a UserModel.
    77 
       
    78 def edit(request, linkname=None, template=DEF_USER_PROFILE_EDIT_TMPL):
       
    79   """View for a User to modify the properties of a User Model entity.
    75 
    80 
    76   Args:
    81   Args:
    77     request: the standard django request object.
    82     request: the standard django request object.
    78     linkname: the User's site-unique "linkname" extracted from the URL
    83     linkname: the User's site-unique "linkname" extracted from the URL
    79     template: the template path to use for rendering the template.
    84     template: the template path to use for rendering the template.
    80 
    85 
    81   Returns:
    86   Returns:
    82     A subclass of django.http.HttpResponse which either contains the form to
    87     A subclass of django.http.HttpResponse which either contains the form to
    83     be filled out, or a redirect to the correct view in the interface.
    88     be filled out, or a redirect to the correct view in the interface.
    84   """
    89   """
    85   #TODO(solydzajs): create controller for User and cleanup code in this handler
    90   id = users.get_current_user()
       
    91 
       
    92   # create default template context for use with any templates
       
    93   context = response_helpers.getUniversalContext(request)
       
    94 
       
    95   if (not id) and (not linkname):
       
    96     # not logged in, and no link name, so request that the user sign in 
       
    97     return simple.requestLogin(request, template, context,
       
    98         # TODO(tlarsen): /user/profile could be a link to a help page instead
       
    99         login_message_fmt='To create a new'
       
   100                           ' <a href="/user/profile">User Profile</a>'
       
   101                           ' or modify an existing one, you must first'
       
   102                           ' <a href="%(sign_in)s">sign in</a>.')
       
   103 
       
   104   if (not id) and linkname:
       
   105     # not logged in, so show read-only public profile for linkname user
       
   106     return simple.public(request, template, linkname, context)
       
   107 
       
   108   # try to fetch User entity corresponding to linkname if one exists    
       
   109   try:
       
   110     linkname_user = id_user.getUserIfLinkName(linkname)
       
   111   except out_of_band.ErrorResponse, error:
       
   112     # show custom 404 page when linkname doesn't exist in Datastore
       
   113     return simple.errorResponse(request, error, template, context)
    86   
   114   
    87   #TODO(solydzajs): use makeSiblingTemplatePath from templates_helpers and pass
   115   # linkname_user will be None here if linkname was already None...
    88   #                 result to public view
   116   if linkname_user and (linkname_user.id != id):
       
   117     # linkname_user exists but is not the currently logged in Google Account,
       
   118     # so show public view for that (other) User entity
       
   119     return simple.public(request, template, linkname, context)
       
   120 
       
   121   user = id_user.getUserFromId(id)
    89   
   122   
    90   # TODO: use something like the code below, define global public tmpl 
       
    91   # template_choices = [makeSiblingTemplatePath(template, 'public.html'),
       
    92   # DEF_USER_PROFILE_PUBLIC_TMPL])
       
    93   # public(request, linkname=linkname, template=template_choices)
       
    94   
       
    95   #: If user not signed and there is no linkname redirect to sign-in page
       
    96   #: otherwise show public profile for linkname user
       
    97   current_id = users.get_current_user()
       
    98   if not current_id and not linkname:
       
    99     return http.HttpResponseRedirect(users.create_login_url(request.path))
       
   100   elif not current_id and linkname:
       
   101     return public(request, linkname)
       
   102     
       
   103   user = id_user.getUserFromId(current_id)
       
   104   
       
   105   #: Show custom 404 page when linkname doesn't exist in datastore
       
   106   #: or show public view for linkname user
       
   107   if linkname:
       
   108     linkname_user = id_user.getUserFromLinkName(linkname)
       
   109     if not linkname_user:
       
   110       return http.HttpResponseNotFound('No user exists with that link name "%s"' %
       
   111                                        linkname)
       
   112     elif linkname_user and (linkname_user.id != current_id):
       
   113       return public(request, linkname)
       
   114 
       
   115   #: GET method
       
   116   if (request.method != 'POST') and user:
       
   117     form = UserForm(initial={'nick_name': user.nick_name,
       
   118                              'link_name': user.link_name})
       
   119     return response_helpers.respond(request,
       
   120         template, {'template': template, 
       
   121                    'form': form})
       
   122   
       
   123   #: POST method
       
   124   form = UserForm()
       
   125   if request.method == 'POST':
   123   if request.method == 'POST':
   126     form = UserForm(request.POST)
   124     form = UserForm(request.POST)
   127 
   125 
   128     if form.is_valid():
   126     if form.is_valid():
   129       linkname = form.cleaned_data.get('link_name')
   127       linkname = form.cleaned_data.get('link_name')
   130       nickname = form.cleaned_data.get("nick_name")
   128       nickname = form.cleaned_data.get("nick_name")
       
   129 
   131       if not user:
   130       if not user:
   132         user = soc.models.user.User(id=id,link_name=linkname,
   131         user = soc.models.user.User(id=id, link_name=linkname,
   133                                     nick_name=nickname)
   132                                     nick_name=nickname)
   134       else:
   133       else:
   135         user.nick_name = nickname
   134         user.nick_name = nickname
   136         user.link_name = linkname
   135         user.link_name = linkname
       
   136 
   137       user.put()
   137       user.put()
   138       return response_helpers.respond(request,
   138       # TODO(tlarsen):
   139               template, {'template': template, 
   139       # if old_linkname:  redirect to new /user/profile/new_linkname
   140                          'form': form,
   140       #   (how to preserve displaying the "Profile saved" message?)
   141                          'submit_message': 'Profile saved.'})
   141       context.update({'submit_message': 'Profile saved.'})
       
   142   else: # request.method == 'GET'
       
   143     if user:
       
   144       # populate form with the existing User entity
       
   145       form = UserForm(instance=user)
       
   146     else:
       
   147       # no User entity exists for this Google Account, so show a blank form
       
   148       form = UserForm()
   142 
   149 
   143   return response_helpers.respond(request,
   150   context.update({'form': form})
   144       template, {'template': template, 'form': form})
   151   return response_helpers.respond(request, template, context)
   145 
       
   146 
       
   147 def public(request, linkname=None,
       
   148            template='soc/user/profile/public.html'):
       
   149   """A "general public" view of a User on the site.
       
   150 
       
   151   Args:
       
   152     request: the standard django request object.
       
   153     linkname: the User's site-unique "linkname" extracted from the URL
       
   154     template: the template path to use for rendering the template.
       
   155 
       
   156   Returns:
       
   157     A subclass of django.http.HttpResponse with generated template.
       
   158   """
       
   159   #: If linkname is empty or not a valid linkname on the site, display
       
   160   #: "user does not exist", otherwise render public view for linkname user
       
   161   if linkname:
       
   162     linkname_user = id_user.getUserFromLinkName(linkname)
       
   163     if not linkname_user:
       
   164       return http.HttpResponseNotFound('No user exists with that link name "%s"' %
       
   165                                        linkname)
       
   166     else:
       
   167       return response_helpers.respond(request, 
       
   168           template, {'template': template,
       
   169                      'user': linkname_user})
       
   170       
       
   171   return http.HttpResponseNotFound('No user exists with that link name "%s"' %
       
   172                                    linkname)