diff --git a/DESCRIPTION b/DESCRIPTION index 5590f19..00268eb 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: decapitated Type: Package Title: Headless 'Chrome' Orchestration -Version: 0.2.0 +Version: 0.3.0 Authors@R: c( person("Bob", "Rudis", email = "bob@rud.is", role = c("aut", "cre"), comment = c(ORCID = "0000-0001-5670-2640")), @@ -16,6 +16,7 @@ URL: https://github.com/hrbrmstr/decapitated BugReports: https://github.com/hrbrmstr/decapitated/issues License: MIT + file LICENSE SystemRequirements: Chrome 59+ on macOS/Linux, 60+ on Windows +Encoding: UTF-8 Suggests: testthat, covr @@ -27,4 +28,4 @@ Imports: processx, tools, utils -RoxygenNote: 6.0.1 +RoxygenNote: 6.0.1.9000 diff --git a/NAMESPACE b/NAMESPACE index ff14564..1ae3f1e 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -4,6 +4,7 @@ export(chrome_dump_pdf) export(chrome_read_html) export(chrome_shot) export(chrome_version) +export(download_chromium) export(get_chrome_env) export(set_chrome_env) import(magick) diff --git a/NEWS.md b/NEWS.md index cc2cd7d..1df837b 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,8 @@ +0.3.0 +* Added `download_chromium()` and highly recommend folks use it vs system Chrome + binaries. +* Slightly modified startup code to check for Chrome being present. + 0.2.0 * Re-design of how the Chrome binary is set * env var functions to help with ^^ diff --git a/R/decapitated-package.R b/R/decapitated-package.R index cf5e1ed..402e3a7 100644 --- a/R/decapitated-package.R +++ b/R/decapitated-package.R @@ -22,17 +22,24 @@ #' #' @section Important: #' -#' You'll need to set an envrionment variable `HEADLESS_CHROME` to one of these two values: +#' You'll need to set an envrionment variable `HEADLESS_CHROME` to use this package. #' -#' - Windows(32bit): `C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe` -#' - Windows(64bit): `C:\\Program Files (x86)/Google\\Chrome\\Application\\chrome.exe` +#' If this value is not set, a location heuristic is used on package start which looks +#' for the following depending on the operating system: +#' +#' - Windows(32bit): `C:/Program Files/Google/Chrome/Application/chrome.exe` +#' - Windows(64bit): `C:/Program Files (x86)/Google/Chrome/Application/chrome.exe` #' - macOS: `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome` #' - Linux: `/usr/bin/google-chrome` #' -#' A guess is made (but not verified yet) if `HEADLESS_CHROME` is non-existent. +#' If a verification test fails, you will be notified. +#' +#' **It is HIGHLY recommended** that you use `decapitated::download_chromium()` to use +#' a standalone version of Chrome with this packge for your platform. #' #' It's best to use `~/.Renviron` to store this value. #' +#' #' @md #' @name decapitated #' @docType package diff --git a/R/download-chromium.R b/R/download-chromium.R new file mode 100644 index 0000000..f7aafc2 --- /dev/null +++ b/R/download-chromium.R @@ -0,0 +1,63 @@ +#' Download a standalone version of Chromium (recommended) +#' +#' @md +#' @param path where to store the Chromium app. +#' @param chromium_revision version to download (keep default unless you require +#' a specific version) +#' @export +download_chromium <- function(path = NULL, chromium_revision = 579032) { + + path <- path.expand(path) + stopifnot(dir.exists(path)) + + dl_src_path <-'https://storage.googleapis.com' + + list( + linux= '%s/chromium-browser-snapshots/Linux_x64/%d/chrome-linux.zip', + mac = '%s/chromium-browser-snapshots/Mac/%d/chrome-mac.zip', + win32 = '%s/chromium-browser-snapshots/Win/%d/chrome-win32.zip', + win64 = '%s/chromium-browser-snapshots/Win_x64/%d/chrome-win32.zip' + ) -> dl_urls + + + dl <- if (unname(Sys.info()["sysname"] == "Windows")) { + if (unname(Sys.info()["machine"] == "x86-64")) "win64" else "win32" + } else if (unname(Sys.info()["sysname"] == "Darwin")) { + "mac" + } else if (unname(Sys.info()["sysname"] == "Linux")) { + "linux" + } else { + stop("Unrecognized platform", call.=FALSE) + } + + dl_url <- sprintf(dl_urls[[dl]], dl_src_path, chromium_revision) + dl_fil <- file.path(path, basename(dl_url)) + + message("Downloading ", dl_url) + + download.file(dl_url, dl_fil, mode="wb") + on.exit(unlink(dl_fil), add=TRUE) + + unzip(dl_fil, unzip = getOption("unzip"), exdir = path) + for (fil in list.files(path, recursive = TRUE)) Sys.chmod(fil, "0755") + + chrome_ex_path <- if (unname(Sys.info()["sysname"] == "Windows")) { + file.path(path, "chrome-win32", "chrome.exe") + } else if (unname(Sys.info()["sysname"] == "Darwin")) { + file.path(path, "chrome-mac", "Chromium.app", "Contents", "MacOS", "Chromium") + } else if (unname(Sys.info()["sysname"] == "Linux")) { + file.path(path, "chrome-linux", "chrome") + } + + message( + sprintf( + "Please set the HEADLESS_CHROME environment variable to:\n '%s'\n\n", chrome_ex_path + ), "This value has also been returned invisibly." + ) + + invisible(chrome_ex_path) + +} + + + diff --git a/R/zzz.R b/R/zzz.R index d37dcc8..06e9d3c 100644 --- a/R/zzz.R +++ b/R/zzz.R @@ -1,36 +1,45 @@ .onAttach <- function(libname, pkgname) { + HEADLESS_CHROME <- Sys.getenv("HEADLESS_CHROME") + if (interactive()) { - if (Sys.getenv("HEADLESS_CHROME") == "") { + if (HEADLESS_CHROME == "") { if (unname(Sys.info()["sysname"] == "Windows")) { if (unname(Sys.info()["machine"] == "x86-64")) { - Sys.setenv(HEADLESS_CHROME="C:/Program Files (x86)/Google/Chrome/Application/chrome.exe") + HEADLESS_CHROME <- "C:/Program Files (x86)/Google/Chrome/Application/chrome.exe" } else { - Sys.setenv(HEADLESS_CHROME="C:/Program Files/Google/Chrome/Application/chrome.exe") + HEADLESS_CHROME <- "C:/Program Files/Google/Chrome/Application/chrome.exe" } } if (unname(Sys.info()["sysname"] == "Darwin")) { - Sys.setenv(HEADLESS_CHROME="/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome") + HEADLESS_CHROME <- "/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome" } if (unname(Sys.info()["sysname"] == "Linux")) { - Sys.setenv(HEADLESS_CHROME="/usr/bin/google-chrome") + HEADLESS_CHROME <- "/usr/bin/google-chrome" } + } + + if (file.exists(HEADLESS_CHROME)) { + Sys.setenv("HEADLESS_CHROME"=HEADLESS_CHROME) packageStartupMessage( - sprintf( - "Set Chrome binary to [%s]. -To override, pass in manually to functions or use decapitated::set_chrome_env()", - Sys.getenv("HEADLESS_CHROME")) + sprintf("Using Chrome binary from [%s].\n", Sys.getenv("HEADLESS_CHROME")) + ) + } else { + packageStartupMessage( + sprintf("Chrome binary not found at [%s].\n", Sys.getenv("HEADLESS_CHROME")), + "Please use decapitated::download_chromium() and set the HEADLESS_CHROME ", + "environment variable to the value returned from the function." ) - } + } } \ No newline at end of file diff --git a/README.Rmd b/README.Rmd index d2e194b..98c5434 100644 --- a/README.Rmd +++ b/README.Rmd @@ -12,16 +12,22 @@ The 'Chrome' browser has a headless mode which can be instrumented programmatically. Tools are provided to perform headless 'Chrome' instrumentation on the command-line, including retrieving the javascript-executed web page, PDF output or screen shot of a URL. -### IMPORTANT +## IMPORTANT -You'll need to set an envrionment variable `HEADLESS_CHROME` to one of these two values: +You'll need to set an envrionment variable `HEADLESS_CHROME` to use this package. + +If this value is not set, a location heuristic is used on package start which looks +for the following depending on the operating system: - Windows(32bit): `C:/Program Files/Google/Chrome/Application/chrome.exe` - Windows(64bit): `C:/Program Files (x86)/Google/Chrome/Application/chrome.exe` - macOS: `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome` - Linux: `/usr/bin/google-chrome` -A guess is made (but not verified yet) if `HEADLESS_CHROME` is non-existent. +If a verification test fails, you will be notified. + +**It is HIGHLY recommended** that you use `decapitated::download_chromium()` to use +a standalone version of Chrome with this packge for your platform. It's best to use `~/.Renviron` to store this value. @@ -56,6 +62,7 @@ Chrome. The following functions are implemented: +- `downlaod_chromium`: Download a standalone version of Chromium (recommended) - `chrome_dump_pdf`: "Print" to PDF - `chrome_read_html`: Read a URL via headless Chrome and return the raw or rendered '' 'innerHTML' DOM elements - `chrome_shot`: Capture a screenshot diff --git a/README.md b/README.md index b062adb..4c84b90 100644 --- a/README.md +++ b/README.md @@ -11,23 +11,24 @@ perform headless ‘Chrome’ instrumentation on the command-line, including retrieving the javascript-executed web page, PDF output or screen shot of a URL. -### IMPORTANT +## IMPORTANT -You’ll need to set an envrionment variable `HEADLESS_CHROME` to one of -these two values: +You'll need to set an envrionment variable `HEADLESS_CHROME` to use this package. - - Windows(32bit): `C:/Program - Files/Google/Chrome/Application/chrome.exe` - - Windows(64bit): `C:/Program Files - (x86)/Google/Chrome/Application/chrome.exe` - - macOS: `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ - Chrome` - - Linux: `/usr/bin/google-chrome` +If this value is not set, a location heuristic is used on package start which looks +for the following depending on the operating system: -A guess is made (but not verified yet) if `HEADLESS_CHROME` is -non-existent. +- Windows(32bit): `C:/Program Files/Google/Chrome/Application/chrome.exe` +- Windows(64bit): `C:/Program Files (x86)/Google/Chrome/Application/chrome.exe` +- macOS: `/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome` +- Linux: `/usr/bin/google-chrome` -It’s best to use `~/.Renviron` to store this value. +If a verification test fails, you will be notified. + +**It is HIGHLY recommended** that you use `decapitated::download_chromium()` to use +a standalone version of Chrome with this packge for your platform. + +It's best to use `~/.Renviron` to store this value. ## Working around headless Chrome & OS security restrictions: @@ -62,6 +63,7 @@ control over the command-line execution of headless Chrome. The following functions are implemented: + - `downlaod_chromium`: Download a standalone version of Chromium (recommended) - `chrome_dump_pdf`: “Print” to PDF - `chrome_read_html`: Read a URL via headless Chrome and return the raw or rendered ’ @@ -87,7 +89,7 @@ library(decapitated) packageVersion("decapitated") ``` - ## [1] '0.2.0' + ## [1] '0.3.0' ``` r chrome_version() diff --git a/man/decapitated.Rd b/man/decapitated.Rd index 29d77fd..6075d90 100644 --- a/man/decapitated.Rd +++ b/man/decapitated.Rd @@ -31,15 +31,21 @@ restrictions or headless Chrome will not function. \section{Important}{ -You'll need to set an envrionment variable \code{HEADLESS_CHROME} to one of these two values: +You'll need to set an envrionment variable \code{HEADLESS_CHROME} to use this package. + +If this value is not set, a location heuristic is used on package start which looks +for the following depending on the operating system: \itemize{ -\item Windows(32bit): \code{C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe} -\item Windows(64bit): \code{C:\\Program Files (x86)/Google\\Chrome\\Application\\chrome.exe} +\item Windows(32bit): \code{C:/Program Files/Google/Chrome/Application/chrome.exe} +\item Windows(64bit): \code{C:/Program Files (x86)/Google/Chrome/Application/chrome.exe} \item macOS: \code{/Applications/Google\ Chrome.app/Contents/MacOS/Google\ Chrome} \item Linux: \code{/usr/bin/google-chrome} } -A guess is made (but not verified yet) if \code{HEADLESS_CHROME} is non-existent. +If a verification test fails, you will be notified. + +\strong{It is HIGHLY recommended} that you use \code{decapitated::download_chromium()} to use +a standalone version of Chrome with this packge for your platform. It's best to use \code{~/.Renviron} to store this value. } diff --git a/man/download_chromium.Rd b/man/download_chromium.Rd new file mode 100644 index 0000000..618e115 --- /dev/null +++ b/man/download_chromium.Rd @@ -0,0 +1,17 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/download-chromium.R +\name{download_chromium} +\alias{download_chromium} +\title{Download a standalone version of Chromium (recommended)} +\usage{ +download_chromium(path = NULL, chromium_revision = 579032) +} +\arguments{ +\item{path}{where to store the Chromium app.} + +\item{chromium_revision}{version to download (keep default unless you require +a specific version)} +} +\description{ +Download a standalone version of Chromium (recommended) +}