Skip to content
Snippets Groups Projects
zenodo.py 4.26 KiB
# Récupérer les DOIs de l'UGA depuis Zenodo
## 2023-12-06, Maxence Larrieu


"""
## todo
- v2 : rechercher UGA comme financeur `grants.funder.doi`

## Documentation
* Liste des métadonnées obligatoires lors du dépôts (upload_type, sub_type, publication_date, titre, creators, ) https://developers.zenodo.org/#representation
* Recherche dans l'interface : https://zenodo.org/search?q=creators.affiliation%3Agrenoble&q=type%3Adataset&l=list&p=1&s=10&sort=bestmatch
* Doc dev API champs de requêtes classsiques https://developers.zenodo.org/#records
* doc champs poussées pour la recherche https://help.zenodo.org/guides/search/
* typologie des dépôts possiblent : publication: Publication, poster: Poster, presentation: Presentation, Dataset: Dataset, image: Image, video: Video/Audio, software: Software, lesson: Lesson, physicalobject: Physical object, other: Other
* descendre au niveau des ORCID des `creator.orcid` et `contributors.orcid`


## Notes sur la récupération
- exemple résultats de requete : https://zenodo.org/api/records?q=creators.affiliation%3A*grenoble*&type=dataset&page=6&size=100&sort=mostrecent&all_version=False
- deux DOI identiques sont présents : un à la racine `[hits][doi]` et un autre dans `[hits][metadata][doi]`
- il y a des DOI renseignés par le déposant qui ne sont pas de Zenodo
"""

import requests, json

print("\n\nRunning zenodo.py")

def req_zenodo_with_page(uga_perimeter, record_type, page_nb) :
    """
    retourne les jeux de données UGA depuis Zenodo
    page_nb précise le numéro de la page de la requête
    """

    r = requests.get(
        "https://zenodo.org/api/records",
        params = {
            "q" : uga_perimeter,
            "type" : record_type,
            "page" : page_nb, 
            "size" : 100,
            "sort" : "mostrecent",
            "all_version" : False,
            } 
    )
    # for debugging 
    #print(r.url)

    ## si pb présent dans les résultats
    if r.status_code != 200 : 
        return {
            "continue" : False,
            "content" : r
            }

    ## if no problem
    res = r.json()
    
    return {
        "continue" : True,
        "content" : res["hits"]
        }


def req_zenodo(uga_perimeter, record_type) : 
    """
    permet de gérer la pagination de zenodo en fonction du nb de résutlat donné par l'API
    tant que le nombre de DOI récolté est inf. au résutlat de la requête
    """

    output_dois = []
    current_page_number = 0
    iterate = True

    while iterate :

        current_page_number += 1
        res = req_zenodo_with_page(uga_perimeter, record_type, current_page_number)

        # verifier si la requete a bien fonctionnée
        if not res["continue"] : 
            print(r"\t/!\ oups, problem with the query")
            print(res["content"].status_code ) ## contient la réponse de la requête
            break

        # pour la premiere iteration, extraire le nb de DOI a récupérer
        if current_page_number == 1 : 
            nb_dois_to_get = res["content"]["total"]
            print(f"\t{record_type}\n\tDOIs to get", nb_dois_to_get )

        #to debug
        #print("\titeration page nb", current_page_number)
        
        ## parcourir tous les DOIs et les placer dans la liste
        ## placer le DOI uniquement si une donnée est présente
        [output_dois.append( item["doi"] ) for item in res["content"]["hits"] if item.get("doi")]

        ## managing the loop
        ### if I have all the DOIs inside my outputs, then I had finish, if not continue
        if len(output_dois) >= nb_dois_to_get : 
            iterate = False

    return output_dois


##_______________________________________________

all_dois = set() # a set to gather all DOIs

uga_perimeter = "creators.affiliation:(grenoble AND alp*) contributors.affiliation:(grenoble AND alp*)"
types_to_req = ["dataset", "image", "video", "software", "other"]

for record_type in types_to_req : 

    temp_dois = req_zenodo(uga_perimeter, record_type)

    ## placer les DOI dans le buffer général qui ne peut contenir que des valeurs uniques
    [all_dois.add(doi) for doi in temp_dois]
    

print("\n\tnb DOIs finded\t",  len(all_dois) )

## ____z____ exporter la liste de DOI au format txt

with open("zenodo-dois.txt", 'w') as f :
    [f.write(f"{line}\n") for line in all_dois]