import argparse
import io
from io import BytesIO
import sys
import config
import string
import pycurl
import unicodecsv as csv
import urllib
import json

#Check if an access token has already been generated
def token_check():
    #If there is an existing saved access token, use that
    try:
        with open ("token.txt", "r") as myfile:
            token=myfile.read()
            print "Using existing access token from token.txt"
            return str(token)
    #If there is not an existing token, create one and save it
    except:
        print "Generating new access token"
        token = get_orcid_token()
        return token

#Generate a /read-public token
def get_orcid_token():
    #set request variables
    client_id = config.client_id
    client_secret = config.client_secret
    token_endpoint = config.token_endpoint
    data = BytesIO()
    #create post data
    post_data = {'client_id': client_id, 'client_secret': client_secret, 'scope': '/read-public', 'grant_type': 'client_credentials'}
    #url encode post data
    postfields = urllib.urlencode(post_data)
    #create and send http request
    c = pycurl.Curl()
    c.setopt(c.URL, token_endpoint)
    c.setopt(c.HTTPHEADER, ['Accept: application/json'])
    c.setopt(c.POSTFIELDS, postfields)
    c.setopt(c.WRITEFUNCTION, data.write)
    c.setopt(pycurl.SSL_VERIFYPEER, 1)
    c.setopt(pycurl.SSL_VERIFYHOST, 2)
    c.setopt(pycurl.CAINFO, "cacert.pem")
    c.perform()
    c.close()
    #get request response
    json_object = json.loads(data.getvalue())
    #get and save the token so it can be reused or return the error if there was one
    if 'access_token' in json_object:
        token = json_object['access_token']
        with open("token.txt", "w") as text_file:
            text_file.write(token)
        return token
    else:
        print "Could not generate token. " + str(json_object)

#Run Search
def search_affiliations(token, start=0):
    startRow = 0
    numRows = 200
    output = []
    #Create search string using search terms and type
    search = config.search
    type = config.type
    if type == 'ringgold':
        search_type = 'ringgold-org-id:'
    elif type == 'grid':
        search_type = 'grid-org-id:'
    elif type == 'name':
        search_type = 'affiliation-org-name:'
    else:
        print "Invalid search type: " + type
        return
    #build search query
    search_string = search_type + "(%22" + "%22+OR+%22".join(search) + "%22)"
    #encode any spaces in search terms
    search_string = search_string.replace(" ", "%20")
    #build search url
    base_url = config.search_endpoint
    while(True):
        data = BytesIO()
        #create request string
        request_string = base_url + "q=" + search_string + "&rows=200&start=" + str(startRow)
        #create and send http request
        c = pycurl.Curl()
        c.setopt(c.URL, request_string)
        c.setopt(c.HTTPHEADER, ['Accept: application/json', 'Authorization: Bearer %s' % token])
        c.setopt(c.POST, 0)
        c.setopt(c.WRITEFUNCTION, data.write)
        c.setopt(pycurl.SSL_VERIFYPEER, 1)
        c.setopt(pycurl.SSL_VERIFYHOST, 2)
        c.setopt(pycurl.CAINFO, "cacert.pem")
        c.perform()
        c.close()
        json_object = json.loads(data.getvalue())
        if 'result' in json_object:
            new_results = json_object['result']
            num_results = json_object['num-found']
            #If there are no results
            if len(new_results) == 0:
                print "No results found for your query"
                break
            #Page through results
            if startRow + numRows > num_results:
                print "Getting results " + str(num_results) + " out of " + str(num_results)
            else:
                print "Getting results " + str(startRow + numRows) + " out of " + str(num_results)
            for result in new_results:
                temp_row = []
                temp_row.append(result['orcid-identifier']['path'])
                names = getName(result['orcid-identifier']['path'])
                if names['name']:
                    if names['name']['given-names']:
                        temp_row.append(names['name']['given-names']['value'])
                    else:
                        temp_row.append('')
                    if names['name']['family-name']:
                        temp_row.append(names['name']['family-name']['value'])
                    else:
                        temp_row.append('')
                else:
                    temp_row.append('')
                    temp_row.append('')
                email_strings = [email['email'] for email in names['emails']['email']]
                temp_row.append(';'.join(email_strings))
                affiliations = getAffiliation(result['orcid-identifier']['path'])
                affiliations = [employments['organization']['name'] for employments in affiliations['employment-summary']]
                temp_row.append(';'.join(affiliations))
                output.append(temp_row)
            startRow += numRows
            if startRow > num_results:
                break
        else:
            print "Error running search. " + str(json_object)
            break
    csv_to_file(output)

