Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 7 additions & 6 deletions DESCRIPTION
Original file line number Diff line number Diff line change
@@ -1,32 +1,33 @@
Package: livecode
Title: Broadcast a source file to multiple concurrant users
Version: 0.1.0.9000
Version: 0.1.0.9001
Authors@R:
person(given = "Colin",
family = "Rundel",
role = c("aut", "cre"),
email = "rundel@gmail.com")
Description: Broadcast a local R (or other text) document over the web and provide live updates as it is edited.
License: GPL-3
License: GPL (>= 3)
Encoding: UTF-8
LazyData: true
Imports:
usethis,
readr,
glue,
withr,
jsonlite,
httpuv,
httr,
purrr,
Rcpp,
iptools,
markdown,
later,
tibble,
crayon,
rstudioapi,
stringi
RoxygenNote: 7.1.0
stringi,
markdown,
processx,
withr
RoxygenNote: 7.3.3
LinkingTo:
Rcpp
4 changes: 2 additions & 2 deletions LICENSE.md
Original file line number Diff line number Diff line change
Expand Up @@ -553,7 +553,7 @@ and each file should have at least the “copyright” line and a pointer to
where the full notice is found.

<one line to give the program's name and a brief idea of what it does.>
Copyright (C) 2020 Colin Rundel
Copyright (C) <year> <name of author>

This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
Expand All @@ -573,7 +573,7 @@ Also add information on how to contact you by electronic and paper mail.
If the program does terminal interaction, make it output a short notice like this
when it starts in an interactive mode:

livecode Copyright (C) 2020 Colin Rundel
<program> Copyright (C) <year> <name of author>
This program comes with ABSOLUTELY NO WARRANTY; for details type 'show w'.
This is free software, and you are welcome to redistribute it
under certain conditions; type 'show c' for details.
Expand Down
5 changes: 5 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,15 +1,20 @@
# Generated by roxygen2: do not edit by hand

export(FileCache)
export(bitly_get_groups)
export(bitly_get_token)
export(bitly_reset_token)
export(bitly_set_token)
export(bitly_shorten)
export(bitly_test_token)
export(file_cache)
export(lc_server_iface)
export(list_servers)
export(network_interfaces)
export(serve_file)
export(stop_all)
importFrom(Rcpp,sourceCpp)
importFrom(stats,setNames)
importFrom(utils,URLencode)
importFrom(utils,browseURL)
useDynLib(livecode, .registration = TRUE)
73 changes: 69 additions & 4 deletions R/bitly_api.R
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ bitly_api_groups = function() {
bitly_api("/groups")[["groups"]]
}

