app/soc/views/models/notification.py
changeset 726 ba3d399ec9be
child 727 ddf44af087a0
equal deleted inserted replaced
725:6180b32d990f 726:ba3d399ec9be
       
     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 """This module contains the view code for Notifications
       
    18 """
       
    19 
       
    20 __authors__ = [
       
    21   '"Lennard de Rijk" <ljvderijk@gmail.com>',
       
    22 ]
       
    23 
       
    24 
       
    25 import time
       
    26 
       
    27 from google.appengine.api import users
       
    28 
       
    29 from django import forms
       
    30 from django import http
       
    31 from django.utils.translation import ugettext_lazy
       
    32 
       
    33 from soc.logic import dicts
       
    34 from soc.logic import validate
       
    35 from soc.models import notification as notification_model
       
    36 from soc.views import helper
       
    37 from soc.views import out_of_band
       
    38 from soc.views.helper import access
       
    39 from soc.views.helper import redirects
       
    40 from soc.views.models import base
       
    41 from soc.logic.models import notification as notification_logic
       
    42 from soc.logic.models import user as user_logic
       
    43 
       
    44 
       
    45 class CreateForm(helper.forms.BaseForm):
       
    46   """Form for creating a Notification.
       
    47   """
       
    48   
       
    49   # to user field
       
    50   to_user = forms.fields.CharField(label='To User')
       
    51   
       
    52   def __init__(self, *args, **kwargs):
       
    53     """ Calls super and then redefines the order in which the fields appear.
       
    54     
       
    55     for parameters see BaseForm.__init__()
       
    56     """    
       
    57     super(CreateForm, self).__init__(*args, **kwargs)
       
    58       
       
    59     # set form fields order
       
    60     self.fields.keyOrder = ['to_user', 'subject', 'message']
       
    61 
       
    62   class Meta:
       
    63     model = notification_model.Notification
       
    64     
       
    65     # exclude the necessary fields from the form
       
    66     exclude = ['link_id', 'scope', 'scope_path', 'from_user', 'has_been_read']
       
    67     
       
    68   def clean_to_user(self):
       
    69     """Check if the to_user field has been filled in correctly.
       
    70     """
       
    71     link_id = self.cleaned_data.get('to_user').lower()
       
    72     
       
    73     if not validate.isLinkIdFormatValid(link_id):
       
    74       raise forms.ValidationError("This link ID is in wrong format.")
       
    75     
       
    76     to_user = user_logic.logic.getForFields({'link_id' : link_id}, unique=True)
       
    77     
       
    78     if not to_user:
       
    79       # user does not exist
       
    80       raise forms.ValidationError("This user does not exist")      
       
    81   
       
    82     return link_id
       
    83 
       
    84 
       
    85 class View(base.View):
       
    86   """View methods for the Notification model.
       
    87   """
       
    88   
       
    89   def __init__(self, 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       params: a dict with params for this View
       
    95     """
       
    96     
       
    97     new_params = {}    
       
    98     new_params['logic'] = notification_logic.logic
       
    99 
       
   100     new_params['name'] = "Notification"
       
   101     new_params['name_short'] = "Notification"
       
   102     new_params['name_plural'] = "Notifications"
       
   103     new_params['url_name'] = "notification"
       
   104     new_params['module_name'] = "notification"
       
   105     
       
   106     new_params['create_form'] = CreateForm
       
   107 
       
   108     # define the django url patterns    
       
   109     new_params['django_patterns_defaults'] = [
       
   110       (r'^%(url_name)s/(?P<access_type>show)/%(key_fields)s$',
       
   111           'soc.views.models.%(module_name)s.public', 'Show %(name_short)s'),
       
   112       (r'^%(url_name)s/(?P<access_type>create)$',
       
   113           'soc.views.models.%(module_name)s.create', 'Create %(name_short)s'),
       
   114       (r'^%(url_name)s/(?P<access_type>create)/%(scope)s$',
       
   115           'soc.views.models.%(module_name)s.create', 'Create %(name_short)s'),
       
   116       (r'^%(url_name)s/(?P<access_type>delete)/%(key_fields)s$',
       
   117           'soc.views.models.%(module_name)s.delete', 'Delete %(name_short)s'),
       
   118       (r'^%(url_name)s/(?P<access_type>list)$',
       
   119           'soc.views.models.%(module_name)s.list', 'List %(name_plural)s'),
       
   120       ]
       
   121     
       
   122     rights = {}
       
   123     rights['unspecified'] = [access.deny]
       
   124     rights['any_access'] = [access.allow]
       
   125     rights['show'] = [access.checkIsMyNotification]
       
   126     rights['delete'] = [access.checkIsDeveloper]
       
   127     rights['list'] = [access.checkIsUser]
       
   128     # create is developer only for the time being to test functionality
       
   129     rights['create'] = [access.checkIsDeveloper]
       
   130     
       
   131     new_params['rights'] = rights
       
   132     
       
   133     params = dicts.merge(params, new_params)
       
   134 
       
   135     super(View, self).__init__(params=params)
       
   136     
       
   137   def create(self, request, access_type,
       
   138              page_name=None, params=None, **kwargs):
       
   139     """On a successful post create redirects the user to the notification list.
       
   140     
       
   141     for parameters see base.create()
       
   142     """
       
   143     
       
   144     if request.method == 'POST':
       
   145       response = super(View, self).create(request, access_type,
       
   146         page_name, params, **kwargs)
       
   147       
       
   148       if (response.__class__ == http.HttpResponseRedirect and
       
   149           response['location'].startswith(
       
   150               '/%s/edit/' %(self._params['url_name']))):             
       
   151         # redirect to list instead of edit view
       
   152         return http.HttpResponseRedirect('/%s/list' %(self._params['url_name']))
       
   153       else:
       
   154         return response
       
   155       
       
   156     else: 
       
   157       # request.method == 'GET' so act normal 
       
   158       return super(View, self).create(request, access_type,
       
   159           page_name, params, **kwargs)
       
   160        
       
   161   def list(self, request, access_type,
       
   162            page_name=None, params=None, seed=None, **kwargs):
       
   163     """Lists all notifications that the current logged in user has stored.
       
   164     
       
   165     for parameters see base.list()
       
   166     """
       
   167     
       
   168     params = dicts.merge(params, self._params)
       
   169       
       
   170     # get the current user
       
   171     properties = {'account': users.get_current_user()}
       
   172     user_entity = user_logic.logic.getForFields(properties, unique=True)
       
   173 
       
   174     # only select the notifications for this user so construct a filter
       
   175     filter = {'scope': user_entity}
       
   176     
       
   177     # create the list parameters
       
   178     list_params = params.copy()
       
   179     
       
   180     # define the list redirect action to show the notification
       
   181     list_params['list_action'] = (redirects.getPublicRedirect, params)
       
   182     list_params['list_description'] = ugettext_lazy(
       
   183         "An overview of your received Notifications.")
       
   184     
       
   185     # TODO(Lennard) when list sorting is implemented sort on descending date
       
   186     
       
   187     # use the generic list method with the filter. The access check in this
       
   188     # method will trigger an errorResponse when user_entity is None
       
   189     return super(View, self).list(request, access_type, 
       
   190         page_name, list_params, filter)
       
   191       
       
   192   def _editPost(self, request, entity, fields):
       
   193     """See base.View._editPost().
       
   194     """
       
   195 
       
   196     account = users.get_current_user()
       
   197     current_user = user_logic.logic.getForFields({'account': account}, unique=True)
       
   198     
       
   199     to_user = user_logic.logic.getForFields(
       
   200         {'link_id' : fields['to_user']}, unique=True)
       
   201 
       
   202     fields['link_id'] = '%i' %(time.time())
       
   203     fields['scope'] = to_user
       
   204     fields['from_user'] = current_user
       
   205     fields['scope_path'] = fields['to_user']
       
   206     
       
   207   def _editSeed(self, request, seed):
       
   208     """Checks if scope_path is seeded and puts it into to_user.
       
   209     
       
   210     for parameters see base._editSeed()
       
   211     """
       
   212     
       
   213     # if scope_path is present    
       
   214     if 'scope_path' in seed.keys():
       
   215       # fill the to_user field with the scope path
       
   216       seed['to_user'] = seed['scope_path']
       
   217 
       
   218   def _public(self, request, entity, context):
       
   219     """Marks the Notification as read if that hasn't happened yet.
       
   220     
       
   221     for parameters see base._public()
       
   222     """
       
   223     
       
   224     # if the user viewing is the user for which this notification is meant
       
   225     # and the notification has not been read yet
       
   226     if not entity.has_been_read:
       
   227       # get the current user
       
   228       account = users.get_current_user()
       
   229       user = user_logic.logic.getForFields({'account': account}, unique=True)
       
   230       
       
   231       if entity.scope.key() == user.key():
       
   232       # mark the entity as read
       
   233         self._logic.updateModelProperties(entity, {'has_been_read' : True} )
       
   234     
       
   235     context['entity_type_url'] = self._params['url_name']
       
   236     context['entity_suffix'] = self._logic.getKeySuffix(entity)
       
   237 
       
   238 
       
   239 view = View()
       
   240 create = view.create
       
   241 edit = view.edit
       
   242 delete = view.delete
       
   243 list = view.list
       
   244 public = view.public