def getName(orcid):
    base_url = config.api_endpoint
    request_string = base_url + orcid + '/person'
    result = getData(request_string)
    return result

def getAffiliation(orcid):
    base_url = config.api_endpoint
    request_string = base_url + orcid + '/employments'
    result = getData(request_string)
    return result

def getData(request_string):
    data = BytesIO()
    #create request string
    #create and send http request
    c = pycurl.Curl()
    c.setopt(c.URL, request_string)
    c.setopt(c.HTTPHEADER, ['Content-Type: application/orcid+xml', 'Accept: application/json'])
    c.setopt(c.POST, 0)
    c.setopt(c.WRITEFUNCTION, data.write)
    c.setopt(pycurl.SSL_VERIFYPEER, 1)
    c.setopt(pycurl.SSL_VERIFYHOST, 2)
    c.setopt(pycurl.CAINFO, "cacert.pem")
    c.setopt(c.WRITEFUNCTION, data.write)
    c.perform()
    c.close()
    #get request response
    json_object = json.loads(data.getvalue())
    return json_object

#Write the output results to a CSV file
def csv_to_file(output):
    with open(config.outputFile, "w") as outputFile:
        wr = csv.writer(outputFile, lineterminator='\n')
        wr.writerows(output)

def main():
    token = token_check()
    search_affiliations(token)

if __name__ == '__main__':
    main()

import argparse
import io
from io import BytesIO
import sys
import config
import string
import pycurl
import unicodecsv as csv
import urllib
import json

#Check if an access token has already been generated
def token_check():
    #If there is an existing saved access token, use that
    try:
        with open ("token.txt", "r") as myfile:
            token=myfile.read()
            print "Using existing access token from token.txt"
            return str(token)
    #If there is not an existing token, create one and save it
    except:
        print "Generating new access token"
        token = get_orcid_token()
        return token

#Generate a /read-public token
def get_orcid_token():
    #set request variables
    client_id = config.client_id
    client_secret = config.client_secret
    token_endpoint = config.token_endpoint
    data = BytesIO()
    #create post data
    post_data = {'client_id': client_id, 'client_secret': client_secret, 'scope': '/read-public', 'grant_type': 'client_credentials'}
    #url encode post data
    postfields = urllib.urlencode(post_data)
    #create and send http request
    c = pycurl.Curl()
    c.setopt(c.URL, token_endpoint)
    c.setopt(c.HTTPHEADER, ['Accept: application/json'])
    c.setopt(c.POSTFIELDS, postfields)
    c.setopt(c.WRITEFUNCTION, data.write)
    c.setopt(pycurl.SSL_VERIFYPEER, 1)
    c.setopt(pycurl.SSL_VERIFYHOST, 2)
    c.setopt(pycurl.CAINFO, "cacert.pem")
    c.perform()
    c.close()
    #get request response
    json_object = json.loads(data.getvalue())
    #get and save the token so it can be reused or return the error if there was one
    if 'access_token' in json_object:
        token = json_object['access_token']
        with open("token.txt", "w") as text_file:
            text_file.write(token)
        return token
    else:
        print "Could not generate token. " + str(json_object)

