def testGetRecord(self): header, metadata, about = self._getProvider().getRecord( 'rif', _get_first_exp_id()) self.assertIn(str(self._experiment.id), header.identifier()) self.assertEqual(header.datestamp().replace(tzinfo=pytz.utc), get_local_time(self._experiment.update_time)) ns = 'http://ands.org.au/standards/rif-cs/registryObjects#relatedInfo' ps_id = ExperimentParameterSet.objects\ .filter(experiment=self._experiment,schema__namespace=ns).first().id self.assertEqual(metadata.getField('id'), self._experiment.id) self.assertEqual(metadata.getField('title'), str(self._experiment.title)) self.assertEqual(metadata.getField('description'), str(self._experiment.description)) self.assertEqual(metadata.getField('licence_uri'), License.get_none_option_license().url) self.assertEqual(metadata.getField('licence_name'), License.get_none_option_license().name) self.assertEqual( list(metadata.getField('related_info')), [{'notes': 'This is a note.', \ 'identifier': 'https://www.example.com/', \ 'type': 'website', \ 'id': ps_id, \ 'title': 'Google'}]) self.assertEqual(len(metadata.getField('collectors')), 2) self.assertIsNone(about)
def testListRecords(self): results = self._getProvider().listRecords('rif') # Iterate through headers for header, metadata, _ in results: if header.identifier().startswith('experiment'): expect(header.identifier()).to_contain(str(self._experiment.id)) expect(header.datestamp().replace(tzinfo=pytz.utc))\ .to_equal(get_local_time(self._experiment.update_time)) expect(metadata.getField('title'))\ .to_equal(str(self._experiment.title)) expect(metadata.getField('description'))\ .to_equal(str(self._experiment.description)) expect(metadata.getField('licence_uri'))\ .to_equal(License.get_none_option_license().url) expect(metadata.getField('licence_name'))\ .to_equal(License.get_none_option_license().name) else: expect(header.identifier()).to_contain(str(self._user.id)) expect(header.datestamp().replace(tzinfo=pytz.utc))\ .to_equal(get_local_time(self._user.last_login)) expect(metadata.getField('id')).to_equal(self._user.id) expect(metadata.getField('email'))\ .to_equal(str(self._user.email)) expect(metadata.getField('given_name'))\ .to_equal(str(self._user.first_name)) expect(metadata.getField('family_name'))\ .to_equal(str(self._user.last_name)) # There should only have been one expect(len(results)).to_equal(2) # Remove public flag self._experiment.public_access = Experiment.PUBLIC_ACCESS_NONE self._experiment.save() headers = self._getProvider().listRecords('rif') # Not public, so should not appear expect(len(headers)).to_equal(0)
def testGetRecord(self): header, metadata, about = self._getProvider().getRecord('rif', _get_first_exp_id()) self.assertIn(str(self._experiment.id), header.identifier()) self.assertEqual( header.datestamp().replace(tzinfo=pytz.utc), get_local_time(self._experiment.update_time)) ns = 'http://ands.org.au/standards/rif-cs/registryObjects#relatedInfo' ps_id = ExperimentParameterSet.objects\ .filter(experiment=self._experiment,schema__namespace=ns).first().id self.assertEqual( metadata.getField('id'), self._experiment.id) self.assertEqual( metadata.getField('title'), str(self._experiment.title)) self.assertEqual( metadata.getField('description'), str(self._experiment.description)) self.assertEqual( metadata.getField('licence_uri'), License.get_none_option_license().url) self.assertEqual( metadata.getField('licence_name'), License.get_none_option_license().name) self.assertEqual( metadata.getField('related_info'), [{'notes': 'This is a note.', \ 'identifier': 'https://www.example.com/', \ 'type': 'website', \ 'id': ps_id, \ 'title': 'Google'}]) self.assertEqual( len(metadata.getField('collectors')), 2) self.assertIsNone(about)
def testListRecords(self): results = self._getProvider().listRecords('rif') # Iterate through headers for header, metadata, _ in results: if header.identifier().startswith('experiment'): e = self._experiment if header.identifier() == _get_first_exp_id() \ else self._experiment2 self.assertIn(str(e.id), header.identifier()) self.assertEqual( header.datestamp().replace(tzinfo=pytz.utc), get_local_time(e.update_time)) self.assertEqual( metadata.getField('title'), str(e.title)) self.assertEqual( metadata.getField('description'), str(e.description)) self.assertEqual( metadata.getField('licence_uri'), License.get_none_option_license().url) self.assertEqual( metadata.getField('licence_name'), License.get_none_option_license().name) if e == self._experiment: ns = 'http://ands.org.au/standards/rif-cs/registryObjects#relatedInfo' ps_id = ExperimentParameterSet.objects\ .filter(experiment=self._experiment,schema__namespace=ns).first().id self.assertEqual( metadata.getField('related_info'), [{'notes': 'This is a note.', \ 'identifier': 'https://www.example.com/', \ 'type': 'website', \ 'id': ps_id, \ 'title': 'Google'}]) else: self.assertEqual( metadata.getField('related_info'), [{}]) else: self.assertIn(str(self._user.id), header.identifier()) self.assertEqual( header.datestamp().replace(tzinfo=pytz.utc), get_local_time(self._user.last_login)) self.assertEqual(metadata.getField('id'), self._user.id) self.assertEqual( metadata.getField('email'), str(self._user.email)) self.assertEqual( metadata.getField('given_name'), str(self._user.first_name)) self.assertEqual( metadata.getField('family_name'), str(self._user.last_name)) # There should have been two self.assertEqual(len(results), 2) # Remove public flag on first experiment self._experiment.public_access = Experiment.PUBLIC_ACCESS_NONE self._experiment.save() headers = self._getProvider().listRecords('rif') # Should now be one self.assertEqual(len(headers), 1)
def _get_experiment_metadata(self, experiment, metadataPrefix): license_ = experiment.license or License.get_none_option_license() # Access Rights statement access_type = None if experiment.public_access == Experiment.PUBLIC_ACCESS_METADATA: access = "Only metadata is publicly available online." + \ " Requests for further access should be directed to a" + \ " listed data manager." access_type = "restricted" else: access = "All data is publicly available online." access_type = "open" def get_related_info(ps): psm = ParameterSetManager(ps) parameter_names = ['type', 'identifier', 'title', 'notes'] try: parameters = { key: psm.get_param(key, True) for key in parameter_names } parameters['id'] = ps.id return parameters except ExperimentParameter.DoesNotExist: return dict() # drop Related_Info record with missing fields ns = 'http://ands.org.au/standards/rif-cs/registryObjects#relatedInfo' related_info = map( get_related_info, ExperimentParameterSet.objects.filter(experiment=experiment, schema__namespace=ns)) def get_subject(ps, type_): psm = ParameterSetManager(ps) return {'text': psm.get_param('code', True), 'type': type_} ns = 'http://purl.org/asc/1297.0/2008/for/' subjects = [ get_subject(ps, 'anzsrc-for') for ps in ExperimentParameterSet.objects.filter( experiment=experiment, schema__namespace=ns) ] collectors = experiment.experimentauthor_set.exclude(url='') return Metadata( experiment, { '_writeMetadata': self._get_experiment_writer_func(), 'id': experiment.id, 'title': experiment.title, 'description': experiment.description, # Note: Property names are US-spelling, but RIF-CS is Australian 'licence_name': license_.name, 'licence_uri': license_.url, 'access': access, 'access_type': access_type, 'collectors': collectors, 'managers': experiment.get_owners(), 'related_info': related_info, 'subjects': subjects })
def _get_experiment_metadata(self, experiment, metadataPrefix): license_ = experiment.license or License.get_none_option_license() # Access Rights statement if experiment.public_access == Experiment.PUBLIC_ACCESS_METADATA: access = "Only metadata is publicly available online."+\ " Requests for further access should be directed to a"+\ " listed data manager." else: access = "All data is publicly available online." def get_related_info(ps): psm = ParameterSetManager(ps) parameter_names = ['type','identifier','title','notes'] return dict([('id', ps.id)]+ # Use set ID zip(parameter_names, (psm.get_param(k, True) for k in parameter_names))) ns = 'http://ands.org.au/standards/rif-cs/registryObjects#relatedInfo' related_info = map(get_related_info, ExperimentParameterSet.objects\ .filter(experiment=experiment, schema__namespace=ns)) return Metadata({ '_writeMetadata': self._get_experiment_writer_func(), 'id': experiment.id, 'title': experiment.title, 'description': experiment.description, # Note: Property names are US-spelling, but RIF-CS is Australian 'licence_name': license_.name, 'licence_uri': license_.url, 'access': access, 'collectors': [experiment.created_by], 'managers': experiment.get_owners(), 'related_info': related_info })
def testListRecords(self): results = self._getProvider().listRecords('rif') # Iterate through headers for header, metadata, _ in results: if header.identifier().startswith('experiment'): e = self._experiment if header.identifier() == 'experiment/1' \ else self._experiment2 expect(header.identifier()).to_contain(str(e.id)) expect(header.datestamp().replace(tzinfo=pytz.utc))\ .to_equal(get_local_time(e.update_time)) expect(metadata.getField('title'))\ .to_equal(str(e.title)) expect(metadata.getField('description'))\ .to_equal(str(e.description)) expect(metadata.getField('licence_uri'))\ .to_equal(License.get_none_option_license().url) expect(metadata.getField('licence_name'))\ .to_equal(License.get_none_option_license().name) if e == self._experiment: expect(metadata.getField('related_info'))\ .to_equal([{'notes': 'This is a note.', \ 'identifier': 'https://www.example.com/', \ 'type': 'website', \ 'id': 1, \ 'title': 'Google'}]) else: expect(metadata.getField('related_info')).to_equal([{}]) else: expect(header.identifier()).to_contain(str(self._user.id)) expect(header.datestamp().replace(tzinfo=pytz.utc))\ .to_equal(get_local_time(self._user.last_login)) expect(metadata.getField('id')).to_equal(self._user.id) expect(metadata.getField('email'))\ .to_equal(str(self._user.email)) expect(metadata.getField('given_name'))\ .to_equal(str(self._user.first_name)) expect(metadata.getField('family_name'))\ .to_equal(str(self._user.last_name)) # There should have been two expect(len(results)).to_equal(2) # Remove public flag on first experiment self._experiment.public_access = Experiment.PUBLIC_ACCESS_NONE self._experiment.save() headers = self._getProvider().listRecords('rif') # Should now be one expect(len(headers)).to_equal(1)
def testGetRecord(self): header, metadata, about = self._getProvider().getRecord( 'rif', 'experiment/1') expect(header.identifier()).to_contain(str(self._experiment.id)) expect(header.datestamp().replace(tzinfo=pytz.utc))\ .to_equal(get_local_time(self._experiment.update_time)) expect(metadata.getField('id')).to_equal(self._experiment.id) expect(metadata.getField('title'))\ .to_equal(str(self._experiment.title)) expect(metadata.getField('description'))\ .to_equal(str(self._experiment.description)) expect(metadata.getField('licence_uri'))\ .to_equal(License.get_none_option_license().url) expect(metadata.getField('licence_name'))\ .to_equal(License.get_none_option_license().name) expect(metadata.getField('related_info'))\ .to_equal([]) expect(about).to_equal(None)
def _get_experiment_metadata(self, experiment, metadataPrefix): license_ = experiment.license or License.get_none_option_license() # Access Rights statement access_type = None if experiment.public_access == Experiment.PUBLIC_ACCESS_METADATA: access = "Only metadata is publicly available online." + \ " Requests for further access should be directed to a" + \ " listed data manager." access_type = "restricted" else: access = "All data is publicly available online." access_type = "open" def get_related_info(ps): psm = ParameterSetManager(ps) parameter_names = ['type', 'identifier', 'title', 'notes'] try: return dict([('id', ps.id)] + # Use set ID zip(parameter_names, (psm.get_param(k, True) \ for k in parameter_names))) except ExperimentParameter.DoesNotExist: return dict() # drop Related_Info record with missing fields ns = 'http://ands.org.au/standards/rif-cs/registryObjects#relatedInfo' related_info = map( get_related_info, ExperimentParameterSet.objects.filter(experiment=experiment, schema__namespace=ns)) def get_subject(ps, type_): psm = ParameterSetManager(ps) return {'text': psm.get_param('code', True), 'type': type_} ns = 'http://purl.org/asc/1297.0/2008/for/' subjects = [get_subject(ps, 'anzsrc-for') for ps in ExperimentParameterSet.objects.filter( experiment=experiment, schema__namespace=ns)] collectors = experiment.experimentauthor_set.exclude(url='') return Metadata( experiment, { '_writeMetadata': self._get_experiment_writer_func(), 'id': experiment.id, 'title': experiment.title, 'description': experiment.description, # Note: Property names are US-spelling, but RIF-CS is Australian 'licence_name': license_.name, 'licence_uri': license_.url, 'access': access, 'access_type': access_type, 'collectors': collectors, 'managers': experiment.get_owners(), 'related_info': related_info, 'subjects': subjects })
def testGetRecord(self): header, metadata, about = self._getProvider().getRecord('rif', 'experiment/1') expect(header.identifier()).to_contain(str(self._experiment.id)) expect(header.datestamp().replace(tzinfo=pytz.utc))\ .to_equal(get_local_time(self._experiment.update_time)) expect(metadata.getField('id')).to_equal(self._experiment.id) expect(metadata.getField('title'))\ .to_equal(str(self._experiment.title)) expect(metadata.getField('description'))\ .to_equal(str(self._experiment.description)) expect(metadata.getField('licence_uri'))\ .to_equal(License.get_none_option_license().url) expect(metadata.getField('licence_name'))\ .to_equal(License.get_none_option_license().name) expect(metadata.getField('related_info'))\ .to_equal([]) expect(about).to_equal(None)
def _get_experiment_metadata(self, experiment, metadataPrefix): license_ = experiment.license or License.get_none_option_license() # Access Rights statement if experiment.public_access == Experiment.PUBLIC_ACCESS_METADATA: access = ( "Only metadata is publicly available online." + " Requests for further access should be directed to a" + " listed data manager." ) else: access = "All data is publicly available online." def get_related_info(ps): psm = ParameterSetManager(ps) parameter_names = ["type", "identifier", "title", "notes"] try: return dict( [("id", ps.id)] + zip(parameter_names, (psm.get_param(k, True) for k in parameter_names)) # Use set ID ) except ExperimentParameter.DoesNotExist: return dict() # drop Related_Info record with missing fields ns = "http://ands.org.au/standards/rif-cs/registryObjects#relatedInfo" related_info = map( get_related_info, ExperimentParameterSet.objects.filter(experiment=experiment, schema__namespace=ns) ) def get_subject(ps, type_): psm = ParameterSetManager(ps) return {"text": psm.get_param("code", True), "type": type_} ns = "http://purl.org/asc/1297.0/2008/for/" subjects = [ get_subject(ps, "anzsrc-for") for ps in ExperimentParameterSet.objects.filter(experiment=experiment, schema__namespace=ns) ] collectors = experiment.author_experiment_set.exclude(url="") return Metadata( { "_writeMetadata": self._get_experiment_writer_func(), "id": experiment.id, "title": experiment.title, "description": experiment.description, # Note: Property names are US-spelling, but RIF-CS is Australian "licence_name": license_.name, "licence_uri": license_.url, "access": access, "collectors": collectors, "managers": experiment.get_owners(), "related_info": related_info, "subjects": subjects, } )
def testGetRecord(self): header, metadata, about = self._getProvider().getRecord('rif', 'experiment/1') expect(header.identifier()).to_contain(str(self._experiment.id)) expect(header.datestamp().replace(tzinfo=pytz.utc))\ .to_equal(get_local_time(self._experiment.update_time)) expect(metadata.getField('id')).to_equal(self._experiment.id) expect(metadata.getField('title'))\ .to_equal(str(self._experiment.title)) expect(metadata.getField('description'))\ .to_equal(str(self._experiment.description)) expect(metadata.getField('licence_uri'))\ .to_equal(License.get_none_option_license().url) expect(metadata.getField('licence_name'))\ .to_equal(License.get_none_option_license().name) expect(metadata.getField('related_info'))\ .to_equal([{'notes': 'This is a note.', \ 'identifier': 'https://www.example.com/', \ 'type': 'website', \ 'id': 1, \ 'title': 'Google'}]) expect(len(metadata.getField('collectors')))\ .to_equal(2) expect(about).to_equal(None)
def testGetRecord(self): header, metadata, about = self._getProvider().getRecord( 'rif', 'experiment/1') expect(header.identifier()).to_contain(str(self._experiment.id)) expect(header.datestamp().replace(tzinfo=pytz.utc))\ .to_equal(get_local_time(self._experiment.update_time)) expect(metadata.getField('id')).to_equal(self._experiment.id) expect(metadata.getField('title'))\ .to_equal(str(self._experiment.title)) expect(metadata.getField('description'))\ .to_equal(str(self._experiment.description)) expect(metadata.getField('licence_uri'))\ .to_equal(License.get_none_option_license().url) expect(metadata.getField('licence_name'))\ .to_equal(License.get_none_option_license().name) expect(metadata.getField('related_info'))\ .to_equal([{'notes': 'This is a note.', \ 'identifier': 'https://www.example.com/', \ 'type': 'website', \ 'id': 1, \ 'title': 'Google'}]) expect(len(metadata.getField('collectors')))\ .to_equal(2) expect(about).to_equal(None)
def testListRecords(self): results = self._getProvider().listRecords('rif') # Iterate through headers for header, metadata, _ in results: if header.identifier().startswith('experiment'): expect(header.identifier()).to_contain(str( self._experiment.id)) expect(header.datestamp().replace(tzinfo=pytz.utc))\ .to_equal(get_local_time(self._experiment.update_time)) expect(metadata.getField('title'))\ .to_equal(str(self._experiment.title)) expect(metadata.getField('description'))\ .to_equal(str(self._experiment.description)) expect(metadata.getField('licence_uri'))\ .to_equal(License.get_none_option_license().url) expect(metadata.getField('licence_name'))\ .to_equal(License.get_none_option_license().name) else: expect(header.identifier()).to_contain(str(self._user.id)) expect(header.datestamp().replace(tzinfo=pytz.utc))\ .to_equal(get_local_time(self._user.last_login)) expect(metadata.getField('id')).to_equal(self._user.id) expect(metadata.getField('email'))\ .to_equal(str(self._user.email)) expect(metadata.getField('given_name'))\ .to_equal(str(self._user.first_name)) expect(metadata.getField('family_name'))\ .to_equal(str(self._user.last_name)) # There should only have been one expect(len(results)).to_equal(2) # Remove public flag self._experiment.public_access = Experiment.PUBLIC_ACCESS_NONE self._experiment.save() headers = self._getProvider().listRecords('rif') # Not public, so should not appear expect(len(headers)).to_equal(0)
def process_form(request): # Decode the form data form_state = json.loads(request.body) def validation_error(error=None): if error is None: error = 'Invalid form data was submitted ' \ '(server-side validation failed)' return HttpResponse(json.dumps({'error': error}), content_type="application/json") # Check if the form data contains a publication ID # If it does, then this publication needs to be updated # rather than created. if 'publicationId' not in form_state: if not form_state['publicationTitle'].strip(): return validation_error() publication = create_draft_publication( request.user, form_state['publicationTitle'], form_state['publicationDescription']) form_state['publicationId'] = publication.id else: publication = get_draft_publication(request.user, form_state['publicationId']) # Check if the publication is finalised (i.e. not in draft) # if it is, then refuse to process the form. if publication is None or not publication.is_publication_draft(): return HttpResponseForbidden() # Get the form state database object form_state_parameter = ExperimentParameter.objects.get( name__name='form_state', name__schema__namespace=getattr( settings, 'PUBLICATION_SCHEMA_ROOT', default_settings.PUBLICATION_SCHEMA_ROOT), parameterset__experiment=publication) # Check if the form state needs to be loaded (i.e. a publication draft # is resumed) # no database changes are made if the form is resumed if form_state['action'] == 'resume': form_state = json.loads(form_state_parameter.string_value) return HttpResponse(json.dumps(form_state), content_type="application/json") if form_state['action'] == 'update-dataset-selection': # Update the publication title/description if changed. # Must not be blank. if not form_state['publicationTitle'].strip() or \ not form_state['publicationDescription'].strip(): return validation_error() if publication.title != form_state['publicationTitle']: publication.title = form_state['publicationTitle'] publication.save() if publication.description != form_state['publicationDescription']: publication.description = form_state['publicationDescription'] publication.save() # Update associated datasets # (note: might not be efficient re: db queries) # ... first clear all current associations current_datasets = Dataset.objects.filter(experiments=publication) for current_dataset in current_datasets: current_dataset.experiments.remove(publication) # ... now (re)add all datasets selected_datasets = [ ds['dataset']['id'] for ds in form_state['addedDatasets'] ] datasets = Dataset.objects.filter( experiments__in=Experiment.safe.owned_and_shared(request.user), pk__in=selected_datasets).distinct() for dataset in datasets: dataset.experiments.add(publication) # --- Get data for the next page --- # # Construct the disclipline-specific form based on the # selected datasets selected_forms = select_forms(datasets) if 'disciplineSpecificFormTemplates' in form_state: # clear extraInfo if the selected forms differ # (i.e. datasets have changed) if json.dumps(selected_forms) != json.dumps( form_state['disciplineSpecificFormTemplates']): form_state['extraInfo'] = {} form_state['disciplineSpecificFormTemplates'] = selected_forms elif form_state['action'] == 'update-extra-info': # Clear any current parameter sets except for those belonging # to the publication draft schema or containing the form_state # parameter clear_publication_metadata(publication) # Loop through form data and create associates parameter sets # Any unrecognised fields or schemas are ignored! map_form_to_schemas(form_state['extraInfo'], publication) # *** Synchrotron specific *** # Search for beamline/EPN information associated with each dataset # and add to the publication. synchrotron_search_epn(publication) # --- Get data for the next page --- # licenses_json = get_licenses() form_state['licenses'] = licenses_json # Select the first license as default if licenses_json: if 'selectedLicenseId' not in form_state: form_state['selectedLicenseId'] = licenses_json[0]['id'] else: # No licenses configured... form_state['selectedLicenseId'] = -1 # Set a default author (current user) if no previously saved data # By default, the form sends a list of authors of one element # with blank fields if len(form_state['authors']) == 1 and \ not form_state['authors'][0]['name']: form_state['authors'] = [{ 'name': ' '.join([request.user.first_name, request.user.last_name]), 'institution': getattr(settings, 'DEFAULT_INSTITUTION', ''), 'email': request.user.email }] elif form_state['action'] == 'submit': # any final form validation should occur here # and specific error messages can be returned # to the browser before the publication's draft # status is removed. if 'acknowledge' not in form_state or not form_state['acknowledge']: return validation_error('You must confirm that you are ' 'authorised to submit this publication') set_publication_authors(form_state['authors'], publication) institutions = '; '.join( set([author['institution'] for author in form_state['authors']])) publication.institution_name = institutions # Attach the publication details schema pub_details_schema = Schema.objects.get( namespace=getattr(settings, 'PUBLICATION_DETAILS_SCHEMA', default_settings.PUBLICATION_DETAILS_SCHEMA)) pub_details_parameter_set = ExperimentParameterSet( schema=pub_details_schema, experiment=publication) pub_details_parameter_set.save() # Add the acknowledgements acknowledgements_parameter_name = ParameterName.objects.get( schema=pub_details_schema, name='acknowledgements') ExperimentParameter( name=acknowledgements_parameter_name, parameterset=pub_details_parameter_set, string_value=form_state['acknowledgements']).save() # Set the release date set_embargo_release_date(publication, dateutil.parser.parse(form_state['embargo'])) # Set the license try: publication.license = License.objects.get( pk=form_state['selectedLicenseId'], is_active=True, allows_distribution=True) except License.DoesNotExist: publication.license = License.get_none_option_license() publication.save() # Send emails about publication in draft subject, message_content = email_pub_requires_authorisation( request.user.username, request.build_absolute_uri( reverse('tardis_portal.view_experiment', args=(publication.id, ))), request.build_absolute_uri('/apps/publication-forms/approvals/')) try: send_mail( subject, message_content, getattr( settings, 'PUBLICATION_NOTIFICATION_SENDER_EMAIL', default_settings.PUBLICATION_NOTIFICATION_SENDER_EMAIL), get_pub_admin_email_addresses(), fail_silently=False) subject, message_content = email_pub_awaiting_approval( publication.title) send_mail_to_authors(publication, subject, message_content, fail_silently=False) except Exception as e: logger.error( "failed to send publication notification email(s): %s" % repr(e)) return HttpResponse(json.dumps({ 'error': 'Failed to send notification email - please ' 'contact the %s administrator (%s), ' 'or try again later. Your draft is saved.' % (get_site_admin_email(), getattr(settings, 'SITE_TITLE', 'MyTardis')) }), content_type="application/json") # Remove the draft status remove_draft_status(publication) # Automatically approve publications if approval is not required if not getattr(settings, 'PUBLICATIONS_REQUIRE_APPROVAL', default_settings.PUBLICATIONS_REQUIRE_APPROVAL): approve_publication(request, publication, message=None, send_email=False) # approve_publication will delete the form state, so don't # bother saving is and return. form_state['action'] = '' return HttpResponse(json.dumps(form_state), content_type="appication/json") # Trigger publication record update tasks.update_publication_records.delay() # Clear the form action and save the state form_state['action'] = '' form_state_parameter.string_value = json.dumps(form_state) form_state_parameter.save() return HttpResponse(json.dumps(form_state), content_type="appication/json")
def process_form(request): # Decode the form data form_state = json.loads(request.body) def validation_error(error=None): if error is None: error = 'Invalid form data was submitted ' \ '(server-side validation failed)' return HttpResponse( json.dumps({ 'error': error}), content_type="application/json") # Check if the form data contains a publication ID # If it does, then this publication needs to be updated # rather than created. if 'publicationId' not in form_state: if not form_state['publicationTitle'].strip(): return validation_error() publication = create_draft_publication( request.user, form_state['publicationTitle'], form_state['publicationDescription']) form_state['publicationId'] = publication.id else: publication = get_draft_publication( request.user, form_state['publicationId']) # Check if the publication is finalised (i.e. not in draft) # if it is, then refuse to process the form. if publication is None or not publication.is_publication_draft(): return HttpResponseForbidden() # Get the form state database object form_state_parameter = ExperimentParameter.objects.get( name__name='form_state', name__schema__namespace=getattr( settings, 'PUBLICATION_SCHEMA_ROOT', default_settings.PUBLICATION_SCHEMA_ROOT), parameterset__experiment=publication) # Check if the form state needs to be loaded (i.e. a publication draft # is resumed) # no database changes are made if the form is resumed if form_state['action'] == 'resume': form_state = json.loads(form_state_parameter.string_value) return HttpResponse(json.dumps(form_state), content_type="application/json") if form_state['action'] == 'update-dataset-selection': # Update the publication title/description if changed. # Must not be blank. if not form_state['publicationTitle'].strip() or \ not form_state['publicationDescription'].strip(): return validation_error() if publication.title != form_state['publicationTitle']: publication.title = form_state['publicationTitle'] publication.save() if publication.description != form_state['publicationDescription']: publication.description = form_state['publicationDescription'] publication.save() # Update associated datasets # (note: might not be efficient re: db queries) # ... first clear all current associations current_datasets = Dataset.objects.filter(experiments=publication) for current_dataset in current_datasets: current_dataset.experiments.remove(publication) # ... now (re)add all datasets selected_datasets = [ds['dataset']['id'] for ds in form_state['addedDatasets']] datasets = Dataset.objects.filter( experiments__in=Experiment.safe.owned_and_shared(request.user), pk__in=selected_datasets).distinct() for dataset in datasets: dataset.experiments.add(publication) # --- Get data for the next page --- # # Construct the disclipline-specific form based on the # selected datasets selected_forms = select_forms(datasets) if 'disciplineSpecificFormTemplates' in form_state: # clear extraInfo if the selected forms differ # (i.e. datasets have changed) if json.dumps(selected_forms) != json.dumps( form_state['disciplineSpecificFormTemplates']): form_state['extraInfo'] = {} form_state['disciplineSpecificFormTemplates'] = selected_forms elif form_state['action'] == 'update-extra-info': # Clear any current parameter sets except for those belonging # to the publication draft schema or containing the form_state # parameter clear_publication_metadata(publication) # Loop through form data and create associates parameter sets # Any unrecognised fields or schemas are ignored! map_form_to_schemas(form_state['extraInfo'], publication) # *** Synchrotron specific *** # Search for beamline/EPN information associated with each dataset # and add to the publication. synchrotron_search_epn(publication) # --- Get data for the next page --- # licenses_json = get_licenses() form_state['licenses'] = licenses_json # Select the first license as default if licenses_json: if 'selectedLicenseId' not in form_state: form_state['selectedLicenseId'] = licenses_json[0]['id'] else: # No licenses configured... form_state['selectedLicenseId'] = -1 # Set a default author (current user) if no previously saved data # By default, the form sends a list of authors of one element # with blank fields if len(form_state['authors']) == 1 and \ not form_state['authors'][0]['name']: form_state['authors'] = [ {'name': ' '.join([request.user.first_name, request.user.last_name]), 'institution': getattr(settings, 'DEFAULT_INSTITUTION', ''), 'email': request.user.email}] elif form_state['action'] == 'submit': # any final form validation should occur here # and specific error messages can be returned # to the browser before the publication's draft # status is removed. if 'acknowledge' not in form_state or not form_state['acknowledge']: return validation_error('You must confirm that you are ' 'authorised to submit this publication') set_publication_authors(form_state['authors'], publication) institutions = '; '.join( set([author['institution'] for author in form_state['authors']])) publication.institution_name = institutions # Attach the publication details schema pub_details_schema = Schema.objects.get( namespace=getattr(settings, 'PUBLICATION_DETAILS_SCHEMA', default_settings.PUBLICATION_DETAILS_SCHEMA)) pub_details_parameter_set = ExperimentParameterSet( schema=pub_details_schema, experiment=publication) pub_details_parameter_set.save() # Add the acknowledgements acknowledgements_parameter_name = ParameterName.objects.get( schema=pub_details_schema, name='acknowledgements') ExperimentParameter(name=acknowledgements_parameter_name, parameterset=pub_details_parameter_set, string_value=form_state['acknowledgements']).save() # Set the release date set_embargo_release_date( publication, dateutil.parser.parse( form_state[ 'embargo'])) # Set the license try: publication.license = License.objects.get( pk=form_state['selectedLicenseId'], is_active=True, allows_distribution=True) except License.DoesNotExist: publication.license = License.get_none_option_license() publication.save() # Send emails about publication in draft subject, message_content = email_pub_requires_authorisation( request.user.username, request.build_absolute_uri( reverse('tardis_portal.view_experiment', args=(publication.id,))), request.build_absolute_uri( '/apps/publication-forms/approvals/')) try: send_mail(subject, message_content, getattr( settings, 'PUBLICATION_NOTIFICATION_SENDER_EMAIL', default_settings.PUBLICATION_NOTIFICATION_SENDER_EMAIL), get_pub_admin_email_addresses(), fail_silently=False) subject, message_content = email_pub_awaiting_approval( publication.title) send_mail_to_authors(publication, subject, message_content, fail_silently=False) except Exception as e: logger.error( "failed to send publication notification email(s): %s" % repr(e) ) return HttpResponse( json.dumps({ 'error': 'Failed to send notification email - please ' 'contact the %s administrator (%s), ' 'or try again later. Your draft is saved.' % (get_site_admin_email(), getattr(settings, 'SITE_TITLE', 'MyTardis')) }), content_type="application/json") # Remove the draft status remove_draft_status(publication) # Automatically approve publications if approval is not required if not getattr(settings, 'PUBLICATIONS_REQUIRE_APPROVAL', default_settings.PUBLICATIONS_REQUIRE_APPROVAL): approve_publication(request, publication, message=None, send_email=False) # approve_publication will delete the form state, so don't # bother saving is and return. form_state['action'] = '' return HttpResponse(json.dumps(form_state), content_type="appication/json") # Trigger publication record update tasks.update_publication_records.delay() # Clear the form action and save the state form_state['action'] = '' form_state_parameter.string_value = json.dumps(form_state) form_state_parameter.save() return HttpResponse(json.dumps(form_state), content_type="appication/json")