コード例 #1
0
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}
コード例 #2
0
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}
コード例 #3
0
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}
コード例 #4
0
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}
コード例 #5
0
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}
コード例 #6
0
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'}