app/soc/views/models/user_self.py
changeset 590 37735d97b541
parent 587 7504504209a3
child 605 4a384d412640
equal deleted inserted replaced
589:ee9122db04af 590:37735d97b541
       
     1 #!/usr/bin/python2.5
       
     2 #
       
     3 # Copyright 2008 the Melange authors.
       
     4 #
       
     5 # Licensed under the Apache License, Version 2.0 (the "License");
       
     6 # you may not use this file except in compliance with the License.
       
     7 # You may obtain a copy of the License at
       
     8 #
       
     9 #   http://www.apache.org/licenses/LICENSE-2.0
       
    10 #
       
    11 # Unless required by applicable law or agreed to in writing, software
       
    12 # distributed under the License is distributed on an "AS IS" BASIS,
       
    13 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
       
    14 # See the License for the specific language governing permissions and
       
    15 # limitations under the License.
       
    16 
       
    17 """Views for the User's own profiles.
       
    18 """
       
    19 
       
    20 __authors__ = [
       
    21     '"Sverre Rabbelier" <sverre@rabbelier.nl>',
       
    22     '"Pawel Solyga" <pawel.solyga@gmail.com>',
       
    23   ]
       
    24 
       
    25 
       
    26 from google.appengine.api import users
       
    27 
       
    28 from django import forms
       
    29 from django.utils.translation import ugettext_lazy
       
    30 
       
    31 from soc.logic import dicts
       
    32 from soc.logic import validate
       
    33 from soc.logic.models import user as user_logic
       
    34 from soc.views import helper
       
    35 from soc.views import out_of_band
       
    36 from soc.views.helper import access
       
    37 from soc.views.models import base
       
    38 
       
    39 import soc.models.linkable
       
    40 import soc.models.user
       
    41 import soc.logic.models.user
       
    42 import soc.views.helper
       
    43 
       
    44 
       
    45 class UserForm(helper.forms.BaseForm):
       
    46   """Django form displayed when creating or editing a User.
       
    47   """
       
    48   class Meta:
       
    49     """Inner Meta class that defines some behavior for the form.
       
    50     """
       
    51     #: db.Model subclass for which the form will gather information
       
    52     model = soc.models.user.User
       
    53 
       
    54     #: list of model fields which will *not* be gathered by the form
       
    55     exclude = ['account', 'former_accounts', 'is_developer']
       
    56 
       
    57   def clean_link_id(self):
       
    58     link_id = self.cleaned_data.get('link_id')
       
    59     if not validate.isLinkIdFormatValid(link_id):
       
    60       raise forms.ValidationError("This link ID is in wrong format.")
       
    61 
       
    62     user = soc.logic.models.user.logic.getForFields({'link_id': link_id},
       
    63                                           unique=True)
       
    64 
       
    65     # Get the currently logged in user account
       
    66     current_account = users.get_current_user()
       
    67 
       
    68     if user:
       
    69       if current_account != user.account:
       
    70         raise forms.ValidationError("This link ID is already in use.")
       
    71 
       
    72     return link_id
       
    73 
       
    74 
       
    75 class View(base.View):
       
    76   """View methods for the User model.
       
    77   """
       
    78 
       
    79   DEF_USER_ACCOUNT_INVALID_MSG_FMT = ugettext_lazy(
       
    80     'The <b><i>%(email)s</i></b> account cannot be used with this site, for'
       
    81     ' one or more of the following reasons:'
       
    82     '<ul>'
       
    83     ' <li>the account is invalid</li>'
       
    84     ' <li>the account is already attached to a User profile and cannot be'
       
    85     ' used to create another one</li>'
       
    86     ' <li>the account is a former account that cannot be used again</li>'
       
    87     '</ul>')
       
    88 
       
    89   def __init__(self, original_params=None):
       
    90     """Defines the fields and methods required for the base View class
       
    91     to provide the user with list, public, create, edit and delete views.
       
    92 
       
    93     Params:
       
    94       original_params: a dict with params for this View
       
    95     """
       
    96 
       
    97     self._logic = soc.logic.models.user.logic
       
    98 
       
    99     rights = {}
       
   100     rights['unspecified'] = [access.deny]
       
   101     rights['any_access'] = [access.allow]
       
   102     rights['editSelf'] = [access.checkIsLoggedIn]
       
   103     rights['roles'] = [access.checkIsUser]
       
   104     rights['signIn'] = [access.checkNotLoggedIn]
       
   105 
       
   106     params = {}
       
   107     params['rights'] = rights
       
   108 
       
   109     params['name'] = "User"
       
   110     params['name_short'] = "User"
       
   111     params['name_plural'] = "Users"
       
   112     params['url_name'] = "user"
       
   113     params['module_name'] = "user_self"
       
   114     
       
   115     params['sidebar_heading'] = 'Users'
       
   116 
       
   117     params = dicts.merge(original_params, params)
       
   118 
       
   119     base.View.__init__(self, params=params)
       
   120 
       
   121   EDIT_SELF_TMPL = 'soc/user/edit_self.html'
       
   122 
       
   123   def edit(self, request, page_name=None, params=None, **kwargs):
       
   124     """Displays User self edit page for the entity specified by **kwargs.
       
   125 
       
   126     Args:
       
   127       request: the standard Django HTTP request object
       
   128       page_name: the page name displayed in templates as page and header title
       
   129       params: a dict with params for this View
       
   130       kwargs: The Key Fields for the specified entity
       
   131     """
       
   132 
       
   133     try:
       
   134       self.checkAccess('editSelf', request)
       
   135     except out_of_band.Error, error:
       
   136       return error.response(request, template=self.EDIT_SELF_TMPL)
       
   137 
       
   138     new_params = {}
       
   139     new_params['edit_template'] = self.EDIT_SELF_TMPL
       
   140 
       
   141     params = dicts.merge(params, new_params)
       
   142     params = dicts.merge(params, self._params)
       
   143 
       
   144     account = users.get_current_user()
       
   145     properties = {'account': account}
       
   146 
       
   147     user = soc.logic.models.user.logic.getForFields(properties, unique=True)
       
   148 
       
   149     # create default template context for use with any templates
       
   150     context = helper.responses.getUniversalContext(request)
       
   151 
       
   152     if request.method == 'POST':
       
   153       form = UserForm(request.POST)
       
   154 
       
   155       if form.is_valid():
       
   156         new_link_id = form.cleaned_data.get('link_id')
       
   157         properties = {
       
   158           'link_id': new_link_id,
       
   159           'name': form.cleaned_data.get("name"),
       
   160           'account': account,
       
   161         }
       
   162 
       
   163         # check if user account is not in former_accounts
       
   164         # if it is show error message that account is invalid
       
   165         if soc.logic.models.user.logic.isFormerAccount(account):
       
   166           msg = self.DEF_USER_ACCOUNT_INVALID_MSG_FMT % {
       
   167             'email': account.email()}
       
   168           error = out_of_band.Error(msg)
       
   169           return error.response(request, template=self.EDIT_SELF_TMPL,
       
   170                                 context=context)
       
   171 
       
   172         user = soc.logic.models.user.logic.updateOrCreateFromFields(
       
   173             properties, {'link_id': new_link_id})
       
   174 
       
   175         # redirect to /user/profile?s=0
       
   176         # (causes 'Profile saved' message to be displayed)
       
   177         return helper.responses.redirectToChangedSuffix(
       
   178             request, None, params=params['edit_params'])
       
   179     else: # request.method == 'GET'
       
   180       if user:
       
   181         # is 'Profile saved' parameter present, but referrer was not ourself?
       
   182         # (e.g. someone bookmarked the GET that followed the POST submit)
       
   183         if (request.GET.get(self.DEF_SUBMIT_MSG_PARAM_NAME)
       
   184             and (not helper.requests.isReferrerSelf(request))):
       
   185           # redirect to aggressively remove 'Profile saved' query parameter
       
   186           return http.HttpResponseRedirect(request.path)
       
   187 
       
   188         # referrer was us, so select which submit message to display
       
   189         # (may display no message if ?s=0 parameter is not present)
       
   190         context['notice'] = (
       
   191             helper.requests.getSingleIndexedParamValue(
       
   192                 request, self.DEF_SUBMIT_MSG_PARAM_NAME,
       
   193                 values=params['save_message']))
       
   194 
       
   195         # populate form with the existing User entity
       
   196         form = UserForm(instance=user)
       
   197       else:
       
   198         if request.GET.get(self.DEF_SUBMIT_MSG_PARAM_NAME):
       
   199           # redirect to aggressively remove 'Profile saved' query parameter
       
   200           return http.HttpResponseRedirect(request.path)
       
   201 
       
   202         # no User entity exists for this Google Account, so show a blank form
       
   203         form = UserForm()
       
   204 
       
   205     context['form'] = form
       
   206 
       
   207     template = params['edit_template']
       
   208 
       
   209     return helper.responses.respond(request, template, context)
       
   210   
       
   211   def _editGet(self, request, entity, form):
       
   212     """See base.View._editGet().
       
   213     """
       
   214     # fill in the email field with the data from the entity
       
   215     form.fields['email'].initial = entity.account.email()
       
   216 
       
   217   def _editPost(self, request, entity, fields):
       
   218     """See base.View._editPost().
       
   219     """
       
   220     # fill in the account field with the user created from email
       
   221     fields['account'] = users.User(fields['email'])
       
   222 
       
   223   def getSidebarLinks(self, request):
       
   224     """Returns an dictionary with the user sidebar entry.
       
   225     """
       
   226 
       
   227     params = {}
       
   228     params['sidebar_heading'] = "User (self)"
       
   229     params['sidebar'] = [
       
   230         (users.create_login_url(request.path), 'Sign In', 'signIn'),
       
   231         ('/' + self._params['url_name'] + '/edit', 'Profile', 'editSelf'),
       
   232         ('/' + self._params['url_name'] + '/roles', 'Roles', 'roles'),
       
   233         ]
       
   234 
       
   235     return super(View, self).getSidebarLinks(request, params)
       
   236 
       
   237   def getDjangoURLPatterns(self):
       
   238     """See base.View.getDjangoURLPatterns().
       
   239     """
       
   240 
       
   241     patterns = []
       
   242     patterns += [(r'^' + self._params['url_name'] + '/edit$',
       
   243                    'soc.views.models.user_self.edit')]
       
   244 
       
   245     page_name = "Requests Overview"
       
   246     patterns += [(r'^' + self._params['url_name'] + '/roles$',
       
   247                    'soc.views.models.request.list_self',
       
   248                    {'page_name': page_name}, page_name)]
       
   249 
       
   250     return patterns
       
   251 
       
   252 
       
   253 view = View()
       
   254 
       
   255 edit = view.edit