Esempio n. 1
0
def authenticate(auth_code, orcid_id):
    user_data = mongo.get_user(orcid_id)
    if 'figshare_token' not in user_data and auth_code is not None:
        params = {
            'client_id': config.get('DEFAULT', 'FIGSHARE_CLIENT_ID'),
            'client_secret': config.get('DEFAULT', 'FIGSHARE_SECRET'),
            'grant_type': 'authorization_code',
            'code': auth_code
        }
        data = urllib.parse.urlencode(params)
        data = data.encode('ascii')
        req = urllib.request.Request(config.get('DEFAULT',
                                                'FIGSHARE_TOKEN_URL'),
                                     data=data,
                                     headers={'Accept': 'application/json'})
        req.get_method = lambda: "POST"
        response = urllib.request.urlopen(req).read()
        figshare_token = json.loads(response)
        user_data['figshare_token'] = figshare_token
        mongo.update_user(orcid_id, user_data)
    elif 'figshare_token' in user_data:
        figshare_token = user_data['figshare_token']
    else:
        figshare_token = None
    return figshare_token['access_token']
def get_works(user_token, orcid_id):
    api = orcid.PublicAPI(config.get("DEFAULT", "ORCID_CLIENT_ID"),
                          config.get("DEFAULT", "ORCID_SECRET"))
    summary = api.read_record_public(orcid_id, "works", user_token)
    metadata = []
    for work in summary["group"]:
        work_summary = work["work-summary"][0]
        work_metadata = dict()
        work_metadata["id"] = work_summary["put-code"]
        work_metadata["title"] = work_summary["title"]["title"]["value"]
        work_metadata["last-modified-date"] = work_summary[
            "last-modified-date"]["value"]
        work_metadata["type"] = work_summary["type"]
        work_metadata["publication-year"] = work_summary["publication-date"][
            "year"]["value"]
        work_metadata["owner"] = orcid_id

        for ext_id in work_summary["external-ids"]["external-id"]:
            if ext_id["external-id-type"] == "doi":
                work_metadata["doi"] = ext_id["external-id-value"]
            if ext_id["external-id-type"] == "pmid":
                work_metadata["pmid"] = ext_id["external-id-value"]
            if ext_id["external-id-type"] == "pmc":
                work_metadata["pmcid"] = ext_id["external-id-value"]

        metadata.append(work_metadata)
    return metadata
Esempio n. 3
0
def harvest_file(user, research_object):
    tmp_dir = config.get("DEFAULT", "TMP_DIR")
    file_name = research_object["source"] + "_" + research_object["name"]
    logger.info(f"Harvesting files for research object: ${file_name}")
    if research_object["source"] == "github":
        downloads_url = research_object["ro"]["archive_url"]
        downloads_url = downloads_url.replace("{archive_format}", "zipball")
        downloads_url = downloads_url.replace("{/ref}", "/master")
        logger.info(
            f"Downloading Github zip files for research object: ${file_name}")
        ro_content = github.download_zip_file(
            downloads_url, user["github_token"]["access_token"])
        file_name += ".zip"
        with open(tmp_dir + file_name, "wb") as f:
            f.write(ro_content)
    elif research_object["source"] == "figshare":
        file_name += ".zip"
        logger.info(
            f"Downloading Figshare files for research object: ${file_name}")
        figshare.download_files(
            research_object["ro"],
            user["figshare_token"]["access_token"],
            tmp_dir + file_name,
        )
    else:
        logger.info(
            f"Generating Orcid JSON file for research object: ${file_name}")
        ro_content = str(research_object["ro"]).encode("utf-8")
        file_name += ".json"
        with open(tmp_dir + file_name, "wb") as f:
            f.write(ro_content)
    return file_name
