def startTasks(request): """Presents a view that allows the user to start update tasks. """ template = 'soc/tasks/start_update.html' context = responses.getUniversalContext(request) options = task_runner.getOptions() sorted_keys = [] for key, option in options.iteritems(): option['name'] = key sorted_keys.append( (option['from_version'], option['in_version_order'], key)) # sort the keys sorted_keys.sort() # store only the true option sorted_options = [] for key_tuple in sorted_keys: option_key = key_tuple[2] sorted_options.append(options[option_key]) context.update( page_name='Update Tasks starter', options=sorted_options, ) content = loader.render_to_string(template, dictionary=context) return http.HttpResponse(content)
def acceptInvite(self, request, access_type, page_name=None, params=None, **kwargs): """Creates the page process an invite into a Role. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: contains the ID for the Request entity """ request_entity = request_logic.getFromIDOr404(int(kwargs['id'])) # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name if request.method == 'POST': return self.acceptInvitePost(request, context, params, request_entity, **kwargs) else: # request.method == 'GET' return self.acceptInviteGet(request, context, params, request_entity, **kwargs)
def applicant(self, request, access_type, page_name=None, params=None, **kwargs): """Handles the creation of an Organization via an approved application. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name get_dict = request.GET record_id = get_dict.get('id', None) org_app_logic = params['org_app_logic'] record_logic = org_app_logic.getRecordLogic() if not record_id or not record_id.isdigit(): raise out_of_band.Error('No valid OrgAppRecord ID specified.') else: record_entity = record_logic.getFromIDOr404(int(record_id)) if request.method == 'POST': return self.applicantPost(request, context, params, record_entity, **kwargs) else: # request.method == 'GET' return self.applicantGet(request, context, params, record_entity, **kwargs)
def invite(self, request, access_type, page_name=None, params=None, **kwargs): """Creates the page on which an invite can be send out. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked context: dictionary containing the context for this view params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name group_entity = params['group_logic'].getFromKeyName( kwargs['scope_path']) context['instruction_message'] = (self.DEF_INVITE_INSTRUCTION_MSG_FMT % (params['name'], group_entity.name)) if request.method == 'POST': return self.invitePost(request, context, params, group_entity, **kwargs) else: # request.method == 'GET' return self.inviteGet(request, context, params, **kwargs)
def process_exception(self, request, exception): """Called when an uncaught exception is raised. See the Django middleware documentation for an explanation of the method signature. """ template = None context = responses.getUniversalContext(request) if isinstance(exception, DeadlineExceededError): template = 'soc/deadline_exceeded.html' if isinstance(exception, MemoryError): template = 'soc/memory_error.html' if isinstance(exception, AssertionError): template = 'soc/assertion_error.html' if isinstance(exception, out_of_band.Error): return responses.errorResponse(exception, request) if template: logging.exception(exception) return responses.respond(request, template, context=context) # let Django handle it return None
def wrapper(self, request, access_type, *args, **kwargs): """Decorator wrapper method. """ params = kwargs.get('params', {}) # Try to extract rights if 'rights' in params: rights = params['rights'] else: rights = self._params['rights'] check_kwargs = kwargs.copy() context = responses.getUniversalContext(request) responses.useJavaScript(context, self._params['js_uses_all']) id = context['account'] user = context['user'] check_kwargs['GET'] = request.GET check_kwargs['POST'] = request.POST check_kwargs['context'] = context # reset and pre-fill the Checker's cache rights.setCurrentUser(id, user) # Do the access check dance try: rights.checkAccess(access_type, check_kwargs) except out_of_band.Error, error: return helper.responses.errorResponse(error, request)
def processRequest(self, request, access_type, page_name=None, params=None, **kwargs): """Creates the page upon which a request can be processed. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the request entity using the information from kwargs request_entity = request_logic.getFromIDOr404(int(kwargs['id'])) # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = '%s from %s to become a %s' % ( page_name, request_entity.user.name, params['name']) # TODO(ljvderijk): Should be a POST request get_dict = request.GET if 'status' in get_dict.keys(): if get_dict['status'] in [ 'group_accepted', 'rejected', 'withdrawn', 'ignored' ]: # update the request_entity and redirect away from this page request_status = get_dict['status'] # only update when the status is changing if request_status != request_entity.status: request_logic.updateEntityProperties( request_entity, {'status': get_dict['status']}) group_view = params.get('group_view') if not group_view: return http.HttpResponseRedirect('/') else: # redirect to the requests list return http.HttpResponseRedirect( redirects.getListRequestsRedirect( request_entity.group, group_view.getParams())) # put the entity in the context context['entity'] = request_entity context['request_status'] = request_entity.status context['role_verbose'] = params['name'] context['url_name'] = params['url_name'] #display the request processing page using the appropriate template template = request_view.view.getParams()['request_processing_template'] return responses.respond(request, template, context=context)
def request(self, request, access_type, page_name=None, params=None, **kwargs): """Handles the request concerning the view that creates a request for attaining a certain Role. Args: request: the standard Django HTTP request object page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name group_entity = params['group_logic'].getFromKeyName( kwargs['scope_path']) context['instruction_message'] = ( self.DEF_REQUEST_INSTRUCTION_MSG_FMT % (params['name'], group_entity.name)) if request.method == 'POST': return self.requestPost(request, context, params, group_entity, **kwargs) else: # request.method == 'GET' return self.requestGet(request, context, params, **kwargs)
def visualize(self, request, access_type, page_name=None, params=None, **kwargs): """Visualization view for a statistic specified in request params. """ link_id = kwargs['link_id'] scope_path = kwargs['scope_path'] logic = params['logic'] statistic = self._getStatisticEntity(link_id, scope_path, logic) context = responses.getUniversalContext(request) if not logic.checkIfStatisticReady(statistic): template = 'soc/error.html' context['message'] = self.DEF_NO_VISUALIZATION_MSG_FMT % ( statistic.name) else: responses.useJavaScript(context, params['js_uses_all']) context['entity'] = statistic context['page_name'] = "Statistic visualization" context['link_id'] = statistic.link_id context['scope_path'] = statistic.scope_path context['visualization_types'] = logic.getVisualizationTypesJson( statistic) template = 'soc/statistic/show.html' return responses.respond(request, template, context)
def invite(self, request, access_type, page_name=None, params=None, **kwargs): """Creates the page on which an invite can be send out. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked context: dictionary containing the context for this view params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name group_entity = params['group_logic'].getFromKeyName(kwargs['scope_path']) context['instruction_message'] = (self.DEF_INVITE_INSTRUCTION_MSG_FMT % (params['name'], group_entity.name)) if request.method == 'POST': return self.invitePost(request, context, params, group_entity, **kwargs) else: # request.method == 'GET' return self.inviteGet(request, context, params, **kwargs)
def maintenance(self, request): """Returns a 'down for maintenance' view. """ context = responses.getUniversalContext(request) context['page_name'] = ugettext('Maintenance') notice = context.pop('site_notice') if not notice: context['body_content'] = DEF_IN_UNEXPECTED_MAINTENANCE_MSG else: context['body_content'] = notice context['header_title'] = DEF_DOWN_FOR_MAINTENANCE_MSG context['sidebar_menu_items'] = [ { 'heading': DEF_DOWN_FOR_MAINTENANCE_MSG, 'group': '' }, ] template = 'soc/base.html' return responses.respond(request, template, context=context)
def visualize(self, request, access_type, page_name=None, params=None, **kwargs): """Visualization view for a statistic specified in request params. """ link_id = kwargs['link_id'] scope_path = kwargs['scope_path'] logic = params['logic'] statistic = self._getStatisticEntity(link_id, scope_path, logic) context = responses.getUniversalContext(request) if not logic.checkIfStatisticReady(statistic): template = 'soc/error.html' context['message'] = self.DEF_NO_VISUALIZATION_MSG_FMT % (statistic.name) else: responses.useJavaScript(context, params['js_uses_all']) context['entity'] = statistic context['page_name'] = "Statistic visualization" context['link_id'] = statistic.link_id context['scope_path'] = statistic.scope_path context['visualization_types'] = logic.getVisualizationTypesJson(statistic) template = 'soc/statistic/show.html' return responses.respond(request, template, context)
def request(self, request, access_type, page_name=None, params=None, **kwargs): """Handles the request concerning the view that creates a request for attaining a certain Role. Args: request: the standard Django HTTP request object page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name group_entity = params['group_logic'].getFromKeyName(kwargs['scope_path']) context['instruction_message'] = (self.DEF_REQUEST_INSTRUCTION_MSG_FMT % (params['name'], group_entity.name)) if request.method == 'POST': return self.requestPost(request, context, params, group_entity, **kwargs) else: # request.method == 'GET' return self.requestGet(request, context, params, **kwargs)
def viewResults(self, request, access_type, page_name=None, params=None, **kwargs): """View for SurveyRecord and SurveyRecordGroup. """ results_logic = params['logic'].getRecordLogic() user = user_logic.getForCurrentAccount() # TODO(ajaksu): use the named parameter link_id from the re if request.path == '/survey/show/user/' + user.link_id: records = tuple(user.surveys_taken.run()) context = responses.getUniversalContext(request) context['content'] = records[0].survey.survey_content responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = u'Your survey records.' else: entity, context = self.getContextEntity(request, page_name, params, kwargs) if context is None: # user cannot see this page, return error response return entity context['content'] = entity.survey_content can_write = False rights = self._params['rights'] try: rights.checkIsSurveyWritable({'key_name': entity.key().name(), 'prefix': entity.prefix, 'scope_path': entity.scope_path, 'link_id': entity.link_id,}, 'key_name') can_write = True except out_of_band.AccessViolation: pass filter = self._params.get('filter') or {} # if user can edit the survey, show everyone's results if can_write: filter['survey'] = entity else: filter.update({'user': user, 'survey': entity}) limit = self._params.get('limit') or 1000 offset = self._params.get('offset') or 0 order = self._params.get('order') or [] idx = self._params.get('idx') or 0 records = results_logic.getForFields(filter=filter, limit=limit, offset=offset, order=order) updates = dicts.rename(params, params['list_params']) context.update(updates) context['results'] = records, records template = 'soc/survey/results_page.html' return responses.respond(request, template, context=context)
def processRequest(self, request, access_type, page_name=None, params=None, **kwargs): """Creates the page upon which a request can be processed. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name # get the request entity using the information from kwargs fields = {'link_id': kwargs['link_id'], 'scope_path': kwargs['scope_path'], 'role': params['logic'].role_name} request_entity = request_logic.logic.getForFields(fields, unique=True) # pylint: disable-msg=E1103 user_entity = user_logic.logic.getFromKeyNameOr404(request_entity.link_id) get_dict = request.GET if 'status' in get_dict.keys(): if get_dict['status'] in ['group_accepted', 'rejected', 'ignored']: # update the request_entity and redirect away from this page request_status = get_dict['status'] # only update when the status is changing if request_status != request_entity.status: request_logic.logic.updateEntityProperties(request_entity, { 'status': get_dict['status']}) group_view = params.get('group_view') if not group_view: return http.HttpResponseRedirect('/') else: # redirect to the requests list return http.HttpResponseRedirect( redirects.getListRequestsRedirect(request_entity.scope, group_view.getParams())) # put the entity in the context context['entity'] = request_entity context['user_in_request'] = user_entity context['request_status'] = request_entity.status context['role_name'] = params['logic'].role_name #display the request processing page using the appropriate template template = request_view.view.getParams()['request_processing_template'] return responses.respond(request, template, context=context)
def manage(self, request, access_type, page_name=None, params=None, **kwargs): """Handles the request concerning the view that let's you manage a role's status. Args: request: the standard Django HTTP request object page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name logic = params['logic'] # get the entity for the given fields in kwargs fields = {'scope_path': kwargs['scope_path'], 'link_id': kwargs['link_id']} role_entity = logic.getForFields(kwargs, unique=True) # get the redirect for the cancel button or when the resignation is done redirect = params['manage_redirect'](role_entity.scope, params['group_view'].getParams()) # check to see if resign is true get_dict = request.GET resign = get_dict.get('resign') if resign == 'true': resign_error = params['logic'].canResign(role_entity) if not resign_error: # change the status of this role_entity to invalid fields = {'status': 'invalid'} logic.updateEntityProperties(role_entity, fields) # redirect to the roles listing return http.HttpResponseRedirect(redirect) else: # show error to the user context['resign_error'] = ugettext(resign_error %params) # set the appropriate context context['entity'] = role_entity context['url_name'] = params['url_name'] context['cancel_redirect'] = redirect # get the manage template template = params['manage_template'] # return a proper response return responses.respond(request, template, context=context)
def processInvite(self, request, access_type, page_name=None, params=None, **kwargs): """Creates the page upon which an invite can be processed. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ from soc.views.models.role import ROLE_VIEWS # get the context for this webpage context = responses.getUniversalContext(request) helper.responses.useJavaScript(context, params['js_uses_all']) # get the request entity using the information from kwargs request_entity = request_logic.getFromIDOr404(int(kwargs['id'])) invite_accepted_redirect = redirects.getInviteAcceptedRedirect( request_entity, self._params) role_params = ROLE_VIEWS[request_entity.role].getParams() role_logic = role_params['logic'] if not role_logic.canRejectInvite(request_entity.group): return http.HttpResponseRedirect(invite_accepted_redirect) # set the page name using the request_entity context['page_name'] = '%s %s for %s' % (page_name, role_params['name'], request_entity.group.name) get_dict = request.GET # TODO(ljvderijk): Should be made a POST request. if 'status' in get_dict.keys(): if get_dict['status'] == 'canceled': # this invite has been canceled mark as such request_logic.updateEntityProperties(request_entity, { 'status': 'canceled'}) # redirect to user request overview return http.HttpResponseRedirect('/user/requests') # put the entity in the context context['entity'] = request_entity context['module_name'] = params['module_name'] context['role_name'] = role_params['name'] context['invite_accepted_redirect'] = (invite_accepted_redirect) #display the invite processing page using the appropriate template template = params['invite_processing_template'] return responses.respond(request, template, context=context)
def processRequest(self, request, access_type, page_name=None, params=None, **kwargs): """Creates the page upon which a request can be processed. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the request entity using the information from kwargs request_entity = request_logic.getFromIDOr404(int(kwargs['id'])) # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = '%s from %s to become a %s' % ( page_name, request_entity.user.name, params['name']) # TODO(ljvderijk): Should be a POST request get_dict = request.GET if 'status' in get_dict.keys(): if get_dict['status'] in ['group_accepted', 'rejected', 'withdrawn', 'ignored']: # update the request_entity and redirect away from this page request_status = get_dict['status'] # only update when the status is changing if request_status != request_entity.status: request_logic.updateEntityProperties(request_entity, { 'status': get_dict['status']}) group_view = params.get('group_view') if not group_view: return http.HttpResponseRedirect('/') else: # redirect to the requests list return http.HttpResponseRedirect( redirects.getListRequestsRedirect(request_entity.group, group_view.getParams())) # put the entity in the context context['entity'] = request_entity context['request_status'] = request_entity.status context['role_verbose'] = params['name'] context['url_name'] = params['url_name'] #display the request processing page using the appropriate template template = request_view.view.getParams()['request_processing_template'] return responses.respond(request, template, context=context)
def processInvite(self, request, access_type, page_name=None, params=None, **kwargs): """Creates the page upon which an invite can be processed. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ from soc.views.models.role import ROLE_VIEWS # get the context for this webpage context = responses.getUniversalContext(request) helper.responses.useJavaScript(context, params['js_uses_all']) # get the request entity using the information from kwargs request_entity = request_logic.getFromIDOr404(int(kwargs['id'])) role_params = ROLE_VIEWS[request_entity.role].getParams() # set the page name using the request_entity context['page_name'] = '%s %s for %s' % ( page_name, role_params['name'], request_entity.group.name) get_dict = request.GET if 'status' in get_dict.keys(): if get_dict['status'] == 'rejected': # this invite has been rejected mark as rejected request_logic.updateEntityProperties(request_entity, {'status': 'rejected'}) # redirect to user request overview return http.HttpResponseRedirect('/user/requests') # put the entity in the context context['entity'] = request_entity context['module_name'] = params['module_name'] context['role_name'] = role_params['name'] context['invite_accepted_redirect'] = ( redirects.getInviteAcceptedRedirect(request_entity, self._params)) #display the invite processing page using the appropriate template template = params['invite_processing_template'] return responses.respond(request, template, context=context)
def acceptOrgAdminIntivation(self, request, access_type, page_name=None, params=None, **kwargs): """Creates the page process an invite into an OrgAdmin role. """ request_entity = request_logic.getFromIDOr404(int(kwargs['id'])) # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name return acceptInvitation(request, context, params, request_entity, 'org_admin', **kwargs)
def process_request(self, request): """Called when a request is made. See the Django middleware documentation for an explanation of the method signature. """ context = responses.getUniversalContext(request) allowed = (context['is_admin'] or ('HTTP_X_APPENGINE_CRON' in os.environ) or ('HTTP_X_APPENGINE_QUEUENAME' in os.environ)) if not allowed and context['in_maintenance']: return self.maintenance(request)
def processInvite(self, request, access_type, page_name=None, params=None, **kwargs): """Creates the page upon which an invite can be processed. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the context for this webpage context = responses.getUniversalContext(request) helper.responses.useJavaScript(context, params['js_uses_all']) request_logic = params['logic'] # get the request entity using the information from kwargs fields = {'link_id': kwargs['link_id'], 'scope_path': kwargs['scope_path'], 'role': kwargs['role'], 'status': 'group_accepted'} request_entity = request_logic.getForFields(fields, unique=True) # set the page name using the request_entity context['page_name'] = '%s %s' % (page_name, request_entity.role_verbose) get_dict = request.GET if 'status' in get_dict.keys(): if get_dict['status'] == 'rejected': # this invite has been rejected mark as rejected request_logic.updateEntityProperties(request_entity, { 'status': 'rejected'}) # redirect to user request overview return http.HttpResponseRedirect('/user/requests') # put the entity in the context context['entity'] = request_entity context['module_name'] = params['module_name'] context['invite_accepted_redirect'] = ( redirects.getInviteAcceptedRedirect(request_entity, self._params)) #display the invite processing page using the appropriate template template = params['invite_processing_template'] return responses.respond(request, template, context=context)
def view_wrapper(request, *args, **kwds): """View decorator wrapper method. """ context = responses.getUniversalContext(request) try: if not context['is_admin'] and context['in_maintenance']: return maintenance(request) return func(request, *args, **kwds) except CapabilityDisabledError, exception: logging.exception(exception) # assume the site is in maintenance if we get CDE return maintenance(request)
def manage(self, request, access_type, page_name=None, params=None, **kwargs): """Handles the request concerning the view that let's you manage a role's status. Args: request: the standard Django HTTP request object page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name logic = params['logic'] # get the entity for the given fields in kwargs role_entity = logic.getFromKeyFieldsOr404(kwargs) # get the redirect for the cancel button or when the resignation is done redirect = params['manage_redirect'](role_entity.scope, params['group_view'].getParams()) if request.method == 'POST': resign_error = logic.canResign(role_entity) if not resign_error: return self.managePost(request, params, role_entity, redirect) # show error to the user context['resign_error'] = resign_error % params # set the appropriate context context['entity'] = role_entity context['url_name'] = params['url_name'] context['cancel_redirect'] = redirect # get the manage template template = params['manage_template'] # return a proper response return responses.respond(request, template, context=context)
def home(self, request, page_name=None, params=None, **kwargs): """Renders the home page for seeding operations. """ template = 'modules/seeder/home.html' configuration_sheet = request.FILES.get('configuration_sheet', None); if configuration_sheet: configuration_sheet = configuration_sheet.read() else: configuration_sheet = '' context = responses.getUniversalContext(request) context['configuration_sheet'] = simplejson.dumps(configuration_sheet) # FIXME : temporarily comment due to errors #responses.useJavaScript(context, params['js_uses_all']) return responses.respond(request, template, context)
def home(self, request, page_name=None, params=None, **kwargs): """Renders the home page for seeding operations. """ template = 'modules/seeder/home.html' configuration_sheet = request.FILES.get('configuration_sheet', None) if configuration_sheet: configuration_sheet = configuration_sheet.read() else: configuration_sheet = '' context = responses.getUniversalContext(request) context['configuration_sheet'] = simplejson.dumps(configuration_sheet) # FIXME : temporarily comment due to errors #responses.useJavaScript(context, params['js_uses_all']) return responses.respond(request, template, context)
def submitForms(self, request, access_type, page_name=None, params=None, **kwargs): """Form upload page for a given student. See base.View.public() for more details. """ template = "modules/gci/student/submit_forms.html" context = responses.getUniversalContext(request) context["page_name"] = page_name logic = params["logic"] entity = logic.getFromKeyFieldsOr404(kwargs) if request.method == "POST": return self.submitFormsPost(request, params, context, entity) else: return self.submitFormsGet(request, params, template, context, entity)
def maintenance(self, request, page_name): """Returns a 'down for maintenance' view. """ context = responses.getUniversalContext(request) context["page_name"] = page_name notice = context.pop("site_notice") if not notice: context["body_content"] = self.DEF_NOT_IN_MAINTENANCE_MSG else: context["body_content"] = notice context["header_title"] = self.DEF_DOWN_FOR_MAINTENANCE_MSG context["sidebar_menu_items"] = [{"heading": self.DEF_DOWN_FOR_MAINTENANCE_MSG, "group": ""}] template = "soc/base.html" return responses.respond(request, template, context=context)
def startTask(self, request, option_name): """Starts the specified Task for the given option. """ context = responses.getUniversalContext(request) context['page_name'] = 'Start Update Task' option = self.options.get(option_name) if not option: template = 'soc/error.html' context['message'] = 'Uknown option "%s".' % option_name else: template = 'soc/tasks/run_update.html' context['option'] = option context['success'] = option['starter'](request, self._getRunUpdateURL(option_name)) content = loader.render_to_string(template, dictionary=context) return http.HttpResponse(content)
def getContextEntity(self, request, page_name, params, kwargs): context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name entity = None # TODO(ajaksu): there has to be a better way in this universe to get these kwargs['prefix'] = 'program' kwargs['link_id'] = request.path.split('/')[-1] kwargs['scope_path'] = '/'.join(request.path.split('/')[4:-1]) entity = survey_logic.getFromKeyFieldsOr404(kwargs) if not self._public(request, entity, context): error = out_of_band.Error('') error = responses.errorResponse( error, request, template=params['error_public'], context=context) return error, None return entity, context
def applicant(self, request, access_type, page_name=None, params=None, **kwargs): """Handles the creation of a group via an approved group application. Args: request: the standard Django HTTP request object access_type : the name of the access type which should be checked page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name if request.method == 'POST': return self.applicantPost(request, context, params, **kwargs) else: # request.method == 'GET' return self.applicantGet(request, context, params, **kwargs)
def maintenance(self, request): """Returns a 'down for maintenance' view. """ context = responses.getUniversalContext(request) context['page_name'] = ugettext('Maintenance') notice = context.pop('site_notice') if not notice: context['body_content'] = DEF_IN_UNEXPECTED_MAINTENANCE_MSG else: context['body_content'] = notice context['header_title'] = DEF_DOWN_FOR_MAINTENANCE_MSG context['sidebar_menu_items'] = [ {'heading': DEF_DOWN_FOR_MAINTENANCE_MSG, 'group': ''}, ] template = 'soc/base.html' return responses.respond(request, template, context=context)
def submitForms(self, request, access_type, page_name=None, params=None, **kwargs): """Form upload page for a given student. See base.View.public() for more details. """ template = 'modules/gci/student/submit_forms.html' context = responses.getUniversalContext(request) context['page_name'] = page_name logic = params['logic'] entity = logic.getFromKeyFieldsOr404(kwargs) if request.method == 'POST': return self.submitFormsPost(request, params, context, entity) else: return self.submitFormsGet(request, params, template, context, entity)
@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'] = '%s "%s" from %s' % (page_name, entity.title, entity.scope.name()) context['entity'] = entity context['entity_type'] = params['name'] context['entity_type_url'] = params['url_name'] if self._show_review_not_appeared_msg: context['header_msg'] = self.DEF_REVIEW_NOT_APPEARED_MSG self._show_review_not_appeared_msg = False # get the roles important for reviewing an application filter = { 'user': user_logic.logic.getCurrentUser(), 'scope': entity.org, 'status': 'active'
class View(base.View): """View methods for the Student Project model. """ DEF_NO_RECORD_AVAILABLE_MSG = ugettext('No Record Available') DEF_VIEW_RECORD_MSG = ugettext('View Record') DEF_TAKE_SURVEY_MSG = ugettext('Take Survey') 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.GSoCChecker(params) rights['any_access'] = ['allow'] rights['create'] = ['checkIsDeveloper'] rights['edit'] = ['checkIsDeveloper'] rights['delete'] = ['checkIsDeveloper'] rights['show'] = ['allow'] rights['list'] = ['checkIsDeveloper'] rights['manage'] = [('checkHasRoleForScope', [org_admin_logic, ['active', 'inactive']]), ('checkStudentProjectHasStatus', [['accepted', 'failed', 'completed', 'withdrawn']])] rights['manage_overview'] = [('checkHasAny', [[ ('checkHasRoleForScope', [org_admin_logic, ['active', 'inactive']]), ('checkHasRoleForScope', [mentor_logic, ['active', 'inactive']]) ]])] # TODO: lack of better name here! rights['st_edit'] = [ 'checkCanEditStudentProjectAsStudent', ('checkStudentProjectHasStatus', [['accepted', 'completed']]) ] rights['overview'] = [('checkIsHostForProgram', [program_logic])] new_params = {} new_params['logic'] = project_logic new_params['rights'] = rights new_params['name'] = 'Student Project' new_params['url_name'] = 'gsoc/student_project' new_params['module_package'] = 'soc.modules.gsoc.views.models' new_params['sidebar_grouping'] = 'Students' new_params['scope_view'] = org_view new_params['scope_redirect'] = redirects.getCreateRedirect new_params['no_create_with_key_fields'] = True new_params['extra_dynaexclude'] = [ 'program', 'status', 'link_id', 'mentor', 'additional_mentors', 'student', 'passed_evaluations', 'failed_evaluations' ] new_params['create_extra_dynaproperties'] = { 'scope_path': forms.CharField(widget=forms.HiddenInput, required=True), 'public_info': forms.fields.CharField(required=True, widget=widgets.FullTinyMCE(attrs={ 'rows': 25, 'cols': 100 })), 'student_id': forms.CharField(label='Student Link ID', required=True), 'mentor_id': forms.CharField(label='Mentor Link ID', required=True), 'clean_abstract': cleaning.clean_content_length('abstract'), 'clean_public_info': cleaning.clean_html_content('public_info'), 'clean_student': cleaning.clean_link_id('student'), 'clean_mentor': cleaning.clean_link_id('mentor'), 'clean_additional_info': cleaning.clean_url('additional_info'), 'clean_feed_url': cleaning.clean_feed_url('feed_url'), 'clean': cleaning.validate_student_project('scope_path', 'mentor_id', 'student_id') } new_params['edit_extra_dynaproperties'] = { 'link_id': forms.CharField(widget=forms.HiddenInput), } patterns = [ (r'^%(url_name)s/(?P<access_type>manage_overview)/%(scope)s$', 'soc.modules.gsoc.views.models.%(module_name)s.manage_overview', 'Overview of %(name_plural)s to Manage for'), (r'^%(url_name)s/(?P<access_type>manage)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.manage', 'Manage %(name)s'), (r'^%(url_name)s/(?P<access_type>st_edit)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.st_edit', 'Edit my %(name)s'), (r'^%(url_name)s/(?P<access_type>overview)/(?P<scope_path>%(ulnp)s)/%(lnp)s$', 'soc.modules.gsoc.views.models.%(module_name)s.overview', 'Overview of all %(name_plural)s for'), ] new_params['extra_django_patterns'] = patterns new_params['edit_template'] = 'soc/student_project/edit.html' new_params['manage_template'] = 'soc/student_project/manage.html' new_params['public_field_prefetch'] = ['mentor', 'student', 'scope'] new_params['public_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': entity.mentor.name(), 'org': entity.scope.name, } new_params['public_field_keys'] = [ 'student', 'title', 'mentor', 'org', 'status' ] new_params['public_field_names'] = [ 'Student', 'Title', 'Mentor', 'Organization', 'Status' ] new_params['org_home_field_prefetch'] = ['mentor', 'student'] new_params['org_home_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': ', '.join(mentor.name() for mentor in [entity.mentor] + db.get( entity.additional_mentors)) } new_params['org_home_field_keys'] = [ 'student', 'title', 'mentor', 'status' ] new_params['org_home_field_names'] = [ 'Student', 'Title', 'Mentor', 'Status' ] # define the list redirect action to show the notification new_params['public_row_extra'] = new_params[ 'org_home_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, new_params) } new_params['org_home_row_action'] = { 'type': 'redirect_custom', 'parameters': dict(new_window=False), } new_params['admin_field_prefetch'] = ['mentor', 'student', 'scope'] new_params['admin_field_extra'] = lambda entity: { 'student': entity.student.name(), 'mentor': entity.mentor.name(), 'student_id': entity.student.link_id } new_params['admin_field_keys'] = [ 'student', 'title', 'mentor', 'status', 'student_id' ] new_params['admin_field_names'] = [ 'Student', 'Title', 'Mentor', 'Status', 'Student Link ID' ] new_params['admin_field_hidden'] = ['student_id'] new_params['admin_conf_extra'] = { 'multiselect': True, } new_params['admin_button_global'] = [{ 'bounds': [1, 'all'], 'id': 'withdraw', 'caption': 'Withdraw Project', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }, { 'bounds': [1, 'all'], 'id': 'accept', 'caption': 'Accept Project', 'type': 'post', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', } }] params = dicts.merge(params, new_params) super(View, self).__init__(params=params) # create the form that students will use to edit their projects dynaproperties = { 'public_info': forms.fields.CharField(required=True, widget=widgets.FullTinyMCE(attrs={ 'rows': 25, 'cols': 100 })), 'clean_abstract': cleaning.clean_content_length('abstract'), 'clean_public_info': cleaning.clean_html_content('public_info'), 'clean_additional_info': cleaning.clean_url('additional_info'), 'clean_feed_url': cleaning.clean_feed_url('feed_url'), } student_edit_form = dynaform.newDynaForm( dynabase=self._params['dynabase'], dynamodel=self._params['logic'].getModel(), dynaexclude=self._params['create_dynaexclude'], dynaproperties=dynaproperties, ) self._params['student_edit_form'] = student_edit_form def _editGet(self, request, entity, form): """See base.View._editGet(). """ form.fields['link_id'].initial = entity.link_id form.fields['student_id'].initial = entity.student.link_id form.fields['mentor_id'].initial = entity.mentor.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' % (int(time.time() * 100)) else: fields['link_id'] = entity.link_id # fill in the scope via call to super super(View, self)._editPost(request, entity, fields) # editing a project so set the program, student and mentor field if entity: organization = entity.scope else: organization = fields['scope'] fields['program'] = organization.scope filter = {'scope': fields['program'], 'link_id': fields['student_id']} fields['student'] = student_logic.logic.getForFields(filter, unique=True) filter = { 'scope': organization, 'link_id': fields['mentor_id'], 'status': 'active' } fields['mentor'] = mentor_logic.getForFields(filter, unique=True) def _public(self, request, entity, context): """Adds the names of all additional mentors to the context. For params see base.View._public() """ additional_mentors = entity.additional_mentors if not additional_mentors: context['additional_mentors'] = [] else: mentor_names = [] for mentor_key in additional_mentors: additional_mentor = mentor_logic.getFromKeyName( mentor_key.id_or_name()) mentor_names.append(additional_mentor.name()) context['additional_mentors'] = ', '.join(mentor_names) def getOverviewData(self, request, params, program): """Return data for withdraw. """ fields = { 'program': program, } idx = lists.getListIndex(request) if idx != 0: return lists.getErrorResponse(request, "idx not valid") contents = lists.getListData(request, params, fields, visibility='admin') return lists.getResponse(request, contents) @decorators.merge_params @decorators.check_access def overview(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Program Admins to see/control all StudentProjects. For args see base.View().public() """ program_entity = program_logic.getFromKeyFieldsOr404(kwargs) if request.POST: return self.overviewPost(request, params, program_entity) else: #request.GET return self.overviewGet(request, page_name, params, program_entity, **kwargs) def overviewPost(self, request, params, program): """Handles the POST request for the Program Admins overview page. Args: request: Django HTTPRequest object params: Params for this view program: GSoCProgram entity """ project_logic = params['logic'] post_dict = request.POST data = simplejson.loads(post_dict.get('data', '[]')) button_id = post_dict.get('button_id', '') if button_id not in ['withdraw', 'accept']: logging.warning('Invalid button ID found %s' % (button_id)) return http.HttpResponse() project_keys = [] for selected in data: project_keys.append(selected['key']) # get all projects and prefetch the program field projects = project_logic.getFromKeyName(project_keys) project_logic.prefetchField('program', projects) # filter out all projects not belonging to the current program projects = [p for p in projects if p.program.key() == program.key()] for p in projects: fields = {} if button_id == 'withdraw': fields['status'] = 'withdrawn' elif button_id == 'accept': fields['status'] = 'accepted' # update the project with the new status project_logic.updateEntityProperties(p, fields) # return a 200 response return http.HttpResponse() def overviewGet(self, request, page_name, params, program_entity, **kwargs): """Handles the GET request for the Program Admins overview page. Args: request: Django HTTPRequest object page_name: Name for this page params: Params for this view program_entity: GSocProgram entity """ page_name = '%s %s' % (page_name, program_entity.name) list_params = params.copy() list_params['admin_row_extra'] = lambda entity: { 'link': redirects.getPublicRedirect(entity, list_params) } list_params['list_description'] = ugettext( 'An overview of all StudentProjects for %s. Click on an item to view ' 'the project, use the buttons on the list for withdrawing a project.' % (program_entity.name)) if lists.isDataRequest(request): return self.getOverviewData(request, list_params, program_entity) project_list = lists.getListGenerator(request, list_params, idx=0, visibility='admin') # fill contents with the list contents = [project_list] # call the _list method from base to display the list return self._list(request, params, contents, page_name) def _getManageData(self, request, gps_params, ps_params, entity): """Returns the JSONResponse for the Manage page. Args: request: HTTPRequest object gps_params: GradingProjectSurvey list params ps_params: ProjectSurvey list params entity: StudentProject entity """ idx = lists.getListIndex(request) if idx == 0: params = gps_params elif idx == 1: params = ps_params else: return lists.getErrorResponse(request, "idx not valid") fields = {'project': entity} record_logic = params['logic'].getRecordLogic() record_entities = record_logic.getForFields(fields) record_dict = dict( (i.survey.key(), i) for i in record_entities if i.survey) record_getter = lambda entity: record_dict.get(entity.key()) args = [record_getter] fields = {'scope': entity.program, 'prefix': 'gsoc_program'} contents = lists.getListData(request, params, fields, args=args) return lists.getResponse(request, contents) @decorators.merge_params @decorators.check_access def manage(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Organization Admins to manage their Student Projects. For params see base.View().public() """ import soc.logic.lists from soc.modules.gsoc.views.models.grading_project_survey import view as \ grading_survey_view from soc.modules.gsoc.views.models.project_survey import view as \ project_survey_view entity = self._logic.getFromKeyFieldsOr404(kwargs) template = params['manage_template'] # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = "%s '%s' from %s" % (page_name, entity.title, entity.student.name()) context['entity'] = entity if project_logic.canChangeMentors(entity): # only accepted project can have their mentors managed self._enableMentorManagement(entity, params, context) # list all surveys for this Project's Program gps_params = grading_survey_view.getParams().copy() gps_params['list_description'] = \ 'List of all Mentor Evaluations for this Project' gps_params['public_row_extra'] = lambda entity, *args: {} gps_params['public_row_action'] = {} gps_params['public_field_keys'] = [ "title", "taken_by", "taken_on", "record_url", "take_url" ] gps_params['public_field_names'] = [ "Title", "Taken by", "Taken on", "View", "(Re) Take", ] no_record = self.DEF_NO_RECORD_AVAILABLE_MSG # TODO(SRabbelier): use buttons instead project_entity = entity getExtra = lambda params: lambda entity, re: { "taken_by": no_record if not re(entity) else re(entity).user.name, "taken_on": no_record if not re(entity) else str(re(entity).modified), "record_url": no_record if not re(entity) else lists.urlize( redirects.getViewSurveyRecordRedirect(re(entity), params), name=self.DEF_VIEW_RECORD_MSG), "take_url": lists.urlize(redirects.getTakeProjectSurveyRedirect( project_entity, { 'survey': entity, 'params': params }), name=self.DEF_TAKE_SURVEY_MSG), } gps_params['public_field_extra'] = getExtra(gps_params) # get the ProjectSurvey list ps_params = project_survey_view.getParams().copy() ps_params['list_description'] = \ 'List of all Student Evaluations for this Project' ps_params['public_row_extra'] = lambda entity, *args: {} ps_params['public_row_action'] = {} ps_params['public_field_keys'] = gps_params['public_field_keys'] ps_params['public_field_names'] = gps_params['public_field_names'] ps_params['public_field_ignore'] = ["take_url"] ps_params['public_field_extra'] = getExtra(ps_params) if lists.isDataRequest(request): return self._getManageData(request, gps_params, ps_params, entity) gps_list = lists.getListGenerator(request, gps_params, idx=0) ps_list = lists.getListGenerator(request, ps_params, idx=1) # store both lists in the content content = [gps_list, ps_list] context['evaluation_list'] = soc.logic.lists.Lists(content) if request.POST: return self.managePost(request, template, context, params, entity, **kwargs) else: #request.GET return self.manageGet(request, template, context, params, entity, **kwargs) def _enableMentorManagement(self, entity, params, context): """Sets the data required to manage mentors for a StudentProject. Args: entity: StudentProject entity to manage params: params dict for the manage view context: context for the manage view """ context['can_manage_mentors'] = True # get all mentors for this organization fields = {'scope': entity.scope, 'status': 'active'} mentors = mentor_logic.getForFields(fields) choices = [(mentor.link_id, '%s (%s)' % (mentor.name(), mentor.link_id)) for mentor in mentors] # create the form that org admins will use to reassign a mentor dynafields = [ { 'name': 'mentor_id', 'base': forms.ChoiceField, 'label': 'Primary Mentor', 'required': True, 'passthrough': ['required', 'choices', 'label'], 'choices': choices, }, ] dynaproperties = params_helper.getDynaFields(dynafields) mentor_edit_form = dynaform.newDynaForm( dynabase=params['dynabase'], dynaproperties=dynaproperties, ) params['mentor_edit_form'] = mentor_edit_form additional_mentors = entity.additional_mentors # we want to show the names of the additional mentors in the context # therefore they need to be resolved to entities first additional_mentors_context = [] for mentor_key in additional_mentors: mentor_entity = mentor_logic.getFromKeyName( mentor_key.id_or_name()) additional_mentors_context.append(mentor_entity) context['additional_mentors'] = additional_mentors_context # all mentors who are not already an additional mentor or # the primary mentor are allowed to become an additional mentor possible_additional_mentors = [ m for m in mentors if (m.key() not in additional_mentors) and ( m.key() != entity.mentor.key()) ] # create the information to be shown on the additional mentor form additional_mentor_choices = [ (mentor.link_id, '%s (%s)' % (mentor.name(), mentor.link_id)) for mentor in possible_additional_mentors ] dynafields = [ { 'name': 'mentor_id', 'base': forms.ChoiceField, 'label': 'Co-Mentor', 'required': True, 'passthrough': ['required', 'choices', 'label'], 'choices': additional_mentor_choices, }, ] dynaproperties = params_helper.getDynaFields(dynafields) additional_mentor_form = dynaform.newDynaForm( dynabase=params['dynabase'], dynaproperties=dynaproperties, ) params['additional_mentor_form'] = additional_mentor_form def manageGet(self, request, template, context, params, entity, **kwargs): """Handles the GET request for the project's manage page. Args: template: the template used for this view entity: the student project entity rest: see base.View.public() """ get_dict = request.GET if 'remove' in get_dict and entity.status == 'accepted': # get the mentor to remove fields = {'link_id': get_dict['remove'], 'scope': entity.scope} mentor = mentor_logic.getForFields(fields, unique=True) additional_mentors = entity.additional_mentors # pylint: disable=E1103 if additional_mentors and mentor.key() in additional_mentors: # remove the mentor from the additional mentors list additional_mentors.remove(mentor.key()) fields = {'additional_mentors': additional_mentors} project_logic.updateEntityProperties(entity, fields) # redirect to the same page without GET arguments redirect = request.path return http.HttpResponseRedirect(redirect) if project_logic.canChangeMentors(entity): # populate forms with the current mentors set initial = {'mentor_id': entity.mentor.link_id} context['mentor_edit_form'] = params['mentor_edit_form']( initial=initial) context['additional_mentor_form'] = params[ 'additional_mentor_form']() return responses.respond(request, template, context) def managePost(self, request, template, context, params, entity, **kwargs): """Handles the POST request for the project's manage page. Args: template: the template used for this view entity: the student project entity rest: see base.View.public() """ post_dict = request.POST if 'set_mentor' in post_dict and project_logic.canChangeMentors( entity): form = params['mentor_edit_form'](post_dict) return self._manageSetMentor(request, template, context, params, entity, form) elif 'add_additional_mentor' in post_dict and \ project_logic.canChangeMentors(entity): form = params['additional_mentor_form'](post_dict) return self._manageAddAdditionalMentor(request, template, context, params, entity, form) else: # unexpected error return the normal page logging.warning('Unexpected POST data found') return self.manageGet(request, template, context, params, entity) def _manageSetMentor(self, request, template, context, params, entity, form): """Handles the POST request for changing a Projects's mentor. Args: template: the template used for this view entity: the student project entity form: instance of the form used to set the mentor rest: see base.View.public() """ if not form.is_valid(): context['mentor_edit_form'] = form # add an a fresh additional mentors form context['additional_mentor_form'] = params[ 'additional_mentor_form']() return responses.respond(request, template, context) _, fields = forms_helper.collectCleanedFields(form) # get the mentor from the form fields = { 'link_id': fields['mentor_id'], 'scope': entity.scope, 'status': 'active' } mentor = mentor_logic.getForFields(fields, unique=True) # update the project with the assigned mentor fields = {'mentor': mentor} additional_mentors = entity.additional_mentors # pylint: disable=E1103 if additional_mentors and mentor.key() in additional_mentors: # remove the mentor that is now becoming the primary mentor additional_mentors.remove(mentor.key()) fields['additional_mentors'] = additional_mentors # update the project with the new mentor and possible # new set of additional mentors project_logic.updateEntityProperties(entity, fields) # redirect to the same page redirect = request.path return http.HttpResponseRedirect(redirect) def _manageAddAdditionalMentor(self, request, template, context, params, entity, form): """Handles the POST request for changing a Projects's additional mentors. Args: template: the template used for this view entity: the student project entity form: instance of the form used to add an additional mentor rest: see base.View.public() """ if not form.is_valid(): context['additional_mentor_form'] = form # add a fresh edit mentor form initial = {'mentor_id': entity.mentor.link_id} context['mentor_edit_form'] = params['mentor_edit_form']( initial=initial) return responses.respond(request, template, context) _, fields = forms_helper.collectCleanedFields(form) # get the mentor from the form fields = { 'link_id': fields['mentor_id'], 'scope': entity.scope, 'status': 'active' } mentor = mentor_logic.getForFields(fields, unique=True) # add this mentor to the additional mentors if not entity.additional_mentors: additional_mentors = [mentor.key()] else: additional_mentors = entity.additional_mentors additional_mentors.append(mentor.key()) fields = {'additional_mentors': additional_mentors} project_logic.updateEntityProperties(entity, fields) # redirect to the same page redirect = request.path return http.HttpResponseRedirect(redirect) def getManageOverviewData(self, request, mo_params, org_entity): """Returns the manageOverview data. """ args = [] fields = {} idx = lists.getListIndex(request) if idx == 0: from soc.modules.gsoc.logic.models.survey import grading_logic as \ grading_survey_logic from soc.modules.gsoc.logic.models.survey import project_logic as \ project_survey_logic from soc.modules.gsoc.logic.models.survey_record import grading_logic from soc.modules.gsoc.logic.models.survey_record import project_logic program_entity = org_entity.scope fields = {'scope_path': program_entity.key().id_or_name()} # count the number of have been active ProjectSurveys project_surveys = project_survey_logic.getForFields(fields) project_survey_count = len(project_surveys) for project_survey in project_surveys: if not project_survey_logic.hasRecord(project_survey): project_survey_count = project_survey_count - 1 # count the number of have been active GradingProjectSurveys grading_surveys = grading_survey_logic.getForFields(fields) grading_survey_count = len(grading_surveys) for grading_survey in grading_surveys: if not grading_survey_logic.hasRecord(grading_survey): grading_survey_count = grading_survey_count - 1 fields = {'scope': org_entity} params = mo_params args = [ project_surveys, project_survey_count, grading_surveys, grading_survey_count ] else: return lists.getErrorResponse(request, 'idx not valid') contents = lists.getListData(request, params, fields, args=args) return lists.getResponse(request, contents) @decorators.merge_params @decorators.check_access def manageOverview(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Organization Admins to see an overview of their Organization's Student Projects. For params see base.View().public() """ from soc.modules.gsoc.logic.models.survey import grading_logic as \ grading_survey_logic from soc.modules.gsoc.logic.models.survey import project_logic as \ project_survey_logic from soc.modules.gsoc.logic.models.survey_record import grading_logic from soc.modules.gsoc.logic.models.survey_record import project_logic # make sure the organization exists org_entity = org_logic.getFromKeyNameOr404(kwargs['scope_path']) page_name = '%s %s' % (page_name, org_entity.name) mo_params = params.copy() #list all active projects mo_params['list_description'] = ugettext( 'List of all %s for %s, if you are an Org Admin you can click ' 'a project for more actions. Such as reassigning mentors or viewing ' 'results of the evaluations.' % (params['name_plural'], org_entity.name)) mo_params['public_field_names'] = params['public_field_names'] + [ 'Mentor evaluation', 'Student Evaluation' ] mo_params['public_field_keys'] = params['public_field_keys'] + [ 'mentor_evaluation', 'student_evaluation' ] fields = {'scope': org_entity, 'status': ['active', 'inactive']} org_admin = org_admin_logic.getForFields(fields, unique=True) # Org Admins get a link to manage the project, others go to public page if org_admin: mo_params['public_row_extra'] = lambda entity, *args: { 'link': redirects.getManageRedirect(entity, mo_params) } else: mo_params['public_row_extra'] = lambda entity, *args: { 'link': redirects.getPublicRedirect(entity, mo_params) } mo_params['public_field_prefetch'] = ['student', 'mentor', 'scope'] mo_params['public_field_extra'] = lambda entity, ps, psc, gs, gsc: { 'org': entity.scope.name, 'student': '%s (%s)' % (entity.student.name(), entity.student.email), 'mentor': entity.mentor.name(), 'mentor_evaluation': '%d/%d' % (grading_logic.getQueryForFields({ 'project': entity }).count(), gsc), 'student_evaluation': '%d/%d' % (project_logic.getQueryForFields({ 'project': entity }).count(), psc), } if lists.isDataRequest(request): return self.getManageOverviewData(request, mo_params, org_entity) mo_list = lists.getListGenerator(request, mo_params, idx=0) contents = [mo_list] # call the _list method from base to display the list return self._list(request, mo_params, contents, page_name) @decorators.merge_params @decorators.check_access def stEdit(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows students to edit information about their project. For params see base.View().public() """ try: entity = self._logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return 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 # cancel should go to the public view params['cancel_redirect'] = redirects.getPublicRedirect(entity, params) if request.POST: return self.stEditPost(request, context, params, entity, **kwargs) else: #request.GET return self.stEditGet(request, context, params, entity, **kwargs)
def manage(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Organization Admins to manage their Student Projects. For params see base.View().public() """ import soc.logic.lists from soc.modules.gsoc.views.models.grading_project_survey import view as \ grading_survey_view from soc.modules.gsoc.views.models.project_survey import view as \ project_survey_view entity = self._logic.getFromKeyFieldsOr404(kwargs) template = params['manage_template'] # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = "%s '%s' from %s" % (page_name, entity.title, entity.student.name()) context['entity'] = entity if project_logic.canChangeMentors(entity): # only accepted project can have their mentors managed self._enableMentorManagement(entity, params, context) # list all surveys for this Project's Program gps_params = grading_survey_view.getParams().copy() gps_params['list_description'] = \ 'List of all Mentor Evaluations for this Project' gps_params['public_row_extra'] = lambda entity, *args: {} gps_params['public_row_action'] = {} gps_params['public_field_keys'] = [ "title", "taken_by", "taken_on", "record_url", "take_url" ] gps_params['public_field_names'] = [ "Title", "Taken by", "Taken on", "View", "(Re) Take", ] no_record = self.DEF_NO_RECORD_AVAILABLE_MSG # TODO(SRabbelier): use buttons instead project_entity = entity getExtra = lambda params: lambda entity, re: { "taken_by": no_record if not re(entity) else re(entity).user.name, "taken_on": no_record if not re(entity) else str(re(entity).modified), "record_url": no_record if not re(entity) else lists.urlize( redirects.getViewSurveyRecordRedirect(re(entity), params), name=self.DEF_VIEW_RECORD_MSG), "take_url": lists.urlize(redirects.getTakeProjectSurveyRedirect( project_entity, { 'survey': entity, 'params': params }), name=self.DEF_TAKE_SURVEY_MSG), } gps_params['public_field_extra'] = getExtra(gps_params) # get the ProjectSurvey list ps_params = project_survey_view.getParams().copy() ps_params['list_description'] = \ 'List of all Student Evaluations for this Project' ps_params['public_row_extra'] = lambda entity, *args: {} ps_params['public_row_action'] = {} ps_params['public_field_keys'] = gps_params['public_field_keys'] ps_params['public_field_names'] = gps_params['public_field_names'] ps_params['public_field_ignore'] = ["take_url"] ps_params['public_field_extra'] = getExtra(ps_params) if lists.isDataRequest(request): return self._getManageData(request, gps_params, ps_params, entity) gps_list = lists.getListGenerator(request, gps_params, idx=0) ps_list = lists.getListGenerator(request, ps_params, idx=1) # store both lists in the content content = [gps_list, ps_list] context['evaluation_list'] = soc.logic.lists.Lists(content) if request.POST: return self.managePost(request, template, context, params, entity, **kwargs) else: #request.GET return self.manageGet(request, template, context, params, entity, **kwargs)
class View(base.View): """View methods for the Student Project 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.GSoCChecker(params) rights['any_access'] = ['allow'] rights['create'] = ['checkIsDeveloper'] rights['edit'] = ['checkIsDeveloper'] rights['delete'] = ['checkIsDeveloper'] rights['show'] = ['allow'] rights['list'] = ['checkIsDeveloper'] rights['manage'] = [('checkHasRoleForScope', [org_admin_logic, ['active', 'inactive']]), ('checkStudentProjectHasStatus', [['accepted', 'failed', 'completed', 'withdrawn']])] rights['manage_overview'] = [('checkHasRoleForScope', [ org_admin_logic, ['active', 'inactive']])] # TODO: lack of better name here! rights['st_edit'] = [ 'checkCanEditStudentProjectAsStudent', ('checkStudentProjectHasStatus', [['accepted', 'completed']]) ] rights['withdraw'] = ['checkIsHostForProgram'] rights['withdraw_project'] = ['checkIsHostForStudentProject', ('checkStudentProjectHasStatus', [['accepted', 'completed']]) ] rights['accept_project'] = ['checkIsHostForStudentProject', ('checkStudentProjectHasStatus', [['withdrawn']]) ] new_params = {} new_params['logic'] = project_logic new_params['rights'] = rights new_params['name'] = "Student Project" new_params['url_name'] = "gsoc/student_project" new_params['module_package'] = 'soc.modules.gsoc.views.models' new_params['sidebar_grouping'] = 'Students' new_params['scope_view'] = org_view new_params['scope_redirect'] = redirects.getCreateRedirect new_params['no_create_with_key_fields'] = True new_params['extra_dynaexclude'] = ['program', 'status', 'link_id', 'mentor', 'additional_mentors', 'student', 'passed_evaluations', 'failed_evaluations'] new_params['create_extra_dynaproperties'] = { 'scope_path': forms.CharField(widget=forms.HiddenInput, required=True), 'public_info': forms.fields.CharField(required=True, widget=widgets.FullTinyMCE(attrs={'rows': 25, 'cols': 100})), 'student_id': forms.CharField(label='Student Link ID', required=True), 'mentor_id': forms.CharField(label='Mentor Link ID', required=True), 'clean_abstract': cleaning.clean_content_length('abstract'), 'clean_public_info': cleaning.clean_html_content('public_info'), 'clean_student': cleaning.clean_link_id('student'), 'clean_mentor': cleaning.clean_link_id('mentor'), 'clean_additional_info': cleaning.clean_url('additional_info'), 'clean_feed_url': cleaning.clean_feed_url, 'clean': cleaning.validate_student_project('scope_path', 'mentor_id', 'student_id') } new_params['edit_extra_dynaproperties'] = { 'link_id': forms.CharField(widget=forms.HiddenInput), } patterns = [ (r'^%(url_name)s/(?P<access_type>manage_overview)/%(scope)s$', 'soc.modules.gsoc.views.models.%(module_name)s.manage_overview', 'Overview of %(name_plural)s to Manage for'), (r'^%(url_name)s/(?P<access_type>manage)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.manage', 'Manage %(name)s'), (r'^%(url_name)s/(?P<access_type>st_edit)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.st_edit', 'Edit my %(name)s'), (r'^%(url_name)s/(?P<access_type>withdraw)/(?P<scope_path>%(ulnp)s)/%(lnp)s$', 'soc.modules.gsoc.views.models.%(module_name)s.withdraw', 'Withdraw %(name_plural)s'), (r'^%(url_name)s/(?P<access_type>withdraw_project)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.withdraw_project', 'Withdraw a %(name)s'), (r'^%(url_name)s/(?P<access_type>accept_project)/%(key_fields)s$', 'soc.modules.gsoc.views.models.%(module_name)s.accept_project', 'Accept a %(name)s'), ] new_params['extra_django_patterns'] = patterns new_params['edit_template'] = 'soc/student_project/edit.html' new_params['manage_template'] = 'soc/student_project/manage.html' new_params['manage_overview_heading'] = \ 'soc/student_project/list/heading_manage.html' new_params['manage_overview_row'] = \ 'soc/student_project/list/row_manage.html' new_params['public_field_extra'] = lambda entity: { "student": entity.student.name(), "mentor": entity.mentor.name(), } new_params['public_field_keys'] = ["student", "title", "mentor", "status"] new_params['public_field_names'] = ["Student", "Title", "Mentor", "Status"] params = dicts.merge(params, new_params) super(View, self).__init__(params=params) # create the form that students will use to edit their projects dynaproperties = { 'public_info': forms.fields.CharField(required=True, widget=widgets.FullTinyMCE(attrs={'rows': 25, 'cols': 100})), 'clean_abstract': cleaning.clean_content_length('abstract'), 'clean_public_info': cleaning.clean_html_content('public_info'), 'clean_additional_info': cleaning.clean_url('additional_info'), 'clean_feed_url': cleaning.clean_feed_url, } student_edit_form = dynaform.newDynaForm( dynabase = self._params['dynabase'], dynamodel = self._params['logic'].getModel(), dynaexclude = self._params['create_dynaexclude'], dynaproperties = dynaproperties, ) self._params['student_edit_form'] = student_edit_form def _editGet(self, request, entity, form): """See base.View._editGet(). """ form.fields['link_id'].initial = entity.link_id form.fields['student_id'].initial = entity.student.link_id form.fields['mentor_id'].initial = entity.mentor.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' % (int(time.time()*100)) else: fields['link_id'] = entity.link_id # fill in the scope via call to super super(View, self)._editPost(request, entity, fields) # editing a project so set the program, student and mentor field if entity: organization = entity.scope else: organization = fields['scope'] fields['program'] = organization.scope filter = {'scope': fields['program'], 'link_id': fields['student_id']} fields['student'] = student_logic.logic.getForFields(filter, unique=True) filter = {'scope': organization, 'link_id': fields['mentor_id'], 'status': 'active'} fields['mentor'] = mentor_logic.getForFields(filter, unique=True) def _public(self, request, entity, context): """Adds the names of all additional mentors to the context. For params see base.View._public() """ additional_mentors = entity.additional_mentors if not additional_mentors: context['additional_mentors'] = [] else: mentor_names = [] for mentor_key in additional_mentors: additional_mentor = mentor_logic.getFromKeyName( mentor_key.id_or_name()) mentor_names.append(additional_mentor.name()) context['additional_mentors'] = ', '.join(mentor_names) def getWithdrawData(self, request, ap_params, wp_params, program_kwargs): """Return data for withdraw. """ program = program_logic.getFromKeyFieldsOr404(program_kwargs) fields = { 'program': program, } idx = request.GET.get('idx', '') idx = int(idx) if idx.isdigit() else -1 if idx == 0: fields['status'] = ['accepted', 'completed'] params = ap_params elif idx == 1: fields['status'] = ['withdrawn'] params = wp_params else: return responses.jsonErrorResponse(request, "idx not valid") contents = lists.getListData(request, params, fields, 'public') json = simplejson.dumps(contents) return responses.jsonResponse(request, json) @decorators.merge_params @decorators.check_access def withdraw(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Program Admins to accept or withdraw Student Projects. For params see base.View().public() """ ap_params = params.copy() # accepted projects ap_params['public_row_extra'] = lambda entity: { 'link': redirects.getWithdrawProjectRedirect(entity,ap_params) } ap_params['list_description'] = ugettext( "An overview of accepted and completed Projects. " "Click on a project to withdraw it.") wp_params = params.copy() # withdrawn projects wp_params['public_row_extra'] = lambda entity: { 'link': redirects.getAcceptProjectRedirect(entity, wp_params) } wp_params['list_description'] = ugettext( "An overview of withdrawn Projects. " "Click on a project to undo the withdrawal.") if request.GET.get('fmt') == 'json': return self.getWithdrawData(request, ap_params, wp_params, kwargs) ap_list = lists.getListGenerator(request, ap_params, idx=0) wp_list = lists.getListGenerator(request, wp_params, idx=1) # fill contents with all the needed lists contents = [ap_list, wp_list] # call the _list method from base to display the list return self._list(request, params, contents, page_name) @decorators.merge_params @decorators.check_access def withdrawProject(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Program Admins to withdraw Student Projects. For params see base.View().public() """ # TODO(POST) logic = params['logic'] entity = logic.getFromKeyFieldsOr404(kwargs) fields = { 'status': 'withdrawn', } logic.updateEntityProperties(entity, fields) url = redirects.getWithdrawRedirect(entity.program, params) return http.HttpResponseRedirect(url) @decorators.merge_params @decorators.check_access def acceptProject(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Program Admins to accept Student Projects. For params see base.View().public() """ # TODO(POST) logic = params['logic'] entity = logic.getFromKeyFieldsOr404(kwargs) fields = { 'status': 'accepted', } logic.updateEntityProperties(entity, fields) url = redirects.getWithdrawRedirect(entity.program, params) return http.HttpResponseRedirect(url) @decorators.merge_params @decorators.check_access def manage(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Organization Admins to manage their Student Projects. For params see base.View().public() """ try: entity = self._logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return responses.errorResponse( error, request, template=params['error_public']) template = params['manage_template'] # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = "%s '%s' from %s" % (page_name, entity.title, entity.student.name()) context['entity'] = entity if project_logic.canChangeMentors(entity): # only accepted project can have their mentors managed self._enableMentorManagement(entity, params, context) context['evaluation_list'] = self._getEvaluationLists(request, params, entity) if request.POST: return self.managePost(request, template, context, params, entity, **kwargs) else: #request.GET return self.manageGet(request, template, context, params, entity, **kwargs)
class View(base.View): """View methods for the GradingSurveyGroup 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.GSoCChecker(params) rights['create'] = [('checkIsHostForProgramInScope', program_logic)] rights['edit'] = [('checkIsHostForProgramInScope', program_logic)] rights['delete'] = ['checkIsDeveloper'] rights['show'] = [('checkIsHostForProgramInScope', program_logic)] rights['list'] = ['checkIsDeveloper'] rights['records'] = [('checkIsHostForProgramInScope', program_logic)] rights['edit_record'] = [('checkIsHostForProgramInScope', program_logic)] new_params = {} new_params['logic'] = survey_group_logic new_params['rights'] = rights new_params['name'] = "Grading Survey Group" new_params['url_name'] = 'gsoc/grading_survey_group' new_params['module_package'] = 'soc.modules.gsoc.views.models' new_params['sidebar_grouping'] = "Surveys" new_params['scope_view'] = program_view new_params['scope_redirect'] = redirects.getCreateRedirect new_params['no_admin'] = True new_params['no_create_with_key_fields'] = True new_params['create_extra_dynaproperties'] = { 'grading_survey': djangoforms.ModelChoiceField(GradingProjectSurvey, required=True), 'student_survey': djangoforms.ModelChoiceField(ProjectSurvey, required=False), } new_params['extra_dynaexclude'] = [ 'link_id', 'scope', 'scope_path', 'last_update_started', 'last_update_complete' ] new_params['edit_extra_dynaproperties'] = { 'link_id': forms.CharField(widget=forms.HiddenInput), } patterns = [ (r'^%(url_name)s/(?P<access_type>records)/%(key_fields)s$', '%(module_package)s.%(module_name)s.view_records', 'Overview of GradingRecords'), (r'^%(url_name)s/(?P<access_type>edit_record)/%(key_fields)s$', '%(module_package)s.%(module_name)s.edit_record', 'Edit a GradingRecord'), ] new_params['extra_django_patterns'] = patterns new_params[ 'view_records_template'] = 'soc/grading_survey_group/records.html' new_params[ 'records_heading_template'] = 'soc/grading_record/list/heading.html' new_params['records_row_template'] = 'soc/grading_record/list/row.html' new_params['record_edit_template'] = 'soc/grading_record/edit.html' # create the form that will be used to edit a GradingRecord record_logic = survey_group_logic.getRecordLogic() record_edit_form = dynaform.newDynaForm( dynabase=soc.views.helper.forms.BaseForm, dynamodel=record_logic.getModel(), dynaexclude=[ 'grading_survey_group', 'mentor_record', 'student_record', 'project' ], ) new_params['record_edit_form'] = record_edit_form new_params['public_field_keys'] = [ "name", "last_update_started", "last_update_completed" ] new_params['public_field_names'] = [ "Name", "Last update started", "Last update completed" ] new_params['records_field_extra'] = lambda entity: { "project_title": entity.project.title, "student_name": "%s (%s)" % (entity.project.student.name, entity.project.student.link_id), "organization": entity.project.name, "mentor_name": "%s (%s)" % (entity.project.mentor.name, entity.project.mentor.link_id), "final_grade": entity.grade_decision.capitalize(), "mentor_grade": ("Pass" if entity.mentor_record.grade else "Fail") if entity.mentor_record else "Not Available", "student_eval": "Yes" if entity.student_record else "Not Available", } new_params['records_field_keys'] = [ "project_title", "student_name", "organization", "mentor_name", "final_grade", "mentor_grade", "student_eval", "locked" ] new_params['records_field_names'] = [ "Project Name", "Student (link id)", "Organization", "Mentor (link id)", "Final Grade", "Mentor Grade", "Student Eval", "Locked" ] params = dicts.merge(params, new_params) super(View, self).__init__(params=params) @decorators.merge_params @decorators.check_access def create(self, request, access_type, page_name=None, params=None, **kwargs): """Pass the correct survey queries to GroupForm. For params see base.View.create(). """ if kwargs.get('scope_path'): self.setQueries(kwargs['scope_path'], params['create_form']) return super(View, self).create(request, access_type, page_name=page_name, params=params, **kwargs) @decorators.merge_params @decorators.check_access def edit(self, request, access_type, page_name=None, params=None, seed=None, **kwargs): """Pass the correct survey queries to GroupForm. For params see base.View.edit(). """ self.setQueries(kwargs['scope_path'], params['edit_form']) return super(View, self).edit(request, access_type, page_name=page_name, params=params, seed=seed, **kwargs) def _editGet(self, request, entity, form): """Performs any required processing on the form to get its edit page. Args: request: the django request object entity: the entity to get form: the django form that will be used for the page """ form.fields['link_id'].initial = entity.link_id return super(View, self)._editGet(request, entity, form) def _editPost(self, request, entity, fields): """See base.View._editPost(). """ if not entity: # generate a unique link_id fields['link_id'] = 't%i' % (int(time.time() * 100)) # TODO: seriously redesign _editPost to pass along kwargs fields['scope_path'] = fields['grading_survey'].scope_path else: fields['link_id'] = entity.link_id # fill in the scope via call to super return super(View, self)._editPost(request, entity, fields) def setQueries(self, program_keyname, group_form): """Add program filtering queries to the GroupForm. Args: program_keyname: keyname of the program to filter on group_form: DynaForm instance to set the queries for """ # fetch the program program = program_logic.getFromKeyNameOr404(program_keyname) # filter grading surveys by program and use title for display grading_query = grading_logic.getQueryForFields( filter={'scope_path': program_keyname}) # filter project surveys by program and use title for display student_query = project_logic.getQueryForFields( filter={'scope_path': program_keyname}) group_form.base_fields['grading_survey'].query = grading_query group_form.base_fields['student_survey'].query = student_query # use survey titles in drop-downs self.choiceTitles(group_form, 'grading_survey', grading_logic) self.choiceTitles(group_form, 'student_survey', project_logic) def choiceTitles(self, group_form, field, logic): """Fetch entity titles for choice field entries. Args: group_form: The form to set the choice field entries for field: the field_name to set the choice entries for logic: the logic for the model to set the choice entries for """ # TODO(ajaksu): subclass ModelChoiceField so we don't need this method choice_list = [] model = logic.getModel() for value, text in tuple(group_form.base_fields[field].choices): if value: entity = model.get(value) text = '%s (%s)' % (entity.title, entity.link_id) choice_list.append((value, text)) choices = tuple(choice_list) group_form.base_fields[field].choices = choices @decorators.merge_params @decorators.check_access def viewRecords(self, request, access_type, page_name=None, params=None, **kwargs): """View which shows all collected records for a given GradingSurveyGroup. For args see base.View.public(). """ from google.appengine.api.labs import taskqueue from soc.logic import lists as lists_logic survey_group_logic = params['logic'] record_logic = survey_group_logic.getRecordLogic() try: entity = survey_group_logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return 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'] = "%s for %s named '%s'" % ( page_name, params['name'], entity.name) context['entity'] = entity template = params['view_records_template'] # get the POST request dictionary and check if we should take action post_dict = request.POST if post_dict.get('update_records'): # start the task to update all GradingRecords for the given group task_params = {'group_key': entity.key().id_or_name()} task_url = '/tasks/grading_survey_group/update_records' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add() # update the GradingSurveyGroup with the new timestamp fields = {'last_update_started': datetime.datetime.now()} survey_group_logic.updateEntityProperties(entity, fields) context['message'] = 'Grading Records update successfully started.' if post_dict.get('update_projects'): # start the task to update all StudentProjects for the given group task_params = {'group_key': entity.key().id_or_name()} task_url = '/tasks/grading_survey_group/update_projects' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add() context[ 'message'] = 'Student Projects update successfully started.' if post_dict.get('update_projects_and_mail'): # Start the task to update all StudentProjects for the given group and # send out emails. task_params = { 'group_key': entity.key().id_or_name(), 'send_mail': 'true' } task_url = '/tasks/grading_survey_group/update_projects' new_task = taskqueue.Task(params=task_params, url=task_url) new_task.add() context['message'] = ( 'Student Projects update successfully started. ' 'And sending out e-mail with the results.') list_params = params.copy() list_params['logic'] = record_logic list_params['list_heading'] = params['records_heading_template'] list_params['list_row'] = params['records_row_template'] list_params['public_row_extra'] = lambda entity: { 'link': redirects.getEditGradingRecordRedirect( entity, list_params) } # TODO(LIST) fields = {'grading_survey_group': entity} # list all records with grading_decision set to pass fields['grade_decision'] = 'pass' # get the list content for passing records pr_params = list_params.copy() pr_params['list_description'] = \ 'List of all Records which have their grading outcome set to pass.' pr_list = lists.getListContent(request, pr_params, fields, idx=0) # list all records with grading_decision set to fail fields['grade_decision'] = 'fail' # get the list content for all failing records fr_params = list_params.copy() fr_params['list_description'] = \ 'List of all Records which have their grading outcome set to fail.' fr_list = lists.getListContent(request, fr_params, fields, idx=1) # list all records with grading decision set to undecided fields['grade_decision'] = 'undecided' # get the list content for all undecided records ur_params = list_params.copy() ur_params['list_description'] = \ 'List of all Records which have their grading outcome set to undecided.' ur_list = lists.getListContent(request, ur_params, fields, idx=2) # specify the contents and create a Lists object for use in the context contents = [pr_list, fr_list, ur_list] context['list'] = lists_logic.Lists(contents) return responses.respond(request, template, context)
def manage(self, request, access_type, page_name=None, params=None, **kwargs): """Handles the request concerning the view that let's you manage a role's status. Args: request: the standard Django HTTP request object page_name: the page name displayed in templates as page and header title params: a dict with params for this View kwargs: the Key Fields for the specified entity """ # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = page_name logic = params['logic'] # get the entity for the given fields in kwargs fields = { 'scope_path': kwargs['scope_path'], 'link_id': kwargs['link_id'] } role_entity = logic.getForFields(kwargs, unique=True) # get the redirect for the cancel button or when the resignation is done redirect = params['manage_redirect'](role_entity.scope, params['group_view'].getParams()) # check to see if resign is true get_dict = request.GET resign = get_dict.get('resign') if resign == 'true': resign_error = params['logic'].canResign(role_entity) if not resign_error: # change the status of this role_entity to invalid fields = {'status': 'invalid'} logic.updateEntityProperties(role_entity, fields) # redirect to the roles listing return http.HttpResponseRedirect(redirect) else: # show error to the user context['resign_error'] = ugettext(resign_error % params) # set the appropriate context context['entity'] = role_entity context['url_name'] = params['url_name'] context['cancel_redirect'] = redirect # get the manage template template = params['manage_template'] # return a proper response return responses.respond(request, template, context=context)
class View(survey_view.View): """View methods for the ProjectSurvey 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'] = org_app_logic new_params['name'] = "Org Application Survey" new_params['url_name'] = 'org_app' new_params['extra_dynaexclude'] = ['taking_access'] new_params['survey_take_form'] = OrgAppSurveyForm new_params['survey_record_form'] = OrgAppRecordForm new_params['extra_django_patterns'] = [ (r'^%(url_name)s/(?P<access_type>list_self)/%(key_fields)s$', '%(module_package)s.%(module_name)s.list_self', 'Overview of %(name_plural)s Taken by You'), (r'^%(url_name)s/(?P<access_type>review)/%(key_fields)s$', '%(module_package)s.%(module_name)s.review', 'Review %(name)s from '), (r'^%(url_name)s/(?P<access_type>review_overview)/%(key_fields)s$', '%(module_package)s.%(module_name)s.review_overview', 'Overview of %(name_plural)s for Review') ] new_params['review_template'] = 'soc/org_app_survey/review.html' new_params['successful_take_message'] = ugettext( 'Organization Application submitted.') params = dicts.merge(params, new_params, sub_merge=True) super(View, self).__init__(params=params) # create the form to review an Organization Application dynaproperties = { 'status': forms.fields.ChoiceField(required=True, label='New Status', choices=[ ('accepted', 'Accept'), ('pre-accepted', 'Pre-Accept'), ('rejected', 'Reject'), ('pre-rejected', 'Pre-Reject'), ('ignored', 'Ignore'), ]) } review_form = dynaform.newDynaForm( dynabase=self._params['dynabase'], dynaproperties=dynaproperties, ) self._params['review_form'] = review_form # define the params for the OrgAppSurveyRecord listing record_list_params = {} record_list_params['logic'] = self._params['logic'].getRecordLogic() record_list_params['js_uses_all'] = self._params['js_uses_all'] record_list_params['list_template'] = self._params['list_template'] # define the fields for the public list record_list_params['public_field_keys'] = ['name', 'home_page'] record_list_params['public_field_names'] = ['Name', 'Home Page'] record_list_params['public_field_extra'] = lambda entity: { 'home_page': lists.urlize(entity.home_page, 'Click Here'), } # define the fields for the self list record_list_params['self_field_keys'] = [ 'name', 'main_admin', 'backup_admin' ] record_list_params['self_field_names'] = [ 'Organization Name', 'Main Admin', 'Backup Admin' ] record_list_params['self_field_prefetch'] = [ 'main_admin', 'backup_admin' ] record_list_params['self_field_extra'] = lambda entity: { 'main_admin': entity.main_admin.name, 'backup_admin': entity.backup_admin.name } record_list_params['self_row_action'] = { "type": "redirect_custom", "parameters": dict(new_window=False), } self._params['record_list_params'] = record_list_params @decorators.check_access def create(self, request, access_type, page_name=None, params=None, **kwargs): """Displays the create page for this entity type. If an OrgAppSurvey already exists it will redirect to the edit page. """ params = dicts.merge(params, self._params) program_view = params['scope_view'] program_logic = program_view.getParams()['logic'] program_entity = program_logic.getFromKeyName(kwargs['scope_path']) org_app = org_app_logic.getForProgram(program_entity) if org_app: # redirect to edit page return http.HttpResponseRedirect( redirects.getEditRedirect(org_app, params)) else: # show create page return super(View, self).create(request, access_type, page_name=page_name, params=params, **kwargs) def _getSurveyRecordFor(self, survey, request, params): """Returns the SurveyRecord for the given Survey and request. This method also take the ID specified as GET param into account when querying for the SurveyRecord. For params see survey.View._getSurveyRecordFor(). """ get_dict = request.GET record_id = get_dict.get('id', None) survey_logic = params['logic'] record_logic = survey_logic.getRecordLogic() if not record_id or not record_id.isdigit(): return None else: return record_logic.getFromIDOr404(int(record_id)) def _takeGet(self, request, template, context, params, entity, record, **kwargs): """Hooking into the view for the take's page GET request. For params see survey.View._takeGet(). """ # the form action should contain the requested record if record: context['form_action'] = "?id=%s" % (request.GET['id']) def _takePost(self, request, params, entity, record, properties): """Hook into the view for the take's page POST request. For params see survey.View._takePost(). """ from soc.logic.models.user import logic as user_logic if not record: # creating a new record user_entity = user_logic.getCurrentUser() properties['main_admin'] = user_entity if properties['agreed_to_tos']: properties['agreed_to_admin_agreement'] = True # remove fields we don't need to store in the SurveyRecord properties.pop('tos') properties.pop('agreed_to_tos') def _getRedirectOnSuccessfulTake(self, request, params, survey, record): """Returns a path to which the user should be redirected after successfully taking a OrgAppSurvey. """ new_params = params['take_params'] new_params['id'] = str(record.key().id_or_name()) return requests.replaceSuffix(request.path, None, params=new_params) @decorators.merge_params @decorators.check_access def listSelf(self, request, access_type, page_name=None, params=None, **kwargs): """View that lists all the OrgAppRecords you have access to. For Args see base.View().public(). """ survey_logic = params['logic'] entity = survey_logic.getFromKeyFieldsOr404(kwargs) list_params = params['record_list_params'].copy() if timeline_helper.isActivePeriod(entity, 'survey'): info = {'url_name': params['url_name'], 'survey': entity} list_params['self_row_extra'] = lambda entity: { 'link': redirects.getRetakeOrgAppSurveyRedirect(entity, info) } else: list_params['self_row_extra'] = lambda entity: { 'link': redirects.getViewSurveyRecordRedirect(entity, params) } ma_params = list_params.copy() ma_params['list_description'] = \ 'List of Applications for which you are Main Admin.' ba_params = list_params.copy() ba_params['list_description'] = \ 'List of Applications for which your are Backup Admin.' if lists.isDataRequest(request): return self._getListSelfData(request, entity, ma_params, ba_params) ma_list = lists.getListGenerator(request, ma_params, visibility='self', idx=0) ba_list = lists.getListGenerator(request, ba_params, visibility='self', idx=1) contents = [ma_list, ba_list] return self._list(request, list_params, contents, page_name) def _getListSelfData(self, request, entity, ma_params, ba_params): """Returns the listSelf data. """ from soc.logic.models.user import logic as user_logic user_entity = user_logic.getCurrentUser() idx = lists.getListIndex(request) if idx == 0: fields = {'survey': entity, 'main_admin': user_entity} params = ma_params elif idx == 1: fields = {'survey': entity, 'backup_admin': user_entity} params = ba_params else: return lists.getErrorResponse(request, "idx not valid") contents = lists.getListData(request, params, fields, visibility='self') return lists.getResponse(request, contents) def processSaveReview(self, json): """Processes a save request from the reviewOverview page. """ data = simplejson.loads(json) records = [] for record_id, update in data.iteritems(): if not record_id.isnumeric(): logging.error("Non-numeric record_id %s in %s", record_id, json) continue record = org_app_record.OrgAppRecord.get_by_id(int(record_id)) if not record: logging.error("No record for id %s in %s", record_id, json) continue new_value = update.get('status', '').lower() if not new_value in org_app_record.OrgAppRecord.status.choices: logging.error("Invalid new value for id %s in %s", new_value, json) continue record.status = new_value records.append(record) db.put(records) @decorators.merge_params @decorators.check_access def reviewOverview(self, request, access_type, page_name=None, params=None, **kwargs): """Displays a list of applications that are in a different status of the application process. """ survey_logic = params['logic'] entity = survey_logic.getFromKeyFieldsOr404(kwargs) if request.POST: # POST request received, check and respond to button actions post_dict = request.POST if post_dict.get('button_id') == 'bulk_process': params['bulk_process_task'].start(entity.scope) if post_dict.get( 'button_id') == 'save_status' and 'data' in request.POST: self.processSaveReview(request.POST['data']) return http.HttpResponse() list_params = params['record_list_params'].copy() list_params['list_description'] = ( 'List of all the Organization Applications made to the %s program. ' 'Click an application to review it, or use the buttons on the top of ' 'the list for bulk actions.' % (entity.scope.name)) info = {'url_name': params['url_name'], 'survey': entity} choices = org_app_record.OrgAppRecord.status.choices values = ";".join("%s:%s" % (i, i.capitalize()) for i in choices) list_params['overview_field_props'] = { 'status': { 'editable': True, 'edittype': "select", 'editoptions': { 'value': values } } } # define the basic fields for the overview list list_params['overview_field_keys'] = [ 'name', 'home_page', 'details', 'status', ] list_params['overview_field_names'] = [ 'Organization Name', 'Home Page', 'Details', 'Application Status', ] list_params['overview_field_extra'] = lambda entity: { 'home_page': lists.urlize(entity.home_page), 'status': entity.status.capitalize(), 'details': lists.urlize(redirects.getReviewOrgAppSurvey(entity, info), name="[details]"), } list_params['overview_button_global'] = [ { 'bounds': [0, 'all'], 'id': 'bulk_process', 'caption': 'Bulk Accept/Reject Organizations', 'type': 'post', 'parameters': { 'url': '' }, }, { 'id': 'save_status', 'caption': 'Save status', 'type': 'post_edit', 'parameters': { 'url': '', 'keys': ['key'], 'refresh': 'current', }, }, ] list_params['overview_row_action'] = { "type": "redirect_custom", "parameters": dict(new_window=False), } self._extendListWithSurveyAnswers(list_params, entity, 'overview') if lists.isDataRequest(request): # get all records for the entity specified in the URL fields = {'survey': entity} # use the overview visibility to show the correct columns to the Host contents = lists.getListData(request, list_params, fields, visibility='overview') return lists.getResponse(request, contents) overview_list = lists.getListGenerator(request, list_params, visibility='overview', idx=0) contents = [overview_list] return self._list(request, list_params, contents, page_name) @decorators.merge_params @decorators.check_access def review(self, request, access_type, page_name=None, params=None, **kwargs): """View that lists a OrgAppSurveyRecord to be reviewed. For Args see base.View().public(). """ survey_logic = params['logic'] record_logic = survey_logic.getRecordLogic() try: survey_entity = survey_logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return responses.errorResponse(error, request, template=params['error_public']) get_dict = request.GET record_id = get_dict.get('id') if record_id and record_id.isdigit(): record_id = int(record_id) record_entity = record_logic.getFromIDOr404(record_id) else: raise out_of_band.Error('No valid Record ID given') if record_entity.survey.key() != survey_entity.key(): # record does not match the retrieved survey raise out_of_band.Error( 'Record ID does not match the given survey') # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = '%s %s' % (page_name, record_entity.name) context['entity'] = survey_entity context['record'] = record_entity # store the read only survey form in the context survey_form = params['survey_record_form']( survey=survey_entity, survey_record=record_entity, survey_logic=self._params['logic'], read_only=True) survey_form.getFields() context['survey_form'] = survey_form if request.POST: return self.reviewPost(request, params, context, survey_entity, record_entity) else: return self.reviewGet(request, params, context, survey_entity, record_entity)
class View(survey_view.View): """View methods for the ProjectSurvey 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'] = org_app_logic new_params['name'] = "Org Application Survey" new_params['url_name'] = 'org_app' new_params['extra_dynaexclude'] = ['taking_access'] new_params['survey_take_form'] = OrgAppSurveyForm new_params['survey_record_form'] = OrgAppRecordForm new_params['extra_django_patterns'] = [ (r'^%(url_name)s/(?P<access_type>list_self)/%(key_fields)s$', '%(module_package)s.%(module_name)s.list_self', 'Overview of %(name_plural)s Taken by You'), ] params = dicts.merge(params, new_params, sub_merge=True) super(View, self).__init__(params=params) @decorators.check_access def create(self, request, access_type, page_name=None, params=None, **kwargs): """Displays the create page for this entity type. If an OrgAppSurvey already exists it will redirect to the edit page. """ params = dicts.merge(params, self._params) program_view = params['scope_view'] program_logic = program_view.getParams()['logic'] program_entity = program_logic.getFromKeyName(kwargs['scope_path']) org_app = org_app_logic.getForProgram(program_entity) if org_app: # redirect to edit page return http.HttpResponseRedirect( redirects.getEditRedirect(org_app, params)) else: # show create page return super(View, self).create(request, access_type, page_name=page_name, params=params, **kwargs) def _getSurveyRecordFor(self, survey, request, params): """Returns the SurveyRecord for the given Survey and request. This method also take the ID specified as GET param into account when querying for the SurveyRecord. For params see survey.View._getSurveyRecordFor(). """ get_dict = request.GET record_id = get_dict.get('id', None) survey_logic = params['logic'] record_logic = survey_logic.getRecordLogic() if not record_id or not record_id.isdigit(): return None else: return record_logic.getFromIDOr404(int(record_id)) def _takeGet(self, request, template, context, params, entity, record, **kwargs): """Hooking into the view for the take's page GET request. For params see survey.View._takeGet(). """ # the form action should contain the requested record if record: context['form_action'] = "?id=%s" % (request.GET['id']) def _takePost(self, request, params, entity, record, properties): """Hook into the view for the take's page POST request. For params see survey.View._takePost(). """ from soc.logic.models.user import logic as user_logic if not record: # creating a new record user_entity = user_logic.getForCurrentAccount() properties['main_admin'] = user_entity if properties['agreed_to_tos']: properties['agreed_to_admin_agreement'] = True # remove fields we don't need to store in the SurveyRecord properties.pop('tos') properties.pop('agreed_to_tos') def _getRedirectOnSuccessfulTake(self, request, params, survey, record): """Returns a path to which the user should be redirected after successfully taking a OrgAppSurvey. """ return request.path + '?id=' + str(record.key().id_or_name()) @decorators.merge_params @decorators.check_access def list_self(self, request, access_type, page_name=None, params=None, **kwargs): """View that lists all the OrgRecords you have access to. For Args see base.View().public(). """ from soc.logic.models.user import logic as user_logic survey_logic = params['logic'] record_logic = survey_logic.getRecordLogic() try: entity = survey_logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return 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['entity'] = entity list_contents = [] user_entity = user_logic.getForCurrentAccount() list_params = params.copy() list_params['logic'] = record_logic list_params[ 'list_heading'] = 'soc/org_app_survey/list/records_heading.html' list_params['list_row'] = 'soc/org_app_survey/list/records_row.html' if timeline_helper.isActivePeriod(entity, 'survey'): info = {'url_name': list_params['url_name'], 'survey': entity} list_params['public_row_extra'] = lambda entity: { 'link': redirects.getRetakeOrgAppSurveyRedirect(entity, info) } else: list_params['public_row_extra'] = lambda entity: { 'link': redirects.getViewSurveyRecordRedirect( entity, list_params) } fields = {'survey': entity, 'main_admin': user_entity} list_params['list_description'] = \ 'List of Applications for which you are Main Admin.' main_list = lists.getListContent(request, list_params, fields, need_content=True, idx=0) # TODO(LIST) if main_list: list_contents.append(main_list) fields = {'survey': entity, 'backup_admin': user_entity} list_params['list_description'] = \ 'List of Applications for which your are Backup Admin.' backup_list = lists.getListContent(request, list_params, fields, need_content=True, idx=1) if backup_list: list_contents.append(backup_list) return self._list(request, list_params, list_contents, page_name, context)
def manage(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Organization Admins to manage their Student Projects. For params see base.View().public() """ import soc.logic.lists from soc.modules.gsoc.views.models.grading_project_survey import view as \ grading_survey_view from soc.modules.gsoc.views.models.project_survey import view as \ project_survey_view entity = self._logic.getFromKeyFieldsOr404(kwargs) template = params['manage_template'] # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = "%s '%s' from %s" % (page_name, entity.title, entity.student.name()) context['entity'] = entity if project_logic.canChangeMentors(entity): # only accepted project can have their mentors managed self._enableMentorManagement(entity, params, context) # list all surveys for this Project's Program gps_params = grading_survey_view.getParams().copy() gps_params['list_description'] = \ 'List of all Mentor Evaluations for this Project' gps_params['public_row_extra'] = lambda entity, *args: {} gps_params['public_row_action'] = {} gps_params['public_field_keys'] = [ "title", "taken_by", "taken_on", "record_url", "take_url" ] gps_params['public_field_names'] = [ "Title", "Taken by", "Taken on", "View", "(Re) Take", ] no_record = self.DEF_NO_RECORD_AVAILABLE_MSG # TODO(SRabbelier): use buttons instead project_entity = entity getExtra = lambda params: lambda entity, re: { "taken_by": no_record if not re(entity) else re(entity).user.name, "taken_on": no_record if not re(entity) else str(re(entity).modified), "record_url": no_record if not re(entity) else lists.urlize( redirects.getViewSurveyRecordRedirect(re(entity), params), name=self.DEF_VIEW_RECORD_MSG), "take_url": lists.urlize(redirects.getTakeProjectSurveyRedirect( project_entity, {'survey': entity, 'params': params}), name=self.DEF_TAKE_SURVEY_MSG), } gps_params['public_field_extra'] = getExtra(gps_params) # get the ProjectSurvey list ps_params = project_survey_view.getParams().copy() ps_params['list_description'] = \ 'List of all Student Evaluations for this Project' ps_params['public_row_extra'] = lambda entity, *args: {} ps_params['public_row_action'] = {} ps_params['public_field_keys'] = gps_params['public_field_keys'] ps_params['public_field_names'] = gps_params['public_field_names'] ps_params['public_field_ignore'] = ["take_url"] ps_params['public_field_extra'] = getExtra(ps_params) if lists.isDataRequest(request): return self._getManageData(request, gps_params, ps_params, entity) gps_list = lists.getListGenerator(request, gps_params, idx=0) ps_list = lists.getListGenerator(request, ps_params, idx=1) # store both lists in the content content = [gps_list, ps_list] context['evaluation_list'] = soc.logic.lists.Lists(content) if request.POST: return self.managePost(request, template, context, params, entity, **kwargs) else: #request.GET return self.manageGet(request, template, context, params, entity, **kwargs)
def manageOverview(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows Organization Admins to see an overview of their Organization's Student Projects. For params see base.View().public() """ # make sure the organization exists org_entity = org_logic.getFromKeyNameOr404(kwargs['scope_path']) fields = {'scope': org_entity} # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = '%s %s' % (page_name, org_entity.name) list_params = params.copy() #list all active projects fields['status'] = ['accepted', 'mid_term_passed'] active_params = list_params.copy() active_params['list_description'] = \ 'List of all active %(name_plural)s' % list_params active_params['list_action'] = (redirects.getManageRedirect, list_params) active_list = lists.getListContent( request, active_params, fields, idx=0) # list all failed projects fields['status'] = ['mid_term_failed', 'final_failed'] failed_params = list_params.copy() failed_params['list_description'] = ('List of all failed %(name_plural)s, ' 'these cannot be managed.') % list_params failed_params['list_action'] = (redirects.getPublicRedirect, list_params) failed_list = lists.getListContent( request, failed_params, fields, idx=1, need_content=True) #list all completed projects fields['status'] = ['passed'] completed_params = list_params.copy() completed_params['list_description'] = ('List of %(name_plural)s that have ' 'successfully completed the program, ' 'these cannot be managed.' % list_params) completed_params['list_action'] = (redirects.getPublicRedirect, list_params) completed_list = lists.getListContent( request, completed_params, fields, idx=2, need_content=True) # always show the list with active projects content = [active_list] if failed_list != None: # do not show empty failed list content.append(failed_list) if completed_list != None: # do not show empty completed list content.append(completed_list) # call the _list method from base to display the list return self._list(request, list_params, content, context['page_name'], context)
@decorators.check_access def stEdit(self, request, access_type, page_name=None, params=None, **kwargs): """View that allows students to edit information about their project. For params see base.View().public() """ try: entity = self._logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return 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 # cancel should go to the public view params['edit_cancel_redirect'] = redirects.getPublicRedirect(entity, params) if request.POST: return self.stEditPost(request, context, params, entity, **kwargs) else: #request.GET return self.stEditGet(request, context, params, entity, **kwargs) def stEditGet(self, request, context, params, entity, **kwargs): """Handles the GET request for the student's edit page. Args: entity: the student project entity
class View(base.View): """View methods for the Survey 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['any_access'] = ['allow'] rights['show'] = [('checkIsSurveyWritable', survey_logic)] rights['create'] = ['checkIsUser'] rights['edit'] = [('checkIsSurveyWritable', survey_logic)] rights['delete'] = ['checkIsDeveloper' ] # TODO: fix deletion of Surveys rights['list'] = ['checkDocumentList'] rights['pick'] = ['checkDocumentPick'] rights['record'] = [('checkHasAny', [[ ('checkIsSurveyReadable', [survey_logic]), ('checkIsMySurveyRecord', [survey_logic, 'id']) ]])] rights['results'] = ['checkIsUser'] rights['take'] = [('checkIsSurveyTakeable', survey_logic)] new_params = {} new_params['logic'] = survey_logic new_params['rights'] = rights new_params['name'] = 'Survey' new_params['sidebar_grouping'] = "Surveys" new_params['extra_django_patterns'] = [ (r'^%(url_name)s/(?P<access_type>take)/%(key_fields)s$', '%(module_package)s.%(module_name)s.take', 'Take %(name)s'), (r'^%(url_name)s/(?P<access_type>json)/%(scope)s$', '%(module_package)s.%(module_name)s.json', 'Export %(name)s as JSON'), (r'^%(url_name)s/(?P<access_type>record)/%(key_fields)s$', '%(module_package)s.%(module_name)s.record', 'View survey record for %(name)s'), (r'^%(url_name)s/(?P<access_type>results)/%(key_fields)s$', '%(module_package)s.%(module_name)s.results', 'View survey results for %(name)s'), (r'^%(url_name)s/(?P<access_type>show)/user/(?P<link_id>)\w+$', '%(module_package)s.%(module_name)s.results', 'View survey results for user'), ] new_params['export_content_type'] = 'text/text' new_params['export_extension'] = '.csv' new_params['export_function'] = surveys.toCSV(self) new_params['delete_redirect'] = '/' new_params['edit_template'] = 'soc/survey/edit.html' new_params['create_template'] = 'soc/survey/edit.html' new_params['public_template'] = 'soc/survey/public.html' new_params['record_template'] = 'soc/survey/view_record.html' new_params['take_template'] = 'soc/survey/take.html' new_params['no_create_raw'] = True new_params['no_create_with_scope'] = True new_params['no_create_with_key_fields'] = True new_params['no_list_raw'] = True new_params['sans_link_id_create'] = True new_params['sans_link_id_list'] = True new_params['create_dynafields'] = [ { 'name': 'link_id', 'base': forms.fields.CharField, 'label': 'Survey Link ID', }, ] new_params['create_extra_dynaproperties'] = { 'content': forms.fields.CharField(required=False, label='Description', widget=widgets.FullTinyMCE(attrs={ 'rows': 25, 'cols': 100 })), 'survey_html': forms.fields.CharField(widget=forms.HiddenInput, required=False), 'scope_path': forms.fields.CharField(widget=forms.HiddenInput, required=True), 'prefix': forms.fields.CharField(widget=widgets.ReadOnlyInput(), required=True), 'clean_content': cleaning.clean_html_content('content'), 'clean_link_id': cleaning.clean_link_id('link_id'), 'clean_scope_path': cleaning.clean_scope_path('scope_path'), 'clean': cleaning.validate_document_acl(self, True), } new_params['extra_dynaexclude'] = [ 'author', 'created', 'home_for', 'modified_by', 'modified', 'take_survey', 'survey_content' ] new_params['edit_extra_dynaproperties'] = { 'doc_key_name': forms.fields.CharField(widget=forms.HiddenInput), 'created_by': forms.fields.CharField(widget=widgets.ReadOnlyInput(), required=False), 'last_modified_by': forms.fields.CharField(widget=widgets.ReadOnlyInput(), required=False), 'clean': cleaning.validate_document_acl(self), } new_params['survey_take_form'] = surveys.SurveyTakeForm new_params['survey_record_form'] = surveys.SurveyRecordForm new_params['public_field_prefetch'] = ['author'] new_params['public_field_extra'] = lambda entity: { "path": entity.scope_path + '/' + entity.link_id, "created_by": entity.author.link_id, } new_params['public_field_keys'] = [ "path", "title", "link_id", "is_featured", "created_by", "created", "modified" ] new_params['public_field_names'] = [ "Path", "Title", "Link ID", "Featured", "Created By", "Created On", "Modified", ] new_params['records_field_keys'] = ['taken_by', 'modified'] new_params['records_field_names'] = [ 'Taken By', 'Taken On', ] new_params['records_field_prefetch'] = ['user'] new_params['records_field_extra'] = lambda entity: { 'taken_by': '%s (%s)' % (entity.user.name, entity.user.link_id), } new_params['take_params'] = {'s': '0'} new_params['successful_take_message'] = ugettext( 'Survey record submitted.') params = dicts.merge(params, new_params, sub_merge=True) super(View, self).__init__(params=params) def list(self, request, access_type, page_name=None, params=None, filter=None, order=None, **kwargs): """See base.View.list. """ if not filter: filter = kwargs return super(View, self).list(request, access_type, page_name=page_name, params=params, filter=filter, **kwargs) def _public(self, request, entity, context): """Add a preview version of the Survey to the page's context. Args: request: the django request object entity: the entity to make public context: the context object """ # construct the form to be shown on the page # TODO(ljvderijk) Generate SurveyForm without passing along the logic survey_form = self._params['survey_take_form']( survey=entity, survey_logic=self._params['logic']) survey_form.getFields() context['survey_form'] = survey_form context['page_name'] = "%s titled '%s'" % (context['page_name'], entity.title) # return True to signal that the page may be displayed return True def _editPost(self, request, entity, fields): """See base.View._editPost(). Processes POST request items to add new dynamic field names, question types, and default prompt values to SurveyContent model. """ user = user_logic.getCurrentUser() schema = {} survey_fields = {} if not entity: # new Survey if 'serialized' in request.POST: fields, schema, survey_fields = self.importSerialized( request, fields, user) fields['author'] = user else: fields['author'] = entity.author schema = self.loadSurveyContent(schema, survey_fields, entity) # remove deleted properties from the model self.deleteQuestions(schema, survey_fields, request.POST) # add new text questions and re-build choice questions self.getRequestQuestions(schema, survey_fields, request.POST) # get schema options for choice questions self.getSchemaOptions(schema, survey_fields, request.POST) survey_content = getattr(entity, 'survey_content', None) # create or update a SurveyContent for this Survey survey_content = survey_logic.createSurvey( survey_fields, schema, survey_content=survey_content) # save survey_content for existent survey or pass for creating a new one if entity: entity.modified_by = user entity.survey_content = survey_content db.put(entity) else: fields['survey_content'] = survey_content fields['modified_by'] = user super(View, self)._editPost(request, entity, fields) def loadSurveyContent(self, schema, survey_fields, entity): """Populate the schema dict and get text survey questions. """ if hasattr(entity, 'survey_content'): # there is a SurveyContent already survey_content = entity.survey_content schema = eval(survey_content.schema) for question_name in survey_content.dynamic_properties(): # get the current questions from the SurveyContent if question_name not in schema: continue if schema[question_name]['type'] not in DEF_CHOICE_TYPES: # Choice questions are always regenerated from request, see # self.get_request_questions() question = getattr(survey_content, question_name) survey_fields[question_name] = question return schema def deleteQuestions(self, schema, survey_fields, POST): """Process the list of questions to delete, from a hidden input. """ deleted = POST.get('__deleted__', '') if deleted: deleted = deleted.split(',') for field in deleted: if field in schema: del schema[field] if field in survey_fields: del survey_fields[field] def getRequestQuestions(self, schema, survey_fields, POST): """Get fields from request. We use two field/question naming and processing schemes: - Choice questions consist of <input/>s with a common name, being rebuilt anew on every edit POST so we can gather ordering, text changes, deletions and additions. - Text questions only have special survey__* names on creation, afterwards they are loaded from the SurveyContent dynamic properties. """ for key, value in POST.items(): if key.startswith('id_'): # Choice question fields, they are always generated from POST contents, # as their 'content' is editable and they're reorderable. Also get # its field index for handling reordering fields later. name, number = key[3:].replace('__field', '').rsplit('_', 1) if name not in schema: if 'NEW_' + name in POST: # new Choice question, set generic type and get its index schema[name] = {'type': 'choice'} if name in schema and schema[name]['type'] in DEF_CHOICE_TYPES: # build an index:content dictionary if name in survey_fields: if value not in survey_fields[name]: survey_fields[name][int(number)] = value else: survey_fields[name] = {int(number): value} elif key.startswith('survey__'): # Text question # this is super ugly but unless data is serialized the regex is needed prefix = re.compile('survey__([0-9]{1,3})__') prefix_match = re.match(prefix, key) index = prefix_match.group(0).replace('survey', '').replace('__', '') index = int(index) field_name = prefix.sub('', key) field = 'id_' + key for ptype in DEF_PROPERTY_TYPES: # should only match one if ptype + "__" in field_name: field_name = field_name.replace(ptype + "__", "") if field_name not in schema: schema[field_name] = {} schema[field_name]["index"] = index schema[field_name]["type"] = ptype # store text question tooltip from the input/textarea value schema[field_name]["tip"] = value # add the question as a dynamic property to survey_content survey_fields[field_name] = value def getSchemaOptions(self, schema, survey_fields, POST): """Get question, type, rendering and option order for choice questions. """ RENDER = { 'checkboxes': 'multi_checkbox', 'select': 'single_select', 'radio_buttons': 'quant_radio' } RENDER_TYPES = { 'select': 'selection', 'checkboxes': 'pick_multi', 'radio_buttons': 'pick_quant' } for key in schema: if schema[key]['type'] in DEF_CHOICE_TYPES and key in survey_fields: render_for = 'render_for_' + key if render_for in POST: schema[key]['render'] = RENDER[POST[render_for]] schema[key]['type'] = RENDER_TYPES[POST[render_for]] # set the choice question's tooltip tip_for = 'tip_for_' + key schema[key]['tip'] = POST.get(tip_for) # handle reordering fields ordered = False order = 'order_for_' + key if order in POST and isinstance(survey_fields[key], dict): order = POST[order] # 'order_for_name' is jquery serialized from a sortable, so it's in # a 'name[]=1&name[]=2&name[]=0' format ('id-li-' is set in our JS) order = order.replace('id-li-%s[]=' % key, '') order = order.split('&') if len(order) == len(survey_fields[key]) and order[0]: order = [int(number) for number in order] if set(order) == set(survey_fields[key]): survey_fields[key] = [ survey_fields[key][i] for i in order ] ordered = True if not ordered: # we don't have a good ordering to use ordered = sorted(survey_fields[key].items()) survey_fields[key] = [ value for index, value in ordered ] # set 'question' entry (free text label for question) in schema question_for = 'NEW_' + key if question_for in POST and POST[question_for]: schema[key]["question"] = POST[question_for] # set wheter the question is required required_for = 'required_for_' + key schema[key]['required'] = DEF_BOOL[POST[required_for]] # set wheter the question allows comments comment_for = 'comment_for_' + key schema[key]['has_comment'] = DEF_BOOL[POST[comment_for]] # set the question index from JS-calculated value index_for = 'index_for_' + key if index_for in POST: schema[key]['index'] = int(POST[index_for].replace('__', '')) def createGet(self, request, context, params, seed): """Pass the question types for the survey creation template. """ context['question_types'] = DEF_QUESTION_TYPES # avoid spurious results from showing on creation context['new_survey'] = True return super(View, self).createGet(request, context, params, seed) def editGet(self, request, entity, context, params=None): """Process GET requests for the specified entity. Builds the SurveyForm that represents the Survey question contents. """ self._entity = entity survey_content = entity.survey_content survey_form = surveys.SurveyEditForm(survey_content=survey_content, survey_logic=params['logic']) survey_form.getFields() local = dict(survey_form=survey_form, question_types=DEF_QUESTION_TYPES, survey_h=entity.survey_content) context.update(local) params['edit_form'] = surveys.HelperForm(params['edit_form']) if entity.survey_end and datetime.datetime.now() > entity.survey_end: # are we already passed the survey_end? context["passed_survey_end"] = True return super(View, self).editGet(request, entity, context, params=params) @decorators.merge_params @decorators.check_access def take(self, request, access_type, page_name=None, params=None, **kwargs): """View for taking a Survey. For Args see base.View().public(). """ survey_logic = params['logic'] try: entity = survey_logic.getFromKeyFieldsOr404(kwargs) except out_of_band.Error, error: return responses.errorResponse(error, request, template=params['error_public']) template = params['take_template'] # get the context for this webpage context = responses.getUniversalContext(request) responses.useJavaScript(context, params['js_uses_all']) context['page_name'] = "%s titled '%s'" % (page_name, entity.title) context['entity'] = entity # try to get an existing SurveyRecord for the current user survey_record = self._getSurveyRecordFor(entity, request, params) post_dict = request.POST # get an instance of SurveyTakeForm to use survey_form = params['survey_take_form'](survey=entity, survey_record=survey_record, survey_logic=params['logic'], data=post_dict) # fill context with the survey_form and additional information context['survey_form'] = survey_form self._setSurveyTakeContext(request, params, context, entity, survey_record) if request.POST: return self.takePost(request, template, context, params, survey_form, entity, survey_record, **kwargs) else: #request.GET return self.takeGet(request, template, context, params, survey_form, entity, survey_record, **kwargs)