def _approve(data_dict, context, type='package'): log.debug('_approve: Approving "{0}" ({1})'.format(data_dict['id'], data_dict.get('name', ''))) # a dataset id i s necessary try: id_or_name = data_dict['id'] except KeyError: raise toolkit.ValidationError({'id': 'missing id'}) dataset_dict = toolkit.get_action('package_show')(context, {'id': id_or_name}) # DOI has to be already reserved (minted) doi = dataset_dict.get('doi', '') default_prefix = config.get('datacite_publication.doi_prefix', '10.xxxxx') allowed_prefixes = config.get('datacite_publication.custom_prefix', '').split(' ') + [default_prefix] log.debug('_approve: Doi "{0}" ({1})'.format(doi, ', '.join(allowed_prefixes))) doi_prefix = doi.split('/')[0].strip() if (not doi) or (len(doi) <= 0) or (doi_prefix not in allowed_prefixes): raise toolkit.ValidationError( {'doi': 'dataset has no valid minted DOI [' + ', '.join(allowed_prefixes) + ']/*'}) # Check authorization package_id = dataset_dict.get('package_id', dataset_dict.get('id', id_or_name)) if not authz.is_authorized( 'package_update', context, {'id': package_id}).get('success', False) or not helpers.datacite_publication_is_admin(): log.error('ERROR approving dataset, current user is not authorized: isAdmin = {0}'.format( helpers.datacite_publication_is_admin())) raise toolkit.NotAuthorized({ 'permissions': ['Not authorized to approve the dataset (admin only).']}) # change publication state dataset_dict['publication_state'] = 'approved' dataset_dict['private'] = False context['message'] = APPROVAL_MESSAGE + " for dataset {0}".format(package_id) toolkit.get_action('package_update')(context=context, data_dict=dataset_dict) # save activity _add_activity(dataset_dict, APPROVAL_MESSAGE, context) # notify owner and involved users dataset_owner = dataset_dict.get('creator_user_id', '') datacite_approved_mail(dataset_owner, dataset_dict, context) return {'success': True, 'error': None}
def _finish_manually(data_dict, context, type='package'): log.debug('_finish_manually: Finishing "{0}" ({1})'.format(data_dict['id'], data_dict.get('name', ''))) # a dataset id i s necessary try: id_or_name = data_dict['id'] except KeyError: raise toolkit.ValidationError({'id': 'missing id'}) dataset_dict = toolkit.get_action('package_show')(context, {'id': id_or_name}) # DOI has to be already reserved (minted) if not dataset_dict.get('doi', None): raise toolkit.ValidationError({'doi': 'dataset has no valid minted DOI'}) # Check authorization package_id = dataset_dict.get('package_id', dataset_dict.get('id', id_or_name)) if not authz.is_authorized( 'package_update', context, {'id': package_id}).get('success', False) or not helpers.datacite_publication_is_admin(): log.error('ERROR finishing publication dataset, current user is not authorized: isAdmin = {0}'.format( helpers.datacite_publication_is_admin())) raise toolkit.NotAuthorized({ 'permissions': ['Not authorized to finish manually the dataset publication (admin only).']}) # change publication state dataset_dict['publication_state'] = 'published' dataset_dict['private'] = False context['message'] = FINISH_MESSAGE + " for dataset {0}".format(package_id) toolkit.get_action('package_update')(context=context, data_dict=dataset_dict) # save activity _add_activity(dataset_dict, FINISH_MESSAGE, context) # notify owner and involved users dataset_owner = dataset_dict.get('creator_user_id', '') datacite_finished_mail(dataset_owner, dataset_dict, context) return {'success': True, 'error': None}
def _publish_resource(data_dict, context): # validate the id and get the resource data try: id = data_dict['id'] except KeyError: raise toolkit.ValidationError({'id': 'missing id'}) resource_dict = toolkit.get_action('resource_show')(context, {'id': id}) package_id = data_dict.get('package_id') package_dict = toolkit.get_action('package_show')(context, {'id': package_id}) # Check authorization ckan_user = _get_username_from_context(context) if not helpers.datacite_publication_is_admin(ckan_user): raise toolkit.NotAuthorized({ 'permissions': ['Not authorized to publish the resource (admins only).']}) # check if it is an update update = data_dict.get('update', False) log.debug('_publish_resource: *UPDATE* = {0}'.format(update)) # state to publish has to be not yet published state = resource_dict.get('publication_state', '') if not update and state == 'published': return {'success': False, 'error': 'Resource is already in state "published"'} # state to update has to be not published if update and state != 'published': return {'success': False, 'error': 'Resource is should be in state "published" for updating'} # DOI has to be already present and valid custom_doi = resource_dict.get('doi', '') if (not custom_doi) or (len(custom_doi) <= 0): log.error('_publish_resource: resource has no minted DOI') return {'success': False, 'error': 'Custom DOI not valid: empty'} default_prefix = config.get('datacite_publication.doi_prefix', '') allowed_prefixes = config.get('datacite_publication.custom_prefix', '').split(' ') + [default_prefix] custom_prefix = custom_doi.split('/')[0].strip() if custom_prefix not in allowed_prefixes: log.error('_publish_resource: resource has no valid minted DOI [' + ', '.join(allowed_prefixes) + ']/*') return {'success': False, 'error': 'Custom DOI not valid: prefix not allowed'} custom_suffix = custom_doi.split('/')[1].strip() if (not custom_suffix) or (len(custom_suffix) <= 0): log.error('_publish_resource: resource has an empty DOI suffix') return {'success': False, 'error': 'Custom DOI not valid: suffix empty'} if update: log.info("updating CUSTOM resource DOI by an Admin {0}/{1}, allowed: {2}".format(custom_prefix, custom_suffix, allowed_prefixes)) else: log.info("publishing CUSTOM resource DOI by an Admin {0}/{1}, allowed: {2}".format(custom_prefix, custom_suffix, allowed_prefixes)) # Get the DOI minter minter_name = config.get('datacite_publication.minter', DEAFULT_MINTER) package_name, class_name = minter_name.rsplit('.', 1) module = importlib.import_module(package_name) minter_class = getattr(module, class_name) minter = minter_class() if update: doi = custom_doi # check when possible if the association doi-ckan id is valid: log.debug("CHECK DOI in minter") is_doi_valid_op = getattr(minter, "is_doi_valid", None) if callable(is_doi_valid_op): valid_doi = minter.is_doi_valid(doi, id, entity_type='resource') if not valid_doi: return {'success': False, 'error': 'DOI and id do not match to the DOI realisation table in the DB'} else: # Mint custom DOI doi, error = minter.mint(custom_prefix, pkg=resource_dict, user=ckan_user, suffix=custom_suffix, entity='resource') log.debug("minter got doi={0}, error={1}".format(doi, error)) if error: log.error("error minting DOI for resource {0}, error{1}".format(id, error)) return {'success': False, 'error': error.split('DETAIL')[0]} log.info("success saving custom minted DOI for resource {0}, doi {1}".format(id, doi)) # Publish to DataCite datacite_publisher = DatacitePublisher() try: doi, error = datacite_publisher.publish_resource(doi, resource=resource_dict, package=package_dict, context=context, update=update) except Exception as e: log.error("exception publishing resource {0} to Datacite, error {1}".format(id, traceback.format_exc())) return {'success': False, 'error': 'Exception when publishing to DataCite: {0}'.format(e)} except: log.error("error publishing resource {0} to Datacite, error {1}".format(id, sys.exc_info()[0])) return {'success': False, 'error': 'Unknown error when publishing to DataCite: {0}'.format(sys.exc_info()[0])} if error: log.error("error publishing resource {0} to Datacite, error {1}".format(id, error)) return {'success': False, 'error': error} if not update: # update dataset publication state resource_patch = {'id': id, 'publication_state': 'published'} resource_patched = toolkit.get_action('resource_patch')(context, resource_patch) return {'success': True, 'error': None}
def _update_in_datacite(data_dict, context, type='package'): log.debug( '_update_in_datacite: Updating in datacite "{0}" ({1})'.format(data_dict['id'], data_dict.get('name', ''))) # a dataset id i s necessary try: id_or_name = data_dict['id'] except KeyError: raise toolkit.ValidationError({'id': 'missing id'}) dataset_dict = toolkit.get_action('package_show')(context, {'id': id_or_name}) # state has to be approved state = dataset_dict.get('publication_state', '') if state != 'published': raise toolkit.ValidationError({'publication_state': 'dataset needs to be in state "published" (in datacite)'}) # DOI has to be already present doi = dataset_dict.get('doi', '') default_prefix = config.get('datacite_publication.doi_prefix', '10.xxxxx') allowed_prefixes = config.get('datacite_publication.custom_prefix', '').split(' ') + [default_prefix] doi_prefix = doi.split('/')[0].strip() if (not doi) or (len(doi) <= 0) or (doi_prefix not in allowed_prefixes): raise toolkit.ValidationError( {'doi': 'dataset has no valid minted DOI [' + ', '.join(allowed_prefixes) + ']/*'}) # Check authorization package_id = dataset_dict.get('package_id', dataset_dict.get('id', id_or_name)) if not authz.is_authorized( 'package_update', context, {'id': package_id}).get('success', False) or not helpers.datacite_publication_is_admin(): log.error( 'ERROR updating publication dataset in datacite, current user is not authorized: isAdmin = {0}'.format( helpers.datacite_publication_is_admin())) raise toolkit.NotAuthorized({ 'permissions': ['Not authorized to perform the dataset update to datacite (admin only).']}) # Get the DOI minter minter_name = config.get('datacite_publication.minter', DEAFULT_MINTER) package_name, class_name = minter_name.rsplit('.', 1) module = importlib.import_module(package_name) minter_class = getattr(module, class_name) minter = minter_class() # check when possible if the association doi-ckan id is valid: log.debug("CHECK DOI in minter") is_doi_valid_op = getattr(minter, "is_doi_valid", None) if callable(is_doi_valid_op): valid_doi = minter.is_doi_valid(doi, package_id) if not valid_doi: return {'success': False, 'error': 'DOI and id do not match to the DOI realisation table in the DB'} datacite_publisher = DatacitePublisher() try: doi, error = datacite_publisher.publish(doi, pkg=dataset_dict, context=context, update=True) except Exception as e: log.error("exception updating package {0} in Datacite, error {1}".format(package_id, traceback.format_exc())) return {'success': False, 'error': 'Exception when updating in DataCite: {0}'.format(e)} except: log.error("error updating package {0} in Datacite, error {1}".format(package_id, sys.exc_info()[0])) return {'success': False, 'error': 'Unknown error when updating in DataCite: {0}'.format(sys.exc_info()[0])} if error: log.error("error updating package {0} to Datacite, error {1}".format(package_id, error)) return {'success': False, 'error': error} # save activity _add_activity(dataset_dict, UPDATE_MESSAGE, context) return {'success': True, 'error': None}
def _publish_to_datacite(data_dict, context, type='package'): log.debug( '_publish_to_datacite: Publishing to datacite "{0}" ({1})'.format(data_dict['id'], data_dict.get('name', ''))) # a dataset id i s necessary try: id_or_name = data_dict['id'] except KeyError: raise toolkit.ValidationError({'id': 'missing id'}) dataset_dict = toolkit.get_action('package_show')(context, {'id': id_or_name}) # state has to be approved state = dataset_dict.get('publication_state', '') if state != 'approved': raise toolkit.ValidationError({'publication_state': 'dataset needs to be in state "approved" (by the admin)'}) # DOI has to be already reserved (minted) doi = dataset_dict.get('doi', '') default_prefix = config.get('datacite_publication.doi_prefix', '10.xxxxx') allowed_prefixes = config.get('datacite_publication.custom_prefix', '').split(' ') + [default_prefix] doi_prefix = doi.split('/')[0].strip() if (not doi) or (len(doi) <= 0) or (doi_prefix not in allowed_prefixes): raise toolkit.ValidationError( {'doi': 'dataset has no valid minted DOI [' + ', '.join(allowed_prefixes) + ']/*'}) # Check authorization package_id = dataset_dict.get('package_id', dataset_dict.get('id', id_or_name)) if not authz.is_authorized( 'package_update', context, {'id': package_id}).get('success', False) or not helpers.datacite_publication_is_admin(): log.error( 'ERROR finishing publication dataset in datacite, current user is not authorized: isAdmin = {0}'.format( helpers.datacite_publication_is_admin())) raise toolkit.NotAuthorized({ 'permissions': ['Not authorized to perform the dataset publication to datacite (admin only).']}) datacite_publisher = DatacitePublisher() try: doi, error = datacite_publisher.publish(doi, pkg=dataset_dict, context=context) except Exception as e: log.error("exception publishing package {0} to Datacite, error {1}".format(package_id, traceback.format_exc())) return {'success': False, 'error': 'Exception when publishing to DataCite: {0}'.format(e)} except: log.error("error publishing package {0} to Datacite, error {1}".format(package_id, sys.exc_info()[0])) return {'success': False, 'error': 'Unknown error when publishing to DataCite: {0}'.format(sys.exc_info()[0])} if error: log.error("error publishing package {0} to Datacite, error {1}".format(package_id, error)) return {'success': False, 'error': error} # change publication state dataset_dict['publication_state'] = 'published' dataset_dict['private'] = False context['message'] = FINISH_MESSAGE + " for dataset {0}".format(package_id) toolkit.get_action('package_update')(context=context, data_dict=dataset_dict) # save activity _add_activity(dataset_dict, FINISH_MESSAGE, context) # notify owner and involved users dataset_owner = dataset_dict.get('creator_user_id', '') datacite_finished_mail(dataset_owner, dataset_dict, context) return {'success': True, 'error': None}
def _publish(data_dict, context, type='package'): try: id_or_name = data_dict['id'] except KeyError: raise toolkit.ValidationError({'id': 'missing id'}) dataset_dict = toolkit.get_action('package_show')(context, {'id': id_or_name}) # Check authorization package_id = dataset_dict.get('package_id', dataset_dict.get('id', id_or_name)) if not authz.is_authorized( 'package_update', context, {'id': package_id}).get('success', False): raise toolkit.NotAuthorized({ 'permissions': ['Not authorized to publish the dataset.']}) # get user ckan_user = _get_username_from_context(context) # check if dataset has a DOI already existing_doi = dataset_dict.get('doi') if existing_doi: if helpers.datacite_publication_is_admin(ckan_user): return _publish_custom_by_admin(dataset_dict, package_id, ckan_user, context, type) else: return {'success': False, 'error': 'Dataset has already a DOI. Registering of custom DOI is currently not allowed'} # Check state if dataset_dict.get('publication_state', False): return {'success': False, 'error': 'Dataset publication state should be empty to request a new DOI'} # mint doi mint_doi(self, ckan_id, ckan_user, prefix_id = None, suffix = None, entity='package') minter_name = config.get('datacite_publication.minter', DEAFULT_MINTER) package_name, class_name = minter_name.rsplit('.', 1) module = importlib.import_module(package_name) minter_class = getattr(module, class_name) minter = minter_class() prefix = config.get('datacite_publication.doi_prefix', '10.xxxxx') doi, error = minter.mint(prefix, pkg=dataset_dict, user=ckan_user) log.debug("minter got doi={0}, error={1}".format(doi, error)) if doi: # update dataset dataset_dict['doi'] = doi dataset_dict['private'] = False # TODO: check what is the proper state once workflow is complete # dataset_dict['publication_state'] = 'reserved' dataset_dict['publication_state'] = 'pub_pending' context['message'] = REQUEST_MESSAGE + " for dataset {0}".format(package_id) toolkit.get_action('package_update')(context=context, data_dict=dataset_dict) # save activity _add_activity(dataset_dict, REQUEST_MESSAGE, context) # notify admin and user datacite_publication_requested_mail(ckan_user, dataset_dict) log.info("success minting DOI for package {0}, doi {1}".format(package_id, doi)) return {'success': True, 'error': None} else: log.error("error minting DOI for package {0}, error{1}".format(package_id, error)) return {'success': False, 'error': error} return {'success': False, 'error': 'Internal error'}