Esempio n. 4
0
def authenticate(auth_code, orcid_id):
    user_data = mongo.get_user(orcid_id)
    if 'github_token' not in user_data:
        params = {'client_id': config.get('DEFAULT', 'GITHUB_CLIENT_ID'),
                  'client_secret': config.get('DEFAULT', 'GITHUB_SECRET'),
                  'code': auth_code
                  }
        data = urllib.parse.urlencode(params)
        data = data.encode('ascii')
        req = urllib.request.Request('https://github.com/login/oauth/access_token', data,
                                     headers={'Accept': 'application/json'})
        response = urllib.request.urlopen(req).read()
        github_token = json.loads(response)
        user_data['github_token'] = github_token
        mongo.update_user(orcid_id, user_data)
    else:
        github_token = user_data['github_token']
    return github_token['access_token']
def research_object_exist(source, research_object):
    composer_url = config.get("DEFAULT", "HYPERLEDGER_COMPOSER_URL")
    research_object_url = (research_object[SOURCE_URL_FIELD_MAP[source]]
                           if SOURCE_URL_FIELD_MAP[source] in research_object
                           else research_object["id"])
    req = requests.get(f"{composer_url}/ResearchOJ/{research_object_url}")
    if req.status_code == 404:
        return False
    return True
def create_researcher(user):
    composer_url = config.get("DEFAULT", "HYPERLEDGER_COMPOSER_URL")
    researcher = {
        "$class": "org.bforos.Researcher",
        "researcherId": f"{user['orcid']}",
        "firstName": user["first_name"],
        "lastName": user["last_name"],
        "email": f"{user['orcid']}@b4os.com",
    }
    req = requests.post(f"{composer_url}/api/Researcher", researcher)
    return True
def claim_research_object(orcid_id, source, research_object):
    composer_url = config.get("DEFAULT", "HYPERLEDGER_COMPOSER_URL")
    research_object_url = (research_object[SOURCE_URL_FIELD_MAP[source]]
                           if SOURCE_URL_FIELD_MAP[source] in research_object
                           else research_object["id"])
    claim_op = {
        "$class": "org.bforos.ClaimRO",
        "researchObjId":
        f"resource:org.bforos.ResearchOJ#{research_object_url}",
        "claimer": f"resource:org.bforos.Researcher#{orcid_id}",
    }
    req = requests.post(f"{composer_url}/api/CreateResearchOJ", claim_op)
    return True
def update_disco(orcid_id, disco_id, disco_name, research_object_urls):
    composer_url = config.get("DEFAULT", "HYPERLEDGER_COMPOSER_URL")
    bforos_ros = [
        f"resource:org.bforos.ResearchOJ#{url}" for url in research_object_urls
    ]
    create_disco_op = {
        "$class": "org.bforos.Disco",
        "discoId": disco_id,
        "title": disco_name,
        "researchObjs": bforos_ros,
        "owner": f"org.bforos.Researcher#{orcid_id}",
    }
    req = requests.put(f"{composer_url}/api/Disco", create_disco_op)
    return True
def create_reaserch_object(orcid_id, source, research_object):
    ro_type = SOURCE_TYPE_MAP[source] if source in SOURCE_TYPE_MAP else "OTHER"
    research_object_url = (research_object[SOURCE_URL_FIELD_MAP[source]]
                           if SOURCE_URL_FIELD_MAP[source] in research_object
                           else research_object["id"])
    composer_url = config.get("DEFAULT", "HYPERLEDGER_COMPOSER_URL")
    create_op = {
        "$class": "org.bforos.CreateResearchOJ",
        "typeRO": ro_type,
        "uri": research_object_url,
        "creator": f"org.bforos.Researcher#{orcid_id}",
        "researchObjId": research_object_url,
    }
    req = requests.post(f"{composer_url}/api/CreateResearchOJ", create_op)
    return True
