app/soc/views/site/user/profile.py
changeset 481 94834a1e6c01
parent 448 075360be6743
child 482 839740b061ad
equal deleted inserted replaced
480:9b07ddeb1412 481:94834a1e6c01
    26 
    26 
    27 from django import forms
    27 from django import forms
    28 from django import http
    28 from django import http
    29 from django.utils.translation import ugettext_lazy
    29 from django.utils.translation import ugettext_lazy
    30 
    30 
       
    31 from soc.logic import accounts
    31 from soc.logic import models
    32 from soc.logic import models
    32 from soc.logic import out_of_band
    33 from soc.logic import out_of_band
    33 from soc.logic import validate
    34 from soc.logic import validate
    34 from soc.logic.site import id_user
       
    35 from soc.views import simple
    35 from soc.views import simple
    36 from soc.views import helper
    36 from soc.views import helper
    37 from soc.views.helper import access
    37 from soc.views.helper import access
    38 from soc.views.helper import decorators
    38 from soc.views.helper import decorators
    39 from soc.views.user import profile
    39 from soc.views.user import profile
    55   required Properties of the User model need to sometimes be omitted.
    55   required Properties of the User model need to sometimes be omitted.
    56   
    56   
    57   Also, this form only permits entry and editing  of some of the User entity
    57   Also, this form only permits entry and editing  of some of the User entity
    58   Properties, not all of them.
    58   Properties, not all of them.
    59   """
    59   """
    60   id = forms.EmailField(required=False,
    60   account = forms.EmailField(required=False,
    61       label=soc.models.user.User.id.verbose_name,
    61       label=soc.models.user.User.account.verbose_name,
    62       help_text=soc.models.user.User.id.help_text)
    62       help_text=soc.models.user.User.account.help_text)
    63 
    63 
    64   link_name = forms.CharField(required=False,
    64   link_name = forms.CharField(required=False,
    65       label=soc.models.user.User.link_name.verbose_name,
    65       label=soc.models.user.User.link_name.verbose_name,
    66       help_text=soc.models.user.User.link_name.help_text)
    66       help_text=soc.models.user.User.link_name.help_text)
    67 
    67 
    78     if not validate.isLinkNameFormatValid(link_name):
    78     if not validate.isLinkNameFormatValid(link_name):
    79       raise forms.ValidationError('This link name is in wrong format.')
    79       raise forms.ValidationError('This link name is in wrong format.')
    80     
    80     
    81     return link_name
    81     return link_name
    82 
    82 
    83   def clean_id(self):
    83   def clean_account(self):
    84     email = self.cleaned_data.get('id')
    84     email = self.cleaned_data.get('account')
    85     
    85     
    86     if not email:
    86     if not email:
    87       # email not supplied (which is OK), so do not try to convert it
    87       # email not supplied (which is OK), so do not try to convert it
    88       return None
    88       return None
    89   
    89   
   128 
   128 
   129   if request.method == 'POST':
   129   if request.method == 'POST':
   130     form = LookupForm(request.POST)
   130     form = LookupForm(request.POST)
   131 
   131 
   132     if form.is_valid():
   132     if form.is_valid():
   133       form_id = form.cleaned_data.get('id')
   133       form_account = form.cleaned_data.get('account')
   134       
   134       
   135       if form_id:
   135       if form_account:
   136         # email provided, so attempt to look up user by email
   136         # email provided, so attempt to look up user by email
   137         user = models.user.logic.getForFields({'id': form_id}, unique=True)
   137         user = models.user.logic.getForFields(
       
   138             {'account': form_account}, unique=True)
   138 
   139 
   139         if user:
   140         if user:
   140           lookup_message = ugettext_lazy('User found by email.')
   141           lookup_message = ugettext_lazy('User found by email.')
   141         else:
   142         else:
   142           email_error = ugettext_lazy('User with that email not found.')
   143           email_error = ugettext_lazy('User with that email not found.')
   143           range_width = helper.lists.getPreferredListPagination()
   144           range_width = helper.lists.getPreferredListPagination()
   144           nearest_user_range_start = id_user.findNearestUsersOffset(
   145           nearest_user_range_start = (
   145               range_width, id=form_id)
   146               models.user.logic.findNearestEntitiesOffset(
       
   147                   width, [('account', form_account)]))
   146             
   148             
   147           if nearest_user_range_start is not None:            
   149           if nearest_user_range_start is not None:            
   148             context['lookup_link'] = './list?offset=%s&limit=%s' % (
   150             context['lookup_link'] = './list?offset=%s&limit=%s' % (
   149                 nearest_user_range_start, range_width)
   151                 nearest_user_range_start, range_width)
   150       if not user:
   152       if not user:
   151         # user not found yet, so see if link name was provided
   153         # user not found yet, so see if link name was provided
   152         link_name = form.cleaned_data.get('link_name')
   154         link_name = form.cleaned_data.get('link_name')
   153         
   155         
   154         if link_name:
   156         if link_name:
   155           # link name provided, so try to look up by link name 
   157           # link name provided, so try to look up by link name 
   156           user = id_user.getUserFromLinkName(link_name)
   158           user = models.user.logic.getForFields({'link_name': link_name},
   157         
   159                                                 unique=True)        
   158           if user:
   160           if user:
   159             lookup_message = ugettext_lazy('User found by link name.')
   161             lookup_message = ugettext_lazy('User found by link name.')
   160             # clear previous error, since User was found
   162             # clear previous error, since User was found
   161             email_error = None
   163             email_error = None
   162             # clear previous lookup_link, since User was found, the lookup_link
   164             # clear previous lookup_link, since User was found, the lookup_link
   165           else:
   167           else:
   166             context['link_name_error'] = ugettext_lazy(
   168             context['link_name_error'] = ugettext_lazy(
   167                 'User with that link name not found.')
   169                 'User with that link name not found.')
   168             if context['lookup_link'] is None:
   170             if context['lookup_link'] is None:
   169               range_width = helper.lists.getPreferredListPagination()
   171               range_width = helper.lists.getPreferredListPagination()
   170               nearest_user_range_start = id_user.findNearestUsersOffset(
   172               nearest_user_range_start = (
   171                   range_width, link_name=link_name)
   173                 models.user.logic.findNearestEntitiesOffset(
       
   174                     width, [('link_name', link_name)]))
   172             
   175             
   173               if nearest_user_range_start is not None:
   176               if nearest_user_range_start is not None:
   174                 context['lookup_link'] = './list?offset=%s&limit=%s' % (
   177                 context['lookup_link'] = './list?offset=%s&limit=%s' % (
   175                     nearest_user_range_start, range_width)
   178                     nearest_user_range_start, range_width)
   176     # else: form was not valid
   179     # else: form was not valid
   177   # else:  # method == 'GET'
   180   # else:  # method == 'GET'
   178 
   181 
   179   if user:
   182   if user:
   180     # User entity found, so populate form with existing User information
   183     # User entity found, so populate form with existing User information
   181     # context['found_user'] = user
   184     # context['found_user'] = user
   182     form = LookupForm(initial={'id': user.id.email(),
   185     form = LookupForm(initial={'account': user.account.email(),
   183                                'link_name': user.link_name})
   186                                'link_name': user.link_name})
   184 
   187 
   185     if request.path.endswith('lookup'):
   188     if request.path.endswith('lookup'):
   186       # convert /lookup path into /profile/link_name path
   189       # convert /lookup path into /profile/link_name path
   187       context['edit_link'] = helper.requests.replaceSuffix(
   190       context['edit_link'] = helper.requests.replaceSuffix(
   205   This form is manually specified, instead of using
   208   This form is manually specified, instead of using
   206     model = soc.models.user.User
   209     model = soc.models.user.User
   207   in the Meta class, because the form behavior is unusual and normally
   210   in the Meta class, because the form behavior is unusual and normally
   208   required Properties of the User model need to sometimes be omitted.
   211   required Properties of the User model need to sometimes be omitted.
   209   """
   212   """
   210   id = forms.EmailField(
   213   account = forms.EmailField(
   211       label=soc.models.user.User.id.verbose_name,
   214       label=soc.models.user.User.account.verbose_name,
   212       help_text=soc.models.user.User.id.help_text)
   215       help_text=soc.models.user.User.account.help_text)
   213 
   216 
   214   link_name = forms.CharField(
   217   link_name = forms.CharField(
   215       label=soc.models.user.User.link_name.verbose_name,
   218       label=soc.models.user.User.link_name.verbose_name,
   216       help_text=soc.models.user.User.link_name.help_text)
   219       help_text=soc.models.user.User.link_name.help_text)
   217 
   220 
   233       raise forms.ValidationError("This link name is in wrong format.")
   236       raise forms.ValidationError("This link name is in wrong format.")
   234 
   237 
   235     key_name = self.data.get('key_name')
   238     key_name = self.data.get('key_name')
   236     user = models.user.logic.getFromKeyName(key_name)
   239     user = models.user.logic.getFromKeyName(key_name)
   237     
   240     
   238     linkname_user_exist = id_user.getUserFromLinkName(link_name)
   241     linkname_user_exist = models.user.logic.getForFields(
       
   242         {'link_name': link_name}, unique=True)
       
   243         
   239     if (user and user.link_name != link_name) and linkname_user_exist:
   244     if (user and user.link_name != link_name) and linkname_user_exist:
   240       raise forms.ValidationError("This link name is already in use.")
   245       raise forms.ValidationError("This link name is already in use.")
   241 
   246 
   242     return link_name
   247     return link_name
   243 
   248 
   244   def clean_id(self):
   249   def clean_account(self):
   245     form_id = users.User(email=self.cleaned_data.get('id'))
   250     form_account = users.User(email=self.cleaned_data.get('account'))
   246     if not id_user.isIdAvailable(
   251     if not accounts.isAccountAvailable(
   247         form_id, existing_key_name=self.data.get('key_name')):
   252         form_account, existing_key_name=self.data.get('key_name')):
   248       raise forms.ValidationError("This account is already in use.")
   253       raise forms.ValidationError("This account is already in use.")
   249     if models.user.logic.isFormerId(form_id):
   254     if models.user.logic.isFormerAccount(form_account):
   250       raise forms.ValidationError("This account is invalid. "
   255       raise forms.ValidationError("This account is invalid. "
   251           "It exists as former id.")
   256           "It exists as a former account.")
   252     return form_id
   257     return form_account
   253 
   258 
   254 
   259 
   255 DEF_SITE_USER_PROFILE_EDIT_TMPL = 'soc/user/edit.html'
   260 DEF_SITE_USER_PROFILE_EDIT_TMPL = 'soc/user/edit.html'
   256 DEF_CREATE_NEW_USER_MSG = ' You can create a new user by visiting' \
   261 DEF_CREATE_NEW_USER_MSG = ' You can create a new user by visiting' \
   257                           ' <a href="/site/user/profile">Create ' \
   262                           ' <a href="/site/user/profile">Create ' \
   287   user = None  # assume that no User entity will be found
   292   user = None  # assume that no User entity will be found
   288 
   293 
   289   # try to fetch User entity corresponding to link_name if one exists
   294   # try to fetch User entity corresponding to link_name if one exists
   290   try:
   295   try:
   291     if link_name:
   296     if link_name:
   292       user = id_user.getUserFromLinkNameOr404(link_name)
   297       user = accounts.getUserFromLinkNameOr404(link_name)
   293   except out_of_band.ErrorResponse, error:
   298   except out_of_band.ErrorResponse, error:
   294     # show custom 404 page when link name doesn't exist in Datastore
   299     # show custom 404 page when link name doesn't exist in Datastore
   295     error.message = error.message + DEF_CREATE_NEW_USER_MSG
   300     error.message = error.message + DEF_CREATE_NEW_USER_MSG
   296     return simple.errorResponse(request, page, error, template, context)
   301     return simple.errorResponse(request, page, error, template, context)
   297 
   302 
   302     if form.is_valid():
   307     if form.is_valid():
   303       key_name = form.cleaned_data.get('key_name')
   308       key_name = form.cleaned_data.get('key_name')
   304       new_link_name = form.cleaned_data.get('link_name')
   309       new_link_name = form.cleaned_data.get('link_name')
   305 
   310 
   306       properties = {}
   311       properties = {}
   307       properties['id'] = form.cleaned_data.get('id')
   312       properties['account'] = form.cleaned_data.get('account')
   308       properties['link_name']  = new_link_name
   313       properties['link_name']  = new_link_name
   309       properties['nick_name']  = form.cleaned_data.get('nick_name')
   314       properties['nick_name']  = form.cleaned_data.get('nick_name')
   310       properties['is_developer'] = form.cleaned_data.get('is_developer')
   315       properties['is_developer'] = form.cleaned_data.get('is_developer')
   311       
   316       
   312       user = models.user.logic.updateOrCreateFromKeyName(properties, key_name)
   317       user = models.user.logic.updateOrCreateFromKeyName(properties, key_name)
   338                 request, profile.SUBMIT_MSG_PARAM_NAME,
   343                 request, profile.SUBMIT_MSG_PARAM_NAME,
   339                 values=profile.SUBMIT_MESSAGES))
   344                 values=profile.SUBMIT_MESSAGES))
   340 
   345 
   341         # populate form with the existing User entity
   346         # populate form with the existing User entity
   342         form = EditForm(initial={'key_name': user.key().name(),
   347         form = EditForm(initial={'key_name': user.key().name(),
   343             'id': user.id.email(), 'link_name': user.link_name,
   348             'account': user.account.email(), 'link_name': user.link_name,
   344             'nick_name': user.nick_name, 'is_developer': user.is_developer})
   349             'nick_name': user.nick_name, 'is_developer': user.is_developer})
   345       else:
   350       else:
   346         if request.GET.get(profile.SUBMIT_MSG_PARAM_NAME):
   351         if request.GET.get(profile.SUBMIT_MSG_PARAM_NAME):
   347           # redirect to aggressively remove 'Profile saved' query parameter
   352           # redirect to aggressively remove 'Profile saved' query parameter
   348           return http.HttpResponseRedirect(request.path)
   353           return http.HttpResponseRedirect(request.path)
   370   This form is manually specified, instead of using
   375   This form is manually specified, instead of using
   371     model = soc.models.user.User
   376     model = soc.models.user.User
   372   in the Meta class, because the form behavior is unusual and normally
   377   in the Meta class, because the form behavior is unusual and normally
   373   required Properties of the User model need to sometimes be omitted.
   378   required Properties of the User model need to sometimes be omitted.
   374   """
   379   """
   375   id = forms.EmailField(
   380   account = forms.EmailField(
   376       label=soc.models.user.User.id.verbose_name,
   381       label=soc.models.user.User.account.verbose_name,
   377       help_text=soc.models.user.User.id.help_text)
   382       help_text=soc.models.user.User.account.help_text)
   378 
   383 
   379   link_name = forms.CharField(
   384   link_name = forms.CharField(
   380       label=soc.models.user.User.link_name.verbose_name,
   385       label=soc.models.user.User.link_name.verbose_name,
   381       help_text=soc.models.user.User.link_name.help_text)
   386       help_text=soc.models.user.User.link_name.help_text)
   382 
   387 
   393   def clean_link_name(self):
   398   def clean_link_name(self):
   394     link_name = self.cleaned_data.get('link_name')
   399     link_name = self.cleaned_data.get('link_name')
   395     if not validate.isLinkNameFormatValid(link_name):
   400     if not validate.isLinkNameFormatValid(link_name):
   396       raise forms.ValidationError("This link name is in wrong format.")
   401       raise forms.ValidationError("This link name is in wrong format.")
   397     else:
   402     else:
   398       if id_user.getUserFromLinkName(link_name):
   403       if models.user.logic.getForFields({'link_name': link_name},
       
   404                                         unique=True):
   399         raise forms.ValidationError("This link name is already in use.")
   405         raise forms.ValidationError("This link name is already in use.")
   400     return link_name
   406     return link_name
   401 
   407 
   402   def clean_id(self):
   408   def clean_account(self):
   403     new_email = self.cleaned_data.get('id')
   409     new_email = self.cleaned_data.get('account')
   404     form_id = users.User(email=new_email)
   410     form_account = users.User(email=new_email)
   405     if models.user.logic.getForFields({'id': form_id}, unique=True):
   411     if models.user.logic.getForFields({'account': form_account}, unique=True):
   406       raise forms.ValidationError("This account is already in use.")
   412       raise forms.ValidationError("This account is already in use.")
   407     if models.user.logic.isFormerId(form_id):
   413     if models.user.logic.isFormerAccount(form_account):
   408       raise forms.ValidationError("This account is invalid. "
   414       raise forms.ValidationError("This account is invalid. "
   409           "It exists as former id.")
   415           "It exists as a former account.")
   410     return form_id
   416     return form_account
   411 
   417 
   412 
   418 
   413 DEF_SITE_CREATE_USER_PROFILE_TMPL = 'soc/user/edit.html'
   419 DEF_SITE_CREATE_USER_PROFILE_TMPL = 'soc/user/edit.html'
   414 
   420 
   415 @decorators.view
   421 @decorators.view
   439 
   445 
   440   if request.method == 'POST':
   446   if request.method == 'POST':
   441     form = CreateForm(request.POST)
   447     form = CreateForm(request.POST)
   442 
   448 
   443     if form.is_valid():
   449     if form.is_valid():
   444       form_id = form.cleaned_data.get('id')
   450       form_account = form.cleaned_data.get('account')
   445       link_name = form.cleaned_data.get('link_name')
   451       link_name = form.cleaned_data.get('link_name')
   446 
   452 
   447       properties = {
   453       properties = {
   448         'id': form_id,
   454         'account': form_account,
   449         'link_name': link_name,
   455         'link_name': link_name,
   450         'nick_name': form.cleaned_data.get('nick_name'),
   456         'nick_name': form.cleaned_data.get('nick_name'),
   451         'is_developer': form.cleaned_data.get('is_developer'),
   457         'is_developer': form.cleaned_data.get('is_developer'),
   452       }
   458       }
   453 
   459 
   454       key_fields = {'email': form_id.email()}
   460       key_fields = {'email': form_account.email()}
   455       user = models.user.logic.updateOrCreateFromFields(properties,
   461       user = models.user.logic.updateOrCreateFromFields(properties,
   456                                                         key_fields)
   462                                                         key_fields)
   457 
   463 
   458       if not user:
   464       if not user:
   459         return http.HttpResponseRedirect('/')
   465         return http.HttpResponseRedirect('/')