diff --git a/.gitignore b/.gitignore index 0d20b64..a303f5b 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,5 @@ *.pyc +*.txt +*.log +*.bib +*.tex diff --git a/examples/README.md b/examples/README.md new file mode 100644 index 0000000..6a40b6e --- /dev/null +++ b/examples/README.md @@ -0,0 +1,17 @@ +### About + +'Ready to run' examples showing how to use **orcid** python module. + +### How to run examples +* To run the examples no installation of **orcid** module is required. +* Download latest package from [github](https://github.com/scholrly/orcid-python) and unzip it +* Install dependencies (see file 'requirements.txt') +* Navigate to the subfolder 'examples' +* For instance, to run **extracting_bibtex.py** use following command: +``` +python extracting_bibtex.py +``` + +### Examples +* **extracting_bibtex.py** + - script that extract all BIBTEX files of given author diff --git a/examples/extracting_bibtex.py b/examples/extracting_bibtex.py new file mode 100644 index 0000000..6ebdc0c --- /dev/null +++ b/examples/extracting_bibtex.py @@ -0,0 +1,119 @@ +# coding: utf-8 + +# importing module located in parent folder +import sys +sys.path.insert(0, '../') + +# maing testing library +import orcid + +# additional libraries +import json +import codecs + +# setting logging to the DEBUG mode +import logging + +#logging.getLogger("#orcid#").setLevel(logging.DEBUG) +logging.getLogger("#orcid#").setLevel(logging.INFO) + +#retrieve my own's profile from his ORCID +me = orcid.get('0000-0001-5661-4587') + +def show_keyword(obj): + print obj.keywords + for key_word in obj.keywords: + print key_word + +def print_publications(obj): + """ + Printing keywords + """ + print '[i] printing the keywords set by author' + for value in obj.publications: + print value + +def save_bibtex(bibtex, file_name='orcid-bibtex-output.bib', encoding='utf-8'): + """ + (dict, str, str) -> None + + Saving bibtex to the file, grouped by year. + """ + + _file = codecs.open(file_name, 'w', encoding) + + for key in bibtex: + _file.write("%%%%%%%%%%%%%%%% \n%% %s \n%%%%%%%%%%%%%%%%\n\n" % key) + bibtex_group = '' + for value in bibtex[key]: + bibtex_group += value + '\n\n' + _file.write(bibtex_group) + + _file.close() + + print '[i] bibtex was created, check following file: %s ' % (file_name) + +def save_nocite(bibtex, file_name='orcid-nocite-output.tex', encoding='utf-8'): + """ + (dict, str, str) -> None + + Saving bibtex to the file, grouped by year. + """ + + def extract_bibtex_id(s): + start = s.find('{') + 1 + end = s.find(',', start) + return s[start:end] + + _file = codecs.open(file_name, 'w', encoding) + + for key in bibtex: + _file.write("%%%%%%%%%%%%%%%% \n%% %s \n%%%%%%%%%%%%%%%%\n\n" % key) + nocite_group = '' + for value in bibtex[key]: + nocite_group += '\\nocite{' + extract_bibtex_id(value) + '}' + '\n' + _file.write(nocite_group) + + _file.close() + + print '[i] tex with \\nocite was created, check following file: %s ' % (file_name) + +def extract_bitex(obj): + """ + (Class) -> dict() + + Method takes as an input object with all publications from ORCID and forms dict with it. + """ + + bibtex = {} + for value in obj.publications: + if value.citation.citation_type == 'BIBTEX': + if value.publicationyear not in bibtex: + bibtex[value.publicationyear] = list() + bibtex[value.publicationyear].append(value.citation.citation) + else: + bibtex[value.publicationyear].append(value.citation.citation) + else: + print '[i] this publications is having no BIBTEX %s ' % (value) + + return bibtex + +def orcid_bibtex(obj): + """ + (Class) -> None + + Extrating bibtex from ORCID, saving it to the file + """ + + # extracting bibtex + orcid_bibtex = extract_bitex(me) + + # saving bibtex to file + save_bibtex(orcid_bibtex) + + # citing extracted bibtex + save_nocite(orcid_bibtex) + +#show_keyword(me) +#print_publications(me) +orcid_bibtex(me) diff --git a/orcid/rest.py b/orcid/rest.py index 0c92a51..7f361e0 100644 --- a/orcid/rest.py +++ b/orcid/rest.py @@ -1,10 +1,17 @@ import requests +import json from .constants import ORCID_PUBLIC_BASE_URL from .utils import dictmapper, MappingRule as to from .exceptions import NotFoundException +# setting logger +import logging +logger = logging.getLogger("#orcid#") +logging.basicConfig(filename='orcid-log.log', level=logging.INFO) + + BASE_HEADERS = {'Accept':'application/orcid+json'} BIO_PATH = ['orcid-profile','orcid-bio'] @@ -15,7 +22,8 @@ def _parse_keywords(d): # (https://github.com/ORCID/ORCID-Parent/issues/27) makes this the best # way. will fix when they do if d is not None: - return d.get('keyword',[{}])[0].get('value','').split(',') + #return d.get('keyword',[{}])[0].get('value','').split(',') + return [val['value'] for val in d['keyword']] return [] WebsiteBase = dictmapper('WebsiteBase', { @@ -63,9 +71,10 @@ def __repr__(self): 'title':['work-title','title','value'], 'subtitle':['work-title','subtitle','value'], 'url':['url','value'], - 'citation':to(['citation'], lambda d: Citation(d) if d is not None else None), + 'citation': to(['work-citation'], lambda d: Citation(d) if d is not None else None), 'external_ids':to(['work-external-identifiers','work-external-identifier'], lambda l: map(ExternalID, l) if l is not None else None), + 'publicationyear': ['publication-date', 'year', 'value'], }) class Publication(PublicationBase): @@ -76,6 +85,7 @@ def __repr__(self): def _parse_publications(l): if l is not None: + #logger.debug(json.dumps(l, sort_keys=True, indent=4, separators=(',', ': '))) return [Publication(d) for d in l] return [] @@ -84,11 +94,12 @@ def _parse_publications(l): }) AuthorBase = dictmapper('AuthorBase', { - 'orcid':['orcid-profile','orcid','value'], + 'orcid':['orcid-profile','orcid-identifier','path'], 'family_name':PERSONAL_DETAILS_PATH + ['family-name','value'], 'given_name':PERSONAL_DETAILS_PATH + ['given-names','value'], 'biography':BIO_PATH + ['biography',], 'keywords':to(BIO_PATH + ['keywords'], _parse_keywords), + #'keywords':to(BIO_PATH + ['keywords', 'keyword'], _parse_keywords), 'researcher_urls':to(BIO_PATH + ['researcher-urls','researcher-url'], _parse_researcher_urls), }) @@ -99,6 +110,7 @@ class Author(AuthorBase): def _load_works(self): resp = requests.get(ORCID_PUBLIC_BASE_URL + self.orcid + '/orcid-works', headers = BASE_HEADERS) + logger.debug(json.dumps(resp.json(), sort_keys=True, indent=4, separators=(',', ': '))) self._loaded_works = Works(resp.json()) @property @@ -116,15 +128,29 @@ def __repr__(self): 'citation_type':['work-citation-type'] }) +def write_logs(resp): + logger.debug(json.dumps(resp.json(), sort_keys=True, indent=4, separators=(',', ': '))) + def get(orcid_id): """ Get an author based on an ORCID identifier. """ resp = requests.get(ORCID_PUBLIC_BASE_URL + unicode(orcid_id), headers=BASE_HEADERS) + write_logs(resp) json_body = resp.json() return Author(json_body) +# def get_with_json(orcid_id): +# """ +# Get an author based on an ORCID identifier and json +# """ +# resp = requests.get(ORCID_PUBLIC_BASE_URL + unicode(orcid_id), +# headers=BASE_HEADERS) +# json_body = resp.json() +# write_logs(resp) +# return Author(json_body), json_body + def search(query): resp = requests.get(ORCID_PUBLIC_BASE_URL + 'search/orcid-bio', params={'q':unicode(query)}, headers=BASE_HEADERS)