Skip to content

Commit

Permalink
openaire: helper functions
Browse files Browse the repository at this point in the history
* Adds helper functions for determining OpenAIRE type of a record.

* Adds function to compute an OpenAIRE identifier as well as portal
  link.

(closes #1105)
  • Loading branch information
lnielsen committed Jun 1, 2017
1 parent 98e48a4 commit 809e08d
Show file tree
Hide file tree
Showing 3 changed files with 216 additions and 5 deletions.
99 changes: 99 additions & 0 deletions tests/unit/openaire/test_openaire_helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
# -*- coding: utf-8 -*-
#
# This file is part of Zenodo.
# Copyright (C) 2017 CERN.
#
# Zenodo is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Zenodo is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Zenodo; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307, USA.
#
# In applying this license, CERN does not
# waive the privileges and immunities granted to it by virtue of its status
# as an Intergovernmental Organization or submit itself to any jurisdiction.

"""Test for OpenAIRE helpers."""

from __future__ import absolute_import, print_function

from zenodo.modules.openaire.helpers import openaire_id, openaire_link, \
openaire_type


def test_openire_type(app, minimal_record):
"""Test OpenAIRE type."""
r = minimal_record
# Default zenodo type is software which has no OpenAIRE type.
assert openaire_type(r) is None

# Datasets just map to datasets.
r['resource_type']['type'] = 'dataset'
assert openaire_type(r) == 'dataset'

# Open publications
r['resource_type']['type'] = 'publication'
assert openaire_type(r) == 'publication'

# Non-open publications
r['access_right'] = 'embargoed'
assert openaire_type(r) is None
# with grants
r['grants'] = [{'id': 'someid'}]
assert openaire_type(r) == 'publication'

# in ecfunded community
del r['grants']
r['communities'] = ['ecfunded']
assert openaire_type(r) == 'publication'
r['communities'] = ['zenodo']
assert openaire_type(r) is None


def test_openire_id(app, minimal_record):
"""Test OpenAIRE ID."""
r = minimal_record
r['doi'] = u'10.5281/zenodo.123'
r['_oai'] = {'id': u'oai:zenodo.org:123'}

# Default zenodo type is software which has no OpenAIRE type.
assert openaire_id(r) is None

# Dataset ID
r['resource_type']['type'] = 'dataset'
assert openaire_id(r) == 'r37b0ad08687::204007f516ddcf0a452c2f22d48695ca'

# Publication ID
r['resource_type']['type'] = 'publication'
assert openaire_id(r) == 'od______2659::47287d1800c112499a117ca17aa1909d'


def test_openire_link(app, minimal_record):
"""Test OpenAIRE ID."""
r = minimal_record
r['doi'] = u'10.5281/zenodo.123'
r['_oai'] = {'id': u'oai:zenodo.org:123'}

# Default zenodo type is software which has no OpenAIRE type.
assert openaire_link(r) is None

# Dataset ID
r['resource_type']['type'] = 'dataset'
assert openaire_link(r) == \
'https://beta.openaire.eu/search/dataset' \
'?datasetId=r37b0ad08687::204007f516ddcf0a452c2f22d48695ca'

# Publication ID
r['resource_type']['type'] = 'publication'
assert openaire_link(r) == \
'https://beta.openaire.eu/search/publication' \
'?articleId=od______2659::47287d1800c112499a117ca17aa1909d'
10 changes: 5 additions & 5 deletions zenodo/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -275,20 +275,20 @@ def _(x):
OPENAIRE_SCHEMAS_HOST = 'zenodo.org'
#: Hostname for OpenAIRE's grant resolver.
OPENAIRE_JSONRESOLVER_GRANTS_HOST = 'dx.zenodo.org'
#: OpenAIRE Zenodo IDs
#: OpenAIRE data source IDs for Zenodo.
OPENAIRE_ZENODO_IDS = {
'publication': 'opendoar____::2659',
'dataset': 're3data_____::r3d100010468',
}
#: OpenAIRE Zenodo namespace prefixes
#: OpenAIRE ID namespace prefixes for Zenodo.
OPENAIRE_NAMESPACE_PREFIXES = {
'publication': 'od______2659',
'dataset': 'r37b0ad08687',
}
#: OpenAIRE API endpoint.
OPENAIRE_API_URL = 'https://beta.services.openaire.eu/is/mvc'
# TODO: Check if we are to use Dev or Beta endpoint...
# OPENAIRE_API_URL = 'http://dev.openaire.research-infrastructures.eu/is/mvc'
OPENAIRE_API_URL = 'http://dev.openaire.research-infrastructures.eu/is/mvc'
#: URL to OpenAIRE portal.
OPENAIRE_PORTAL_URL = 'https://beta.openaire.eu'

# OpenDefinition
# ==============
Expand Down
112 changes: 112 additions & 0 deletions zenodo/modules/openaire/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
# -*- coding: utf-8 -*-
#
# This file is part of Zenodo.
# Copyright (C) 2017 CERN.
#
# Zenodo is free software; you can redistribute it
# and/or modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 2 of the
# License, or (at your option) any later version.
#
# Zenodo is distributed in the hope that it will be
# useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with Zenodo; if not, write to the
# Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston,
# MA 02111-1307, USA.
#
# In applying this license, CERN does not
# waive the privileges and immunities granted to it by virtue of its status
# as an Intergovernmental Organization or submit itself to any jurisdiction.

"""OpenAIRE related helpers."""

from __future__ import absolute_import, print_function

import hashlib

from flask import current_app


class _OAType(object):
"""OpenAIRE types."""

publication = 'publication'
dataset = 'dataset'


def is_openaire_publication(record):
"""Determine if record is a publication for OpenAIRE."""
types = ['publication', 'presentation', 'poster']
if record.get('resource_type', {}).get('type') not in types:
return False

# Has grants, is part of ecfunded community or is open access.
if record.get('grants') or 'ecfunded' in record.get('communities', []) or \
'open' == record.get('access_right'):
return True
return False


def is_openaire_dataset(record):
"""Determine if record is a dataset for OpenAIRE."""
if record.get('resource_type', {}).get('type') == 'dataset':
return True
return False


def openaire_type(record):
"""Get the OpenAIRE type of a record."""
if is_openaire_publication(record):
return _OAType.publication
elif is_openaire_dataset(record):
return _OAType.dataset
return None


def openaire_id(record):
"""Compute the OpenAIRE identifier."""
return _openaire_id(record, openaire_type(record))


def _openaire_id(record, oatype):
"""Compute the OpenAIRE identifier."""
prefix = None
value = None
if oatype == _OAType.publication:
# Hard-coded prefix from OpenAIRE.
prefix = current_app.config['OPENAIRE_ID_PREFIX_PUBLICATION']
value = record.get('_oai', {}).get('id')
elif oatype == _OAType.dataset:
# Hard-coded prefix from OpenAIRE.
prefix = current_app.config['OPENAIRE_ID_PREFIX_DATASET']
value = record.get('doi')

if not value or not prefix:
return None

m = hashlib.md5()
m.update(value.encode('utf8'))

return '{}::{}'.format(prefix, m.hexdigest())


def openaire_link(record):
"""Compute an OpenAIRE link."""
oatype = openaire_type(record)
oaid = _openaire_id(record, oatype)

if oatype == _OAType.publication:
return '{}/search/publication?articleId={}'.format(
current_app.config['OPENAIRE_PORTAL_URL'],
oaid,
)
elif oatype == _OAType.dataset:
return '{}/search/dataset?datasetId={}'.format(
current_app.config['OPENAIRE_PORTAL_URL'],
oaid,
)
return None

0 comments on commit 809e08d

Please sign in to comment.