Skip to content

Commit

Permalink
fix: swap_vanity_urls() works predictably with unset vanity URLs (#361
Browse files Browse the repository at this point in the history
)
  • Loading branch information
toph-allen authored Jan 27, 2025
1 parent f6d69b4 commit 002ed73
Show file tree
Hide file tree
Showing 45 changed files with 297 additions and 70 deletions.
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -141,6 +141,7 @@ export(set_schedule_year)
export(set_thumbnail)
export(set_vanity_url)
export(swap_vanity_url)
export(swap_vanity_urls)
export(tbl_connect)
export(terminate_jobs)
export(user_guid_from_username)
Expand Down
9 changes: 9 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,19 @@
client with permissions scoped to the content visitor when running on a Connect
server. (#362)

## Enhancements and fixes

- `swap_vanity_urls()` can correctly perform a swap involving a content item
with no vanity URL. (#360)
- `swap_vanity_urls()` handles permissions errors gracefully, attempting to roll
back any changes made. (#360)

## Newly deprecated

- `get_job()` (singular) is now deprecated, its functionality taken care of by
other functions, including `get_log()`.
- `swap_vanity_url(old, new)` has been deprecated and renamed to
`swap_vanity_urls(content_a, content_b)`.

# connectapi 0.5.0

Expand Down
99 changes: 62 additions & 37 deletions R/deploy.R
Original file line number Diff line number Diff line change
Expand Up @@ -413,7 +413,7 @@ deploy_current <- function(content) {

#' Set the Vanity URL
#'
#' Sets the Vanity URL for a piece of content.
#' Set the vanity URL for a piece of content.
#'
#' @param content A Content object
#' @param url The path component of the URL
Expand Down Expand Up @@ -453,7 +453,7 @@ set_vanity_url <- function(content, url, force = FALSE) {

#' Delete the Vanity URL
#'
#' Deletes the Vanity URL for a piece of content.
#' Delete the vanity URL for a piece of content.
#'
#' @param content A Content object
#'
Expand All @@ -464,14 +464,14 @@ delete_vanity_url <- function(content) {
error_if_less_than(con$version, "1.8.6")
guid <- content$get_content()$guid

con$DELETE(v1_url("content", guid, "vanity"))
con$DELETE(v1_url("content", guid, "vanity"), parser = "parsed")

content
}

#' Get the Vanity URL
#'
#' Gets the Vanity URL for a piece of content.
#' Get the vanity URL for a piece of content.
#'
#' @param content A Content object
#'
Expand Down Expand Up @@ -501,55 +501,80 @@ get_vanity_url <- function(content) {
return(van$path)
}

#' Swap the Vanity URL
#' Swap Vanity URLs
#'
#' Swaps the Vanity URLs between two pieces of content
#' Swap the vanity URLs of two pieces of content.
#'
#' @param from_content A Content object
#' @param to_content A Content object
#' @param content_a A Content object
#' @param content_b A Content object
#'
#' @returns A list of the new vanity URLs for `content_a` and `content_b`
#'
#' @family content functions
#' @export
swap_vanity_url <- function(from_content, to_content) {
warn_experimental("swap_vanity_url")
scoped_experimental_silence()
swap_vanity_urls <- function(content_a, content_b) {
# TODO: Add prompt if in an interactive session
# TODO: Add pretty print output of what is happening
# TODO: Test error cases super thoroughly!!
# TODO: Do a "dry run" of sorts...? Check privileges... etc...
# TODO: Do the changes within a TryCatch so we can undo...?
# TODO: Need a way to "unset" a vanity URL

from_vanity <- get_vanity_url(from_content)
to_vanity <- get_vanity_url(to_content)

if (is.null(from_vanity) && is.null(to_vanity)) {
warning("Neither content has a Vanity URL. Exiting")
} else {
# swapping vanity URLs
tmp_vanity <- paste0("vanity-url-swap-", create_random_name(length = 50))
validate_R6_class(content_a, "Content")
validate_R6_class(content_b, "Content")

if (!is.null(from_vanity)) {
set_vanity_url(from_content, tmp_vanity)
} else {
set_vanity_url(to_content, tmp_vanity)
}
vanity_a <- get_vanity_url(content_a)
vanity_b <- get_vanity_url(content_b)

if (!is.null(from_vanity)) {
set_vanity_url(to_content, from_vanity)
if (is.null(vanity_a) && is.null(vanity_b)) {
warning("Neither content has a vanity URL")
} else {
tryCatch(
delete_vanity_url(content_a),
error = function(e) {
stop("Unable to modify the vanity URL for content_a: ", e$message, call. = FALSE)
}
)
tryCatch(
delete_vanity_url(content_b),
error = function(e) {
set_vanity_url(content_a, vanity_a)
stop("Unable to modify the vanity URL for content_b: ", e$message, call. = FALSE)
}
)
if (!is.null(vanity_a)) {
set_vanity_url(content_b, vanity_a)
}
if (!is.null(to_vanity)) {
set_vanity_url(from_content, to_vanity)
if (!is.null(vanity_b)) {
set_vanity_url(content_a, vanity_b)
}

from_vanity <- get_vanity_url(from_content)
to_vanity <- get_vanity_url(to_content)
vanity_a <- get_vanity_url(content_a)
vanity_b <- get_vanity_url(content_b)
}

return(
list(
from = from_vanity,
to = to_vanity
content_a = vanity_a,
content_b = vanity_b
)
)
}

#' Swap Vanity URLs
#'
#' Swap the vanity URLs of two pieces of content.
#' This function is deprecated; please use \code{\link{swap_vanity_urls}}.
#'
#' @param from A Content object
#' @param to A Content object
#'
#' @returns A list of the new vanity URLs for `from` and `to`
#'
#' @family content functions
#' @export
swap_vanity_url <- function(from, to) {
lifecycle::deprecate_warn("0.6.0", "swap_vanity_url()", "swap_vanity_urls()")
res <- swap_vanity_urls(from, to)
return(
list(
from = res[["content_a"]],
to = res[["content_b"]]
)
)
}
Expand Down
1 change: 1 addition & 0 deletions man/content_delete.Rd

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

1 change: 1 addition & 0 deletions man/content_item.Rd

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

1 change: 1 addition & 0 deletions man/content_title.Rd

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

1 change: 1 addition & 0 deletions man/content_update.Rd

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

1 change: 1 addition & 0 deletions man/create_random_name.Rd

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

1 change: 1 addition & 0 deletions man/dashboard_url.Rd

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

1 change: 1 addition & 0 deletions man/dashboard_url_chr.Rd

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

1 change: 1 addition & 0 deletions man/delete_thumbnail.Rd

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

3 changes: 2 additions & 1 deletion man/delete_vanity_url.Rd

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

1 change: 1 addition & 0 deletions man/deploy_repo.Rd

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

1 change: 1 addition & 0 deletions man/environment.Rd

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

2 changes: 2 additions & 0 deletions man/get_bundles.Rd

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

1 change: 1 addition & 0 deletions man/get_image.Rd

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

1 change: 1 addition & 0 deletions man/get_job.Rd

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

1 change: 1 addition & 0 deletions man/get_jobs.Rd

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

1 change: 1 addition & 0 deletions man/get_log.Rd

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

1 change: 1 addition & 0 deletions man/get_thumbnail.Rd

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

3 changes: 2 additions & 1 deletion man/get_vanity_url.Rd

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

1 change: 1 addition & 0 deletions man/git.Rd

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

1 change: 1 addition & 0 deletions man/has_thumbnail.Rd

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

1 change: 1 addition & 0 deletions man/permissions.Rd

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

1 change: 1 addition & 0 deletions man/set_image.Rd

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

1 change: 1 addition & 0 deletions man/set_run_as.Rd

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

1 change: 1 addition & 0 deletions man/set_thumbnail.Rd

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

Loading

0 comments on commit 002ed73

Please sign in to comment.