#' Wraps around a function which is returned from \code{\link[purrr]{safely}}.
#' Makes it return the result or the error message
#'
#' @param .function A \code{function} to be wrapped
#'
#' @return Returns a \code{function}.
#' @export
return_result_or_message <- function(.function) {
force(.function)
function(...){
res = .function(...)
if(is.null(res$result)){
list("error" = c("message" = res$error$message))
} else {
res$result
}
}
}
#' Add progress tick \code{pb$tick()} to a function
#'
#' @param .function .function A \code{function} to which the progress should be
#' added
#' @param pb A progress bar as created by \code{\link[progress]{progress_bar}}
#'
#' @return Returns a \code{function}.
#' @export
with_progress = function(.function, pb){
force(.function)
function(...){
pb$tick()
.function(...)
}
}
#' Makes a function slow (delay before it's called) insistent (retries
#' execution on fail) and safe (return error message instead of stopping)
#'
#' @param .function A \code{function} to be made slow, insistent and safe
#' @param delay \code{numeric scalar} giving the number of seconds to wait
#' before the function is called
#' @param attempts \code{numeric scalar} giving the number of retry attempts
#' if the function fails
#'
#' @importFrom purrr slowly rate_delay insistently rate_backoff safely
#'
#' @return Returns a \code{function}
#' @export
make_function_safe_slow_insistent <- function(.function,
delay = 0,
attempts = 3) {
# Return function
.function %>%
ifelse(delay > 0,
slowly(., rate = rate_delay(delay)),
.) %>%
ifelse(attempts > 0,
insistently(., rate = rate_backoff(pause_base = delay,
pause_cap = delay,
pause_min = delay,
max_times = attempts)),
.) %>%
safely() %>%
return_result_or_message()
}
scfun = function(a){
print(a)
as.numeric(a)
}
#' Scrape a list of links or html files using a scrapefun
#'
#' @param ... arguments passed to the \code{scrapefun}.
#' @param scrapefun A \code{function} that defines the scraping logic. See
#' \code{vignette(scrapefuns_and_helpers)} for examples.
#' @param map_fun A map_... \code{function} from \code{purrr} ord \code{furrr}.
#' @param display_progress_bar \code{logical scalar} indicating whether to display
#' a progress bar
#' @inheritParams make_function_safe_slow_insistent
#'
#' @return Returns a \code{list}.
#' @export
#'
#' @import progress
scrapurrr = function(..., scrapefun, map_fun,
delay = 0, attempts = 3,
display_progress_bar = F){
scrapefun = scrapefun %>%
make_function_safe_slow_insistent(delay, attempts)
if(display_progress_bar){
args = list(...)
pb = progress_bar$new(total = length(args[[1]]),
format = " Scraping :current/:total [:bar] :percent eta: :eta",
force = T,
stream = stdout())
scrapefun = with_progress(scrapefun, pb)
}
map_fun(..., .f = scrapefun)
}
Add the following code to your website.
For more information on customizing the embed code, read Embedding Snippets.