diff --git a/DESCRIPTION b/DESCRIPTION index 467feb0..dd84ebd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -24,7 +24,8 @@ Imports: utils, stats, methods, - purrr + purrr, + digest RoxygenNote: 7.1.2 Suggests: testthat (>= 3.0.0), diff --git a/NAMESPACE b/NAMESPACE index 62179a3..9e7b1bf 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -30,6 +30,7 @@ export(rbcb_dataset) export(rbcb_get) export(rbcb_search) export(sgs) +importFrom(digest,digest) importFrom(httr,GET) importFrom(httr,POST) importFrom(httr,add_headers) diff --git a/R/http_util.R b/R/http_util.R index a5f165a..75035d1 100644 --- a/R/http_util.R +++ b/R/http_util.R @@ -38,4 +38,48 @@ http_gettext <- function(res, encoding = "UTF-8", as = "raw") { } else { x } -} \ No newline at end of file +} + +http_download <- function(method = c("get", "post"), ...) { + method <- match.arg(method) + cache <- getOption("rbcb_cache", default = TRUE) + params <- list(...) + code <- digest(params) + dest <- file.path(tempdir(), code) + + if (cache && file.exists(dest)) { + message("Skipping download - using cached version") + return(dest) + } + + res <- if (method == "get") { + http_getter(...) + } else { + http_poster(...) + } + + bin <- content(res, as = "raw") + writeBin(bin, dest) + + dest +} + +#' rbcb options +#' +#' Options used in rbcb inside some of its functions. +#' +#' * `rbcb_cache`: all downloaded data is stored in temporary directories, +#' if `rbcb_cache` is FALSE downloaded data overwrites files if it already +#' exists. Otherwise, download is not executed and the existing file is +#' returned. Defaults to TRUE. +#' * `rbcb_verbose`: if TRUE verbose messages are displayed when http requests +#' are executed with httr. Defaults to FALSE. +#' +#' @name rbcb-options +#' +#' @examples +#' \dontrun{ +#' options(rbcb_cache = FALSE) +#' options(rbcb_verbose = TRUE) +#' } +NULL \ No newline at end of file diff --git a/R/rbcb-package.R b/R/rbcb-package.R index 5b18609..e9272dd 100644 --- a/R/rbcb-package.R +++ b/R/rbcb-package.R @@ -19,5 +19,6 @@ #' @importFrom methods is #' @importFrom tibble tibble as_tibble #' @importFrom purrr map map_dfr +#' @importFrom digest digest #' NULL \ No newline at end of file diff --git a/R/rbcb_get_currencies.R b/R/rbcb_get_currencies.R index 0db20c7..91f7d04 100644 --- a/R/rbcb_get_currencies.R +++ b/R/rbcb_get_currencies.R @@ -160,11 +160,7 @@ get_all_currencies <- function(date) { ChkMoeda = 1 ) res <- http_poster(url, body = body, encode = "form") - if (res$status_code != 200) { - stop("BCB API Request error") - } - x <- content(res, as = "text") - # x <- http_gettext(res) + x <- http_gettext(res) m <- regexec("gerarCSVTodasAsMoedas&id=(\\d+)", x) if (length(m[[1]]) == 1 && m[[1]] == -1) { stop("BCB API Request error") @@ -173,10 +169,6 @@ get_all_currencies <- function(date) { url2 <- "https://ptax.bcb.gov.br/ptax_internet/consultaBoletim.do?method=gerarCSVTodasAsMoedas&id=%s" url2 <- sprintf(url2, id) res <- http_getter(url2) - if (res$status_code != 200) { - stop("BCB API Request error") - } - # x <- content(res, as = "text", encoding = "UTF-8") x <- http_gettext(res) df <- read.table(text = x, sep = ";", header = FALSE, colClasses = "character") names(df) <- c("date", "code", "type", "symbol", "bid", "ask", "bid.USD", "ask.USD") @@ -241,15 +233,8 @@ get_currency <- function(symbol, start_date, end_date, as = c("tibble", "xts", " id <- get_currency_id(symbol) url <- currency_url(id, start_date, end_date) res <- http_getter(url) - if (res$status_code != 200) { - stop("BCB API Request error, status code = ", res$status_code) - } if (grepl("text/html", headers(res)[["content-type"]])) { - # x <- content(res, as = 'text') - x <- http_gettext(res) - x <- read_html(x) - x <- xml_find_first(x, "//div[@class='msgErro']") - stop("BCB API returned error: ", xml_text(x)) + stop("BCB API returned error") } csv_ <- http_gettext(res) diff --git a/R/rbcb_get_market_expectations.R b/R/rbcb_get_market_expectations.R index 2bc0f96..cade961 100644 --- a/R/rbcb_get_market_expectations.R +++ b/R/rbcb_get_market_expectations.R @@ -710,9 +710,8 @@ get_market_expectations <- function(type = c( indic, start_date, end_date, ... ) - res <- http_getter(url) - text_ <- http_gettext(res, as = "text") - data_ <- fromJSON(text_) + f <- http_download("get", url) + data_ <- fromJSON(f) if (!is.null(data_$value) && length(data_$value) == 0) { return(tibble()) diff --git a/R/rbcb_olinda_get_currencies.R b/R/rbcb_olinda_get_currencies.R index dc03cf8..ee66a57 100644 --- a/R/rbcb_olinda_get_currencies.R +++ b/R/rbcb_olinda_get_currencies.R @@ -44,8 +44,8 @@ olinda_usd_url <- function(start_date, end_date) { #' @export olinda_list_currencies <- function() { url <- "https://olinda.bcb.gov.br/olinda/servico/PTAX/versao/v1/odata/Moedas" - res <- GET(url) - data <- fromJSON(content(res, as = "text")) + f <- http_download("get", url) + data <- fromJSON(f) df <- data$value names(df) <- c("symbol", "name", "currency_type") df diff --git a/R/sgs.R b/R/sgs.R index b603684..c4d44e9 100644 --- a/R/sgs.R +++ b/R/sgs.R @@ -43,13 +43,13 @@ sgs_info <- function(x) { url <- "https://www3.bcb.gov.br/sgspub/consultarvalores/consultarValoresSeries.do?method=consultarGraficoPorId" url <- modify_url(url, query = list(hdOidSeriesSelecionadas = x$code)) - res <- http_getter(url) + f <- http_download("get", url) - sgs_parse_info(x, http_gettext(res, encoding = "latin1", as = "text")) + sgs_parse_info(x, f) } -sgs_parse_info <- function(x, txt) { - doc <- read_html(txt) +sgs_parse_info <- function(x, f) { + doc <- read_html(f, encoding = "latin1") info <- xml_find_first(doc, '//tr[@class="fundoPadraoAClaro3"]') if (length(info) == 0) { @@ -137,9 +137,8 @@ print.sgs <- function(x, ...) { rbcb_get.sgs <- function(x, from = NULL, to = NULL, last = 0, ...) { map_dfr(x, function(ser) { url <- sgs_url(ser, from, to, last) - res <- http_getter(url) - json <- http_gettext(res, as = "text") - sgs_create_series(ser, json) + f <- http_download("get", url) + sgs_create_series(ser, f) }) } diff --git a/man/rbcb-options.Rd b/man/rbcb-options.Rd new file mode 100644 index 0000000..3f75fa6 --- /dev/null +++ b/man/rbcb-options.Rd @@ -0,0 +1,22 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/http_util.R +\name{rbcb-options} +\alias{rbcb-options} +\title{rbcb options} +\description{ +Options used in rbcb inside some of its functions. +} +\details{ +* `rbcb_cache`: all downloaded data is stored in temporary directories, + if `rbcb_cache` is FALSE downloaded data overwrites files if it already + exists. Otherwise, download is not executed and the existing file is + returned. Defaults to TRUE. +* `rbcb_verbose`: if TRUE verbose messages are displayed when http requests + are executed with httr. Defaults to FALSE. +} +\examples{ +\dontrun{ +options(rbcb_cache = FALSE) +options(rbcb_verbose = TRUE) +} +} diff --git a/tests/testthat/test-http.R b/tests/testthat/test-http.R new file mode 100644 index 0000000..9ff89d3 --- /dev/null +++ b/tests/testthat/test-http.R @@ -0,0 +1,9 @@ +test_that("it should test http download", { + url <- "https://olinda.bcb.gov.br/olinda/servico/PTAX/versao/v1/odata/Moedas" + f <- http_download("get", url) + expect_message(http_download("get", url)) + expect_true(file.exists(f)) + options(rbcb_cache = FALSE) + expect_silent(http_download("get", url)) + options(rbcb_cache = TRUE) +})