Skip to content

Commit

Permalink
Merge e131d50 into 98e48a4
Browse files Browse the repository at this point in the history
  • Loading branch information
lnielsen committed Jun 1, 2017
2 parents 98e48a4 + e131d50 commit d5b1c18
Show file tree
Hide file tree
Showing 12 changed files with 438 additions and 49 deletions.
1 change: 1 addition & 0 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@
'zenodo_communities = zenodo.modules.communities.views:blueprint',
'zenodo_deposit = zenodo.modules.deposit.views:blueprint',
'zenodo_frontpage = zenodo.modules.frontpage.views:blueprint',
'zenodo_openaire = zenodo.modules.openaire.views:blueprint',
'zenodo_redirector = zenodo.modules.redirector.views:blueprint',
'zenodo_search_ui = zenodo.modules.search_ui.views:blueprint',
'zenodo_theme = zenodo.modules.theme.views:blueprint',
Expand Down
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'
20 changes: 13 additions & 7 deletions tests/unit/records/test_schemas_openaire_json.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,10 @@ def minimal_oai_record(minimal_record):
minimal_record['_oai'] = {
'id': 'oai:zenodo.org:{}'.format(minimal_record['recid'])
}
minimal_record['resource_type'] = {
'type': 'publication',
'subtype': 'article'
}
return minimal_record


Expand Down Expand Up @@ -80,7 +84,7 @@ def test_resource_types(app, db, minimal_oai_record, recid_pid):
assert obj['originalId'] == 'oai:zenodo.org:123'
assert obj['collectedFromId'] == 'opendoar____::2659'
assert obj['hostedById'] == 'opendoar____::2659'
assert obj['resourceType'] == '0001'
assert obj['resourceType'] == '0004'
assert obj['type'] == 'publication'


Expand All @@ -89,6 +93,7 @@ def test_grants(app, db, minimal_oai_record, recid_pid):
minimal_oai_record['grants'] = [
{
'acronym': 'WorkAble',
'title': 'Making Capabilities/Design Work',
'identifiers': {
'eurepo': 'info:eu-repo/grantAgreement/EC/FP7/244909/'
},
Expand All @@ -99,23 +104,24 @@ def test_grants(app, db, minimal_oai_record, recid_pid):
obj = openaire_json_v1.transform_record(
recid_pid, Record(minimal_oai_record))
assert obj['linksToProjects'] == [
'info:eu-repo/grantAgreement/EC/FP7/244909///WorkAble'
'info:eu-repo/grantAgreement/EC/FP7/244909/'
'/Making Capabilities%2FDesign Work/WorkAble'
]


def test_pids(app, db, minimal_oai_record, recid_pid):
""""Test PIDs."""
obj = openaire_json_v1.transform_record(
recid_pid, Record(minimal_oai_record))
assert sorted(obj['pids']) == \
sorted([{'value': 'oai:zenodo.org:123', 'type': 'oai'}])
assert obj['pids'] == \
[{'value': 'oai:zenodo.org:123', 'type': 'oai'}]

minimal_oai_record['doi'] = '10.1234/foo'
obj = openaire_json_v1.transform_record(
recid_pid, Record(minimal_oai_record))
assert sorted(obj['pids']) == \
sorted([{'value': 'oai:zenodo.org:123', 'type': 'oai'},
{'value': '10.1234/foo', 'type': 'doi'}])
assert obj['pids'] == \
[{'value': 'oai:zenodo.org:123', 'type': 'oai'},
{'value': '10.1234/foo', 'type': 'doi'}]


def test_publisher(app, db, minimal_oai_record, recid_pid):
Expand Down
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
2 changes: 1 addition & 1 deletion zenodo/modules/deposit/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@
from invenio_pidstore.resolver import Resolver
from invenio_records_files.models import RecordsBuckets

from zenodo.modules.deposit.utils import delete_record
from zenodo.modules.records.permissions import record_permission_factory

from .api import ZenodoDeposit
from .fetchers import zenodo_deposit_fetcher
from .forms import RecordDeleteForm
from .tasks import datacite_inactivate, datacite_register
from zenodo.modules.deposit.utils import delete_record

blueprint = Blueprint(
'zenodo_deposit',
Expand Down
119 changes: 119 additions & 0 deletions zenodo/modules/openaire/helpers.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
# -*- 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

from zenodo.modules.records.models import ObjectType


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

publication = 'publication'
dataset = 'dataset'


def is_openaire_publication(record):
"""Determine if record is a publication for OpenAIRE."""
oatype = ObjectType.get_by_dict(record.get('resource_type')).get(
'openaire', {})
if not oatype or oatype['type'] != _OAType.publication:
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."""
oatype = ObjectType.get_by_dict(record.get('resource_type')).get(
'openaire', {})
return oatype and oatype['type'] == _OAType.dataset


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, identifier = openaire_original_id(record, oatype)

if not identifier or not prefix:
return None

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

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


def openaire_original_id(record, oatype):
"""Original original identifier."""
prefix = current_app.config['OPENAIRE_NAMESPACE_PREFIXES'].get(oatype)

value = None
if oatype == _OAType.publication:
value = record.get('_oai', {}).get('id')
elif oatype == _OAType.dataset:
value = record.get('doi')

return prefix, value


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
Loading

0 comments on commit d5b1c18

Please sign in to comment.