def update_doi(package_id, **kwargs): """Updates the DOI metadata""" doi = get_doi(package_id) kwargs["identifier"] = doi.identifier doi_api = get_doi_api() try: doi_api.update(**kwargs) except HTTPError as e: log.error("Could not update DOI for package {0}. " + "Failed with error: {1}".format(package_id, e.message)) raise e
def create_unique_identifier(package_id, prefix): """ Create a unique identifier, using the prefix and a random number: 10.5072/0044634 Check the random number doesn't exist in the table or the datacite repository """ doi_api = get_doi_api() # validate prefix here prefix must be defined in the ini file, either # ckanext.doi.prefix and ckanext.doi.shoulder, or in # ckanext.doi.prefix_choices. # If prefix doesn't have at least one `/`, add one to the end prefix = _prepare_prefix(prefix) while True: # the api provider may have a make_identifier_id method, try it first, # then fall back to default. try: identifier_id = doi_api.make_identifier_id() except AttributeError: identifier_id = "{0:07}".format(random.randint(1, 100000)) # identifier = os.path.join(get_prefix(), identifier_id) identifier = prefix + identifier_id # Check this identifier doesn't exist in the table if not Session.query(DOI).filter(DOI.identifier == identifier).count(): # And check against the api service try: doi = doi_api.get(identifier) except HTTPError: pass else: if doi.text: continue doi = create_doi_from_identifier(package_id, identifier) return doi
def publish_doi(package_id, **kwargs): """ Publish a DOI to provider See MetadataDataCiteAPI.metadata_to_xml for param information @param package_id: @param kwargs contains metadata: @param title: @param creator: @param publisher: @param publisher_year: """ identifier = kwargs.get("identifier") doi_api = get_doi_api() # The ID of a dataset never changes, so use that for the URL url = os.path.join(get_site_url(), "dataset", package_id) try: r = doi_api.create(url=url, **kwargs) except HTTPError as e: log.error("Publishing DOI for package {0} failed with error: {1}".format(package_id, e.message)) raise e # If we have created the DOI, save it to the database if r.status_code == 201: # Update status for this package and identifier num_affected = ( Session.query(DOI) .filter_by(package_id=package_id, identifier=identifier) .update({"published": datetime.datetime.now()}) ) # Raise an error if update has failed - should never happen unless # DataCite and local db get out of sync - in which case requires # investigating assert num_affected == 1, "Updating local DOI failed"
def test_get_doi_api_returns_correct_config_set_api_interface(self): '''Calling get_doi_api will return the correct api interface when ckanext.doi.api_provider has been set''' # api is the correct interface class for EZID doi_api = get_doi_api() assert_true(isinstance(doi_api, ezid_api.DOIEzidAPI))
def test_get_doi_api_returns_correct_default_api_interface(self): '''Calling get_doi_api returns the correct api interface when nothing has been set for ckanext.doi.api_provider''' # default api is EZID. doi_api = get_doi_api() assert_true(isinstance(doi_api, ezid_api.DOIEzidAPI))