From 4e31f125a95a4784d315ade33265cd1f2dcbe105 Mon Sep 17 00:00:00 2001 From: Panos Paparrigopoulos Date: Thu, 29 Sep 2016 15:40:33 +0200 Subject: [PATCH] orcid: send to orcid fixes * Fixes wrong field names. * Fixes serializer not being able to import configurations. * Fixes `get_author_collection_records_from_valid_authors` query to return expected data. * Adds plug for `orcid id` extraction method. Signed-off-by: Panos Paparrigopoulos --- invenio_orcid/config.py | 1 + invenio_orcid/serializers/orcid_serializer.py | 13 ++++---- invenio_orcid/tasks.py | 33 +++++++------------ invenio_orcid/utils.py | 22 +++++++++++-- 4 files changed, 38 insertions(+), 31 deletions(-) diff --git a/invenio_orcid/config.py b/invenio_orcid/config.py index 3cca53d..2b65bf4 100644 --- a/invenio_orcid/config.py +++ b/invenio_orcid/config.py @@ -31,6 +31,7 @@ } ORCID_JSON_CONVERTER_MODULE = 'invenio_orcid.utils:convert_to_orcid' +ORCID_ID_FETCHER = 'invenio_orcid.utils:get_orcid_id' ORCID_AUTHORS_SEARCH_CLASS = 'invenio_search:RecordsSearch' diff --git a/invenio_orcid/serializers/orcid_serializer.py b/invenio_orcid/serializers/orcid_serializer.py index 791e150..3bb7a14 100644 --- a/invenio_orcid/serializers/orcid_serializer.py +++ b/invenio_orcid/serializers/orcid_serializer.py @@ -26,21 +26,20 @@ from __future__ import absolute_import, print_function -import json - -from flask import jsonify +from flask import current_app, jsonify from invenio_orcid.utils import convert_to_orcid -from werkzeug import import_string +from werkzeug import cached_property, import_string class ORCIDSerializer(object): """Orcid serializer for records.""" - def __init__(self): - """Initialize state.""" - self.convert_to_orcid = import_string( + @cached_property + def convert_to_orcid(self): + """Import the orcid converter.""" + return import_string( current_app.config['ORCID_JSON_CONVERTER_MODULE']) def serialize(self, pid, record, links_factory=None): diff --git a/invenio_orcid/tasks.py b/invenio_orcid/tasks.py index ab75814..1bbdef8 100644 --- a/invenio_orcid/tasks.py +++ b/invenio_orcid/tasks.py @@ -51,15 +51,14 @@ def prepare_authors_data_for_pushing_to_orcid(data): fetcher_name = current_app.config['ORCID_RECORDS_PID_FETCHER'] pid = current_pidstore.fetchers[fetcher_name](None, data) record_identifier = pid.pid_value - record_id = resolver.resolve(data.get(record_identifier))[ - 0].object_uuid + record_id = resolver.resolve(record_identifier)[0].object_uuid authors = get_orcid_valid_authors(data) token = None author_orcid = '' authors_with_orcid_credentials = [] for author in authors: try: - token, author_orcid = get_authors_credentials(author['_source']) + token, author_orcid = get_authors_credentials(author) except AttributeError: continue try: @@ -86,14 +85,13 @@ def delete_from_orcid(sender, api=None): fetcher_name = current_app.config['ORCID_RECORDS_PID_FETCHER'] pid = current_pidstore.fetchers[fetcher_name](None, sender) record_identifier = pid.pid_value - record_id = resolver.resolve(sender.get(record_identifier))[ - 0].object_uuid + record_id = resolver.resolve(record_identifier)[0].object_uuid records = ORCIDRecords.query.filter_by(record_id=record_id).all() for record in records: raw_user = UserIdentity.query.filter_by( id=record.orcid, method='orcid').first() user = RemoteAccount.query.filter_by(user_id=raw_user.id_user).first() - token = user.tokens[0].access_token + token = user.remote_tokens[0].access_token api.remove_record(record.orcid, token, 'work', record.put_code) with db.session.begin_nested(): db.session.delete(record) @@ -114,7 +112,8 @@ def send_to_orcid(sender, api=None): fetcher_name = current_app.config['ORCID_RECORDS_PID_FETCHER'] pid = current_pidstore.fetchers[fetcher_name](None, sender) record_identifier = pid.pid_value - current_app.logger.info('Sending "{0}" to orcid.'.format(record_identifier)) + current_app.logger.info('Sending "{0}" to orcid.'.format( + record_identifier)) try: api = api or current_orcid.member convert_to_orcid = import_string( @@ -158,27 +157,19 @@ def send_to_orcid(sender, api=None): def get_author_collection_records_from_valid_authors(authors_refs): """Query elasticsearch for the author of the given authors references.""" - es_query = { - "filter": { - "bool": { - "must": [ - {"terms": { - "self.$ref": authors_refs - }}, {"match": { - "ids.type": "ORCID" - }} - ] - } - } + search_args = { + 'self__$ref': authors_refs } - return current_orcid.author_search.execute(es_query).hits.hits + query = current_orcid.author_search().query('match', ids__type='ORCID') \ + .query('terms', **search_args) + return query.execute().hits def get_orcid_valid_authors(record): """Return all the valid author-records from a record. - A valid author-rerord is one that contains an orcid id. + A valid author-rerord is one that contains an ORCID iD. """ authors_refs = [] for author in record['authors']: diff --git a/invenio_orcid/utils.py b/invenio_orcid/utils.py index 708749f..473e5fd 100644 --- a/invenio_orcid/utils.py +++ b/invenio_orcid/utils.py @@ -22,19 +22,35 @@ """Implement helper functions.""" +from flask import current_app + from invenio_oauthclient.models import RemoteAccount, UserIdentity +from werkzeug.utils import import_string + -def get_authors_credentials(author_identifier, method='orcid'): +def get_authors_credentials(author, method='orcid'): """Return the access token for a specific author (if available). - :param author_identifier: The id of the author (e.g. the orcid-id). + :param author: An author record. :param method: The service associated with the author_identifier. """ + get_identifier = import_string( + current_app.config['ORCID_ID_FETCHER']) + author_identifier = get_identifier(author) raw_user = UserIdentity.query.filter_by( id=author_identifier, method=method).first() user = RemoteAccount.query.filter_by(user_id=raw_user.id_user).first() - return user.tokens[0].access_token + + return user.remote_tokens[0].access_token, author_identifier + + +def get_orcid_id(author): + """Return the ORCID iD of a given author record. + + :param author: An author record. + """ + return author['orcid'] def convert_to_orcid(record):