Skip to content

Plugin

DOIPlugin

Bases: SingletonPlugin, DefaultDatasetForm

CKAN DOI Extension.

Source code in ckanext/doi/plugin.py
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
class DOIPlugin(SingletonPlugin, toolkit.DefaultDatasetForm):
    """
    CKAN DOI Extension.
    """

    implements(interfaces.IConfigurer)
    implements(interfaces.IPackageController, inherit=True)
    implements(interfaces.ITemplateHelpers, inherit=True)
    implements(interfaces.IClick)

    ## IClick
    def get_commands(self):
        return cli.get_commands()

    ## IConfigurer
    def update_config(self, config):
        """
        Adds templates.
        """
        toolkit.add_template_directory(config, 'theme/templates')

    ## IPackageController
    def after_dataset_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, before resources have been
        added, so state = draft.
        """
        DOIQuery.read_package(pkg_dict['id'], create_if_none=True)

    ## IPackageController
    def after_dataset_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.
        """
        # 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']

            # remove user-defined update schemas first (if needed)
            context.pop('schema', None)

            # Load the package_show version of the dict
            pkg_show_dict = toolkit.get_action('package_show')(
                context, {'id': package_id}
            )

            # Load or create the local DOI (package may not have a DOI if extension was loaded
            # after package creation)
            doi = DOIQuery.read_package(package_id, create_if_none=True)

            metadata_dict = build_metadata_dict(pkg_show_dict)
            xml_dict = build_xml_dict(metadata_dict)

            client = DataciteClient()

            if doi.published is None:
                # metadata gets created before minting
                client.set_metadata(doi.identifier, xml_dict)
                client.mint_doi(doi.identifier, package_id)

                try:
                    toolkit.h.flash_success('DataCite DOI created')
                except RuntimeError:
                    # fix out of context issue while running cli commands
                    pass
            else:
                same = client.check_for_update(doi.identifier, xml_dict)
                if not same:
                    # Not the same, so we want to update the metadata
                    client.set_metadata(doi.identifier, xml_dict)

                    try:
                        toolkit.h.flash_success('DataCite DOI metadata updated')
                    except RuntimeError:
                        # fix out of context issue while running cli commands
                        pass

        return pkg_dict

    # IPackageController
    def after_dataset_show(self, context, pkg_dict):
        """
        Add the DOI details to the pkg_dict so it can be displayed.
        """
        doi = DOIQuery.read_package(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'] = toolkit.config.get('ckanext.doi.publisher')

    def after_create(self, *args, **kwargs):
        """
        CKAN 2.9 compat version of after_dataset_create.
        """
        return self.after_dataset_create(*args, **kwargs)

    def after_update(self, *args, **kwargs):
        """
        CKAN 2.9 compat version of after_dataset_update.
        """
        return self.after_dataset_update(*args, **kwargs)

    def after_show(self, *args, **kwargs):
        """
        CKAN 2.9 compat version of after_dataset_show.
        """
        return self.after_dataset_show(*args, **kwargs)

    # ITemplateHelpers
    def get_helpers(self):
        return {
            'package_get_year': package_get_year,
            'now': datetime.now,
            'get_site_title': get_site_title,
            'doi_test_mode': doi_test_mode,
        }

after_create(*args, **kwargs)

CKAN 2.9 compat version of after_dataset_create.

Source code in ckanext/doi/plugin.py
127
128
129
130
131
def after_create(self, *args, **kwargs):
    """
    CKAN 2.9 compat version of after_dataset_create.
    """
    return self.after_dataset_create(*args, **kwargs)

after_dataset_create(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, before resources have been added, so state = draft.

Source code in ckanext/doi/plugin.py
48
49
50
51
52
53
54
55
def after_dataset_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, before resources have been
    added, so state = draft.
    """
    DOIQuery.read_package(pkg_dict['id'], create_if_none=True)

after_dataset_show(context, pkg_dict)

Add the DOI details to the pkg_dict so it can be displayed.

Source code in ckanext/doi/plugin.py
113
114
115
116
117
118
119
120
121
122
123
124
125
def after_dataset_show(self, context, pkg_dict):
    """
    Add the DOI details to the pkg_dict so it can be displayed.
    """
    doi = DOIQuery.read_package(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'] = toolkit.config.get('ckanext.doi.publisher')

after_dataset_update(context, pkg_dict)

Dataset has been created/updated.

Check status of the dataset to determine if we should publish DOI to datacite network.

Source code in ckanext/doi/plugin.py
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
def after_dataset_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.
    """
    # 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']

        # remove user-defined update schemas first (if needed)
        context.pop('schema', None)

        # Load the package_show version of the dict
        pkg_show_dict = toolkit.get_action('package_show')(
            context, {'id': package_id}
        )

        # Load or create the local DOI (package may not have a DOI if extension was loaded
        # after package creation)
        doi = DOIQuery.read_package(package_id, create_if_none=True)

        metadata_dict = build_metadata_dict(pkg_show_dict)
        xml_dict = build_xml_dict(metadata_dict)

        client = DataciteClient()

        if doi.published is None:
            # metadata gets created before minting
            client.set_metadata(doi.identifier, xml_dict)
            client.mint_doi(doi.identifier, package_id)

            try:
                toolkit.h.flash_success('DataCite DOI created')
            except RuntimeError:
                # fix out of context issue while running cli commands
                pass
        else:
            same = client.check_for_update(doi.identifier, xml_dict)
            if not same:
                # Not the same, so we want to update the metadata
                client.set_metadata(doi.identifier, xml_dict)

                try:
                    toolkit.h.flash_success('DataCite DOI metadata updated')
                except RuntimeError:
                    # fix out of context issue while running cli commands
                    pass

    return pkg_dict

after_show(*args, **kwargs)

CKAN 2.9 compat version of after_dataset_show.

Source code in ckanext/doi/plugin.py
139
140
141
142
143
def after_show(self, *args, **kwargs):
    """
    CKAN 2.9 compat version of after_dataset_show.
    """
    return self.after_dataset_show(*args, **kwargs)

after_update(*args, **kwargs)

CKAN 2.9 compat version of after_dataset_update.

Source code in ckanext/doi/plugin.py
133
134
135
136
137
def after_update(self, *args, **kwargs):
    """
    CKAN 2.9 compat version of after_dataset_update.
    """
    return self.after_dataset_update(*args, **kwargs)

update_config(config)

Adds templates.

Source code in ckanext/doi/plugin.py
41
42
43
44
45
def update_config(self, config):
    """
    Adds templates.
    """
    toolkit.add_template_directory(config, 'theme/templates')