Added Notifications.
Notifications will primarily be used to serve the user information message like "New Request Pending". The system can be expanded later on to a messaging system.
If you are a developer you can create message by going to notification/create . This has been done so the system can easily be tested. But will of course be visible in an easy-to-access location when the transition to a message system has been made.
Patch by: Lennard de Rijk
#!/usr/bin/python2.5
#
# Copyright 2008 the Melange authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""This module contains the view code for Notifications
"""
__authors__ = [
'"Lennard de Rijk" <ljvderijk@gmail.com>',
]
import time
from google.appengine.api import users
from django import forms
from django import http
from django.utils.translation import ugettext_lazy
from soc.logic import dicts
from soc.logic import validate
from soc.models import notification as notification_model
from soc.views import helper
from soc.views import out_of_band
from soc.views.helper import access
from soc.views.helper import redirects
from soc.views.models import base
from soc.logic.models import notification as notification_logic
from soc.logic.models import user as user_logic
class CreateForm(helper.forms.BaseForm):
"""Form for creating a Notification.
"""
# to user field
to_user = forms.fields.CharField(label='To User')
def __init__(self, *args, **kwargs):
""" Calls super and then redefines the order in which the fields appear.
for parameters see BaseForm.__init__()
"""
super(CreateForm, self).__init__(*args, **kwargs)
# set form fields order
self.fields.keyOrder = ['to_user', 'subject', 'message']
class Meta:
model = notification_model.Notification
# exclude the necessary fields from the form
exclude = ['link_id', 'scope', 'scope_path', 'from_user', 'has_been_read']
def clean_to_user(self):
"""Check if the to_user field has been filled in correctly.
"""
link_id = self.cleaned_data.get('to_user').lower()
if not validate.isLinkIdFormatValid(link_id):
raise forms.ValidationError("This link ID is in wrong format.")
to_user = user_logic.logic.getForFields({'link_id' : link_id}, unique=True)
if not to_user:
# user does not exist
raise forms.ValidationError("This user does not exist")
return link_id
class View(base.View):
"""View methods for the Notification model.
"""
def __init__(self, params=None):
"""Defines the fields and methods required for the base View class
to provide the user with list, public, create, edit and delete views.
Params:
params: a dict with params for this View
"""
new_params = {}
new_params['logic'] = notification_logic.logic
new_params['name'] = "Notification"
new_params['name_short'] = "Notification"
new_params['name_plural'] = "Notifications"
new_params['url_name'] = "notification"
new_params['module_name'] = "notification"
new_params['create_form'] = CreateForm
# define the django url patterns
new_params['django_patterns_defaults'] = [
(r'^%(url_name)s/(?P<access_type>show)/%(key_fields)s$',
'soc.views.models.%(module_name)s.public', 'Show %(name_short)s'),
(r'^%(url_name)s/(?P<access_type>create)$',
'soc.views.models.%(module_name)s.create', 'Create %(name_short)s'),
(r'^%(url_name)s/(?P<access_type>create)/%(scope)s$',
'soc.views.models.%(module_name)s.create', 'Create %(name_short)s'),
(r'^%(url_name)s/(?P<access_type>delete)/%(key_fields)s$',
'soc.views.models.%(module_name)s.delete', 'Delete %(name_short)s'),
(r'^%(url_name)s/(?P<access_type>list)$',
'soc.views.models.%(module_name)s.list', 'List %(name_plural)s'),
]
rights = {}
rights['unspecified'] = [access.deny]
rights['any_access'] = [access.allow]
rights['show'] = [access.checkIsMyNotification]
rights['delete'] = [access.checkIsDeveloper]
rights['list'] = [access.checkIsUser]
# create is developer only for the time being to test functionality
rights['create'] = [access.checkIsDeveloper]
new_params['rights'] = rights
params = dicts.merge(params, new_params)
super(View, self).__init__(params=params)
def create(self, request, access_type,
page_name=None, params=None, **kwargs):
"""On a successful post create redirects the user to the notification list.
for parameters see base.create()
"""
if request.method == 'POST':
response = super(View, self).create(request, access_type,
page_name, params, **kwargs)
if (response.__class__ == http.HttpResponseRedirect and
response['location'].startswith(
'/%s/edit/' %(self._params['url_name']))):
# redirect to list instead of edit view
return http.HttpResponseRedirect('/%s/list' %(self._params['url_name']))
else:
return response
else:
# request.method == 'GET' so act normal
return super(View, self).create(request, access_type,
page_name, params, **kwargs)
def list(self, request, access_type,
page_name=None, params=None, seed=None, **kwargs):
"""Lists all notifications that the current logged in user has stored.
for parameters see base.list()
"""
params = dicts.merge(params, self._params)
# get the current user
properties = {'account': users.get_current_user()}
user_entity = user_logic.logic.getForFields(properties, unique=True)
# only select the notifications for this user so construct a filter
filter = {'scope': user_entity}
# create the list parameters
list_params = params.copy()
# define the list redirect action to show the notification
list_params['list_action'] = (redirects.getPublicRedirect, params)
list_params['list_description'] = ugettext_lazy(
"An overview of your received Notifications.")
# TODO(Lennard) when list sorting is implemented sort on descending date
# use the generic list method with the filter. The access check in this
# method will trigger an errorResponse when user_entity is None
return super(View, self).list(request, access_type,
page_name, list_params, filter)
def _editPost(self, request, entity, fields):
"""See base.View._editPost().
"""
account = users.get_current_user()
current_user = user_logic.logic.getForFields({'account': account}, unique=True)
to_user = user_logic.logic.getForFields(
{'link_id' : fields['to_user']}, unique=True)
fields['link_id'] = '%i' %(time.time())
fields['scope'] = to_user
fields['from_user'] = current_user
fields['scope_path'] = fields['to_user']
def _editSeed(self, request, seed):
"""Checks if scope_path is seeded and puts it into to_user.
for parameters see base._editSeed()
"""
# if scope_path is present
if 'scope_path' in seed.keys():
# fill the to_user field with the scope path
seed['to_user'] = seed['scope_path']
def _public(self, request, entity, context):
"""Marks the Notification as read if that hasn't happened yet.
for parameters see base._public()
"""
# if the user viewing is the user for which this notification is meant
# and the notification has not been read yet
if not entity.has_been_read:
# get the current user
account = users.get_current_user()
user = user_logic.logic.getForFields({'account': account}, unique=True)
if entity.scope.key() == user.key():
# mark the entity as read
self._logic.updateModelProperties(entity, {'has_been_read' : True} )
context['entity_type_url'] = self._params['url_name']
context['entity_suffix'] = self._logic.getKeySuffix(entity)
view = View()
create = view.create
edit = view.edit
delete = view.delete
list = view.list
public = view.public