Skip to content

Commit

Permalink
Merge pull request #18 from ropensci/v2
Browse files Browse the repository at this point in the history
Support oaDOI API Version 2, which becomes the default version by 1 Octovber
  • Loading branch information
njahn82 authored Sep 21, 2017
2 parents 084f6cc + ecd8f8c commit e2bb8da
Show file tree
Hide file tree
Showing 11 changed files with 425 additions and 390 deletions.
10 changes: 6 additions & 4 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: roadoi
Type: Package
Title: Find Free Versions of Scholarly Publications via the oaDOI Service
Version: 0.3
Version: 0.3.9000
Authors@R: c(
person("Najko", "Jahn", role = c("aut", "cre"), email = "najko.jahn@gmail.com"),
person("Tuija", "Sonkkila", role = c("ctb"), comment = "Tuija Sonkkila
Expand All @@ -26,16 +26,18 @@ Imports:
jsonlite,
dplyr,
plyr,
purrr,
tibble,
miniUI,
shiny (>= 1.0.3)
shiny (>= 1.0.3),
tidyr
Suggests:
roxygen2 (>= 6.0.1),
testthat,
knitr,
covr,
rmarkdown,
lubridate,
rcrossref,
purrr
rcrossref
RoxygenNote: 6.0.1
VignetteBuilder: knitr
5 changes: 5 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ importFrom(miniUI,miniContentPanel)
importFrom(miniUI,miniPage)
importFrom(plyr,create_progress_bar)
importFrom(plyr,ldply)
importFrom(purrr,compact)
importFrom(purrr,map)
importFrom(purrr,map_if)
importFrom(shiny,actionButton)
importFrom(shiny,dialogViewer)
importFrom(shiny,observeEvent)
Expand All @@ -30,3 +33,5 @@ importFrom(shiny,stopApp)
importFrom(shiny,tableOutput)
importFrom(shiny,tags)
importFrom(shiny,textAreaInput)
importFrom(tibble,tibble)
importFrom(tidyr,unnest)
5 changes: 3 additions & 2 deletions R/oadoiAddins.R
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ roadoi_addin <- function() {
my_input <- reactive({
# avoid warnings about "no visible binding for global variable"
`Free fulltext link` <- NULL
`_best_open_url` <- NULL
`best_oa_location` <- NULL
doi <- NULL
dois <- unlist(strsplit(input$text, "\n"))
# limit input to 10
Expand All @@ -55,7 +55,8 @@ roadoi_addin <- function() {
"name@example.com")
# fetch full-text links and return the best match
roadoi::oadoi_fetch(dois, email) %>%
dplyr::select(`Free fulltext link` = `_best_open_url`, doi) %>%
tidyr::unnest(best_oa_location) %>%
dplyr::select(`Free fulltext link` = url, doi) %>%
dplyr::mutate(`Free fulltext link` = ifelse(
is.na(`Free fulltext link`),
NA,
Expand Down
153 changes: 87 additions & 66 deletions R/oadoi_fetch.r
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@
#'
#' This is the main function to retrieve comprehensive open access status
#' information from the oaDOI service. Please play nice with the API. At the
#' moment only 100k request are allowed per user and day.
#' moment only 100k request are suggested per user and day.
#' For more info see \url{https://oadoi.org/api}.
#'
#' @param dois character vector, search by a single DOI or many DOIs.
#' A rate limit of 100k requests per day is suggested. If you need to access
#' more data, use the data dump \url{https://oadoi.org/api#dataset} instead.
#' @param email character vector, required! It is strongly encourage to tell
#' oaDOI your email address, so that they can track usage and notify you
#' when something breaks. Set email address in your `.Rprofile` file with
#' @param email character vector, mandatory! oaDOI requires your email address,
#' so that they can track usage and notify you when something breaks.
#' Set email address in your `.Rprofile` file with
#' the option `roadoi_email` \code{options(roadoi_email = "name@example.com")}.
#' @param .progress Shows the \code{plyr}-style progress bar.
#' Options are "none", "text", "tk", "win", and "time".
Expand All @@ -23,67 +23,61 @@
#'
#'
#' \tabular{ll}{
#' \code{`_best_open_url`} \tab link to free full-text \cr
#' \code{`_closed_base_ids`} \tab internal ids for closed access copies \cr
#' returned from the Bielefeld Academic Search Engine (BASE) \cr
#' \code{`_closed_urls`} \tab links to closed access copies \cr
#' \code{`_green_base_collections`} \tab internal collection ID from the
#' Bielefeld Academic Search Engine (BASE) \cr
#' \code{`_open_base_ids`} \tab ids of oai metadata records with open access
#' full-text links collected by the Bielefeld Academic Search Engine (BASE) \cr
#' \code{`_open_urls`} \tab full-text url \cr
#' \code{`_title`} \tab title of the work \cr
#' \code{doi} \tab DOI \cr
#' \code{doi_resolver} \tab DOI agency \cr
#' \code{evidence} \tab A phrase summarizing the step of the
#' open access detection process where the full-text links were found. \cr
#' \code{found_green} \tab logical indicating whether a self-archived
#' copy in a repository was found \cr
#' \code{found_hybrid} \tab logical indicating whether an open access
#' article was published in a toll-access journal \cr
#' \code{free_fulltext_url}\tab URL where the free version was found \cr
#' \code{is_boai_license} \tab TRUE whenever the license indications are
#' Creative Commons - Attribution (CC BY), Creative Commons CC - Universal(CC 0))
#' or Public Domain. These permissive licenses comply with the
#' highly-regarded Budapest Open Access Initiative (BOAI) definition of
#' open access \cr
#' \code{is_free_to_read} \tab TRUE if freely available full-text
#' was found \cr
#' \code{is_subscription_journal} \tab TRUE if article is published in
#' toll-access journal \cr
#' \code{license} \tab Contains the name of the Creative
#' Commons license associated with the free_fulltext_url, whenever one
#' was found. \cr
#' \code{oa_color} \tab OA delivered by journal (gold),
#' by repository (green) or others (blue) \cr
#' \code{oa_color_long} \tab Long form of open access color \cr
#' \code{reported_noncompliant_copies} \tab links to free full-texts found
#' provided by service often considered as not open access compliant \cr
#' \code{url} \tab the canonical DOI UR \cr
#' \code{year} \tab publishing year \cr
#' \code{doi} \tab DOI (always in lowercase). \cr
#' \code{best_oa_location} \tab list-column describing the best OA location.
#' Algorithm prioritizes publisher hosted content (eg Hybrid or Gold),
#' then prioritizes versions closer to the version of record (PublishedVersion
#' over AcceptedVersion), then more authoritative repositories (PubMed Central
#' over CiteSeerX). \cr
#' \code{oa_locations} \tab list-column of all the OA locations. \cr
#' \code{data_standard} \tab Indicates the data collection approaches used
#' for this resource. \code{1} mostly uses Crossref for hybrid detection. \code{2}
#' uses more comprehensive hybrid detection methods. \cr
#' \code{is_oa} \tab Is there an OA copy (logical)? \cr
#' \code{journal_is_oa} \tab Is the article published in a fully OA journal?
#' Uses the Directory of Open Access Journals (DOAJ) as source. \cr
#' \code{journal_issns} \tab ISSNs, i.e. unique numbers to identify
#' journals. \cr
#' \code{journal_name} \tab Journal title, not normalized. \cr
#' \code{publisher} \tab Publisher, not normalized. \cr
#' \code{title} \tab Publication title. \cr
#' \code{year} \tab Year published. \cr
#' \code{updated} \tab Time when the data for this resource was last updated. \cr
#' \code{non_compliant} \tab Lists other full-text resources that are not
#' hosted by either publishers or repositories. \cr
#' }
#'
#' The columns \code{best_oa_location} and \code{oa_locations} are list-columns
#' that contain useful metadata about the OA sources found by oaDOI. These are
#'
#' \tabular{ll}{
#' \code{evidence} \tab How the OA location was found and is characterized
#' by oaDOI? \cr
#' \code{host_type} \tab OA full-text provided by \code{publisher} or
#' \code{repository}. \cr
#' \code{license} \tab The license under which this copy is published,
#' e.g. Creative Commons license. \cr
#' \code{url} \tab The URL where you can find this OA copy. \cr
#' \code{versions} \tab The content version accessible at this location
#' following the DRIVER 2.0 Guidelines
#' (\url{https://wiki.surfnet.nl/display/DRIVERguidelines/DRIVER-VERSION+Mappings}\cr
#' }
#'
#' The columns \code{`_closed_base_ids`}, \code{`_closed_urls`},
#' \code{`_open_base_ids`}, \code{`_open_urls`}, and
#' \code{`reported_noncompliant_copies`} are list-columns and may
#' have multiple entries.
#'
#' To unnest list-columns, you want to use tidyr's unnest function
#' \code{\link[tidyr]{unnest}} makes each element of the list its own row.

#' @examples \dontrun{
#' oadoi_fetch("10.1038/nature12373")
#' oadoi_fetch("10.1038/nature12373", email = "name@example.com")
#' oadoi_fetch(dois = c("10.1016/j.jbiotec.2010.07.030",
#' "10.1186/1471-2164-11-245"))
#'
#' # you can unnest list-columns with tidyr:
#' tt %>%
#' tidyr::unnest(open_base_ids)
#' "10.1186/1471-2164-11-245", email = "name@example.com"))
#' }
#'
#' @export
oadoi_fetch <-
function(dois = NULL,
email = getOption("roadoi_email"),
.progress = "none") {
# limit
# input validation
stopifnot(!is.null(dois))
email <- val_email(email)
Expand All @@ -95,8 +89,8 @@ oadoi_fetch <-
.call = FALSE
)
# Call API for every DOI, and return results as tbl_df
plyr::ldply(dois, oadoi_fetch_, email, .progress = .progress) %>%
dplyr::as_data_frame()
plyr::llply(dois, oadoi_fetch_, email, .progress = .progress) %>%
dplyr::bind_rows()
}

#' Get open access status information.
Expand All @@ -115,17 +109,13 @@ oadoi_fetch <-
#' }
#' @export
oadoi_fetch_ <- function(doi = NULL, email) {
u <- httr::modify_url(oadoi_baseurl(),
query = list(email = email),
path = doi)
u <- httr::modify_url(
oadoi_baseurl(),
query = list(email = email),
path = c(oadoi_api_version(), doi)
)
# Call oaDOI API
resp <- httr::GET(u,
ua,
# be explicit about the API version roadoi has to request
add_headers(
Accept = paste0("application/x.oadoi.",
oadoi_api_version(), "+json")
), timeout(10))
resp <- httr::GET(u, ua)

# test for valid json
if (httr::http_type(resp) != "application/json") {
Expand All @@ -151,6 +141,37 @@ oadoi_fetch_ <- function(doi = NULL, email) {
),
call. = FALSE
)
NULL
} else {
httr::content(resp, "text", encoding = "UTF-8") %>%
jsonlite::fromJSON() %>%
purrr::map(purrr::compact) %>% # remove empty list elements
parse_oadoi()
}
jsonlite::fromJSON(httr::content(resp, "text", encoding = "UTF-8"))$results
}

#' Parser for OADOI JSON
#'
#' @param req unparsed JSON
#'
#' @noRd
parse_oadoi <- function(req) {
# be aware of empty list elements
req <- purrr::map_if(req, is.null, ~ NA_character_)
tibble::tibble(
doi = req$doi,
best_oa_location = list(as_data_frame(req$best_oa_location)),
oa_locations = list(as_data_frame(req$oa_location)),
data_standard = req$data_standard,
is_oa = req$is_oa,
journal_is_oa = as.logical(ifelse(is.null(req$journal_is_oa),
FALSE, req$journal_is_oa)),
journal_issns = req$journal_issns,
journal_name = req$journal_name,
publisher = req$publisher,
title = req$title,
year = as.character(req$year),
updated = req$updated,
non_compliant = list(req$x_reported_noncompliant_copies)
)
}
3 changes: 3 additions & 0 deletions R/roadoi-package.r
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
#' @importFrom dplyr as_data_frame %>% select mutate
#' @importFrom miniUI miniContentPanel gadgetTitleBar miniPage
#' @importFrom shiny dialogViewer runGadget renderTable reactive observeEvent tableOutput actionButton textAreaInput tags stopApp
#' @importFrom purrr map map_if compact
#' @importFrom tibble tibble
#' @importFrom tidyr unnest
#' @name roadoi-package
#' @aliases roadoi
#' @docType package
Expand Down
2 changes: 1 addition & 1 deletion R/utils.r
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ oadoi_baseurl <- function()
"https://api.oadoi.org/"
# API version
oadoi_api_version <- function()
"1.3.0"
"v2"
# If you require access to more data, please use the data dump
api_limit <- 100000

Expand Down
9 changes: 6 additions & 3 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,13 @@ knitr::opts_chunk$set(
[![review](https://badges.ropensci.org/115_status.svg)](https://github.com/ropensci/onboarding/issues/115)


roadoi interacts with the [oaDOI API](http://oadoi.org/), a simple interface which links DOIs
and open access versions of scholarly works. oaDOI powers [unpaywall](http://unpaywall.org/).
roadoi interacts with the [oaDOI API](http://oadoi.org/), a simple web-interface
which links DOIs and open access versions of scholarly works.
oaDOI powers [unpaywall](http://unpaywall.org/).

API Documentation: <http://oadoi.org/api>
This client supports the most recent API Version 2.

API Documentation: <http://oadoi.org/api/v2>

## How do I use it?

Expand Down
Loading

0 comments on commit e2bb8da

Please sign in to comment.