Rename too short variable name in soc.logic.mail_dispatcher module.
Patch by: Pawel Solyga
Reviewed by: to-be-reviewed
#!/usr/bin/python2.5## Copyright 2009 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."""Views for Student Proposal."""__authors__ = [ '"Lennard de Rijk" <ljvderijk@gmail.com>', ]import datetimeimport timefrom django import formsfrom django import httpfrom soc.logic import cleaningfrom soc.logic import dictsfrom soc.logic.models import mentor as mentor_logicfrom soc.logic.models import organization as org_logicfrom soc.logic.models import org_admin as org_admin_logicfrom soc.logic.models import student as student_logicfrom soc.logic.models import user as user_logicfrom soc.views import helperfrom soc.views import out_of_bandfrom soc.views.helper import accessfrom soc.views.helper import decoratorsfrom soc.views.helper import dynaformfrom soc.views.helper import params as params_helperfrom soc.views.helper import redirectsfrom soc.views.helper import responsesfrom soc.views.helper import widgetsfrom soc.views.models import basefrom soc.views.models import student as student_viewimport soc.logic.models.student_proposalclass View(base.View): """View methods for the Student Proposal 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 """ rights = access.Checker(params) rights['create'] = ['checkIsDeveloper'] rights['edit'] = [('checkCanStudentPropose', 'scope_path'), ('checkRoleAndStatusForStudentProposal', [['proposer'], ['active'], ['new', 'pending']])] rights['delete'] = ['checkIsDeveloper'] rights['show'] = [ ('checkRoleAndStatusForStudentProposal', [['proposer', 'org_admin', 'mentor', 'host'], ['active', 'inactive'], ['new', 'pending', 'accepted', 'rejected']])] rights['list'] = ['checkIsDeveloper'] rights['list_orgs'] = [ ('checkIsStudent', ['scope_path', ['active']]), ('checkCanStudentPropose', 'scope_path')] rights['list_self'] = [ ('checkIsStudent', ['scope_path', ['active', 'inactive']])] rights['apply'] = [ ('checkIsStudent', ['scope_path', ['active']]), ('checkCanStudentPropose', 'scope_path')] rights['review'] = [('checkRoleAndStatusForStudentProposal', [['org_admin', 'mentor', 'host'], ['active'], ['new', 'pending']])] new_params = {} new_params['logic'] = soc.logic.models.student_proposal.logic new_params['rights'] = rights new_params['name'] = "Student Proposal" new_params['url_name'] = "student_proposal" new_params['sidebar_grouping'] = 'Student Proposal' new_params['scope_view'] = student_view new_params['scope_redirect'] = redirects.getCreateRedirect new_params['no_create_with_key_fields'] = True patterns = [ (r'^%(url_name)s/(?P<access_type>apply)/%(scope)s$', 'soc.views.models.%(module_name)s.apply', 'Create a new %(name)s'), (r'^%(url_name)s/(?P<access_type>list_self)/%(scope)s$', 'soc.views.models.%(module_name)s.list_self', 'List my %(name_plural)s'), (r'^%(url_name)s/(?P<access_type>list_orgs)/%(scope)s$', 'soc.views.models.%(module_name)s.list_orgs', 'List my %(name_plural)s'), (r'^%(url_name)s/(?P<access_type>review)/%(key_fields)s$', 'soc.views.models.%(module_name)s.review', 'Review %(name)s'), ] new_params['extra_django_patterns'] = patterns new_params['extra_dynaexclude'] = ['org', 'program', 'score', 'status', 'mentor', 'link_id', 'possible_mentors'] new_params['create_extra_dynaproperties'] = { 'content': forms.fields.CharField(required=True, widget=widgets.FullTinyMCE(attrs={'rows': 25, 'cols': 100})), 'scope_path': forms.CharField(widget=forms.HiddenInput, required=True), 'organization': forms.CharField(label='Organization Link ID', required=True), 'clean_organization': cleaning.clean_link_id('organization'), 'clean_additional_info': cleaning.clean_url('additional_info'), 'clean': cleaning.validate_student_proposal('organization', 'scope_path', student_logic, org_logic), } new_params['edit_extra_dynaproperties'] = { 'organization': forms.CharField(label='Organization Link ID', widget=widgets.ReadOnlyInput), 'link_id': forms.CharField(widget=forms.HiddenInput) } new_params['edit_template'] = 'soc/student_proposal/edit.html' new_params['review_template'] = 'soc/student_proposal/review.html' params = dicts.merge(params, new_params) super(View, self).__init__(params=params) # create the special form for students dynafields = [ {'name': 'organization', 'base': forms.CharField, 'label': 'Organization Link ID', 'widget': widgets.ReadOnlyInput(), 'required': False, }, ] dynaproperties = params_helper.getDynaFields(dynafields) student_create_form = dynaform.extendDynaForm( dynaform=self._params['create_form'], dynaproperties=dynaproperties) params['student_create_form'] = student_create_form # create the special form for mentors dynafields = [ {'name': 'score', 'base': forms.ChoiceField, 'label': 'Score', 'initial': 0, 'required': False, 'passthrough': ['initial', 'required', 'choices'], 'choices': [(-4,'-4: Wow. This. Sucks.'), (-3,'-3: Needs a lot of work'), (-2,'-2: This is bad'), (-1,'-1: I dont like this'), (0,'0: No score'), (1,'1: Might have potential'), (2,'2: Good'), (3,'3: Almost there'), (4,'4: Made. Of. Awesome.')] }, {'name': 'comment', 'base': forms.CharField, 'widget': forms.Textarea, 'label': 'Comment', 'required': False, }, {'name': 'public', 'base': forms.BooleanField, 'label': 'Public comment', 'initial': False, 'required': False, }, ] dynaproperties = params_helper.getDynaFields(dynafields) mentor_review_form = dynaform.newDynaForm(dynamodel=None, dynabase=helper.forms.BaseForm, dynainclude=None, dynaexclude=None, dynaproperties=dynaproperties) params['mentor_review_form'] = mentor_review_form # TODO see if autocomplete can be used for this field dynafields = [ {'name': 'mentor', 'base': forms.CharField, 'label': 'Assign Mentor (Link ID)', 'required': False }, ] dynaproperties = params_helper.getDynaFields(dynafields) admin_review_form = dynaform.extendDynaForm(dynaform=mentor_review_form, dynaproperties=dynaproperties) params['admin_review_form'] = admin_review_form def _editGet(self, request, entity, form): """See base.View._editGet(). """ form.fields['link_id'].initial = entity.link_id form.fields['organization'].initial = entity.org.link_id return super(View, self)._editGet(request, entity, form) def _editPost(self, request, entity, fields): """See base.View._editPost(). """ if not entity: fields['link_id'] = 't%i' % (time.time()) else: fields['link_id'] = entity.link_id # fill in the scope via call to super super(View, self)._editPost(request, entity, fields) if not entity: # creating a new application so set the program and org field fields['program'] = fields['scope'].scope filter = {'scope': fields['program'], 'link_id': fields['organization']} fields['org'] = org_logic.logic.getForFields(filter, unique=True) # explicitly change the last_modified_on since the content has been edited fields['last_modified_on'] = datetime.datetime.now() def _public(self, request, entity, context): """See base.View._public(). """ context['student_name'] = entity.scope.name() if entity.mentor: context['mentor_name'] = entity.mentor.name() else: context['mentor_name'] = "No mentor assigned" @decorators.merge_params @decorators.check_access def apply(self, request, access_type, page_name=None, params=None, **kwargs): """Special view used to prepopulate the form with the organization contributors template. For params see base.View.public() """ get_dict = request.GET if get_dict.get('organization'): # organization chosen, prepopulate with template # get the organization student_entity = student_logic.logic.getFromKeyName(kwargs['scope_path']) program_entity = student_entity.scope filter = {'link_id': get_dict['organization'], 'scope': program_entity} org_entity = org_logic.logic.getForFields(filter, unique=True) if org_entity: # organization found use special form params['create_form'] = params['student_create_form'] kwargs['content'] = org_entity.contrib_template # Create page is an edit page with no key fields empty_kwargs = {} fields = self._logic.getKeyFieldNames() for field in fields: empty_kwargs[field] = None return super(View, self).edit(request, access_type, page_name=page_name, params=params, seed=kwargs, **empty_kwargs) @decorators.merge_params @decorators.check_access def edit(self, request, access_type, page_name=None, params=None, seed=None, **kwargs): """If the POST contains (action, Withdraw) the proposal in kwargs will be marked as invalid. For params see base.View.edit() """ # check if request.POST contains action post_dict = request.POST if 'action' in post_dict and post_dict['action'] == 'Withdraw': # withdraw this proposal filter = {'scope_path': kwargs['scope_path'], 'link_id': kwargs['link_id']} proposal_logic = params['logic'] student_proposal_entity = proposal_logic.getForFields(filter, unique=True) # update the entity mark it as invalid proposal_logic.updateEntityProperties(student_proposal_entity, {'status': 'invalid'}) # redirect to the program's homepage redirect_url = redirects.getHomeRedirect(student_proposal_entity.program, {'url_name': 'program'}) return http.HttpResponseRedirect(redirect_url) return super(View, self).edit(request=request, access_type=access_type, page_name=page_name, params=params, seed=seed, **kwargs) @decorators.merge_params @decorators.check_access def listOrgs(self, request, access_type, page_name=None, params=None, **kwargs): """Lists all organization which the given student can propose to. For params see base.View.public(). """ from soc.views.models import organization as org_view student_entity = student_logic.logic.getFromKeyName(kwargs['scope_path']) filter = {'scope' : student_entity.scope, 'status': 'active'} list_params = org_view.view.getParams().copy() list_params['list_description'] = ('List of %(name_plural)s you can send ' 'your proposal to.') % list_params list_params['list_action'] = (redirects.getStudentProposalRedirect, {'student_key': student_entity.key().name(), 'url_name': params['url_name']}) return self.list(request, access_type=access_type, page_name=page_name, params=list_params, filter=filter, **kwargs) @decorators.merge_params @decorators.check_access def listSelf(self, request, access_type, page_name=None, params=None, **kwargs): """Lists all proposals from the current logged-in user for the given student. For params see base.View.public(). """ student_entity = student_logic.logic.getFromKeyName(kwargs['scope_path']) filter = {'scope' : student_entity, 'status': ['new', 'pending', 'accepted', 'rejected']} list_params = params.copy() list_params['list_description'] = 'List of my %(name_plural)s' % list_params return self.list(request, access_type=access_type, page_name=page_name, params=list_params, filter=filter, **kwargs) @decorators.merge_params @decorators.check_access def review(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Organization Admins and Mentors to review the proposal. For Args see base.View.public(). """ try: entity = self._logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return helper.responses.errorResponse( error, request, template=params['error_public']) # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name context['student_name'] = entity.scope.name() if entity.mentor: context['mentor_name'] = entity.mentor.name() else: context['mentor_name'] = "No mentor assigned" context['entity'] = entity context['entity_type'] = params['name'] context['entity_type_url'] = params['url_name'] # get the roles important for reviewing an application filter = {'user': user_logic.logic.getForCurrentAccount(), 'scope': entity.org, 'status': 'active'} org_admin_entity = org_admin_logic.logic.getForFields(filter, unique=True) mentor_entity = mentor_logic.logic.getForFields(filter, unique=True) # check if the current user is a mentor and wants # to change his role for this app choice = request.GET.get('mentor') if mentor_entity and choice: self._adjustPossibleMentors(entity, mentor_entity, choice) # set the possible mentors in the context possible_mentors = entity.possible_mentors if not possible_mentors: context['possible_mentors'] = "None" else: mentor_names = [] for mentor_key in possible_mentors: mentor = mentor_logic.logic.getFromKeyName(mentor_key.name()) mentor_names.append(mentor.name()) context['possible_mentors'] = ', '.join(mentor_names) # decide which form to use if org_admin_entity: form = params['admin_review_form'] else: form = params['mentor_review_form'] if request.method == 'POST': return self.reviewPost(request, context, params, entity, form, org_admin_entity, mentor_entity, **kwargs) else: # request.method == 'GET' return self.reviewGet(request, context, params, entity, form, org_admin_entity, mentor_entity, **kwargs) def reviewPost(self, request, context, params, entity, form, org_admin, mentor, **kwargs): """Handles the POST request for the proposal review view. Args: entity: the student proposal entity form: the form to use in this view org_admin: org admin entity for the current user/proposal (iff available) mentor: mentor entity for the current user/proposal (iff available) rest: see base.View.public() """ # populate the form using the POST data form = form(request.POST) if not form.is_valid(): # return the invalid form response return self._constructResponse(request, entity=entity, context=context, form=form, params=params, template=params['review_template']) fields = form.cleaned_data if org_admin: # org admin found, try to adjust the assigned mentor self._adjustMentor(entity, fields['mentor']) is_public = fields['public'] comment = fields['comment'] given_score = int(fields['score']) if (org_admin or mentor) and (not is_public) and (given_score is not 0): # if it is not a public comment and it's made by a member of the # organization we score and display an additional message in the comment new_score = given_score + entity.score if org_admin: name = org_admin.name() elif mentor: name = mentor.name() # TODO(ljvderijk) hook up comments comment = '%s has given %i points \n %s' % (name, given_score, comment) properties = {'score': new_score} # if the proposal is new we change it status to pending if entity.status == 'new': properties['status'] = 'pending' # update the proposal with the new score self._logic.updateEntityProperties(entity, properties) # redirect to the same page return http.HttpResponseRedirect('') def reviewGet(self, request, context, params, entity, form, org_admin, mentor, **kwargs): """Handles the GET request for the proposal review view. Args: entity: the student proposal entity form: the form to use in this view org_admin: org admin entity for the current user/proposal (iff available) mentor: mentor entity for the current user/proposal (iff available) rest: see base.View.public() """ # set the initial score since the default is ignored initial = {'score': 0} if org_admin and entity.mentor: # set the mentor field to the current mentor initial['mentor'] = entity.mentor.link_id context['form'] = form(initial) template = params['review_template'] context['mentor'] = mentor return responses.respond(request, template, context=context) def _adjustPossibleMentors(self, entity, mentor, choice): """Adjusts the possible mentors list for a proposal. Args: entity: Student Proposal entity mentor: Mentor entity choice: 1 means want to mentor, 0 do not want to mentor """ possible_mentors = entity.possible_mentors if choice == '1': # add the mentor to possible mentors list if not already in if mentor.key() not in possible_mentors: possible_mentors.append(mentor.key()) fields = {'possible_mentors': possible_mentors} self._logic.updateEntityProperties(entity, fields) elif choice == '0': # remove the mentor from the possible mentors list if mentor.key() in possible_mentors: possible_mentors.remove(mentor.key()) fields = {'possible_mentors': possible_mentors} self._logic.updateEntityProperties(entity, fields) def _adjustMentor(self, entity, mentor_id): """Changes the mentor to the given link_id. Args: entity: Student Proposal entity mentor_id: Link ID of the mentor that needs to be assigned Iff not given then removes the assigned mentor """ if entity.mentor and entity.mentor.link_id == mentor_id: # no need to change return if mentor_id: # try to locate the mentor fields = {'link_id': mentor_id, 'scope': entity.org, 'status': 'active'} mentor_entity = mentor_logic.logic.getForFields(fields, unique=True) if not mentor_entity: # no mentor found, do not update return else: # reset to None mentor_entity = None # update the proposal properties = {'mentor': mentor_entity} self._logic.updateEntityProperties(entity, properties)view = View()admin = decorators.view(view.admin)apply = decorators.view(view.apply)create = decorators.view(view.create)delete = decorators.view(view.delete)edit = decorators.view(view.edit)list = decorators.view(view.list)list_orgs = decorators.view(view.listOrgs)list_self = decorators.view(view.listSelf)public = decorators.view(view.public)review = decorators.view(view.review)export = decorators.view(view.export)pick = decorators.view(view.pick)