def create_disco(orcid_id, disco_id, disco_name, research_object_urls):
    composer_url = config.get("DEFAULT", "HYPERLEDGER_COMPOSER_URL")
    bforos_ros = [
        f"resource:org.bforos.ResearchOJ#{url}" for url in research_object_urls
    ]
    create_disco_op = {
        "$class": "org.bforos.Disco",
        "discoId": disco_id,
        "title": disco_name,
        "researchObjs": bforos_ros,
        "owner": f"org.bforos.Researcher#{orcid_id}",
        "collectors": [f"org.bforos.Researcher#{orcid_id}"],
    }
    logger.info(create_disco_op)
    headers = {"Content-Type": "application/json"}
    req = requests.post(f"{composer_url}/api/Disco",
                        json.dumps(create_disco_op),
                        headers=headers)
    logger.info(req.text)
    return True
from scholarly_wallet import config
from scholarly_wallet import mongo_access as mongo, github_api as github
from scholarly_wallet import figshare_api as figshare
from scholarly_wallet import zenodo_api as zenodo
from flask_jwt_extended import (
    JWTManager,
    jwt_required,
    create_access_token,
    get_jwt_identity,
)
from scholarly_wallet import hyperledger_api as hyperledger
from threading import Thread

app = Flask(__name__)

app.config["JWT_SECRET_KEY"] = config.get("DEFAULT", "JWT_SECRET")
app.config["JWT_ACCESS_TOKEN_EXPIRES"] = int(config.get("DEFAULT", "JWT_EXPIRES"))
jwt = JWTManager(app)

DEFAULT_SORT = {"orcid": "title", "github": "full_name", "figshare": "title"}


@app.route("/api/auth/orcid", methods=["GET", "OPTIONS"])
def signin():
    auth_code = request.args.get("orcid_auth_code")
    user_data = orcid.authenticate(auth_code)
    if user_data is None:
        return jsonify({"msg": "Failed authetication with Orcid"}), 403
    access_token = create_access_token(identity=user_data)
    return jsonify(access_token=access_token), 200
Esempio n. 12
0
def publish_to_zenodo(author, disco):
    turtle = get_rmap_rdf(author, disco)

    zenodo_url = config.get("DEFAULT", "ZENODO_REPOSITIONS_URL")
    zenodo_token = config.get("DEFAULT", "ZENODO_ACCESS_TOKEN")

    headers = {"Content-Type": "application/json"}
    r = requests.post(zenodo_url,
                      params={"access_token": zenodo_token},
                      json={},
                      headers=headers)
    r = r.json()
    deposition_id = r["id"]
    deposition_doi = r["metadata"]["prereserve_doi"]["doi"]
    file_name_base = deposition_doi.replace("/", "_")

    tmp_dir = config.get("DEFAULT", "TMP_DIR")

    with open(tmp_dir + file_name_base + ".rdf", "w+") as t_file:
        t_file.write(turtle.decode("utf-8"))

    turtle_file = open(tmp_dir + deposition_doi.replace("/", "_") + ".rdf",
                       "rb")

    data = {"filename": deposition_doi + ".rdf"}
    files = {"file": turtle_file}
    r = requests.post(
        f"{zenodo_url}/{deposition_id}/files",
        params={"access_token": zenodo_token},
        data=data,
        files=files,
    )

    img_data = base64.b64decode(disco["thumb"].split(",")[1])
    png_file = f"{file_name_base}.png"
    with open(tmp_dir + png_file, "wb") as f:
        f.write(img_data)

    png_file = open(tmp_dir + png_file, "rb")
    data = {"filename": deposition_doi.replace("/", "_") + ".png"}
    files = {"file": png_file}
    r = requests.post(
        f"{zenodo_url}/{deposition_id}/files",
        params={"access_token": zenodo_token},
        data=data,
        files=files,
    )
    for research_object in disco["diagram"]["elements"]["nodes"]:
        research_object = research_object["data"]
        file_name = harvest_file(author, research_object)
        ro_file = open(tmp_dir + file_name, "rb")
        data = {"filename": file_name}
        files = {"file": ro_file}
        logger.info(f"Uploading ${file_name} to Zenodo")
        r = requests.post(
            f"{zenodo_url}/{deposition_id}/files",
            params={"access_token": zenodo_token},
            data=data,
            files=files,
        )
    notes = ""

    # TODO Design a implement a queue for publication2zenodo

    data = {
        "metadata": {
            "title":
            disco["name"],
            "upload_type":
            "dataset",
            "publication_type":
            "milestone",
            "description":
            disco["description"] if disco["description"] else disco["name"],
            "creators": [{
                "name": author["name"],
                "orcid": author["orcid"]
            }],
            "keywords": ["disco", "scholarly wallet", "bundle"],
            "notes":
            notes,
            "access_right":
            "open",
            "communities": [{
                "identifier": "b4ossw"
            }],
        }
    }
    r = requests.put(
        f"{zenodo_url}/{deposition_id}",
        params={"access_token": zenodo_token},
        data=json.dumps(data),
        headers=headers,
    )
    r = requests.post(
        f"{zenodo_url}/{deposition_id}/actions/publish",
        params={"access_token": zenodo_token},
    )
    mongo.update_disco(
        author["orcid"],
        disco["_id"],
        {
            "doi": deposition_doi,
            "zenodo_id": deposition_id,
            "status": "published"
        },
    )
    return dumps({"doi": deposition_doi, "zenodo_id": deposition_id})
