diff --git a/R/ZenodoManager.R b/R/ZenodoManager.R index c3d9678..cded29d 100644 --- a/R/ZenodoManager.R +++ b/R/ZenodoManager.R @@ -497,18 +497,18 @@ ZenodoManager <- R6Class("ZenodoManager", awards <- resp$hits$hits hasAwards <- length(awards)>0 }else{ - warnMsg = sprintf("Maximum allowed size for list of awars at page %s", page) + warnMsg = sprintf("Maximum allowed size for list of awards at page %s", page) cli::cli_alert_warning(warnMsg) self$WARN(warnMsg) break } } - infoMsg = "Successfully fetched list of grants!" + infoMsg = "Successfully fetched list of awards!" cli::cli_alert_success(infoMsg) self$INFO(infoMsg) }else{ out <- zenReq$getResponse() - errMsg = sprintf("Error while fetching grants: %s", out$message) + errMsg = sprintf("Error while fetching awards: %s", out$message) cli::cli_alert_danger(errMsg) self$ERROR(errMsg) for(error in out$errors){ @@ -593,6 +593,126 @@ ZenodoManager <- R6Class("ZenodoManager", return(out) }, + #Special vocabulary/Affiliations + #------------------------------------------------------------------------------------------ + + #' @description Get Affiliations supported by Zenodo. + #' @param pretty Prettify the output. By default the argument \code{pretty} is set to + #' \code{TRUE} which will returns the list of affiliations as \code{data.frame}. + #' Set \code{pretty = FALSE} to get the raw list of affiliations + #' @param q an ElasticSearch compliant query, object of class \code{character}. Default is emtpy. + #' Note that the Zenodo API restrains a maximum number of 10,000 records to be retrieved. Consequently, + #' not all affiliations can be listed from Zenodo, a query has to be specified. + #' @param size number of affiliations to be returned. By default equal to 500. + #' @return list of affiliations as \code{data.frame} or \code{list} + getAffiliations = function(q = "", pretty = TRUE, size = 500){ + page <- 1 + zenReq <- ZenodoRequest$new(private$url, "GET", sprintf("affiliations?q=%s&size=%s&page=%s", URLencode(q), size, page), + token = self$getToken(), + logger = self$loggerType) + zenReq$execute() + out <- NULL + if(zenReq$getStatus() == 200){ + resp <- zenReq$getResponse() + affiliations <- resp$hits$hits + total <- resp$hits$total + if(total > 10000){ + warnMsg = sprintf("Total of %s records found: the Zenodo API limits to a maximum of 10,000 records!", total) + cli::cli_alert_warning(warnMsg) + self$WARN(warnMsg) + } + total_remaining <- total + hasAwards <- length(affiliations)>0 + while(hasAwards){ + out <- c(out, affiliations) + total_remaining <- total_remaining-length(affiliations) + if(total_remaining <= size) size = total_remaining + if(total_remaining == 0){ + break + } + + #next page + page = page+1 + zenReq <- ZenodoRequest$new(private$url, "GET", sprintf("affiliations?q=%s&size=%s&page=%s", URLencode(q), size, page), + token = self$getToken(), + logger = self$loggerType) + zenReq$execute() + if(zenReq$getStatus() == 200){ + resp <- zenReq$getResponse() + affiliations <- resp$hits$hits + hasAwards <- length(affiliations)>0 + }else{ + warnMsg = sprintf("Maximum allowed size for list of affiliations at page %s", page) + cli::cli_alert_warning(warnMsg) + self$WARN(warnMsg) + break + } + } + infoMsg = "Successfully fetched list of affiliations!" + cli::cli_alert_success(infoMsg) + self$INFO(infoMsg) + }else{ + out <- zenReq$getResponse() + errMsg = sprintf("Error while fetching affiliations: %s", out$message) + cli::cli_alert_danger(errMsg) + self$ERROR(errMsg) + for(error in out$errors){ + errMsg = sprintf("Error: %s - %s", error$field, error$message) + cli::cli_alert_danger(errMsg) + self$ERROR(errMsg) + } + } + + if(pretty){ + out = do.call("rbind", lapply(out,function(x){ + rec = data.frame( + id = x$id, + acronym = if(!is.null(x$acronym)) x$acronym else NA, + name = if(!is.null(x$name)) x$name else NA, + title = x$title[[1]], + created = x$created, + updated = x$updated, + stringsAsFactors = FALSE + ) + return(rec) + })) + } + return(out) + }, + + #' @description Get affiliations by name. + #' @param name name + #' @param pretty Prettify the output. By default the argument \code{pretty} is set to + #' \code{TRUE} which will returns the list of affiliations as \code{data.frame}. + #' Set \code{pretty = FALSE} to get the raw list of affiliations + #' @return list of affiliations as \code{data.frame} or \code{list} + getAffiliationByName = function(name, pretty = TRUE){ + query = sprintf("title.en:%s", URLencode(paste0("\"",name,"\""))) + self$getAffiliations(q = query, pretty = pretty) + }, + + #' @description Get affiliation by Id. + #' @param id affiliation id + #' @return the affiliation + getAffiliationById = function(id){ + zenReq <- ZenodoRequest$new(private$url, "GET", sprintf("affiliations/%s",id), + token= self$getToken(), + logger = self$loggerType) + zenReq$execute() + out <- zenReq$getResponse() + if(zenReq$getStatus() == 200){ + infoMsg = sprintf("Successfully fetched affiliation '%s'",id) + cli::cli_alert_success(infoMsg) + self$INFO(infoMsg) + }else{ + errMsg = sprintf("Error while fetching affiliation '%s': %s", id, out$message) + cli::cli_alert_danger(errMsg) + self$ERROR(errMsg) + out <- NULL + } + return(out) + }, + #Funders #------------------------------------------------------------------------------------------ diff --git a/man/ZenodoManager.Rd b/man/ZenodoManager.Rd index 9c995c0..88d9f33 100644 --- a/man/ZenodoManager.Rd +++ b/man/ZenodoManager.Rd @@ -106,6 +106,9 @@ Emmanuel Blondel \item \href{#method-ZenodoManager-getAwardsByName}{\code{ZenodoManager$getAwardsByName()}} \item \href{#method-ZenodoManager-getGrantById}{\code{ZenodoManager$getGrantById()}} \item \href{#method-ZenodoManager-getAwardById}{\code{ZenodoManager$getAwardById()}} +\item \href{#method-ZenodoManager-getAffiliations}{\code{ZenodoManager$getAffiliations()}} +\item \href{#method-ZenodoManager-getAffiliationByName}{\code{ZenodoManager$getAffiliationByName()}} +\item \href{#method-ZenodoManager-getAffiliationById}{\code{ZenodoManager$getAffiliationById()}} \item \href{#method-ZenodoManager-getFunders}{\code{ZenodoManager$getFunders()}} \item \href{#method-ZenodoManager-getFundersByName}{\code{ZenodoManager$getFundersByName()}} \item \href{#method-ZenodoManager-getFunderById}{\code{ZenodoManager$getFunderById()}} @@ -515,6 +518,78 @@ the award } } \if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-ZenodoManager-getAffiliations}{}}} +\subsection{Method \code{getAffiliations()}}{ +Get Affiliations supported by Zenodo. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{ZenodoManager$getAffiliations(q = "", pretty = TRUE, size = 500)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{q}}{an ElasticSearch compliant query, object of class \code{character}. Default is emtpy. +Note that the Zenodo API restrains a maximum number of 10,000 records to be retrieved. Consequently, +not all affiliations can be listed from Zenodo, a query has to be specified.} + +\item{\code{pretty}}{Prettify the output. By default the argument \code{pretty} is set to +\code{TRUE} which will returns the list of affiliations as \code{data.frame}. +Set \code{pretty = FALSE} to get the raw list of affiliations} + +\item{\code{size}}{number of affiliations to be returned. By default equal to 500.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +list of affiliations as \code{data.frame} or \code{list} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-ZenodoManager-getAffiliationByName}{}}} +\subsection{Method \code{getAffiliationByName()}}{ +Get affiliations by name. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{ZenodoManager$getAffiliationByName(name, pretty = TRUE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{name}}{name} + +\item{\code{pretty}}{Prettify the output. By default the argument \code{pretty} is set to +\code{TRUE} which will returns the list of affiliations as \code{data.frame}. +Set \code{pretty = FALSE} to get the raw list of affiliations} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +list of affiliations as \code{data.frame} or \code{list} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-ZenodoManager-getAffiliationById}{}}} +\subsection{Method \code{getAffiliationById()}}{ +Get affiliation by Id. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{ZenodoManager$getAffiliationById(id)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{id}}{affiliation id} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +the affiliation +} +} +\if{html}{\out{
}} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-ZenodoManager-getFunders}{}}} \subsection{Method \code{getFunders()}}{ diff --git a/tests/testthat/test_affiliations.R b/tests/testthat/test_affiliations.R new file mode 100644 index 0000000..760e78a --- /dev/null +++ b/tests/testthat/test_affiliations.R @@ -0,0 +1,25 @@ +# test_affiliations.R +# Author: Emmanuel Blondel +# +# Description: Unit tests for Zenodo affiliation operations +#======================= +require(zen4R, quietly = TRUE) +require(testthat) + +context("affiliation") + +test_that("affiliation are retrieved",{ + zenodo <- ZenodoManager$new(logger = "INFO") + zen_affiliations_df <- zenodo$getAffiliations() + expect_is(zen_affiliations_df, "data.frame") + Sys.sleep(2) + zen_affiliations_raw <- zenodo$getAffiliations(pretty = FALSE) + expect_is(zen_affiliations_raw, "list") + Sys.sleep(2) +}) + +test_that("affiliation is retrieved by id",{ + zenodo <- ZenodoManager$new(logger = "INFO") + zen_affiliation <- zenodo$getAffiliationById("fisheries") + Sys.sleep(2) +}) \ No newline at end of file