Skip to content

Commit

Permalink
let download_file() return the file path instead of useless status co…
Browse files Browse the repository at this point in the history
…de 0
  • Loading branch information
yihui committed Feb 10, 2025
1 parent 60e6ac1 commit 39024b0
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 48 deletions.
2 changes: 1 addition & 1 deletion DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
Package: xfun
Type: Package
Title: Supporting Functions for Packages Maintained by 'Yihui Xie'
Version: 0.50.6
Version: 0.50.7
Authors@R: c(
person("Yihui", "Xie", role = c("aut", "cre", "cph"), email = "[email protected]", comment = c(ORCID = "0000-0003-0645-5666", URL = "https://yihui.org")),
person("Wush", "Wu", role = "ctb"),
Expand Down
2 changes: 2 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@

- `upload_imgur()` shows the error message instead of the error code when it fails to upload the image, which is more informative.

- `download_file()` returns the path of the file downloaded instead of the command status code now.

# CHANGES IN xfun VERSION 0.50

- The function `isFALSE()` has been removed from this package. The deprecation notice was given two years ago: https://yihui.org/en/2023/02/xfun-isfalse/
Expand Down
54 changes: 22 additions & 32 deletions R/io.R
Original file line number Diff line number Diff line change
Expand Up @@ -254,25 +254,23 @@ grep_sub = function(pattern, replacement, x, ...) {

#' Try various methods to download a file
#'
#' Try all possible methods in [download.file()] (e.g.,
#' `libcurl`, `curl`, `wget`, and `wininet`) and see if any
#' method can succeed. The reason to enumerate all methods is that sometimes the
#' default method does not work, e.g.,
#' <https://stat.ethz.ch/pipermail/r-devel/2016-June/072852.html>.
#' Try all possible methods in [download.file()] (e.g., `libcurl`, `curl`,
#' `wget`, and `wininet`) and see if any method can succeed. The reason to
#' enumerate all methods is that sometimes the default method does not work,
#' e.g., <https://stat.ethz.ch/pipermail/r-devel/2016-June/072852.html>.
#' @param url The URL of the file.
#' @param output Path to the output file. By default, it is determined by
#' [url_filename()].
#' @param ... Other arguments to be passed to [download.file()]
#' (except `method`).
#' @param ... Other arguments to be passed to [download.file()] (except
#' `method`).
#' @param .error An error message to signal when the download fails.
#' @note To allow downloading large files, the `timeout` option in
#' [options()] will be temporarily set to one hour (3600 seconds)
#' inside this function when this option has the default value of 60 seconds.
#' If you want a different `timeout` value, you may set it via
#' `options(timeout = N)`, where `N` is the number of seconds (not
#' 60).
#' @return The integer code `0` for success, or an error if none of the
#' methods work.
#' @note To allow downloading large files, the `timeout` option in [options()]
#' will be temporarily set to one hour (3600 seconds) inside this function
#' when this option has the default value of 60 seconds. If you want a
#' different `timeout` value, you may set it via `options(timeout = N)`, where
#' `N` is the number of seconds (not 60).
#' @return The `output` file path if the download succeeded, or an error if none
#' of the download methods worked.
#' @export
download_file = function(
url, output = url_filename(url), ...,
Expand All @@ -283,28 +281,20 @@ download_file = function(
on.exit(options(opts), add = TRUE)
}
download = function(method = 'auto') suppressWarnings({
# curl needs to add a -L option to follow redirects
if (method == 'curl' && is.null(getOption('download.file.extra'))) {
opts2 = options(download.file.extra = c('-L', '--fail'))
on.exit(options(opts2), add = TRUE)
}
tryCatch(download.file(url, output, ..., method = method), error = function(e) 1L)
})
for (method in c(if (is_windows()) 'wininet', 'libcurl', 'auto')) {
if (download(method = method) == 0) return(0L)
for (method in c('libcurl', 'auto', if (is_windows()) 'wininet')) {
if (download(method) == 0) return(output)
}

# check for libcurl/curl/wget/lynx, call download.file with appropriate method
if (Sys.which('curl') != '') {
# curl needs to add a -L option to follow redirects
opts2 = if (is.null(getOption('download.file.extra')))
options(download.file.extra = c('-L', '--fail'))
res = download(method = 'curl')
options(opts2)
if (res == 0) return(res)
for (method in c('curl', 'wget', 'lynx')) {
if (Sys.which(method) != '' && download(method) == 0) return(output)
}
if (Sys.which('wget') != '') {
if ((res <- download(method = 'wget')) == 0) return(res)
}
if (Sys.which('lynx') != '') {
if ((res <- download(method = 'lynx')) == 0) return(res)
}

stop(.error)
}

Expand Down
28 changes: 13 additions & 15 deletions man/download_file.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 39024b0

Please sign in to comment.