From 68f612495d086f1ad0dd9297c2417a27042873be Mon Sep 17 00:00:00 2001 From: Cesar Luis Aybar Camacho Date: Sun, 2 Aug 2020 01:29:04 -0500 Subject: [PATCH 01/10] changes in ee_Initialize() --- R/ee_Initialize.R | 48 +++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 40 insertions(+), 8 deletions(-) diff --git a/R/ee_Initialize.R b/R/ee_Initialize.R index 726b7e08..f32d1d6d 100644 --- a/R/ee_Initialize.R +++ b/R/ee_Initialize.R @@ -16,6 +16,8 @@ #' @param gcs Logical (optional). If TRUE, the Google Cloud Storage #' credential will be cached in the path \code{~/.config/earthengine/}. #' +#' @param display Logical. If TRUE display the earthengine authentification URL. +#' #' @param quiet Logical. Suppress info messages. #' #' @importFrom utils read.table browseURL write.table packageVersion @@ -56,6 +58,7 @@ ee_Initialize <- function(email = NULL, drive = FALSE, gcs = FALSE, + display = FALSE, quiet = FALSE) { # Message for new user init_rgee_message <- ee_search_init_message() @@ -222,7 +225,8 @@ ee_Initialize <- function(email = NULL, blue("Initializing Google Earth Engine:") ) } - ee_create_credentials_earthengine(email_clean) + + ee_create_credentials_earthengine(email_clean, display = display) ee$Initialize() if (!quiet) { @@ -292,7 +296,7 @@ ee_Initialize <- function(email = NULL, #' where they can be automatically refreshed, as necessary. #' } #' @noRd -ee_create_credentials_earthengine <- function(email_clean) { +ee_create_credentials_earthengine <- function(email_clean, display) { oauth_func_path <- system.file("python/ee_utils.py", package = "rgee") utils_py <- ee_source_python(oauth_func_path) @@ -317,15 +321,34 @@ ee_create_credentials_earthengine <- function(email_clean) { code_verifier <- oauth_codes[[1]] code_challenge <- oauth_codes[[2]] earthengine_auth <- ee$oauth$get_authorization_url(code_challenge) - browseURL(earthengine_auth) - auth_code <- getPass("Enter Earth Engine Authentication: ") - token <- ee$oauth$request_token(auth_code, code_verifier) - credential <- sprintf('{"refresh_token":"%s"}', token) - write(credential, main_ee_credential) - write(credential, user_ee_credential) + # Display URL? + if (display) { + replaceMessage(paste0(paste0(earthengine_auth))) + } + ee_save_eecredentials( + url = earthengine_auth, + code_verifier = code_verifier, + main_ee_credential = main_ee_credential, + user_ee_credential = user_ee_credential + ) + if (display) { + replaceMessage("") + } + invisible(TRUE) } } +#' Save EE credentials +#' @noRd +ee_save_eecredentials <- function(url, code_verifier, main_ee_credential, user_ee_credential) { + browseURL(url) + auth_code <- getPass("Enter Earth Engine Authentication: ") + token <- ee$oauth$request_token(auth_code, code_verifier) + credential <- sprintf('{"refresh_token":"%s"}', token) + write(credential, main_ee_credential) + write(credential, user_ee_credential) +} + #' Create credentials - Google Drive #' @noRd ee_create_credentials_drive <- function(email) { @@ -662,3 +685,12 @@ ee_createAssetHome <- function() { } ) } + +#' Replace text +#' Created by jthetzel +#' https://stackoverflow.com/questions/10218796/is-there-a-simpler-way-to-erase-the-end-of-the-line-using-cat-in-r +#' @noRd +replaceMessage <- function(x, width = 500) { + cat("\r", rep(" ", times = width - length(x)), "\r", append = T) + cat(x, append = F) +} From d3d8bf181983034cfabd39caaba400f16bd01a20 Mon Sep 17 00:00:00 2001 From: Cesar Luis Aybar Camacho Date: Sun, 2 Aug 2020 01:32:01 -0500 Subject: [PATCH 02/10] description changed --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 98c291ae..85222414 100755 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: rgee Title: R Bindings for Calling the 'Earth Engine' API -Version: 1.0.2 +Version: 1.0.3 Authors@R: c(person(given = "Cesar", family = "Aybar", From 8d6c069f67fcbdb1d4a9b0481be034e9bf182707 Mon Sep 17 00:00:00 2001 From: Cesar Luis Aybar Camacho Date: Sun, 2 Aug 2020 01:52:04 -0500 Subject: [PATCH 03/10] getPass removed --- DESCRIPTION | 1 - NAMESPACE | 1 - R/ee_Initialize.R | 17 ++--------------- man/ee_Initialize.Rd | 10 +++++++++- 4 files changed, 11 insertions(+), 18 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 85222414..c5a809f2 100755 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -89,7 +89,6 @@ Imports: methods, reticulate (>= 1.15), magrittr, - getPass, crayon, cli Suggests: diff --git a/NAMESPACE b/NAMESPACE index 6e9da8bb..68345184 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -93,7 +93,6 @@ importFrom(crayon,green) importFrom(crayon,red) importFrom(crayon,white) importFrom(crayon,yellow) -importFrom(getPass,getPass) importFrom(magrittr,"%>%") importFrom(methods,as) importFrom(methods,is) diff --git a/R/ee_Initialize.R b/R/ee_Initialize.R index f32d1d6d..6df544d2 100644 --- a/R/ee_Initialize.R +++ b/R/ee_Initialize.R @@ -22,7 +22,6 @@ #' #' @importFrom utils read.table browseURL write.table packageVersion #' @importFrom reticulate import_from_path import install_miniconda py_available -#' @importFrom getPass getPass #' @importFrom cli symbol rule #' @importFrom crayon blue green black red bold white #' @@ -323,7 +322,7 @@ ee_create_credentials_earthengine <- function(email_clean, display) { earthengine_auth <- ee$oauth$get_authorization_url(code_challenge) # Display URL? if (display) { - replaceMessage(paste0(paste0(earthengine_auth))) + cat("\n", earthengine_auth) } ee_save_eecredentials( url = earthengine_auth, @@ -331,9 +330,6 @@ ee_create_credentials_earthengine <- function(email_clean, display) { main_ee_credential = main_ee_credential, user_ee_credential = user_ee_credential ) - if (display) { - replaceMessage("") - } invisible(TRUE) } } @@ -342,7 +338,7 @@ ee_create_credentials_earthengine <- function(email_clean, display) { #' @noRd ee_save_eecredentials <- function(url, code_verifier, main_ee_credential, user_ee_credential) { browseURL(url) - auth_code <- getPass("Enter Earth Engine Authentication: ") + auth_code <- readline("Enter Earth Engine Authentication: ") token <- ee$oauth$request_token(auth_code, code_verifier) credential <- sprintf('{"refresh_token":"%s"}', token) write(credential, main_ee_credential) @@ -685,12 +681,3 @@ ee_createAssetHome <- function() { } ) } - -#' Replace text -#' Created by jthetzel -#' https://stackoverflow.com/questions/10218796/is-there-a-simpler-way-to-erase-the-end-of-the-line-using-cat-in-r -#' @noRd -replaceMessage <- function(x, width = 500) { - cat("\r", rep(" ", times = width - length(x)), "\r", append = T) - cat(x, append = F) -} diff --git a/man/ee_Initialize.Rd b/man/ee_Initialize.Rd index c7a6fa36..dd154901 100644 --- a/man/ee_Initialize.Rd +++ b/man/ee_Initialize.Rd @@ -4,7 +4,13 @@ \alias{ee_Initialize} \title{Authenticate and Initialize Earth Engine} \usage{ -ee_Initialize(email = NULL, drive = FALSE, gcs = FALSE, quiet = FALSE) +ee_Initialize( + email = NULL, + drive = FALSE, + gcs = FALSE, + display = FALSE, + quiet = FALSE +) } \arguments{ \item{email}{Character (optional, e.g. \code{data.colec.fbf@gmail.com}). The email @@ -17,6 +23,8 @@ will be cached in the path \code{~/.config/earthengine/}.} \item{gcs}{Logical (optional). If TRUE, the Google Cloud Storage credential will be cached in the path \code{~/.config/earthengine/}.} +\item{display}{Logical. If TRUE display the earthengine authentification URL.} + \item{quiet}{Logical. Suppress info messages.} } \description{ From d523caec0fb4a3ccf88b7f89fc4e421dbb459847 Mon Sep 17 00:00:00 2001 From: Cesar Luis Aybar Camacho Date: Sun, 2 Aug 2020 02:01:41 -0500 Subject: [PATCH 04/10] colab not display cat but message! --- R/ee_Initialize.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/ee_Initialize.R b/R/ee_Initialize.R index 6df544d2..f130c71d 100644 --- a/R/ee_Initialize.R +++ b/R/ee_Initialize.R @@ -322,7 +322,7 @@ ee_create_credentials_earthengine <- function(email_clean, display) { earthengine_auth <- ee$oauth$get_authorization_url(code_challenge) # Display URL? if (display) { - cat("\n", earthengine_auth) + message("\n", earthengine_auth) } ee_save_eecredentials( url = earthengine_auth, From 28c807af5744a02b453836d52da4d0773b0678ef Mon Sep 17 00:00:00 2001 From: Cesar Luis Aybar Camacho Date: Sun, 2 Aug 2020 03:07:09 -0500 Subject: [PATCH 05/10] ee_help now returns a html rather than a TRUE --- R/ee_help.R | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/R/ee_help.R b/R/ee_help.R index 049c5e7f..97fd59bb 100644 --- a/R/ee_help.R +++ b/R/ee_help.R @@ -116,7 +116,7 @@ ee_help <- function(eeobject, browser = FALSE) { close(fileConn) browseURL(temp_file) } - invisible(TRUE) + invisible(temp_file) } From c42a744f3d6b4982186537e85ae7588278a9777e Mon Sep 17 00:00:00 2001 From: Cesar Luis Aybar Camacho Date: Sun, 2 Aug 2020 03:25:20 -0500 Subject: [PATCH 06/10] ee_help now supports characters --- R/ee_help.R | 68 ++++++++++++++++++++++++++++------------------------- 1 file changed, 36 insertions(+), 32 deletions(-) diff --git a/R/ee_help.R b/R/ee_help.R index 97fd59bb..378dae18 100644 --- a/R/ee_help.R +++ b/R/ee_help.R @@ -28,40 +28,44 @@ ee_help <- function(eeobject, browser = FALSE) { ee_functions <- eequery_scope[search_funnames] fun_name <- paste0("ee$",gsub("\\.","$",tail(ee_functions,1))) } else { - wrap_lhs <- function(x) gsub("rgee", "", ee_get_lhs()) - fun_name <- wrap_lhs(eeobject) - if (length(fun_name) == 0) { - fun_name <- deparse(substitute(eeobject)) - } + if (is.character(eeobject)) { + fun_name <- eeobject + } else { + wrap_lhs <- function(x) gsub("rgee", "", ee_get_lhs()) + fun_name <- wrap_lhs(eeobject) + if (length(fun_name) == 0) { + fun_name <- deparse(substitute(eeobject)) + } - if (is.null(eequery_scope)) { - components <- strsplit(fun_name, "\\$")[[1]] - topic <- components[[length(components)]] - source <- paste(components[1:(length(components) - 1)], - collapse = "$") - # The name is a base function? - is_a_basefunction <- tryCatch( - expr = {eval(parse(text = sprintf("base::%s", fun_name))); TRUE}, - error = function(e) FALSE - ) - if (isTRUE(is_a_basefunction)) { - stop( - "'", fun_name, "' is not subsettable. Are you using a ", - "function name that matches the names of the R base", - " library?. If 'base::", fun_name, "' exists ee_help will not work." + if (is.null(eequery_scope)) { + components <- strsplit(fun_name, "\\$")[[1]] + topic <- components[[length(components)]] + source <- paste(components[1:(length(components) - 1)], + collapse = "$") + # The name is a base function? + is_a_basefunction <- tryCatch( + expr = {eval(parse(text = sprintf("base::%s", fun_name))); TRUE}, + error = function(e) FALSE ) - } - if (topic == source) { - fun_name <- topic - } else { - # Remove just the last parenthesis - extract_parenthesis_text <- gregexpr("(?=\\().*?(?<=\\))", - topic, - perl = TRUE) - parenthesis_text <- regmatches(topic, extract_parenthesis_text)[[1]] - to_display <- gsub(parenthesis_text, "", topic, fixed = TRUE) - to_display <- gsub("\\(|\\)", "", to_display) - fun_name <- paste(source,to_display,sep = "$") + if (isTRUE(is_a_basefunction)) { + stop( + "'", fun_name, "' is not subsettable. Are you using a ", + "function name that matches the names of the R base", + " library?. If 'base::", fun_name, "' exists ee_help will not work." + ) + } + if (topic == source) { + fun_name <- topic + } else { + # Remove just the last parenthesis + extract_parenthesis_text <- gregexpr("(?=\\().*?(?<=\\))", + topic, + perl = TRUE) + parenthesis_text <- regmatches(topic, extract_parenthesis_text)[[1]] + to_display <- gsub(parenthesis_text, "", topic, fixed = TRUE) + to_display <- gsub("\\(|\\)", "", to_display) + fun_name <- paste(source,to_display,sep = "$") + } } } } From 726d2936366bb79110f3d995086894158e0ddab4 Mon Sep 17 00:00:00 2001 From: barja8 Date: Mon, 3 Aug 2020 13:32:34 -0500 Subject: [PATCH 07/10] Fix a bug with reticulate ee_Initialize --- R/ee_Initialize.R | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/R/ee_Initialize.R b/R/ee_Initialize.R index f130c71d..cdd7e8ab 100644 --- a/R/ee_Initialize.R +++ b/R/ee_Initialize.R @@ -106,7 +106,16 @@ ee_Initialize <- function(email = NULL, # get the path of earth engine credentials ee_current_version <- system.file("python/ee_utils.py", package = "rgee") - ee_utils <- ee_source_python(ee_current_version) + ee_utils <- try(ee_source_python(ee_current_version), silent = TRUE) + # counter added to prevent problems with reticulate + con_reticulate_counter <- 0 + while (any(class(ee_utils) %in% "try-error") & con_reticulate_counter < 3) { + ee_utils <- try(ee_source_python(ee_current_version), silent = TRUE) + con_reticulate_counter <- con_reticulate_counter + 1 + if (con_reticulate_counter == 2) { + stop("reticulate refuse to connect with rgee") + } + } earthengine_version <- ee_utils_py_to_r(ee_utils$ee_getversion()) if (!quiet) { From 4be47d596b9266c185354a0ac695a7dbc169b77b Mon Sep 17 00:00:00 2001 From: barja8 Date: Mon, 3 Aug 2020 13:57:27 -0500 Subject: [PATCH 08/10] Fix a bug in ee_Initialize ee_Initialize requires googledrive and googleCloudStorageR when drive and gcs arguements are TRUE --- R/ee_Initialize.R | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/R/ee_Initialize.R b/R/ee_Initialize.R index cdd7e8ab..28910f49 100644 --- a/R/ee_Initialize.R +++ b/R/ee_Initialize.R @@ -172,6 +172,12 @@ ee_Initialize <- function(email = NULL, gcs_credentials <- list(path = NA, message = NA) if (drive) { + if (!requireNamespace("googledrive", quietly = TRUE)) { + stop("The googledrive package is not installed. Try", + ' install.packages("googledrive")', + call. = FALSE + ) + } if (!quiet) { cat( "", @@ -192,6 +198,12 @@ ee_Initialize <- function(email = NULL, } if (gcs) { + if (!requireNamespace("googleCloudStorageR", quietly = TRUE)) { + stop("The googleCloudStorageR package is not installed. Try", + ' install.packages("googleCloudStorageR")', + call. = FALSE + ) + } if (!quiet) { cat( "", From fe8ddf79bcb0eb5e2cd890aea9ff461a4b2516a6 Mon Sep 17 00:00:00 2001 From: csaybar Date: Mon, 3 Aug 2020 23:08:21 -0500 Subject: [PATCH 09/10] fix small bugs in ee_user_info and ee_users --- R/ee_Initialize.R | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/R/ee_Initialize.R b/R/ee_Initialize.R index 28910f49..851dae03 100644 --- a/R/ee_Initialize.R +++ b/R/ee_Initialize.R @@ -492,7 +492,7 @@ ee_create_credentials_gcs <- function(email) { ee_users <- function(quiet = FALSE) { #space among columns wsc <- " " - title <- c('user', ' EE', ' GD', ' GCS') + title <- c('user', ' EE', ' GCS', ' GD') oauth_func_path <- system.file("python/ee_utils.py", package = "rgee") utils_py <- ee_source_python(oauth_func_path) @@ -572,6 +572,10 @@ ee_user_info <- function(quiet = FALSE) { # google drive gd <- user_session_list[grepl("@gmail.com", user_session_list)] + if (length(gd) == 0) { + gd <- "NOT FOUND" + } + if (!quiet) { cat(blue$bold('\nGoogle Drive Credentials:')) cat("\n - ", basename(gd)) @@ -580,6 +584,10 @@ ee_user_info <- function(quiet = FALSE) { # google cloud storage gcs <- user_session_list[grepl(".json", user_session_list)] + if (length(gcs) == 0) { + gcs <- "NOT FOUND" + } + if (!quiet) { cat(blue$bold('\nGoogle Cloud Storage Credentials:')) cat("\n - ",basename(gcs)) @@ -587,13 +595,14 @@ ee_user_info <- function(quiet = FALSE) { } ee_user <- ee_exist_credentials() - if (isFALSE(grepl(email_drive, ee_user$email)) & ee_user$email != "ndef") { - message( - "\nNOTE: Google Drive credential does not match with your Google", - " Earth Engine credentials. All functions which depend on Google", - " Drive will not work (e.g. ee_image_to_drive)." - ) - } + # if (isFALSE(grepl(email_drive, ee_user$email)) & ee_user$email != "ndef") { + # message( + # "\nNOTE: Google Drive credential does not match with your Google", + # " Earth Engine credentials. All functions which depend on Google", + # " Drive will not work (e.g. ee_image_to_drive)." + # ) + # } + ee_check_python_packages(quiet = TRUE) invisible(TRUE) } From 1a0c0ced4fc2349386a54b48e057b1b3839f40d0 Mon Sep 17 00:00:00 2001 From: csaybar Date: Mon, 3 Aug 2020 23:45:45 -0500 Subject: [PATCH 10/10] small changes in README.md --- README.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index b2523099..080b2763 100755 --- a/README.md +++ b/README.md @@ -1,3 +1,4 @@ +Open in Colab [![R build status](https://github.com/r-spatial/rgee/workflows/R-CMD-check/badge.svg)](https://github.com/r-spatial/rgee/actions) [![Project Status: Active – The project has reached a stable, usable state and is being actively @@ -110,7 +111,11 @@ Install the `rgee` package from GitHub is quite simple, you just have to run in remotes::install_github("r-spatial/rgee") ``` -**`rgee` depends on [sf](https://github.com/r-spatial/sf)**. Therefore, is necessary to install its external libraries, follow the installation steps specified [here](https://github.com/r-spatial/sf#installing). +**`rgee` depends on [sf](https://github.com/r-spatial/sf)**. Therefore, is necessary to install its external libraries, follow the installation steps specified [here](https://github.com/r-spatial/sf#installing). If you are using a Debian-based operating system, you probably need to install **virtualenv** as well. If you are using a Debian-based operating system, you probably need to install virtualenv as well. + +``` +sudo pip3 install virtualenv +``` #### Docker image