From f18dc13636237369fc5a8636383aebd52c3edccf Mon Sep 17 00:00:00 2001 From: cpsievert Date: Mon, 18 Jan 2016 20:41:23 -0600 Subject: [PATCH 1/5] Add sharing argument and deprecate world_readable. Fixes #332 --- R/plotly_POST.R | 55 +++++++++++++++++++++++++++++++++++-------------- 1 file changed, 40 insertions(+), 15 deletions(-) diff --git a/R/plotly_POST.R b/R/plotly_POST.R index c3b92cb303..dfa5d911c2 100644 --- a/R/plotly_POST.R +++ b/R/plotly_POST.R @@ -4,15 +4,26 @@ #' \url{https://plot.ly/rest/} #' #' @param x either a ggplot object, a plotly object, or a list. -#' @param filename character string describing the name of the plot in your plotly account. -#' Use / to specify directories. If a directory path does not exist it will be created. -#' If this argument is not specified and the title of the plot exists, -#' that will be used for the filename. -#' @param fileopt character string describing whether to create a "new" plotly, "overwrite" an existing plotly, -#' "append" data to existing plotly, or "extend" it. -#' @param world_readable logical. If \code{TRUE}, the graph is viewable -#' by anyone who has the link and in the owner's plotly account. -#' If \code{FALSE}, graph is only viewable in the owner's plotly account. +#' @param filename character string describing the name of the plot in your +#' plotly account. Use / to specify directories. If a directory path does not +#' exist it will be created. If this argument is not specified and the title +#' of the plot exists, that will be used for the filename. +#' @param fileopt character string describing whether to create a "new" plotly, +#' "overwrite" an existing plotly, "append" data to existing plotly, +#' or "extend" it. +#' @param sharing If 'public', anyone can view this graph. It will appear in +#' your profile and can appear in search engines. You do not need to be +#' logged in to Plotly to view this chart. +#' If 'private', only you can view this plot. It will not appear in the +#' Plotly feed, your profile, or search engines. You must be logged in to +#' Plotly to view this graph. You can privately share this graph with other +#' Plotly users in your online Plotly account and they will need to be logged +#' in to view this plot. +#' If 'secret', anyone with this secret link can view this chart. It will +#' not appear in the Plotly feed, your profile, or search engines. +#' If it is embedded inside a webpage or an IPython notebook, anybody who is +#' viewing that page will be able to view the graph. +#' You do not need to be logged in to view this plot. #' @export #' @seealso \link{plot_ly}, \link{signup} #' @return An R object created by mapping the JSON content of the plotly API @@ -24,7 +35,8 @@ #' plotly_POST(p, filename = "mtcars-bar-plot") #' } -plotly_POST <- function(x, filename, fileopt = "new", world_readable = TRUE) { +plotly_POST <- function(x, filename, fileopt = "new", + sharing = c("public", "private", "secret")) { x <- plotly_build(x) x$filename <- if (!missing(filename)) { filename @@ -34,12 +46,17 @@ plotly_POST <- function(x, filename, fileopt = "new", world_readable = TRUE) { paste(c(x$layout$xaxis$title, x$layout$yaxis$title, x$layout$zaxis$title), collapse = " vs. ") %||% "plot from api" } - if (!is.null(x$fileopt)) - warning("fileopt was specified in the wrong place. Please specify in plotly_POST()") + if (!is.null(x$fileopt)) { + warning("fileopt was specified in the wrong place.", + "Please specify in plotly_POST()") + } x$fileopt <- fileopt - if (!is.null(x$world_readable)) - warning("world_readable was specified in the wrong place. Please specify in plotly_POST()") - x$world_readable <- world_readable + if (!is.null(x$world_readable)) { + warning("world_readable was specified in the wrong place.", + "Please use the sharing argument in plotly_POST()") + } + x$world_readable <- if (sharing[1] == "public") TRUE else FALSE + # plotly server has trouble with empty properties x <- x[sapply(x, length) > 0] # construct body of message to plotly server @@ -55,6 +72,14 @@ plotly_POST <- function(x, filename, fileopt = "new", world_readable = TRUE) { base_url <- file.path(get_domain(), "clientresp") resp <- httr::POST(base_url, body = bod) con <- process(struct(resp, "clientresp")) + if (sharing[1] == "secret") { + bits <- strsplit(con$url, "/")[[1]] + plot_id <- bits[length(bits)] + url <- paste0(get_domain("v2"), "files/", verify("username"), ":", plot_id) + bod <- list(share_key_enabled = TRUE) + con2 <- httr::PATCH(url, plotly_headers("v2"), body = bod, encode = "json") + con$url <- paste0(con$url, "?share_key=", content(con2)$share_key) + } msg <- switch(x$fileopt %||% "new", new = "Success! Created a new plotly here -> ", overwrite = "Success! Modified your plotly here -> ") From aa33ec84128b51fb41677d2f2e7543814db1890a Mon Sep 17 00:00:00 2001 From: cpsievert Date: Mon, 18 Jan 2016 20:44:07 -0600 Subject: [PATCH 2/5] bump version, update news, document --- DESCRIPTION | 2 +- NEWS | 4 ++++ man/plotly_POST.Rd | 32 ++++++++++++++++++++++---------- 3 files changed, 27 insertions(+), 11 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 4809a22080..70227bb4e6 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,6 +1,6 @@ Package: plotly Title: Create Interactive Web Graphics via Plotly's JavaScript Graphing Library -Version: 2.2.4 +Version: 2.3.0 Authors@R: c(person("Carson", "Sievert", role = c("aut", "cre"), email = "cpsievert1@gmail.com"), person("Chris", "Parmer", role = c("aut", "cph"), diff --git a/NEWS b/NEWS index f368c774c6..303d11692c 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,7 @@ +2.3.0 -- 19 Jan 2015 + +Add sharing argument and deprecate world_readable. Fixes #332 + 2.2.4 -- 18 Jan 2015 Fix for error in embed_notebook(). See #409. diff --git a/man/plotly_POST.Rd b/man/plotly_POST.Rd index ceed8ce8b7..e68f806b91 100644 --- a/man/plotly_POST.Rd +++ b/man/plotly_POST.Rd @@ -4,22 +4,34 @@ \alias{plotly_POST} \title{Create/Modify plotly graphs} \usage{ -plotly_POST(x, filename, fileopt = "new", world_readable = TRUE) +plotly_POST(x, filename, fileopt = "new", sharing = c("public", "private", + "secret")) } \arguments{ \item{x}{either a ggplot object, a plotly object, or a list.} -\item{filename}{character string describing the name of the plot in your plotly account. -Use / to specify directories. If a directory path does not exist it will be created. -If this argument is not specified and the title of the plot exists, -that will be used for the filename.} +\item{filename}{character string describing the name of the plot in your +plotly account. Use / to specify directories. If a directory path does not +exist it will be created. If this argument is not specified and the title +of the plot exists, that will be used for the filename.} -\item{fileopt}{character string describing whether to create a "new" plotly, "overwrite" an existing plotly, -"append" data to existing plotly, or "extend" it.} +\item{fileopt}{character string describing whether to create a "new" plotly, +"overwrite" an existing plotly, "append" data to existing plotly, +or "extend" it.} -\item{world_readable}{logical. If \code{TRUE}, the graph is viewable -by anyone who has the link and in the owner's plotly account. -If \code{FALSE}, graph is only viewable in the owner's plotly account.} +\item{sharing}{If 'public', anyone can view this graph. It will appear in +your profile and can appear in search engines. You do not need to be +logged in to Plotly to view this chart. +If 'private', only you can view this plot. It will not appear in the +Plotly feed, your profile, or search engines. You must be logged in to +Plotly to view this graph. You can privately share this graph with other +Plotly users in your online Plotly account and they will need to be logged +in to view this plot. +If 'secret', anyone with this secret link can view this chart. It will +not appear in the Plotly feed, your profile, or search engines. +If it is embedded inside a webpage or an IPython notebook, anybody who is +viewing that page will be able to view the graph. +You do not need to be logged in to view this plot.} } \value{ An R object created by mapping the JSON content of the plotly API From 690e985be1170a0372c0ec1a8e52dcb6eb256faa Mon Sep 17 00:00:00 2001 From: cpsievert Date: Mon, 18 Jan 2016 22:09:43 -0600 Subject: [PATCH 3/5] Better warning. s/secret/hidden/g --- R/plotly_POST.R | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/R/plotly_POST.R b/R/plotly_POST.R index dfa5d911c2..eb9c41c5b7 100644 --- a/R/plotly_POST.R +++ b/R/plotly_POST.R @@ -19,7 +19,7 @@ #' Plotly to view this graph. You can privately share this graph with other #' Plotly users in your online Plotly account and they will need to be logged #' in to view this plot. -#' If 'secret', anyone with this secret link can view this chart. It will +#' If 'hidden', anyone with this hidden link can view this chart. It will #' not appear in the Plotly feed, your profile, or search engines. #' If it is embedded inside a webpage or an IPython notebook, anybody who is #' viewing that page will be able to view the graph. @@ -36,7 +36,7 @@ #' } plotly_POST <- function(x, filename, fileopt = "new", - sharing = c("public", "private", "secret")) { + sharing = c("public", "private", "hidden")) { x <- plotly_build(x) x$filename <- if (!missing(filename)) { filename @@ -52,8 +52,10 @@ plotly_POST <- function(x, filename, fileopt = "new", } x$fileopt <- fileopt if (!is.null(x$world_readable)) { - warning("world_readable was specified in the wrong place.", - "Please use the sharing argument in plotly_POST()") + warning('world_readable is no longer supported. Instead, set the sharing\n', + 'argument to "private" (you must be logged in to access),\n', + '"hidden" (anybody with the obscured URL can access) or "public"\n', + '(anybody can view).') } x$world_readable <- if (sharing[1] == "public") TRUE else FALSE @@ -72,7 +74,7 @@ plotly_POST <- function(x, filename, fileopt = "new", base_url <- file.path(get_domain(), "clientresp") resp <- httr::POST(base_url, body = bod) con <- process(struct(resp, "clientresp")) - if (sharing[1] == "secret") { + if (sharing[1] == "hidden") { bits <- strsplit(con$url, "/")[[1]] plot_id <- bits[length(bits)] url <- paste0(get_domain("v2"), "files/", verify("username"), ":", plot_id) From dd4839df875663b4d23aa5396f9e90be6a4eb812 Mon Sep 17 00:00:00 2001 From: cpsievert Date: Tue, 19 Jan 2016 09:18:22 -0600 Subject: [PATCH 4/5] add a basic test --- tests/testthat/test-plotly-getfigure.R | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/tests/testthat/test-plotly-getfigure.R b/tests/testthat/test-plotly-getfigure.R index ef4b845f3c..bfa607199b 100644 --- a/tests/testthat/test-plotly-getfigure.R +++ b/tests/testthat/test-plotly-getfigure.R @@ -37,3 +37,10 @@ test_that("can add traces to a subplot figure", { expect_equivalent(length(plotly_build(fig)$data) + 1, length(l$data)) }) +test_that("posting a hidden plot returns a secret key", { + skip_on_cran() + res <- plotly_POST(plot_ly(), sharing = "hidden") + key <- strsplit(res$url, "=")[[1]][2] + expect_true(nchar(key) > 1) +}) + From 311d68b724d7515c5578a84b13874e8060ab737f Mon Sep 17 00:00:00 2001 From: cpsievert Date: Tue, 19 Jan 2016 09:39:24 -0600 Subject: [PATCH 5/5] use my credentials for testbot --- .travis.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index 607eea7548..c0682b22b6 100644 --- a/.travis.yml +++ b/.travis.yml @@ -14,7 +14,7 @@ env: global: - R_LIBS_USER=~/R/library NOT_CRAN=true # plotly_api_key (for posting to plot.ly) - - secure: "UAETDsmeXkXm9eUpZa3JTm8/cv+jyLmArXE0TQD0yQNICFNPkGeNergoQmkesRqG+ifLu6V1lPXu1XlqQPdXY60clUHThDN+AjsBmcv9F170k6RtBSV8pIKL9fsW8t0v/maEet86qOSf3cNa5+gK8GjBH1pmLrN2rF9r7RhwUdg=" + - secure: "jlIAFoBGaDWUQDh6oGNb2BgU31/80iioM4y4xwx35yWkGKkNIID1eMEuiIn+/ipLvOVHkPTDS6DYnOtD8EIBpROgAKHFY33gM1h7P6NRxVszzC6WLP2ASnq95DWq36DAC2Oevy05V7nwSRFilPwSt6JLppYUInG+WdaZ+QOSRi4=" # GITHUB_PAT (for pushing to plotly-test-table) - secure: "LHJONgWOo+98vNeFLI7LSJU3RtbMVszlI79GB8CcXmc2mlgM/UtZ5b6RnkNlhmg3Gj1/uObfm/rIybVTwuS1yNpeKv73+gsZOYhobVXiUGVxdRFG/mg5mbqwyWkkuofjPGFlMZCEMgHim37eZzgjSibwVH1LClRDsCoFMCgvgV0=" @@ -24,7 +24,7 @@ cache: before_script: - mkdir -p "$R_LIBS_USER" - - echo "Sys.setenv('plotly_username' = 'RTestBot3000')" > ~/.Rprofile + - echo "Sys.setenv('plotly_username' = 'cpsievert')" > ~/.Rprofile - git clone https://github.com/cpsievert/plotly-test-table.git ../plotly-test-table - "wget -q -O - https://github.com/yihui/crandalf/raw/master/inst/scripts/install-pandoc | bash" - Rscript -e 'if (length(find.package("devtools", quiet = TRUE)) == 0L) { install.packages("devtools", repos = "http://cran.rstudio.com") }'