#Run Search
def search_affiliations(token, start=0):
    startRow = 0
    numRows = 200
    output = []
    #Create search string using search terms and type
    search = config.search
    type = config.type
    if type == 'ringgold':
        search_type = 'ringgold-org-id:'
    elif type == 'grid':
        search_type = 'grid-org-id:'
    elif type == 'name':
        search_type = 'affiliation-org-name:'
    else:
        print "Invalid search type: " + type
        return
    #build search query
    search_string = search_type + "(%22" + "%22+OR+%22".join(search) + "%22)"
    #encode any spaces in search terms
    search_string = search_string.replace(" ", "%20")
    #build search url
    base_url = config.search_endpoint
    while(True):
        data = BytesIO()
        #create request string
        request_string = base_url + "q=" + search_string + "&rows=200&start=" + str(startRow)
        #create and send http request
        c = pycurl.Curl()
        c.setopt(c.URL, request_string)
        c.setopt(c.HTTPHEADER, ['Accept: application/json', 'Authorization: Bearer %s' % token])
        c.setopt(c.POST, 0)
        c.setopt(c.WRITEFUNCTION, data.write)
        c.setopt(pycurl.SSL_VERIFYPEER, 1)
        c.setopt(pycurl.SSL_VERIFYHOST, 2)
        c.setopt(pycurl.CAINFO, "cacert.pem")
        c.perform()
        c.close()
        json_object = json.loads(data.getvalue())
        if 'result' in json_object:
            new_results = json_object['result']
            num_results = json_object['num-found']
            #If there are no results
            if len(new_results) == 0:
                print "No results found for your query"
                break
            #Page through results
            if startRow + numRows > num_results:
                print "Getting results " + str(num_results) + " out of " + str(num_results)
            else:
                print "Getting results " + str(startRow + numRows) + " out of " + str(num_results)
            for result in new_results:
                temp_row = []
                temp_row.append(result['orcid-identifier']['path'])
                names = getName(result['orcid-identifier']['path'])
                if names['name']:
                    if names['name']['given-names']:
                        temp_row.append(names['name']['given-names']['value'])
                    else:
                        temp_row.append('')
                    if names['name']['family-name']:
                        temp_row.append(names['name']['family-name']['value'])
                    else:
                        temp_row.append('')
                else:
                    temp_row.append('')
                    temp_row.append('')
                email_strings = [email['email'] for email in names['emails']['email']]
                temp_row.append(';'.join(email_strings))
                affiliations = getAffiliation(result['orcid-identifier']['path'])
                affiliations = [employments['organization']['name'] for employments in affiliations['employment-summary']]
                temp_row.append(';'.join(affiliations))
                output.append(temp_row)
            startRow += numRows
            if startRow > num_results:
                break
        else:
            print "Error running search. " + str(json_object)
            break
    csv_to_file(output)

def getName(orcid):
    base_url = config.api_endpoint
    request_string = base_url + orcid + '/person'
    result = getData(request_string)
    return result

def getAffiliation(orcid):
    base_url = config.api_endpoint
    request_string = base_url + orcid + '/employments'
    result = getData(request_string)
    return result

def getData(request_string):
    data = BytesIO()
    #create request string
    #create and send http request
    c = pycurl.Curl()
    c.setopt(c.URL, request_string)
    c.setopt(c.HTTPHEADER, ['Content-Type: application/orcid+xml', 'Accept: application/json'])
    c.setopt(c.POST, 0)
    c.setopt(c.WRITEFUNCTION, data.write)
    c.setopt(pycurl.SSL_VERIFYPEER, 1)
    c.setopt(pycurl.SSL_VERIFYHOST, 2)
    c.setopt(pycurl.CAINFO, "cacert.pem")
    c.setopt(c.WRITEFUNCTION, data.write)
    c.perform()
    c.close()
    #get request response
    json_object = json.loads(data.getvalue())
    return json_object

#Write the output results to a CSV file
def csv_to_file(output):
    with open(config.outputFile, "w") as outputFile:
        wr = csv.writer(outputFile, lineterminator='\n')
        wr.writerows(output)

def main():
    token = token_check()
    search_affiliations(token)

if __name__ == '__main__':
    main()

#Check if an access token has already been generated #If there is an existing saved access token, use that #If there is not an existing token, create one and save it #Generate a /read-public token #set request variables #create post data #url encode post data #create and send http request #get request response #get and save the token so it can be reused or return the error if there was one #Run Search #Create search string using search terms and type #build search query #encode any spaces in search terms #build search url #create request string #create and send http request #If there are no results #Page through results #create request string #create and send http request #get request response #Write the output results to a CSV file