def authenticate(auth_code):
    params = {
        "client_id": config.get("DEFAULT", "ORCID_CLIENT_ID"),
        "client_secret": config.get("DEFAULT", "ORCID_SECRET"),
        "grant_type": "authorization_code",
        "code": auth_code,
        "redirect_uri": config.get("DEFAULT", "CLIENT_URL"),
    }
    data = urllib.parse.urlencode(params)
    data = data.encode("ascii")
    req = urllib.request.Request(
        config.get("DEFAULT", "ORCID_AUTH_URL"),
        data,
        headers={"Accept": "application/json"},
    )
    try:
        response = urllib.request.urlopen(req).read()
        user_data: Dict = json.loads(response)

        orcid_token = {
            "access_token": user_data.pop("access_token"),
            "token_type": user_data.pop("token_type"),
            "refresh_token": user_data.pop("refresh_token"),
            "expires_in": user_data.pop("expires_in"),
            "scope": user_data.pop("scope"),
        }
        user_data["orcid_token"] = orcid_token

        if not mongo.user_exists(user_data["orcid"]):
            req = urllib.request.Request(
                config.get("DEFAULT", "ORCID_API_URL") + "/" +
                user_data["orcid"] + "/person",
                data,
                headers={
                    "Accept": "application/json",
                    "Authorization": f'Bearer {orcid_token["access_token"]}',
                },
            )
            response = urllib.request.urlopen(req).read()
            user_profile_data: Dict = json.loads(response)
            first_name = user_profile_data["name"]["given-names"]["value"]
            last_name = user_profile_data["name"]["family-name"]["value"]
            user_data["first_name"] = first_name
            user_data["last_name"] = last_name
            mongo.create_user(user_data)
            thread_user = Thread(target=hyperledger.create_researcher,
                                 args=(user_data, ))
            thread_user.start()
            user_data.pop("_id")
        else:
            mongo.update_user(user_data["orcid"], user_data)
        works = get_works(user_data["orcid_token"]["access_token"],
                          user_data["orcid"])
        for work in works:
            if not mongo.work_exists(work["id"], user_data["orcid"]):
                mongo.save_ros([work], "orcid")
        thread_works = Thread(target=hyperledger.claim_ros,
                              args=(user_data["orcid"], "orcid", works))
        thread_works.start()
        for field_name in user_data.keys():
            if field_name.endswith("_token"):
                user_data[field_name.replace("_token", "_access")] = True
                user_data.pop(field_name)
        return user_data

    except urllib.error.HTTPError as e:
        return None