def toggleFeatured(self, data, value): """Makes the project featured. Args: data: A RequestData describing the current request. value: can be either "checked" or "unchecked". """ if value != 'checked' and value != 'unchecked': raise exception.BadRequest(message="Invalid post data.") if value == 'checked' and not data.url_project.is_featured: raise exception.BadRequest(message="Invalid post data.") if value == 'unchecked' and data.url_project.is_featured: raise exception.BadRequest(message="Invalid post data.") project_key = data.url_project.key() def make_featured_txn(): # transactionally get latest version of the project project = db.get(project_key) if value == 'unchecked': project.is_featured = True elif value == 'checked': project.is_featured = False db.put(project) db.run_in_transaction(make_featured_txn)
def post(self): """Processes the form post data by checking what buttons were pressed.""" idx = lists.getListIndex(self.data.request) if idx != self.IDX: return None data = self.data.POST.get('data') if not data: raise exception.BadRequest(message='Missing data') parsed = json.loads(data) button_id = self.data.POST.get('button_id') if not button_id: raise exception.BadRequest(message='Missing button_id') if button_id == self.PUBLISH_BUTTON_ID: return self.postPublish(parsed, True) if button_id == self.UNPUBLISH_BUTTON_ID: return self.postPublish(parsed, False) raise exception.BadRequest(message="Unknown button_id")
def toggleStatus(self, data, value): """Toggles the the application state between accept and pending. Args: data: A RequestData describing the current request. value: can be either "checked" or "unchecked". """ if value != 'checked' and value != 'unchecked': raise exception.BadRequest(message="Invalid post data.") if value == 'checked' and not data.url_proposal.accept_as_project: raise exception.BadRequest(message="Invalid post data.") if value == 'unchecked' and data.url_proposal.accept_as_project: raise exception.BadRequest(message="Invalid post data.") proposal_key = data.url_proposal.key() def update_status_txn(): # transactionally get latest version of the proposal proposal = db.get(proposal_key) if value == 'unchecked': proposal.accept_as_project = True elif value == 'checked': proposal.accept_as_project = False db.put(proposal) db.run_in_transaction(update_status_txn)
def togglePublicVisibilty(self, data, value): """Toggles the the public visibility of the application. Args: data: A RequestData describing the current request. value: can be either "checked" or "unchecked". """ if value != 'checked' and value != 'unchecked': raise exception.BadRequest(message="Invalid post data.") if value == 'checked' and not data.url_proposal.is_publicly_visible: raise exception.BadRequest(message="Invalid post data.") if value == 'unchecked' and data.url_proposal.is_publicly_visible: raise exception.BadRequest(message="Invalid post data.") def update_publicly_visibility_txn(): # transactionally get latest version of the proposal proposal = db.get(data.url_proposal.key()) if value == 'unchecked': proposal.is_publicly_visible = True elif value == 'checked': proposal.is_publicly_visible = False db.put(proposal) db.run_in_transaction(update_publicly_visibility_txn)
def toggleModificationPermission(self, data, value): """Toggles the permission to modify the proposal after proposal deadline. Args: data: A RequestData describing the current request. value: can be either "checked" or "unchecked". """ if value != 'checked' and value != 'unchecked': raise exception.BadRequest(message="Invalid post data.") if value == 'checked' and not data.url_proposal.is_editable_post_deadline: raise exception.BadRequest(message="Invalid post data.") if value == 'unchecked' and data.url_proposal.is_editable_post_deadline: raise exception.BadRequest(message="Invalid post data.") proposal_key = data.url_proposal.key() def update_modification_perm_txn(): # transactionally get latest version of the proposal proposal = db.get(proposal_key) if value == 'unchecked': proposal.is_editable_post_deadline = True elif value == 'checked': proposal.is_editable_post_deadline = False db.put(proposal) db.run_in_transaction(update_modification_perm_txn)
def document(self): """Returns document property.""" if not self._isSet(self._document): fields = [] kwargs = self.kwargs.copy() prefix = kwargs.pop('prefix', None) fields.append(prefix) if prefix in ['gsoc_program', 'gsoc_org', 'gci_program', 'gci_org']: fields.append(kwargs.pop('sponsor', None)) fields.append(kwargs.pop('program', None)) if prefix in ['gsoc_org', 'gci_org']: fields.append(kwargs.pop('organization', None)) fields.append(kwargs.pop('document', None)) if any(kwargs.values()): raise exception.BadRequest(message="Unexpected value for document url") if not all(fields): raise exception.BadRequest(message="Missing value for document url") # TODO(daniel): remove key_name from it. self.key_name = '/'.join(fields) self._document = document_model.Document.get_by_key_name(self.key_name) return self._document
def post(self, data, check, mutator): """See base.RequestHandler.post for specification.""" form = _formToCreateOrgProfile(request_data=data, data=data.POST) if not form.is_valid(): # TODO(nathaniel): problematic self-use. return self.get(data, check, mutator) else: contact_properties = form.getContactProperties() result = contact_logic.createContact(**contact_properties) if not result: raise exception.BadRequest(message=result.extra) else: org_properties = form.getOrgProperties() org_properties['contact'] = result.extra # org_id is a special property org_id = org_properties['org_id'] del org_properties['org_id'] result = createOrganizationTxn( data, org_id, data.program.key(), org_properties, [data.ndb_profile.key, form.cleaned_data['backup_admin'].key], data.models) if not result: raise exception.BadRequest(message=result.extra) else: url = links.LINKER.organization( result.extra.key, urls.UrlNames.ORG_APPLICATION_SUBMIT) return http.HttpResponseRedirect(url)
def toggleIgnoreProposal(self, data, value): """Toggles the ignore status of the proposal. Args: data: A RequestData describing the current request. value: can be either "checked" or "unchecked". """ if value != 'checked' and value != 'unchecked': raise exception.BadRequest(message="Invalid post data.") if value == 'checked' and data.url_proposal.status != 'ignored': raise exception.BadRequest(message="Invalid post data.") if value == 'unchecked' and data.url_proposal.status not in [ 'pending', 'withdrawn' ]: raise exception.BadRequest(message="Invalid post data.") proposal_key = data.url_proposal.key() def update_status_txn(): # transactionally get latest version of the proposal proposal = db.get(proposal_key) if value == 'unchecked': proposal.status = 'ignored' elif value == 'checked': proposal.status = 'pending' db.put(proposal) db.run_in_transaction(update_status_txn)
def post(self, data, check, mutator): """See base.GSoCRequestHandler.post for specification.""" button_id = data.POST.get('button_id') if button_id is not None: if button_id == _SET_STATUS_BUTTON_ID: handler = SetOrganizationStatusHandler(self) return handler.handle(data, check, mutator) elif button_id == _APPLY_ORG_ADMISSION_DECISION_ID: handler = ApplyOrgAdmissionDecisionHandler(self) return handler.handle(data, check, mutator) else: raise exception.BadRequest( message='Button id %s not supported.' % button_id) else: raise exception.BadRequest(message='Invalid POST data.')
def post(self, data, check, mutator): """See base.post for specification.""" profile_key = ndb.Key.from_old_key(data.url_project.parent_key()) # get type of survey based on submitted form name survey_type = _getSurveyType(data.POST) survey_key = project_survey_logic.constructEvaluationKey( data.program.key(), survey_type) # check if the survey exists if not db.get(survey_key): raise exception.BadRequest(message='Survey of type %s not found.' % survey_type) # try setting a personal extension form = PersonalExtensionForm(data=data.POST) result = _setPersonalExtension(profile_key, survey_key, form) if result: # redirect to somewhere url = links.LINKER.userId(data.url_ndb_profile.key, data.url_project.key().id(), urls.UrlNames.PROJECT_MANAGE_ADMIN) # TODO(daniel): append GET parameter in a better way url = url + '?validated' return http.HttpResponseRedirect(url) else: # TODO(nathaniel): problematic self-use. return self.get(data, check, mutator)
def url_ndb_org(self): """Returns url_org property. This property represents organization entity whose identifier is a part of the URL of the processed request. Returns: Retrieved organization entity. Raises: exception.BadRequest: if the current request does not contain any organization data. exception.NotFound: if the organization is not found. """ if not self._isSet(self._url_ndb_org): try: fields = ['sponsor', 'program', 'organization'] entity_id = '/'.join(self.kwargs[i] for i in fields) except KeyError: raise exception.BadRequest( message='The request does not contain full organization data.') self._url_ndb_org = self.models.ndb_org_model.get_by_id(entity_id) if not self._url_ndb_org: raise exception.NotFound( message='Requested organization does not exist.') return self._url_ndb_org
def url_proposal(self): """Returns the url_proposal field. This property represents a proposal entity corresponding to a profile whose identifier is a part of the URL of the processed request. Numerical identifier of the proposal is also a part of the URL. Returns: Retrieved proposal entity. Raises: exception.BadRequest: if some data is missing in the current request. exception.NotFound: if no entity is found. """ if not self._isSet(self._url_proposal): if 'id' not in self.kwargs: raise exception.BadRequest( message='The request does not contain proposal id.') else: self._url_proposal = proposal_model.GSoCProposal.get_by_id( int(self.kwargs['id']), self.url_ndb_profile.key.to_old_key()) if not self._url_proposal: raise exception.NotFound( message='Requested proposal does not exist.') return self._url_proposal
def url_connection(self): """Returns url_connection property. This property represents connection entity corresponding to profile whose identifier is a part of the URL of the processed request. Numerical identifier of the connection is also a part of the URL. Returns: Retrieved connection entity. Raises: exception.BadRequest: if some data is missing in the current request. exception.NotFound: if no entity is found. """ if not self._isSet(self._url_connection): try: connection_key = ndb.Key( connection_model.Connection._get_kind(), int(self.kwargs['id']), parent=self._getUrlNdbProfileKey()) except KeyError: raise exception.BadRequest( message='The request does not contain connection id.') self._url_connection = connection_key.get() if not self._url_connection: raise exception.NotFound( message='Requested connection does not exist.') return self._url_connection
def jsonContext(self, data, check, mutator): list_content = SlotsList(data).getListData() if list_content: return list_content.content() else: raise exception.BadRequest( message='Missing idx parameter for component.')
def url_ndb_user(self): """Returns url_user property. This property represents user entity for a person whose identifier is a part of the URL of the processed request. Returns: Retrieved user entity. Raises: exception.BadRequest: if the current request does not contain any user data. exception.NotFound: if the user is not found. """ if not self._isSet(self._url_ndb_user): key_id = self.kwargs.get('user') if not key_id: raise exception.BadRequest( message='The request does not contain user data.') self._url_ndb_user = self.models.user_model.get_by_id(key_id) if not self._url_ndb_user: raise exception.NotFound(message='Requested user does not exist.') return self._url_ndb_user
def jsonContext(self, data, check, mutator): """See base.GSoCRequestHandler.jsonContext for specification.""" idx = lists.getListIndex(data.request) if idx == 0: list_data = OrgApplicationList(data, data.org_app).getListData() return list_data.content() else: raise exception.BadRequest(message='Invalid ID has been specified.')
def post(self, data, check, mutator): """Edits records from commands received by the list code.""" post_dict = data.request.POST data.redirect.program() if (post_dict.get('process', '') == org_app.PROCESS_ORG_APPS_FORM_BUTTON_VALUE): mapreduce_control.start_map( 'ProcessOrgApp', { 'program_type': 'gsoc', 'program_key': data.program.key().name() }) return data.redirect.to('gsoc_list_org_app_records', validated=True) if post_dict.get('button_id', None) != 'save': raise exception.BadRequest(message='No valid POST data found') post_data = post_dict.get('data') if not post_data: raise exception.BadRequest(message='Missing data') parsed = json.loads(post_data) url = 'TODO(daniel): remove this part as it is not used anymore' for oaid, properties in parsed.iteritems(): record = OrgAppRecord.get_by_id(long(oaid)) if not record: logging.warning('%s is an invalid OrgAppRecord ID', oaid) continue if record.survey.key() != data.org_app.key(): logging.warning( '%s is not a record for the Org App in the URL', record.key()) continue new_status = properties['status'] org_app_logic.setStatus(data, record, new_status, url) return http.HttpResponse()
def createOrUpdateScore(self, data, value): """Creates a new score or updates a score if there is already one posted by the current user. If the value passed in is 0 then the Score of the user will be removed and None will be returned. Args: data: A RequestData describing the current request. value: The value of the score the user gave as an integer. Returns: The score entity that was created/updated or None if value is 0. """ org_key = proposal_model.GSoCProposal.org.get_value_for_datastore( data.url_proposal) org = ndb.Key.from_old_key(org_key).get() max_score = org.max_score if value < 0 or value > max_score: raise exception.BadRequest( message="Score must not be higher than %d" % max_score) query = db.Query(GSoCScore) query.filter('author = ', data.ndb_profile.key.to_old_key()) query.ancestor(data.url_proposal) def update_score_trx(): delta = 0 # update score entity score = query.get() if not score: if not value: return old_value = 0 score = GSoCScore(parent=data.url_proposal, author=data.ndb_profile.key.to_old_key(), value=value) score.put() delta = 1 else: old_value = score.value if not value: delta = -1 score.delete() else: score.value = value score.put() # update total score for the proposal proposal = db.get(data.url_proposal.key()) proposal.score += value - old_value proposal.nr_scores += delta proposal.put() db.run_in_transaction(update_score_trx)
def get(self, data, check, mutator): """Get handler for the code sample download file.""" assert isSet(data.url_project) try: id_value = int(data.request.GET['id']) code_sample = GSoCCodeSample.get_by_id(id_value, data.url_project) if not code_sample or not code_sample.upload_of_work: raise exception.BadRequest( message='Requested project or code sample not found') else: return bs_helper.sendBlob(code_sample.upload_of_work) except KeyError: raise exception.BadRequest( message='id argument missing in GET data') except ValueError: raise exception.BadRequest( message='id argument in GET data is not a number')
def post(self): idx = lists.getListIndex(self.data.request) if idx != 0: return None list_data = self.data.POST.get('data') if not list_data: raise exception.BadRequest(message="Missing data") button_id = self.data.POST.get('button_id') if button_id == 'accept': return self.postHandler(json.loads(list_data)) elif button_id: raise exception.BadRequest(message='Unknown button_id') else: raise exception.BadRequest(message="Missing button_id")
def toggleNotificationsEnabled(self, data, value): """Makes email notifications enabled or disabled. Args: data: A RequestData describing the current request. value: can be either "checked" or "unchecked". """ assert access_checker.isSet(data.conversation) assert access_checker.isSet(data.user) query = gciconversation_logic.queryConversationUserForConversationAndUser( data.conversation.key, ndb.Key.from_old_key(data.user.key())) conv_user_results = query.fetch(1) assert conv_user_results conv_user = conv_user_results[0] if value != 'checked' and value != 'unchecked': raise exception.BadRequest( message='Invalid post data. Value must be checked or unchecked.' ) if value == 'checked' and not conv_user.enable_notifications: raise exception.BadRequest( message='Notifications were already disabled.') if value == 'unchecked' and conv_user.enable_notifications: raise exception.BadRequest( message='Notifications were already enabled.') conv_user_key = conv_user.key # TODO(nathaniel): Remove the suppression on the following line when # https://bitbucket.org/logilab/pylint.org/issue/6/false-positive-no # is fixed. @ndb.transactional(xg=True) # pylint: disable=no-value-for-parameter def set_notifications_enabled_txn(): # transactionally get latest GCIConversationUser conv_user = conv_user_key.get() if value == 'unchecked': conv_user.enable_notifications = True elif value == 'checked': conv_user.enable_notifications = False conv_user.put() set_notifications_enabled_txn()
def checkAccess(self, data, check): """See AccessChecker.checkAccess for specification.""" key_id = data.kwargs.get('user') if not key_id: raise exception.BadRequest( 'The request does not contain user data.') ensureLoggedIn(data) if not data.ndb_user or data.ndb_user.key.id() != key_id: raise exception.Forbidden(message=_MESSAGE_NOT_USER_IN_URL)
def handle(self, data, check, mutator): """See form_handler.FormHandler.handle for specification.""" post_data = data.POST.get('data') if not post_data: raise exception.BadRequest(message='Missing data.') parsed_data = json.loads(post_data) for org_key_id, properties in parsed_data.iteritems(): org_key = ndb.Key( data.models.ndb_org_model._get_kind(), org_key_id) new_status = _STATUS_ID_TO_ENUM_MAP.get(properties.get('status')) if not new_status: raise exception.BadRequest( message='Missing or invalid new status in POST data.') else: organization = org_key.get() org_logic.setStatus(organization, data.program, data.site, data.program.getProgramMessages(), new_status) return http.HttpResponse()
def forUserId(user_id): """Retrieves the user entity for the specified user id. If there is no user logged in, or they have no valid associated User entity, None is returned. """ if not user_id: raise exception.BadRequest(message="Missing argument 'user_id'") q = user_model.User.all() q.filter('user_id', user_id) q.filter('status', 'valid') return q.get()
def post(self): idx = lists.getListIndex(self.data.request) if idx != 0: return None data = self.data.POST.get('data') if not data: raise exception.BadRequest(message="Missing data") parsed = json.loads(data) button_id = self.data.POST.get('button_id') if not button_id: raise exception.BadRequest(message="Missing button_id") elif button_id == 'withdraw': return self.postHandler(parsed) elif button_id == 'accept': return self.postHandler(parsed, withdraw=False) else: raise exception.BadRequest(message="Unknown button_id")
def get(self, data, check, mutator): """Allows hosts to download the student forms.""" if url_names.CONSENT_FORM_GET_PARAM in data.GET: download = data.url_ndb_profile.student_data.consent_form elif url_names.ENROLLMENT_FORM_GET_PARAM in data.GET: download = data.url_ndb_profile.student_data.enrollment_form else: raise exception.BadRequest(message='No file requested') # download has been requested if download: return bs_helper.sendBlob(blobstore.BlobInfo(download)) else: raise exception.NotFound(message='File not found')
def get(self, data, check, mutator): """Attempts to download the blob in the worksubmission that is specified in the GET argument. """ id_string = data.request.GET.get('id', '') submission_id = int(id_string) if id_string.isdigit() else -1 work = work_submission_model.GCIWorkSubmission.get_by_id( submission_id, data.task) if work and work.upload_of_work: return bs_helper.sendBlob(work.upload_of_work) else: raise exception.BadRequest(message=DEF_NO_WORK_FOUND % id_string)
def post(self, data, check, mutator): """Get handler for the code sample delete file.""" assert isSet(data.url_project) try: id_value = int(data.request.POST['id']) code_sample = GSoCCodeSample.get_by_id(id_value, data.url_project) if not code_sample: raise exception.BadRequest( message='Requested code sample not found') upload_of_work = code_sample.upload_of_work def txn(): code_sample.delete() if upload_of_work: # this is executed outside of transaction upload_of_work.delete() if data.url_project.countCodeSamples() <= 1: project = GSoCProject.get(data.url_project.key()) project.code_samples_submitted = False project.put() db.run_in_transaction(txn) url = links.LINKER.userId(data.url_profile.key(), data.url_project.key().id(), url_names.GSOC_PROJECT_UPDATE) return http.HttpResponseRedirect(url) except KeyError: raise exception.BadRequest( message='id argument missing in POST data') except ValueError: raise exception.BadRequest( message='id argument in POST data is not a number')
def forAccount(account): """Retrieves the user entity for the specified account. If there is no user logged in, or they have no valid associated User entity, None is returned. """ if not account: raise exception.BadRequest(message="Missing argument 'account'") account = accounts.normalizeAccount(account) q = user_model.User.all() q.filter('account', account) q.filter('status', 'valid') return q.get()
def post(self, data, check, mutator): """Handles all POST calls for the TaskViewPage.""" # TODO(nathaniel): What? Why is data.GET being read in this POST handler? if data.is_visible and 'reply' in data.GET: return self._postComment(data, check, mutator) elif 'button' in data.GET: return self._postButton(data) elif 'send_for_review' in data.GET: return self._postSendForReview(data) elif 'delete_submission' in data.GET: return self._postDeleteSubmission(data) elif 'work_file_submit' in data.POST or 'submit_work' in data.GET: return self._postSubmitWork(data, check, mutator) else: raise exception.BadRequest()