#' @importFrom utils URLencode browseURL
bitly_api_shorten = function(long_url, group_guid = bitly_get_groups()[1]) {
bitly_api(
"/shorten", "POST",
Expand All @@ -50,23 +51,87 @@ bitly_api_shorten = function(long_url, group_guid = bitly_get_groups()[1]) {
)
}

#' Retrieve available Bitly groups
#'
#' @description
#' Queries the authenticated Bitly account and returns the groups available
#' to the current user. Bitly groups are organizational containers used to
#' manage branded links, users, and link ownership.
#'
#' This function returns a named character vector where the names are group
#' names and the values are the corresponding Bitly group GUIDs.
#'
#' @return
#' A named character vector of Bitly group GUIDs. Names correspond to the
#' human-readable Bitly group names.
#'
#' @details
#' This function is primarily used internally by \code{bitly_shorten()} to
#' determine a default group when creating a short link.
#'
#' @examples
#' \dontrun{
#' # View available Bitly groups
#' bitly_get_groups()
#' }
#'
#' @importFrom stats setNames
#' @seealso
#' \code{\link{bitly_shorten}}
#'
#' @export
bitly_get_groups = function() {
l = bitly_api_groups()
names = purrr::map_chr(l, "name")
guids = purrr::map_chr(l, "guid")

setNames(guids, names)
}



#' Create a Bitly short link
#'
#' @description
#' Creates a shortened Bitly link for a supplied URL using the authenticated
#' Bitly account.
#'
#' By default, the short link is created using the first available Bitly group
#' returned by \code{bitly_get_groups()}.
#'
#' @param url Character string giving the URL to shorten.
#' @param guid Character string giving the Bitly group GUID under which the
#' short link should be created. Defaults to the first available group.
#'
#' @return
#' A character string containing the shortened Bitly URL.
#'
#' @details
#' A success message is displayed when the short link is created.
#'
#' This function requires a valid Bitly personal access token configured via
#' \code{bitly_get_token()}.
#'
#' @examples
#' \dontrun{
#' # Shorten a local livecode URL
#' bitly_shorten("http://192.168.1.10:4321")
#'
#' # Shorten using a specific Bitly group
#' groups <- bitly_get_groups()
#' bitly_shorten("http://192.168.1.10:4321", guid = groups[1])
#' }
#'
#' @seealso
#' \code{\link{bitly_get_groups}}
#'
#' @export
bitly_shorten = function(url, guid = bitly_get_groups()[1]) {
# TODO: add group handling
link = bitly_api_shorten(url, guid)[["link"]]

usethis::ui_done(
"Created bitlink {usethis::ui_value(link)} for {usethis::ui_value(url)}."
)

link
}
143 changes: 130 additions & 13 deletions R/bitly_auth.R
Original file line number Diff line number Diff line change
@@ -1,50 +1,167 @@
#' Retrieve the active Bitly token
#'
#' @description
#' Retrieves the Bitly personal access token used for authentication with the
#' Bitly API.
#'
#' The token is searched for in the following order:
#' \enumerate{
#' \item The \code{BITLY_PAT} environment variable.
#' \item A local file at \code{~/.bitly/token}.
#' }
#'
#' If a token file is found, it is loaded automatically using
#' \code{bitly_set_token()}.
#'
#' @return
#' An invisible character string containing the active Bitly token.
#'
#' @details
#' If no token can be located, an error is raised instructing the user to set
#' a token manually.
#'
#' @examples
#' \dontrun{
#' bitly_get_token()
#' }
#'
#' @seealso
#' \code{\link{bitly_set_token}},
#' \code{\link{bitly_reset_token}},
#' \code{\link{bitly_test_token}}
#'
#' @export

bitly_get_token = function() {
token = Sys.getenv("BITLY_PAT", "")
if (token != "")
return(invisible(token))

if (file.exists("~/.bitly/token")) {
bitly_set_token("~/.bitly/token")
return(invisible(bitly_get_token()))
}

usethis::ui_stop( paste0(
usethis::ui_stop(paste0(
"Unable to locate bitly token, please use {usethis::ui_code('bitly_set_token')}",
" or define the BITLY_PAT environmental variable."
) )
))
}

#' @export


#' Set the active Bitly token
#'
#' @description
#' Sets the Bitly personal access token used for authentication with the Bitly
#' API by storing it in the current R session environment variable
#' \code{BITLY_PAT}.
#'
#' The token may be supplied directly as a character string or indirectly as a
#' path to a file containing the token.
#'
#' @param token Character string giving the Bitly token, or a path to a file
#' containing the token.
#'
#' @return
#' Invisibly returns \code{NULL}. Called for side effects.
#'
#' @details
#' If \code{token} is a valid file path, the first line(s) of the file are read
#' and used as the token value.
#'
#' This affects only the current R session unless the user also stores the token
#' in a startup file such as \code{~/.Renviron}.
#'
#' @examples
#' \dontrun{
#' # Set directly
#' bitly_set_token("your_token_here")
#'
#' # Set from file
#' bitly_set_token("~/.bitly/token")
#' }
#'
#' @seealso
#' \code{\link{bitly_get_token}},
#' \code{\link{bitly_reset_token}}
#'
#' @export
bitly_set_token = function(token) {
token = as.character(token)

if (file.exists(token))
token = readLines(token, warn=FALSE)

token = readLines(token, warn = FALSE)
Sys.setenv(BITLY_PAT = token)
}

#' @export


#' Remove the active Bitly token
#'
#' @description
#' Removes the \code{BITLY_PAT} environment variable from the current R session,
#' effectively clearing the active Bitly token.
#'
#' @return
#' Invisibly returns \code{NULL}. Called for side effects.
#'
#' @examples
#' \dontrun{
#' bitly_reset_token()
#' }
#'
#' @seealso
#' \code{\link{bitly_set_token}},
#' \code{\link{bitly_get_token}}
#'
#' @export
bitly_reset_token = function() {
Sys.unsetenv("BITLY_PAT")
}



#' Test Bitly authentication
#'
#' @description
#' Verifies that the current Bitly personal access token can successfully
#' authenticate with the Bitly API.
#'
#' By default, the token is obtained from \code{bitly_get_token()}.
#'
#' @param token Character string giving a Bitly token to test. Defaults to the
#' active token returned by \code{bitly_get_token()}.
#'
#' @return
#' Returns the result of \code{status_msg()}, typically a logical or invisible
#' status indicator depending on implementation.
#'
#' @details
#' A success or failure message is displayed indicating whether authentication
#' succeeded.
#'
#' @examples
#' \dontrun{
#' bitly_test_token()
#'
#' bitly_test_token("your_token_here")
#' }
#'
#' @seealso
#' \code{\link{bitly_get_token}},
#' \code{\link{bitly_set_token}}
#'
#' @export
bitly_test_token = function(token = bitly_get_token()) {
res = purrr::safely(bitly_api_user)()

status_msg(
res,
"Your bitly token is functioning correctly.",
"Your bitly token failed to authenticate.",
"Your bitly token failed to authenticate."
)
}

bitly_available = function() {
res = purrr::safely(bitly_api_user)()
succeeded(res)
Expand Down
Loading