def after_show(self, context, pkg_dict): # Load the DOI ready to display doi = get_doi(pkg_dict['id']) if doi: pkg_dict['doi'] = doi.identifier pkg_dict['doi_status'] = True if doi.published else False pkg_dict['domain'] = get_site_url().replace('http://', '')
def after_update(self, context, pkg_dict): """ Dataset has been created / updated Check status of the dataset to determine if we should publish DOI to datacite network @param pkg_dict: @return: pkg_dict """ # Is this active and public? If so we need to make sure we have an active DOI if pkg_dict.get('state', 'active') == 'active' and not pkg_dict.get('private', False): package_id = pkg_dict['id'] # Load the original package, so we can determine if user has changed any fields orig_pkg_dict = get_action('package_show')(context, {'id': package_id}) # Metadata created isn't populated in pkg_dict - so copy from the original pkg_dict['metadata_created'] = orig_pkg_dict['metadata_created'] # Load the local DOI doi = get_doi(package_id) # If we don't have a DOI, create one # This could happen if the DOI module is enabled after a dataset has been creates if not doi: doi = create_unique_identifier(package_id) # Build the metadata dict to pass to DataCite service metadata_dict = self.build_metadata(pkg_dict, doi) # Perform some basic checks against the data - we require at the very least # title and author fields - they're mandatory in the DataCite Schema # This will only be an issue if another plugin has removed a mandatory field self.validate_metadata(metadata_dict) # Is this an existing DOI? Update it if doi.published: # Before updating, check if any of the metadata has been changed - otherwise # We end up sending loads of revisions to DataCite for minor edits # Load the current version orig_metadata_dict = self.build_metadata(orig_pkg_dict, doi) # Check if the two dictionaries are the same if cmp(orig_metadata_dict, metadata_dict) != 0: # Not the same, so we want to update the metadata update_doi(package_id, **metadata_dict) h.flash_success('DataCite DOI metadata updated') # TODO: If editing a dataset older than 5 days, create DOI revision # New DOI - publish to datacite else: h.flash_success('DataCite DOI created') publish_doi(package_id, **metadata_dict) return pkg_dict
def test_doi_not_created_when_manually_entered(self): '''If auto_doi_identifier is false, don't create a doi.''' pkg = factories.Dataset(author='Ben', auto_doi_identifier=False, doi_identifier=None) doi = doi_lib.get_doi(pkg['id']) assert_true(doi is None)
def test_auto_then_clear(self): '''Auto creating a DOI, then clear it will delete DOI object.''' pkg = factories.Dataset(author='Ben', auto_doi_identifier=True, doi_identifier=None, doi_prefix='10.5072/FK2') doi = doi_lib.get_doi(pkg['id']) # a DOI object has been created assert_true(isinstance(doi, doi_lib.DOI)) # Update the package pkg['auto_doi_identifier'] = False pkg['doi_identifier'] = '' helpers.call_action('package_update', **pkg) # we shouldn't have a DOI object now doi = doi_lib.get_doi(pkg['id']) assert_true(doi is None)
def after_show(self, context, pkg_dict): # Load the DOI ready to display doi = get_doi(pkg_dict['id']) if doi: pkg_dict['doi'] = doi.identifier pkg_dict['doi_status'] = True if doi.published else False pkg_dict['domain'] = get_site_url().replace('http://', '') pkg_dict['doi_date_published'] = datetime.strftime(doi.published, "%Y-%m-%d") if doi.published else None pkg_dict['doi_publisher'] = config.get("ckanext.doi.publisher")
def after_show(self, context, pkg_dict): # Load the DOI ready to display doi = get_doi(pkg_dict['id']) if doi: pkg_dict['doi'] = doi.identifier pkg_dict['doi_status'] = True if doi.published else False pkg_dict['domain'] = get_site_url().replace('http://', '') pkg_dict['doi_date_published'] = datetime.strftime( doi.published, "%Y-%m-%d") if doi.published else None pkg_dict['doi_publisher'] = config.get("ckanext.doi.publisher")
def test_doi_not_created_normal_user_no_owner_org_only_in_orgs(self): '''A normal user can not create a doi from auto_doi_identifier if doi_request_only_in_orgs=True''' user = factories.User() pkg = factories.Dataset(auto_doi_identifier=True, doi_identifier=None, author='My Author', user=user, doi_prefix='10.5072/FK2') doi = doi_lib.get_doi(pkg['id']) assert_true(doi is None)
def test_doi_auto_created_when_field_not_defined(self): '''On package creation, a DOI object should be created and doi_identifier field should be populated with the DOI id.''' pkg = factories.Dataset(author='Ben', auto_doi_identifier=True, doi_identifier=None, doi_prefix='10.5072/FK2') retrieved_pkg = helpers.call_action('package_show', id=pkg['id']) doi = doi_lib.get_doi(pkg['id']) assert_equal(doi.identifier, retrieved_pkg['doi_identifier'])
def test_doi_stuff(self): my_user = factories.User() # org owned by my_user org = factories.Organization(user=my_user) pkg = factories.Dataset(auto_doi_identifier=True, doi_identifier=None, author='My Author', user=my_user, owner_org=org['id'], doi_prefix='10.5072/FK2') doi = doi_lib.get_doi(pkg['id']) assert_true(doi is not None) assert_true('10.5072' in doi.identifier)
def test_doi_create_org_admin_owner_org_only_in_orgs(self): '''An org admin can create dois if doi_request_only_in_orgs=True''' my_user = factories.User() # org owned by my_user org = factories.Organization(user=my_user) pkg = factories.Dataset(auto_doi_identifier=True, doi_identifier=None, author='My Author', user=my_user, owner_org=org['id'], doi_prefix='10.5072/FK2') doi = doi_lib.get_doi(pkg['id']) assert_true(doi is not None) assert_true('10.5072' in doi.identifier)
def test_doi_not_created_when_field_is_defined_manually_created(self): '''On package creation, DOI object should not be created if auto_doi_identifier is false.''' pkg = factories.Dataset(author='Ben', doi_identifier='example-doi-id', auto_doi_identifier=False) retrieved_pkg = helpers.call_action('package_show', id=pkg['id']) doi = doi_lib.get_doi(pkg['id']) assert_equal(retrieved_pkg['doi_identifier'], 'example-doi-id') assert_true(doi is None)
def test_doi_auto_created_when_field_is_defined(self): '''On package creation, DOI object should be created with the doi_identifier field value. A passed doi_identifier is ignored.''' pkg = factories.Dataset(author='Ben', doi_identifier='example-doi-id', auto_doi_identifier=True, doi_prefix='10.5072/FK2') retrieved_pkg = helpers.call_action('package_show', id=pkg['id']) doi = doi_lib.get_doi(pkg['id']) assert_not_equal(retrieved_pkg['doi_identifier'], 'example-doi-id') assert_equal(doi.identifier, retrieved_pkg['doi_identifier'])
def test_manually_entered_then_auto_create_doi(self, mock_publish): '''On package creation, DOI object should not be created if doi_identifier is manually entered and auto_doi_identifier is False. DOI object should then be created if package is edited with auto_doi_identifier True.''' # Can't publish without proper auth, so mock it mock_publish.return_value = None pkg = factories.Dataset(author='Ben', doi_identifier='example-doi-id', auto_doi_identifier=False) retrieved_pkg = helpers.call_action('package_show', id=pkg['id']) doi = doi_lib.get_doi(pkg['id']) assert_equal(retrieved_pkg['doi_identifier'], 'example-doi-id') assert_true(doi is None) # edit package with auto_doi_identifier True retrieved_pkg['auto_doi_identifier'] = True retrieved_pkg['doi_prefix'] = '10.5072/FK2' helpers.call_action('package_update', **retrieved_pkg) # A DOI object has been created doi = doi_lib.get_doi(pkg['id']) assert_true(isinstance(doi, doi_lib.DOI)) # and the id value should be correct updated_retrieved_pkg = helpers.call_action('package_show', id=pkg['id']) assert_equal(updated_retrieved_pkg['doi_identifier'], doi.identifier) assert_not_equal(updated_retrieved_pkg['doi_identifier'], 'example-doi-id')
def test_doi_auto_create_identifier(self): '''Test a DOI has been created with the package.''' # creating the package should also create a DOI instance pkg = factories.Dataset(author='Ben', auto_doi_identifier=True, doi_identifier=None, doi_prefix='10.5072/FK2') # let's get it doi = doi_lib.get_doi(pkg['id']) # Make sure we have a DOI model assert_true(isinstance(doi, doi_lib.DOI)) # And the package ID is correct assert_equal(doi.package_id, pkg['id']) # And published should be none assert_true(doi.published is None)
def test_doi_metadata(self): ''' Test the creation and validation of metadata ''' pkg = factories.Dataset(author='Ben', auto_doi_identifier=True, doi_identifier=None, doi_prefix='10.5072/FK2') doi = doi_lib.get_doi(pkg['id']) # Build the metadata dict to pass to DataCite service metadata_dict = doi_lib.build_metadata(pkg, doi) # Perform some basic checks against the data - we require at the very # least title and author fields - they're mandatory in the DataCite # Schema. This will only be an issue if another plugin has removed a # mandatory field doi_lib.validate_metadata(metadata_dict)
def test_doi_metadata_missing_author(self): '''Validating a DOI created from a package with no author will raise an exception.''' pkg = factories.Dataset(auto_doi_identifier=True, author='My Author', doi_identifier=None, doi_prefix='10.5072/FK2') doi = doi_lib.get_doi(pkg['id']) # remove author value from pkg_dict before attempting validation pkg['author'] = None # Build the metadata dict to pass to DataCite service metadata_dict = doi_lib.build_metadata(pkg, doi) # No author in pkg_dict, so exception should be raised assert_raises(DOIMetadataException, doi_lib.validate_metadata, metadata_dict)
def test_doi_publish_datacite(self): import ckanext.doi.lib as doi_lib doi = doi_lib.get_doi(self.package_dict['id']) if not doi: doi = doi_lib.create_unique_identifier(self.package_dict['id']) # Build the metadata dict to pass to DataCite service metadata_dict = doi_lib.build_metadata(self.package_dict, doi) # Perform some basic checks against the data - we require at the very least # title and author fields - they're mandatory in the DataCite Schema # This will only be an issue if another plugin has removed a mandatory field doi_lib.validate_metadata(metadata_dict) doi_lib.publish_doi(self.package_dict['id'], **metadata_dict)
def after_show(self, context, pkg_dict): ''' :param context: :param pkg_dict: ''' # Load the DOI ready to display doi = get_doi(pkg_dict[u'id']) if doi: pkg_dict[u'doi'] = doi.identifier pkg_dict[u'doi_status'] = True if doi.published else False pkg_dict[u'domain'] = get_site_url().replace(u'http://', u'') pkg_dict[u'doi_date_published'] = datetime.strftime(doi.published, u'%Y-%m-%d') if \ doi.published else None pkg_dict[u'doi_publisher'] = toolkit.config.get( u'ckanext.doi.publisher')
def test_doi_create_editor_not_allowed(self): '''Editor role not allowed to create dois''' my_user = factories.User() editor = factories.User() # org owned by my_user other_users = [ {'name': editor['id'], 'capacity': 'editor'} ] org = factories.Organization(user=my_user, users=other_users) pkg = factories.Dataset(auto_doi_identifier=True, doi_identifier=None, author='My Author', user=editor, owner_org=org['id'], doi_prefix='10.5072/FK2') doi = doi_lib.get_doi(pkg['id']) assert_true(doi is None)
def after_create(self, context, pkg_dict): """ A new dataset has been created, so we need to create a new DOI NB: This is called after creation of a dataset, and before resources have been added so state = draft @param context: @param pkg_dict: @return: """ # Only create a new DOI if the user has requested it if "dataset_category" in pkg_dict: # Load the local DOI doi = get_doi(pkg_dict['id']) # There is a chance that a doi has already been created for this pkg_id # and could cause an integrity error if another is added if not doi: # Create a new doi create_unique_identifier(pkg_dict['id']) # Remove the auto create field from the dataset pkg pkg_dict.pop('dataset_category') return pkg_dict
def after_update(self, context, pkg_dict): ''' Dataset has been created / updated. Check status of the dataset to determine if we should publish DOI. @param pkg_dict: @return: pkg_dict ''' package_id = pkg_dict['id'] # Load the local DOI doi = get_doi(package_id) # If we're not auto managing the doi, but there is a DOI object # associated with the package, delete it. if not pkg_dict.get('auto_doi_identifier') and doi: delete_doi(package_id) doi = None # We might be short circuiting the after_update if context.get('no_after_update') \ or not pkg_dict.get('auto_doi_identifier'): return pkg_dict # If we don't have a DOI, create one. # This could happen if the DOI module is enabled after a dataset # has been created, or if a user has added their own on dataset # creation, but subsequently deleted it. if not doi: prefix = pkg_dict.get('doi_prefix') doi = create_unique_identifier(package_id, prefix) # ensure doi.identifier and pkg['doi_identifier'] are the same if doi.identifier != pkg_dict['doi_identifier']: self._update_pkg_doi(context, package_id, doi.identifier) # Is this active and public? If so we need to make sure we have an # active DOI if pkg_dict.get('state', 'active') == 'active' \ and not pkg_dict.get('private', False): # Load the original package, so we can determine if user has # changed any fields orig_pkg_dict = get_action('package_show')(context, {'id': package_id}) # Metadata created isn't populated in pkg_dict - so copy from the # original pkg_dict['metadata_created'] = orig_pkg_dict['metadata_created'] # Build the metadata dict to pass to DataCite service metadata_dict = build_metadata(pkg_dict, doi) # Perform some basic checks against the data - we require at the # very least title and author fields - they're mandatory in the # DataCite Schema This will only be an issue if another plugin has # removed a mandatory field validate_metadata(metadata_dict) # Is this an existing DOI? Update it if doi.published: # Before updating, check if any of the metadata has been # changed - otherwise we end up sending loads of revisions to # DataCite for minor edits Load the current version orig_metadata_dict = build_metadata(orig_pkg_dict, doi) # Check if the two dictionaries are the same if cmp(orig_metadata_dict, metadata_dict) != 0: # Not the same, so we want to update the metadata update_doi(package_id, **metadata_dict) # TODO: If editing a dataset older than 5 days, create DOI # revision # New DOI - publish to datacite else: publish_doi(package_id, **metadata_dict) return pkg_dict
def after_update(self, context, pkg_dict): """ Dataset has been created / updated Check status of the dataset to determine if we should publish DOI to datacite network @param pkg_dict: @return: pkg_dict """ # Is this active and public? If so we need to make sure we have an active DOI if pkg_dict.get('state', 'active') == 'active' and not pkg_dict.get( 'private', False): package_id = pkg_dict['id'] # Load the original package, so we can determine if user has changed any fields orig_pkg_dict = get_action('package_show')(context, { 'id': package_id }) # Metadata created isn't populated in pkg_dict - so copy from the original pkg_dict['metadata_created'] = orig_pkg_dict['metadata_created'] # Load the local DOI doi = get_doi(package_id) # If we don't have a DOI, create one # This could happen if the DOI module is enabled after a dataset has been creates if not doi: doi = create_unique_identifier(package_id) # Build the metadata dict to pass to DataCite service metadata_dict = self.build_metadata(pkg_dict, doi) # Perform some basic checks against the data - we require at the very least # title and author fields - they're mandatory in the DataCite Schema # This will only be an issue if another plugin has removed a mandatory field self.validate_metadata(metadata_dict) # Is this an existing DOI? Update it if doi.published: # Before updating, check if any of the metadata has been changed - otherwise # We end up sending loads of revisions to DataCite for minor edits # Load the current version orig_metadata_dict = self.build_metadata(orig_pkg_dict, doi) # Check if the two dictionaries are the same if cmp(orig_metadata_dict, metadata_dict) != 0: # Not the same, so we want to update the metadata update_doi(package_id, **metadata_dict) h.flash_success('DataCite DOI metadata updated') # TODO: If editing a dataset older than 5 days, create DOI revision # New DOI - publish to datacite else: h.flash_success('DataCite DOI created') publish_doi(package_id, **metadata_dict) return pkg_dict