From fe0be1532b10022c53de92a2fa0de1f457e2660e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Sun, 21 May 2023 13:20:55 +0200 Subject: [PATCH 01/21] Fix error in documentation --- R/user_blocked.R | 4 ++-- man/user_blocked.Rd | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/R/user_blocked.R b/R/user_blocked.R index 1bf8eee1..265adce0 100644 --- a/R/user_blocked.R +++ b/R/user_blocked.R @@ -1,6 +1,6 @@ -#' Find followers. +#' Find users blocked. #' -#' List of users that follow the specified user ID. +#' List of users that are blocked. #' @inheritParams filtered_stream #' @param ... Other arguments passed to the API. #' @param n Number of tweets to query. diff --git a/man/user_blocked.Rd b/man/user_blocked.Rd index e0705fd7..6fe08ed9 100644 --- a/man/user_blocked.Rd +++ b/man/user_blocked.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/user_blocked.R \name{user_blocked} \alias{user_blocked} -\title{Find followers.} +\title{Find users blocked.} \usage{ user_blocked( id, @@ -40,7 +40,7 @@ Twitter API.} \item{verbose}{A logical value to provide more information about paginated queries.} } \description{ -List of users that follow the specified user ID. +List of users that are blocked. } \examples{ if (FALSE) { From e67ca942d5da9fdd222419f7b3217da6a50fd832 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Thu, 25 May 2023 01:24:16 +0200 Subject: [PATCH 02/21] Automatic token refresh (not interactive) --- DESCRIPTION | 3 +- NEWS.md | 3 + R/auth.R | 102 ++++++++++++++++--------------- tests/testthat/test-auth.R | 2 +- tests/testthat/test-req_errors.R | 2 +- 5 files changed, 61 insertions(+), 51 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 0609aa70..38989567 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -29,13 +29,14 @@ Imports: bit64 (>= 4.0.5), curl (>= 4.3.2), httr (>= 1.3.0), - httr2 (>= 0.2.2), + httr2 (> 0.2.3), jsonlite (>= 0.9.22), lifecycle (>= 1.0.0), methods, progress (>= 1.2.2), rlang (>= 0.4.10), tibble (>= 1.3.4), + tools, utils, withr (>= 2.5.0) Suggests: diff --git a/NEWS.md b/NEWS.md index 98ea0da0..1b81b1f5 100644 --- a/NEWS.md +++ b/NEWS.md @@ -6,6 +6,9 @@ * New `tweet_post()` and `tweet_delete()` to post and delete tweets to work with the [free product](https://developer.twitter.com/en/portal/products/free). +* Since httr2 > 0.2.3, rtweet refreshes OAuth 2.0 tokens automatically, + also if possible, replacing the file where they are saved. + # rtweet 1.2.0 ## Authentication changes diff --git a/R/auth.R b/R/auth.R index 80fdbc0b..82ba6a4f 100644 --- a/R/auth.R +++ b/R/auth.R @@ -162,13 +162,13 @@ rtweet_app <- function(bearer_token) { ) } -ask_pass <- function(type, call = caller_env()) { - check_installed("askpass", call = call) +ask_pass <- function(type) { + check_installed("askpass", call = current_call()) message <- paste0("Please enter your ", type, ": ") val <- askpass::askpass(message) if (is.null(val)) { - abort("Cancelled by user") + abort("Cancelled by user", call = current_call()) } val } @@ -286,7 +286,7 @@ auth_as <- function(auth = NULL) { invisible(old) } -find_auth <- function(auth = NULL, call = caller_env()) { +find_auth <- function(auth = NULL) { if (is.null(auth)) { if (is_developing()) { rtweet_test() %||% no_token() @@ -296,30 +296,34 @@ find_auth <- function(auth = NULL, call = caller_env()) { } else if (is_auth(auth)) { auth } else if (is_string(auth)) { - load_token(auth, call) + load_token(auth) } else { abort("Unrecognised input to `auth`", - call = call) + call = current_call()) } } -load_token <- function(auth_name, call = caller_env) { +load_token <- function(auth_name) { if (file.exists(auth_name)) { path <- auth_name + name <- tools::file_path_sans_ext(basename(auth_name)) } else { path <- auth_path(paste0(auth_name, ".rds")) + name <- auth_name } if (!file.exists(path)) { abort(paste0("Can't find saved auth with name '", auth_name, "'"), - call = call) + call = current_call()) } if (!is_developing()) { inform(paste0("Reading auth from '", path, "'")) } - readRDS(path) + token <- readRDS(path) + # Store the name of the token as an attribute + attr(token, "name") <- name + token } - default_cached_auth <- function() { default <- auth_path("default.rds") @@ -329,12 +333,13 @@ default_cached_auth <- function() { names <- auth_list() if (length(names) == 0) { - abort("No default authentication found. Please call `auth_setup_default()`") + abort("No default authentication found. Please call `auth_setup_default()`", + call = caller_call()) } else { abort(c( "No default authentication found. Pick existing auth with:", paste0("auth_as('", names, "')") - )) + ), call = caller_call()) } } @@ -344,11 +349,11 @@ auth_has_default <- function() { file.exists(auth_path("default.rds")) } -no_token <- function(call = caller_env()) { +no_token <- function() { if (is_testing()) { testthat::skip("Auth not available") } else { - abort("Could not authenticate", call = call) + abort("Could not authenticate", call = current_call()) } } # Internal function to generate the bot used for testing @@ -421,12 +426,14 @@ rtweet_oauth2 <- function(client = NULL, scopes = NULL) { client <- client %||% client_get() if (!is_client(client)) { abort(c("Client not valid", - i = "Check out the `vignette('auth', 'rtweet')`.")) + i = "Check out the `vignette('auth', 'rtweet')`."), + call = current_call()) } if (is.null(scopes)) { scopes <- client_scopes(client) } else if (!check_scopes(scopes)) { - abort("Scopes is not in the right format.") + abort("Scopes is not in the right format.", + call = current_call()) } # Guide to all urls for OAuth 2 @@ -444,7 +451,7 @@ rtweet_oauth2 <- function(client = NULL, scopes = NULL) { ) # Example of valid url for authorization (created via client_as("academic_dev");rtweet_oauth2() ) # https://twitter.com/i/oauth2/authorize?response_type=code&client_id=Tm5FWFA3OGFUVUMxTjhUREwzZzQ6MTpjaQ&redirect_uri=http%3A%2F%2F127.0.0.1%3A1410%2F&scope=tweet.read%20tweet.write%20tweet.moderate.write%20users.read%20follows.read%20follows.write%20offline.access%20space.read%20mute.read%20mute.write%20like.read%20like.write%20list.read%20list.write%20block.read%20block.write%20bookmark.read%20bookmark.write&state=PVgWK3MviQ5MBsfj0Iy5D89HBFR4mPwTl0yumjSPlWo&code_challenge=FNcGvupIzNIbWOL8rdJOrxsVS_b2R01vIbynF_iQIMQ&code_challenge_method=S256 - # # Note that the cliend_id should match in the url + # # Note that the client_id should match in the url inform("Requires confirming permissions to the app (client) every two hours!") attr(token, "app") <- attr(client, "app") token @@ -452,56 +459,55 @@ rtweet_oauth2 <- function(client = NULL, scopes = NULL) { # Renew token if needed # Makes the assumption that the right app is still in the user computer -auth_renew <- function(token, scopes = NULL, call = caller_env()) { +auth_renew <- function(token, scopes = NULL) { stopifnot(auth_is_pkce(token)) if (.POSIXct(token$expires_at) >= Sys.time()) { return(token) } - msg <- "Impossible to renew the authentication without interactive usage." - if (!interactive() && is_testing()) { - testthat::skip(msg) - } else if (!interactive() && !is_developing()) { - abort(msg) - } if (!is.null(scopes) && check_scopes(scopes)) { scopes <- scopes } else if (is.null(scopes)) { scopes <- strsplit(token$scope, " ", fixed = TRUE)[[1]] } else { - abort("Scopes is not in the right format.") + abort("Scopes is not in the right format.", + call = current_call()) } client_name <- attr(token, "app", TRUE) client <- load_client(client_name) - # TODO: once it is possible to silently update the token (see https://github.com/r-lib/httr2/issues/197) - # activate this branch to reauthorize the app - if (FALSE ) { - !any(grepl("offline.access", scopes, fixed = TRUE)) - abort(c("Not possible to update the client")) - token <- rtweet_oauth2(client, scopes) - return(token) - } - - # inform("You'll need to give again permissions to the app every two hours!") - token <- rtweet_oauth2(client, scopes) - # The provided refresh token can only be used once: - # https://twittercommunity.com/t/unable-to-obtain-new-access-token-by-using-refresh-token/164123/16 - # token <- httr2::oauth_flow_refresh(client, refresh_token = token$refresh_token, - # scope = token$scopes) - # This is reported to upstream: https://github.com/r-lib/httr2/issues/197 - + # Is possible to silently update the token + # see https://github.com/r-lib/httr2/issues/197 + token2 <- httr2::oauth_flow_refresh(client, + refresh_token = token$refresh_token, + scope = token$scope) # Save token in the environment - # It could be that token is not from the environment, but this feel safer than saving it in a file directly. - auth_as(token) - inform(c("i" = "Using renewed token", - "!" = "Save your new oauth2 token with the appropriate name:", - "`auth_save(auth_get(), 'renewed_token')`")) - token + auth_as(token2) + # If possible replace it in the user storage. + resave_token(token2, token_name(token)) + token2 } decrypt <- function(x) { check_installed("openssl") # Suggested! rawToChar(openssl::rsa_decrypt(x[[2]], x[[1]])) } + +token_name <- function(x){ + attr(x, "name", TRUE) +} + +resave_token <- function(token, name) { + name <- token_name(token) + if (is.null(name)) { + inform(c("!" = "It was not possible to save your token", + "i" = "Saving your new oauth2 token with: `auth_save(auth_get(), 'renewed_token')`")) + auth_save(auth_get(), 'renewed_token') + } + + path <- auth_path(paste0(name, ".rds")) + # Protects in case the folder gets deleted while the token is loaded + dir.create(auth_path(), showWarnings = FALSE, recursive = TRUE) + saveRDS(token, path) +} diff --git a/tests/testthat/test-auth.R b/tests/testthat/test-auth.R index b68fcd16..e8b403a2 100644 --- a/tests/testthat/test-auth.R +++ b/tests/testthat/test-auth.R @@ -20,7 +20,7 @@ test_that("can save and reload auth", { auth_save(auth1, "test") auth2 <- find_auth("test") }) - expect_equal(auth1, auth2) + expect_equal(auth1, auth2, ignore_attr = TRUE) }) test_that("find auth errors politely", { diff --git a/tests/testthat/test-req_errors.R b/tests/testthat/test-req_errors.R index 40bc8be3..830c402a 100644 --- a/tests/testthat/test-req_errors.R +++ b/tests/testthat/test-req_errors.R @@ -1,5 +1,5 @@ test_that("req_error works", { - testing_with_authentication("renewed_token") + testing_with_authentication("bearer_testing_app") expect_error(user_blocked("407200271", n = Inf), "must be the same as the authenticating user") }) From f79961d0f0f30b2550283b01c3db403b3b32b05a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Thu, 25 May 2023 01:26:32 +0200 Subject: [PATCH 03/21] Improve error reporting --- R/api_v2_responses.R | 11 ++++++----- R/api_v2_utils.R | 27 ++++++++++----------------- R/clean_tweets.R | 3 ++- R/client.R | 15 +++++++++------ R/direct_messages.R | 4 ++-- R/expansions.R | 13 ++++++------- R/extractors.R | 4 ++-- R/fields.R | 9 ++++----- R/friends.R | 2 +- R/http.R | 14 +++++++------- R/ids.R | 4 ++-- R/rt_stream.R | 24 ++++++++++++------------ R/scopes.R | 16 ++++++++-------- R/user_id.R | 29 +++++++++++++++-------------- R/utils.R | 4 ++-- tests/testthat/_snaps/auth.md | 8 ++++---- tests/testthat/test-req_errors.R | 3 +-- 17 files changed, 93 insertions(+), 97 deletions(-) diff --git a/R/api_v2_responses.R b/R/api_v2_responses.R index 09992a9e..50539d56 100644 --- a/R/api_v2_responses.R +++ b/R/api_v2_responses.R @@ -1,11 +1,12 @@ # Handling responses #### -parsing <- function(x, expansions, fields, call = caller_env()) { +parsing <- function(x, expansions, fields) { if (!is_logical(x)) { - abort("parse should be either TRUE or FALSE", call = call) + abort("parse should be either TRUE or FALSE", call = current_call()) } if (isTRUE(x) && (!is.null(expansions) || !is.null(fields))) { abort(c("Not yet implemented!", - i = "Stay tuned for further updates or use `parse = FALSE`")) + i = "Stay tuned for further updates or use `parse = FALSE`"), + call = current_call()) } } @@ -83,7 +84,7 @@ resp <- function(x, ...) { class(out) <- c("Twitter_resp", class(out)) if (has_name_(out, "errors")) { - abort(req_errors(out), call = NULL) + abort(req_errors(out), call = current_call()) } if (has_name_(out, "meta")) { @@ -103,7 +104,7 @@ resp <- function(x, ...) { } if (nrow(rest) > 1) { - abort("Please check", call = call) + abort("Please check", call = current_call()) } out$meta <- rest } diff --git a/R/api_v2_utils.R b/R/api_v2_utils.R index 01b6046d..3d9b2150 100644 --- a/R/api_v2_utils.R +++ b/R/api_v2_utils.R @@ -37,7 +37,7 @@ auth_is_pkce <- function(token = NULL) { # if (auth_has_default()) { # tryCatch(check_token_v2()) # } -check_token_v2 <- function(token = NULL, mechanism = "bearer", call = caller_env()) { +check_token_v2 <- function(token = NULL, mechanism = "bearer") { token <- token %||% auth_get() @@ -49,29 +49,23 @@ check_token_v2 <- function(token = NULL, mechanism = "bearer", call = caller_env } else if (length(mechanism) == 2) { # To make it easier testing interactively if (is_developing()) { - return(load_token("bearer_academic_dev", call = call)) + return(load_token("bearer_academic_dev")) } abort(c( "x" = "You must use a token accepted by the endpoints v2.", "i" = "Check the `vignette('auth', package = 'rtweet')` about how to get them."), - call = call) + call = current_call()) } if (mechanism == "bearer" && !auth_is_bearer(token)) { - # To make it easier testing interactively - if (is_developing()) { - return(load_token("bearer_academic_dev", call = call)) - } + abort(c("x" = "A bearer `token` is needed for this endpoint.", "i" = "Get one via `rtweet_app()`"), - call = call) + call = current_call()) } if (mechanism == "pkce" && !auth_is_pkce(token)) { - # To make it easier testing interactively - if (is_developing()) { - return(load_token("renewed_token", call = call)) - } + client <- client_get() if (!is_client(client)) { msg <- c(">" = "Check the vignette('auth', 'rtweet')", @@ -82,7 +76,7 @@ check_token_v2 <- function(token = NULL, mechanism = "bearer", call = caller_env abort(c("x" = "An OAuth 2.0 is needed for this endpoint.", msg, "i" = "Get the authorization via `rtweet_oauth2()`"), - call = call) + call = current_call()) } token } @@ -93,7 +87,6 @@ req_auth <- function(req, token) { token <- token$token } else if (auth_is_pkce(token)) { token <- auth_renew(token) - token <- token$access_token } httr2::req_auth_bearer_token(req, token) } @@ -131,7 +124,7 @@ req_errors <- function(resp) { # Prepare the requests #### # General function to create the requests for Twitter API v2 with retry limits # and error handling -req_v2 <- function(token = NULL, call = caller_env()) { +req_v2 <- function(token = NULL) { req <- httr2::request("https://api.twitter.com/2") req_agent <- httr2::req_user_agent(req, "rtweet (https://docs.ropensci.org/rtweet)") req_authorized <- req_auth(req_agent, token) @@ -155,9 +148,9 @@ twitter_after <- function(resp) { } -endpoint_v2 <- function(token, path, throttle, call = caller_call()) { +endpoint_v2 <- function(token, path, throttle) { - req <- httr2::req_url_path_append(req_v2(token, call), path) + req <- httr2::req_url_path_append(req_v2(token), path) httr2::req_throttle(req, throttle, realm = path) } diff --git a/R/clean_tweets.R b/R/clean_tweets.R index b1606d8f..35b561c6 100644 --- a/R/clean_tweets.R +++ b/R/clean_tweets.R @@ -17,7 +17,8 @@ #' } clean_tweets <- function(x, clean = c("users", "hashtags", "urls", "media")) { if (is.character(x)) { - abort("You should provide tweets with all the users and hashtags information") + abort("You should provide tweets with all the users and hashtags information", + call = current_call()) } tweets <- nrow(x) diff --git a/R/client.R b/R/client.R index d53e04ca..b741138b 100644 --- a/R/client.R +++ b/R/client.R @@ -71,7 +71,8 @@ default_client <- function(client_id = NULL, client_secret = NULL) { if (is.null(client_id) && is.null(client_secret)) { # The sysdat file is in #./R and loaded automagically abort(c("The default rtweet client is no longer authorized.", - i = "You'll need to register as developer in order to use the Twitter API.")) + i = "You'll need to register as developer in order to use the Twitter API."), + call = current_call()) client_id <- decrypt(sysdat$e914c55d2f) client_secret <- decrypt(sysdat$d5571d4003) } else { @@ -141,7 +142,7 @@ find_client <- function(client = NULL) { } else if (is_string(client)) { load_client(client) } else { - abort("Unrecognised input to `client`") + abort("Unrecognised input to `client`", call = current_call()) } } @@ -154,7 +155,8 @@ load_client <- function(client_name) { path <- client_path(paste0(client_name, ".rds")) } if (!file.exists(path) && !is_developing()) { - abort(paste0("Can't find saved client with name '", client_name, "'")) + abort(paste0("Can't find saved client with name '", client_name, "'"), + call = current_call()) } else if (!file.exists(path)) { return(NULL) } @@ -169,7 +171,7 @@ no_client <- function(call = caller_env()) { if (is_testing()) { testthat::skip("Client not available") } else { - abort("Could not find client", call = call) + abort("Could not find client", call = current_call()) } } @@ -248,7 +250,8 @@ client_setup_default <- function() { inform("Using default client available.") } else { abort(c("The default rtweet client is no longer authorized.", - i = "You'll need to register as developer in order to use the Twitter API.")) + i = "You'll need to register as developer in order to use the Twitter API."), + call = current_call()) client <- rtweet_client(decrypt(sysdat$DYKcJfBkgMnGveI), decrypt(sysdat$MRsnZtaKXqGYHju), app = "rtweet") @@ -259,7 +262,7 @@ client_setup_default <- function() { } -client_scopes <- function(client, call = caller_env()) { +client_scopes <- function(client) { if (!is_client(client)) { abort(c("Missing client.", ">" = "Check the vignette('auth', 'rtweet')", diff --git a/R/direct_messages.R b/R/direct_messages.R index 611b4657..b55a315b 100644 --- a/R/direct_messages.R +++ b/R/direct_messages.R @@ -85,7 +85,7 @@ direct_messages_received <- function(since_id = NULL, parse = TRUE, token = NULL) { abort("The endpoint for `direct_messages_received()` no longer exists. ", - "Please use `direct_messages()` instead.") + "Please use `direct_messages()` instead.", call = current_call()) } #' @export @@ -96,5 +96,5 @@ direct_messages_sent <- function(since_id = NULL, parse = TRUE, token = NULL) { abort("The endpoint for `direct_messages_received()` no longer exists. ", - "Please use `direct_messages()` instead.") + "Please use `direct_messages()` instead.", call = current_call()) } diff --git a/R/expansions.R b/R/expansions.R index 4b755e76..84fe1c6c 100644 --- a/R/expansions.R +++ b/R/expansions.R @@ -22,10 +22,10 @@ set_expansions <- function(tweet = tweet_expansions(), list = list_expansions()) { if (is.numeric(tweet)) { - abort("Invalid tweet expansions.") + abort("Invalid tweet expansions.", call = current_call()) } if (is.numeric(user)) { - abort("Invalid user expansions.") + abort("Invalid user expansions.", call = current_call()) } expansions <- c(tweet, user, list) @@ -60,8 +60,7 @@ list_expansions <- function() { } check_expansions <- function(passed, - allowed = c(tweet_expansions(), user_expansions(), list_expansions()), - call = caller_env()) { + allowed = c(tweet_expansions(), user_expansions(), list_expansions())) { # Empty list or NA return NULL to disable the expansions empty_list <- is.list(passed) && length(passed) == 0 na <- length(passed) == 1L && is.na(passed) @@ -73,7 +72,7 @@ check_expansions <- function(passed, if (any(within)) { extensions <- passed[within] abort(paste0("These extensions are not allowed: ", - paste(extensions, collapse = ", ")), call = call) + paste(extensions, collapse = ", ")), call = current_call()) } passed } @@ -84,7 +83,7 @@ check_expansions <- function(passed, # attachments.poll_ids is required by any poll.fields (go to includes) # referenced_tweets.id is required by any tweet.fields (go to includes) # author_id, entities.mentions.username, in_reply_to_user_id, referenced_tweets.id.author_id is required by any user.fields (go to includes) -expansions_for_fields <- function(expansion, fields, call = caller_env()) { +expansions_for_fields <- function(expansion, fields) { # Empty fields but might be expansions: no problem if (is.null(fields)) { return(TRUE) @@ -106,7 +105,7 @@ expansions_for_fields <- function(expansion, fields, call = caller_env()) { msg5 <- NULL } if (length(c(msg2, msg3, msg4, msg5)) >= 1) { - abort(c(msg, msg2, msg3, msg4, msg5), call = call) + abort(c(msg, msg2, msg3, msg4, msg5), call = current_call()) } TRUE } diff --git a/R/extractors.R b/R/extractors.R index 5e568dc1..f5dbc221 100644 --- a/R/extractors.R +++ b/R/extractors.R @@ -25,7 +25,7 @@ users_data <- function(tweets) { users <- attr(tweets, "users", exact = TRUE) if (is.null(users)) { - abort("`tweets` does not have a `users` attribute") + abort("`tweets` does not have a `users` attribute", call = current_call()) } users } @@ -36,7 +36,7 @@ users_data <- function(tweets) { tweets_data <- function(users) { tweets <- attr(users, "tweets", exact = TRUE) if (is.null(tweets)) { - abort("`users` does not have a `tweets` attribute") + abort("`users` does not have a `tweets` attribute", call = current_call()) } tweets } diff --git a/R/fields.R b/R/fields.R index cbbc061e..d85f8b98 100644 --- a/R/fields.R +++ b/R/fields.R @@ -119,7 +119,7 @@ set_fields <- function(media = media_fields, fields_c <- vapply(fields, is.character, logical(1L)) if (any(!fields_c)) { - abort("There is a field without characters.") + abort("There is a field without characters.", call = current_call()) } error <- c( @@ -146,8 +146,7 @@ check_fields <- function(fields, tweet = tweet_fields, user = user_fields, list = list_fields, - metrics = metrics_fields, - call = caller_env()) { + metrics = metrics_fields) { # If null, empty list or NA return NULL to disable the fields empty_list <- is.list(fields) && length(fields) == 0 @@ -162,7 +161,7 @@ check_fields <- function(fields, valid_fields <- paste0(valid_fields, ".fields") if (length(setdiff(n_fields, valid_fields)) >= 1) { - warning("Invalid fields provided, they are omitted", call. = FALSE) + warn("Invalid fields provided, they are omitted") } error <- c( @@ -174,7 +173,7 @@ check_fields <- function(fields, check_field_helper(fields, metrics, "metrics.fields") ) if (!is.null(error)) { - abort(error, call = call) + abort(error, call = current_call()) } fields <- fields[intersect(n_fields, valid_fields)] diff --git a/R/friends.R b/R/friends.R index 9d206bc4..b85d201e 100644 --- a/R/friends.R +++ b/R/friends.R @@ -101,7 +101,7 @@ my_friendships <- function(user, token = NULL) { if (!isFALSE(parse)) { - abort("`my_friendships()` can only return unparsed data") + abort("`my_friendships()` can only return unparsed data", call = current_call()) } params <- list() diff --git a/R/http.R b/R/http.R index 64732605..af4bf6b2 100644 --- a/R/http.R +++ b/R/http.R @@ -479,7 +479,8 @@ handle_codes <- function(x) { handle_error <- function(x, params) { chk_message <- "Check error message at https://developer.twitter.com/en/support/twitter-api/error-troubleshooting" if (is.null(x$headers[["content-type"]])) { - stop("Twitter API failed [", x$status_code, "]\n", chk_message, call. = FALSE) + abort(paste0("Twitter API failed [", x$status_code, "]\n", chk_message), + call = caller_call()) } json <- from_js(x) error <- if (!is.null(json$error)) json$error else json$errors @@ -487,20 +488,19 @@ handle_error <- function(x, params) { if (any(c("screen_name", "user_id") %in% names(params))) { account <- params$screen_name if (is.null(account)) account <- params$user_id - warning("Skipping unauthorized account: ", account, call. = FALSE) + warn(paste0("Skipping unauthorized account: ", account)) } else { - warning("Something went wrong with the authentication:\n\t", - error, call. = FALSE) + warn(paste0("Something went wrong with the authentication:\n\t", error)) } } else if (length(error) == 2) { - stop("Twitter API failed [", x$status_code, "]. ", chk_message, " \n", + abort(paste0("Twitter API failed [", x$status_code, "]:\n"), paste0(" * ", error$message, " (", error$code, ")"), - call. = FALSE) + call. = caller_call()) } else { if (is_testing()) { testthat::skip("Something went wrong with the requests") } - warning("Something went wrong with the requests", call. = FALSE) + warn("Something went wrong with the requests") } } diff --git a/R/ids.R b/R/ids.R index f793f188..de6faa37 100644 --- a/R/ids.R +++ b/R/ids.R @@ -23,7 +23,7 @@ ids.default <- function(x, ...) { out <- x[["id_str"]] if (is.null(out)) { stop("Ids are not present. Are you sure this is a rtweet object?", - call. = FALSE) + call = caller_call()) } out } @@ -62,7 +62,7 @@ ids.page <- function(x, ...) { #' @export ids.post_tweet <- function(x, ...) { if (httr::status_code(x) != 200L) { - stop("Your message has not been posted!", call. = FALSE) + abort("Your message has not been posted!", call = caller_call()) } cpt <- httr::content(x) cpt$id_str diff --git a/R/rt_stream.R b/R/rt_stream.R index 864d913a..73deed7c 100644 --- a/R/rt_stream.R +++ b/R/rt_stream.R @@ -70,7 +70,7 @@ filtered_stream <- function(timeout, file = tempfile(), data <- unlist(prepare_params(data), recursive = FALSE) req_stream <- httr2::req_url_query(req_stream, !!!data) if (file.exists(file) && isFALSE(append)) { - stop("File already exists and append = FALSE", call. = FALSE) + abort("File already exists and append = FALSE", call = caller_call()) } out <- stream(req_stream, file, timeout = timeout) if (!parse) { @@ -163,8 +163,8 @@ handle_rules_resp <- function(x) { df } -stream_rules <- function(query = NULL, token = NULL, ..., call = caller_env()) { - token <- check_token_v2(token, call = call) +stream_rules <- function(query = NULL, token = NULL, ...) { + token <- check_token_v2(token) req <- endpoint_v2(token, "tweets/search/stream/rules", 450 / (15 * 60)) if (!is.null(query)) { @@ -175,24 +175,24 @@ stream_rules <- function(query = NULL, token = NULL, ..., call = caller_env()) { is_rule <- function(q) { if (!has_name(q, "value")) { - stop("Please add value for filtering and a tag", call. = FALSE) + abort("Please add value for filtering and a tag", call = current_call()) } nc <- nchar(q[["value"]]) if (any(nc > 1024)) { - stop("Value cannot be longer than 1024 characters", call. = FALSE) + abort("Value cannot be longer than 1024 characters", call = current_call()) } else if (any(nc > 512)) { - warning("Requires academic research access.", call. = FALSE) + warn("Requires academic research access.") } if (length(nc) > 1000) { - stop("Impossible to have more than 1000 rules", call. = FALSE) + abort("Impossible to have more than 1000 rules", call = current_call()) } else if (length(nc) > 5) { - warning("Requires elevated or academic research access", call. = FALSE) + warn("Requires elevated or academic research access") } if (is.null(q[["tag"]]) || any(nchar(q[["tag"]]) == 0)) { - stop("Add tags for the rules for better handling of the streaming output", - call. = FALSE) + abort("Add tags for the rules for better handling of the streaming output", + call = current_call()) } q } @@ -213,7 +213,7 @@ check_stream_remove <- function(q) { } if (!any(grepl("^[0-9]{19}$", q))) { - stop("Streaming ids should be 19 numbers long", call. = FALSE) + abort("Streaming ids should be 19 numbers long", call = caller_call()) } if (length(q) == 1) { list(delete = list(ids = list(q))) @@ -283,7 +283,7 @@ sample_stream <- function(timeout, file = tempfile(), data <- unlist(prepare_params(data), recursive = FALSE) req_stream <- httr2::req_url_query(req_stream, !!!data) if (file.exists(file) && isFALSE(append)) { - stop("File already exists and append = FALSE", call. = FALSE) + abort("File already exists and append = FALSE", call = caller_call()) } out <- stream(req_stream, file, timeout = timeout) if (!parse) { diff --git a/R/scopes.R b/R/scopes.R index 20c35eb9..595b9012 100644 --- a/R/scopes.R +++ b/R/scopes.R @@ -43,34 +43,34 @@ set_scopes <- function(read = TRUE, write = TRUE, tweet_moderate = TRUE, regener scopes } -get_scopes <- function(token, call = caller_env()) { - token <- check_token_v2(token, "pkce", call) +get_scopes <- function(token) { + token <- check_token_v2(token, "pkce") strsplit(token$scope, " ")[[1]] } -check_scopes <- function(scopes, required = NULL, call = caller_env()) { +check_scopes <- function(scopes, required = NULL) { if (is.null(required)) { diff <- setdiff(scopes, all_scopes) if (length(diff) != 0) { msg <- paste0("Scopes required are not valid: ", paste0(sQuote(diff), collapse = ", ")) - abort(msg, call = call) + abort(msg, call = current_call()) } } missing <- setdiff(required, scopes) if (length(missing) != 0) { msg <- c("This endpoint requires missing scopes.", paste0("Authenticate with scopes:", paste0(sQuote(missing), collapse = ", "))) - abort(msg, call = call) + abort(msg, call = current_call()) } TRUE } -check_scopes_token <- function(token, required, call = caller_env()) { +check_scopes_token <- function(token, required) { if (!auth_is_pkce(token)) { return(TRUE) } - check_scopes(required, call = call) - check_scopes(get_scopes(token), required, call = call) + check_scopes(required) + check_scopes(get_scopes(token), required) TRUE } diff --git a/R/user_id.R b/R/user_id.R index a39dc3c7..e4a71118 100644 --- a/R/user_id.R +++ b/R/user_id.R @@ -1,28 +1,28 @@ #' Mark a user id as a screen name -#' -#' @description +#' +#' @description #' There are two ways to identify a Twitter user: a screen name (e.g. #' "justinbieber") or a user identifier (e.g. "27260086"). User identifiers -#' look like regular numbers, but are actually 64-bit integers which can't be -#' stored in R's numeric vectors. For this reason, rtweet always returns ids as +#' look like regular numbers, but are actually 64-bit integers which can't be +#' stored in R's numeric vectors. For this reason, rtweet always returns ids as #' strings. -#' -#' Unfortunately this introduces an ambiguity, because user names can +#' +#' Unfortunately this introduces an ambiguity, because user names can #' also consist solely of numbers (e.g. "123456") so it's not obvious whether -#' a string consisting only of numbers is a screen name or a user id. By +#' a string consisting only of numbers is a screen name or a user id. By #' default, rtweet will assume its a user id, so if you have a screen name #' that consists only of numbers, you'll need to use `as_screenname()` to #' tell rtweet that it's actually a screen name. -#' +#' #' Note that in general, you are best off using user ids; screen names are -#' not static and may change over longer periods of time. -#' +#' not static and may change over longer periods of time. +#' #' @param x A character vector of Twitter screen names. #' @examples #' if (auth_has_default()) { -#' # Look up user with id -#' lookup_users("25594077") -#' +#' # Look up user with id +#' lookup_users("25594077") +#' #' # Look up user with name 25594077 #' lookup_users(as_screenname("123456")) #' } @@ -68,7 +68,8 @@ user_type <- function(x, arg_name = "user") { "screen_name" } } else { - stop("`", arg_name, "` must be a screen name or user id", call. = FALSE) + abort(paste0("`", arg_name, "` must be a screen name or user id"), + call = caller_call()) } } diff --git a/R/utils.R b/R/utils.R index 9dd9d1aa..4e1e5b74 100644 --- a/R/utils.R +++ b/R/utils.R @@ -62,11 +62,11 @@ is_id <- function(x) { is.character(x) && all(nchar(x) >= 18) && all(grepl("[0-9]{18,}", x)) || is.numeric(x) } -is_user_id <- function(x, call = caller_env()) { +is_user_id <- function(x) { is.character(x) && all(nchar(x) >= 8) && all(grepl("[0-9]{8,}", x)) || is.numeric(x) } -is_list_id <- function(x, call = caller_env()) { +is_list_id <- function(x) { is.character(x) && all(nchar(x) >= 17) && all(grepl("[0-9]{17,}", x)) || is.numeric(x) } diff --git a/tests/testthat/_snaps/auth.md b/tests/testthat/_snaps/auth.md index 4a94beae..565cc756 100644 --- a/tests/testthat/_snaps/auth.md +++ b/tests/testthat/_snaps/auth.md @@ -10,12 +10,12 @@ Code find_auth(1:10) Condition - Error: + Error in `find_auth()`: ! Unrecognised input to `auth` Code find_auth("not-present") Condition - Error: + Error in `load_token()`: ! Can't find saved auth with name 'not-present' # default_cached_auth() handles 0, 1, and n saved @@ -23,7 +23,7 @@ Code default_cached_auth() Condition - Error in `default_cached_auth()`: + Error: ! No default authentication found. Please call `auth_setup_default()` --- @@ -31,7 +31,7 @@ Code default_cached_auth() Condition - Error in `default_cached_auth()`: + Error: ! No default authentication found. Pick existing auth with: * auth_as('test1') * auth_as('test2') diff --git a/tests/testthat/test-req_errors.R b/tests/testthat/test-req_errors.R index 830c402a..ab934af3 100644 --- a/tests/testthat/test-req_errors.R +++ b/tests/testthat/test-req_errors.R @@ -1,5 +1,4 @@ test_that("req_error works", { testing_with_authentication("bearer_testing_app") - expect_error(user_blocked("407200271", n = Inf), - "must be the same as the authenticating user") + expect_error(user_blocked("407200271", n = Inf)) }) From 89cbe74c0efb8495773e59e874f86bfb07533b8f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Thu, 25 May 2023 01:37:58 +0200 Subject: [PATCH 04/21] Increment version number to 1.2.0.9004 --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 38989567..77d37821 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: rtweet Title: Collecting Twitter Data -Version: 1.2.0.9003 +Version: 1.2.0.9004 Authors@R: c( person("Michael W.", "Kearney", , "kearneymw@missouri.edu", role = "aut", comment = c(ORCID = "0000-0002-0730-4694")), From 53d560763e5c8495a6710e06a9ea4f8cbbe8066f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Fri, 26 May 2023 00:15:34 +0200 Subject: [PATCH 05/21] Patch the problems with the authentication --- R/auth.R | 35 ++++++++++++++++++++++++++--------- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/R/auth.R b/R/auth.R index 82ba6a4f..a60320a0 100644 --- a/R/auth.R +++ b/R/auth.R @@ -460,11 +460,11 @@ rtweet_oauth2 <- function(client = NULL, scopes = NULL) { # Renew token if needed # Makes the assumption that the right app is still in the user computer auth_renew <- function(token, scopes = NULL) { - stopifnot(auth_is_pkce(token)) + check_token_v2(token, "pkce") - if (.POSIXct(token$expires_at) >= Sys.time()) { - return(token) - } + # if (.POSIXct(token$expires_at) >= Sys.time()) { + # return(token) + # } if (!is.null(scopes) && check_scopes(scopes)) { scopes <- scopes @@ -476,16 +476,33 @@ auth_renew <- function(token, scopes = NULL) { } client_name <- attr(token, "app", TRUE) client <- load_client(client_name) - # Is possible to silently update the token # see https://github.com/r-lib/httr2/issues/197 - token2 <- httr2::oauth_flow_refresh(client, + # Seen in https://twittercommunity.com/t/unable-to-obtain-new-access-token-by-using-refresh-token/164123 + # That it requires the client_id parameter! + # Still sometimes the refresh_token is not accepted + token2 <- tryCatch(httr2::oauth_flow_refresh(client, refresh_token = token$refresh_token, - scope = token$scope) + scope = token$scope, + token_params = list(client_id = client$id)), + error = function(err){TRUE}) + + if (isTRUE(token2) && !interactive()) { + abort() + } else if (isTRUE(token2)) { + warn(c("It couldn't authomatically renew the authentication.", + i = "Please accept the window it will open up.")) + + Sys.sleep(1) + token2 <- rtweet_oauth2(client, get_scopes(token)) + } + + attr(token2, "app") <- client_name + attr(token2, "name") <- token_name(token) # Save token in the environment auth_as(token2) # If possible replace it in the user storage. - resave_token(token2, token_name(token)) + resave_token(token2) token2 } @@ -498,7 +515,7 @@ token_name <- function(x){ attr(x, "name", TRUE) } -resave_token <- function(token, name) { +resave_token <- function(token) { name <- token_name(token) if (is.null(name)) { inform(c("!" = "It was not possible to save your token", From dae59c83cca390807afd38b5f0871bade569db94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Fri, 26 May 2023 00:15:59 +0200 Subject: [PATCH 06/21] Improve errors appearance --- R/http.R | 14 +++++++++----- tests/testthat/test-auth.R | 4 ++-- 2 files changed, 11 insertions(+), 7 deletions(-) diff --git a/R/http.R b/R/http.R index af4bf6b2..bd4ebaad 100644 --- a/R/http.R +++ b/R/http.R @@ -483,7 +483,7 @@ handle_error <- function(x, params) { call = caller_call()) } json <- from_js(x) - error <- if (!is.null(json$error)) json$error else json$errors + error <- if (!is.null(json[["error"]])) json[["error"]] else json[["errors"]] if (length(error) == 1) { if (any(c("screen_name", "user_id") %in% names(params))) { account <- params$screen_name @@ -493,8 +493,8 @@ handle_error <- function(x, params) { warn(paste0("Something went wrong with the authentication:\n\t", error)) } } else if (length(error) == 2) { - abort(paste0("Twitter API failed [", x$status_code, "]:\n"), - paste0(" * ", error$message, " (", error$code, ")"), + abort(c(paste0("Twitter API failed [", x$status_code, "]:"), + paste0(error$message, " (", error$code, ")")), call. = caller_call()) } else { if (is_testing()) { @@ -536,9 +536,13 @@ check_token <- function(token = NULL) { if (inherits(token, "Token1.0")) { token - } else if (inherits(token, "rtweet_bearer")) { + } else if (auth_is_bearer(token)) { httr::add_headers(Authorization = paste0("Bearer ", token$token)) + } else if (auth_is_pkce(token)) { + abort(c("This OAuth 2.0 `token` is not a valid access token", + "i" = "Please use a bearer token via `rtweet_app()`."), + call = caller_call()) } else { - abort("`token` is not a valid access token") + abort("`token` is not a valid access token", call = caller_call()) } } diff --git a/tests/testthat/test-auth.R b/tests/testthat/test-auth.R index e8b403a2..c1c97d2c 100644 --- a/tests/testthat/test-auth.R +++ b/tests/testthat/test-auth.R @@ -56,7 +56,7 @@ test_that("rtweet_user works", { skip("requires manual testing") # Avoid saving it but check that it is redirected in the browser. withr::local_options("rtweet:::config_dir" = tempfile()) - expect_error(rtweet_user(), NA) + expect_error(rtweet_user()) }) test_that("rtweet_bot works", { @@ -69,7 +69,7 @@ test_that("rtweet_oauth2 works", { skip("requires manual testing") # Avoid saving it but check that it is redirected in the browser. withr::local_options("rtweet:::config_dir" = tempfile()) - expect_error(b <- rtweet_client(app = "academic_dev"), NA) + expect_error(b <- rtweet_client(app = "academic_dev")) client_as(b) expect_error(rtweet_oauth2(), NA) }) From fdf6a0b0afb6e22293a7a04e61b16d2cfc17464a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Fri, 26 May 2023 00:16:48 +0200 Subject: [PATCH 07/21] Fix an oversight --- R/api_v2_utils.R | 1 + 1 file changed, 1 insertion(+) diff --git a/R/api_v2_utils.R b/R/api_v2_utils.R index 3d9b2150..1c0c9d75 100644 --- a/R/api_v2_utils.R +++ b/R/api_v2_utils.R @@ -87,6 +87,7 @@ req_auth <- function(req, token) { token <- token$token } else if (auth_is_pkce(token)) { token <- auth_renew(token) + token <- token$access_token } httr2::req_auth_bearer_token(req, token) } From 1276a32a123fbe31cbb785ffd337bde24144741e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Fri, 26 May 2023 00:17:15 +0200 Subject: [PATCH 08/21] Explore the generation of bearers tokens with OAuth 2.0 --- R/api_v2_utils.R | 4 +++- R/auth.R | 48 ++++++++++++++++++++++++++++++++++++++++++++++++ R/bearer_token.R | 4 +++- 3 files changed, 54 insertions(+), 2 deletions(-) diff --git a/R/api_v2_utils.R b/R/api_v2_utils.R index 1c0c9d75..4fad1930 100644 --- a/R/api_v2_utils.R +++ b/R/api_v2_utils.R @@ -4,7 +4,9 @@ auth_is_bearer <- function(token = NULL) { if (is.null(token)) { token <- auth_get() } - inherits(token, "rtweet_bearer") + # if the bearer is created with rtweet_bearer the class is different + bearer_httr2 <- inherits(token, "httr2_token") && is.null(token$refresh_token) + inherits(token, "rtweet_bearer") || bearer_httr2 } prepare_bearer <- function(x, y) { diff --git a/R/auth.R b/R/auth.R index a60320a0..369b59b3 100644 --- a/R/auth.R +++ b/R/auth.R @@ -173,6 +173,54 @@ ask_pass <- function(type) { val } +#' Generate a Bearer token from a client +#' +#' @export +rtweet_bearer <- function(client = NULL, scopes = set_scopes()) { + + client <- client %||% client_get() + if (!is_client(client)) { + abort(c("Client not valid", + i = "Check out the `vignette('auth', 'rtweet')`."), + call = current_call()) + } + + if (!is.null(scopes) && check_scopes(scopes)) { + scopes <- scopes + } else { + abort("Scopes is not in the right format.", call = current_call()) + } + + token <- httr2::oauth_flow_client_credentials(client, + scope = scopes, + token_params = list(client_secret = client$secret, + client_type = "third_party_app", + grant_type = "refresh_token")) + attr(token, "app", TRUE) <- client + token +} + +#' @seealso [invalidate_bearer()] +rtweet_invalidate <- function(api_key, api_secret, token = NULL) { + if (missing(api_key)) { + api_key <- ask_pass("API key") + } + if (missing(api_secret)) { + api_secret <- ask_pass("API secret") + } + + token <- check_token_v2(token, mechanism = "bearer") + if (!is.null(token$token)) { + abort("Not possible to invalidate bearer token generated with OAuth 1.0", + call = caller_call()) + } + httr2::request("https://api.twitter.com/oauth2/invalidate_token") |> + httr2::req_method("POST") |> + httr2::req_auth_basic(api_key, api_secret) |> + httr2::req_body_form(access_token = token$access_token) |> + httr2::req_perform() +} + is_auth <- function(x) { inherits(x, "Token") || inherits(x, "rtweet_bearer") || inherits(x, "httr2_token") } diff --git a/R/bearer_token.R b/R/bearer_token.R index 45132c02..5ba89a2b 100644 --- a/R/bearer_token.R +++ b/R/bearer_token.R @@ -9,6 +9,7 @@ #' [Twitter developer portal](https://developer.twitter.com/en/portal/projects-and-apps). #' See `vignette("auth", package = "rtweet")` for full details. #' @keywords internal +#' @seealso [rtweet_bearer()] #' @export bearer_token <- function(token = NULL) { lifecycle::deprecate_stop("1.0.0", "bearer_token()", "rtweet_app()") @@ -25,9 +26,10 @@ bearer_token <- function(token = NULL) { #' @references #' #' @keywords internal +#' @seealso [rtweet_invalidate()] #' @export invalidate_bearer <- function(api_key, api_secret, client = NULL, token = NULL) { - +# See also rtweet_invalidate in auth.R if (is.null(client)) { client <- client_as(client) api_key <- client["id"] From 56509fe2db536375a53cb8f92b40d18bd4ea42c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Sat, 27 May 2023 10:59:26 +0200 Subject: [PATCH 09/21] Add messages and handling when the renewal is needed. --- DESCRIPTION | 2 +- R/auth.R | 18 ++++++++++++------ 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/DESCRIPTION b/DESCRIPTION index 77d37821..f2a39b95 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Type: Package Package: rtweet Title: Collecting Twitter Data -Version: 1.2.0.9004 +Version: 1.2.0.9005 Authors@R: c( person("Michael W.", "Kearney", , "kearneymw@missouri.edu", role = "aut", comment = c(ORCID = "0000-0002-0730-4694")), diff --git a/R/auth.R b/R/auth.R index 369b59b3..c0f067b4 100644 --- a/R/auth.R +++ b/R/auth.R @@ -510,9 +510,9 @@ rtweet_oauth2 <- function(client = NULL, scopes = NULL) { auth_renew <- function(token, scopes = NULL) { check_token_v2(token, "pkce") - # if (.POSIXct(token$expires_at) >= Sys.time()) { - # return(token) - # } + if (.POSIXct(token$expires_at) >= Sys.time()) { + return(token) + } if (!is.null(scopes) && check_scopes(scopes)) { scopes <- scopes @@ -536,10 +536,16 @@ auth_renew <- function(token, scopes = NULL) { error = function(err){TRUE}) if (isTRUE(token2) && !interactive()) { - abort() + if (is_testing()) { + testthat::skip(paste0("Not possible to refresh the token automatically", + " and not in interactive environment.")) + } + abort("Automatic refresh of the token was not possible.", + call = caller_call()) } else if (isTRUE(token2)) { - warn(c("It couldn't authomatically renew the authentication.", - i = "Please accept the window it will open up.")) + warn(c("It couldn't automatically renew the authentication.", + i = "Please accept the window it will open up."), + call = caller_call()) Sys.sleep(1) token2 <- rtweet_oauth2(client, get_scopes(token)) From 5163269278090ae397d3a55f82c040ba7811faeb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Wed, 13 Sep 2023 00:02:51 +0200 Subject: [PATCH 10/21] Minor tweak to requirements --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index f2a39b95..0b44b053 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -29,7 +29,7 @@ Imports: bit64 (>= 4.0.5), curl (>= 4.3.2), httr (>= 1.3.0), - httr2 (> 0.2.3), + httr2 (>= 0.2.3.9000), jsonlite (>= 0.9.22), lifecycle (>= 1.0.0), methods, From f8e4c8f13afab5f341a72906711777d255218d17 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Sun, 8 Oct 2023 12:30:22 +0200 Subject: [PATCH 11/21] Update tests --- tests/testthat/_snaps/search_tweets.md | 2 +- tests/testthat/test-post-tweet.R | 1 - tests/testthat/test-stream.R | 1 - tests/testthat/test-tweet_threading.R | 23 +++++++++++------------ tests/testthat/test-users.R | 1 - 5 files changed, 12 insertions(+), 16 deletions(-) diff --git a/tests/testthat/_snaps/search_tweets.md b/tests/testthat/_snaps/search_tweets.md index 55fc42e1..dfcefa61 100644 --- a/tests/testthat/_snaps/search_tweets.md +++ b/tests/testthat/_snaps/search_tweets.md @@ -4,7 +4,7 @@ search_tweets(c(1:10), verbose = FALSE) Condition Error in `search_params()`: - ! length(q) == 1L is not TRUE + ! is.atomic(q) && !is.null(q) && length(q) == 1L is not TRUE --- diff --git a/tests/testthat/test-post-tweet.R b/tests/testthat/test-post-tweet.R index 847d2c72..a4153277 100644 --- a/tests/testthat/test-post-tweet.R +++ b/tests/testthat/test-post-tweet.R @@ -56,7 +56,6 @@ test_that("post_tweet works", { test_that("post_tweet geolocated works", { skip_if_offline() # destroy id changes on each test - # Test geolocated tweet msg <- paste("test geolocated", Sys.time()) # To avoid having duplicated status expect_message(pt <- post_tweet(msg, lat = -36.811784, long = 174.792657), diff --git a/tests/testthat/test-stream.R b/tests/testthat/test-stream.R index 967471b3..45613f86 100644 --- a/tests/testthat/test-stream.R +++ b/tests/testthat/test-stream.R @@ -1,5 +1,4 @@ test_that("stream_tweets returns tweets data", { - skip(message = "No longer working") path <- tempfile() x1 <- stream_tweets(timeout = 1, file_name = path, verbose = FALSE) expect_s3_class(x1, "tweets") diff --git a/tests/testthat/test-tweet_threading.R b/tests/testthat/test-tweet_threading.R index 32dd9a4d..cbafd1f8 100644 --- a/tests/testthat/test-tweet_threading.R +++ b/tests/testthat/test-tweet_threading.R @@ -1,23 +1,23 @@ write_thread <- function() { - pt1 <- suppressMessages(post_tweet(status = paste0("first in a thread", Sys.time()))) - pt2 <- suppressMessages(post_tweet(paste0("second in the thread", Sys.time()), + pt1 <- suppressMessages(tweet_post(status = paste0("first in a thread", Sys.time()))) + pt2 <- suppressMessages(tweet_post(paste0("second in the thread", Sys.time()), in_reply_to_status_id = ids(pt1))) - pt3 <- suppressMessages(post_tweet(paste0("3rd in the thread", Sys.time()), + pt3 <- suppressMessages(tweet_post(paste0("3rd in the thread", Sys.time()), in_reply_to_status_id = ids(pt2))) - pt4 <- suppressMessages(post_tweet(paste0("4th in the thread", Sys.time()), + pt4 <- suppressMessages(tweet_post(paste0("4th in the thread", Sys.time()), in_reply_to_status_id = ids(pt3))) - pt5 <- suppressMessages(post_tweet(paste0("5th in the thread", Sys.time()), + pt5 <- suppressMessages(tweet_post(paste0("5th in the thread", Sys.time()), in_reply_to_status_id = ids(pt4))) - pt6 <- suppressMessages(post_tweet(paste0("6th in the thread", Sys.time()), + pt6 <- suppressMessages(tweet_post(paste0("6th in the thread", Sys.time()), in_reply_to_status_id = ids(pt5))) - pt7 <- suppressMessages(post_tweet(paste0("7th in the thread", Sys.time()), + pt7 <- suppressMessages(tweet_post(paste0("7th in the thread", Sys.time()), in_reply_to_status_id = ids(pt6))) - pt8 <- suppressMessages(post_tweet(paste0("8th in the thread", Sys.time()), + pt8 <- suppressMessages(tweet_post(paste0("8th in the thread", Sys.time()), in_reply_to_status_id = ids(pt7))) - pt9 <- suppressMessages(post_tweet(paste0("9th in the thread", Sys.time()), + pt9 <- suppressMessages(tweet_post(paste0("9th in the thread", Sys.time()), in_reply_to_status_id = ids(pt8))) - pt10 <- suppressMessages(post_tweet(paste0("10th in the thread", Sys.time()), + pt10 <- suppressMessages(tweet_post(paste0("10th in the thread", Sys.time()), in_reply_to_status_id = ids(pt9))) c(ids(pt1), ids(pt2), ids(pt3), ids(pt4), ids(pt5), ids(pt6), ids(pt7), ids(pt8), ids(pt9), ids(pt10)) @@ -25,13 +25,12 @@ write_thread <- function() { delete_thread <- function(ids) { for (id in ids) { - suppressMessages(post_destroy(id)) + suppressMessages(tweet_delete(id)) } } test_that("tweet_threading works", { skip_if_offline() - tryCatch(thread <- write_thread(), error = function(x){ skip("Not able to post.") }) diff --git a/tests/testthat/test-users.R b/tests/testthat/test-users.R index 3c30e1e1..4f893404 100644 --- a/tests/testthat/test-users.R +++ b/tests/testthat/test-users.R @@ -50,5 +50,4 @@ test_that("lookup_users only works with ids", { skip_if_offline() expect_error(b <- lookup_tweets(twd), NA) expect_s3_class(b, "tweets") - }) From 91d019107d8d9c60522bf5dc3d5259c4f2e35d34 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Sun, 8 Oct 2023 12:31:23 +0200 Subject: [PATCH 12/21] Handle change in R of atomic and NULL --- R/coords.R | 3 ++- R/followers.R | 2 +- R/friends.R | 3 ++- R/post-block.R | 2 +- R/post-favorite.R | 4 ++-- R/post-list.R | 5 +++-- R/post-user.R | 4 ++-- R/search_tweets.R | 3 ++- R/search_users.R | 20 ++++++++++---------- R/stream.R | 2 +- R/trends.R | 2 +- R/ts_plot.R | 4 ++-- 12 files changed, 29 insertions(+), 25 deletions(-) diff --git a/R/coords.R b/R/coords.R index 22ee8b94..8ac44cbe 100644 --- a/R/coords.R +++ b/R/coords.R @@ -56,7 +56,8 @@ #' @export lookup_coords <- function(address, components = NULL, apikey = NULL, ...) { if (missing(address)) stop("must supply address", call. = FALSE) - stopifnot(is.atomic(address), is.atomic(components)) + stopifnot(is.atomic(address) && !is.null(address), + is.atomic(components)) place <- address if (grepl("^us$|^usa$|^united states$|^u\\.s", address, ignore.case = TRUE)) { diff --git a/R/followers.R b/R/followers.R index 0e2863f1..41cc79a6 100644 --- a/R/followers.R +++ b/R/followers.R @@ -32,7 +32,7 @@ get_followers <- function(user, n = 5000, cursor <- page } - stopifnot(is.atomic(user), isTRUE(length(user) == 1)) + stopifnot(is.atomic(user) && !is.null(user), isTRUE(length(user) == 1)) params <- list(stringify_ids = TRUE) params[[user_type(user)]] <- user diff --git a/R/friends.R b/R/friends.R index b85d201e..f14feada 100644 --- a/R/friends.R +++ b/R/friends.R @@ -139,7 +139,8 @@ lookup_friendships_ <- function(source, target, parse = TRUE, token = NULL) { - stopifnot(is.atomic(source), is.atomic(target)) + stopifnot(is.atomic(source) && !is.null(source), + is.atomic(target) && !is.null(target)) params <- list() params[[paste0("source_", user_type(source, "source"))]] <- source diff --git a/R/post-block.R b/R/post-block.R index 7ac20116..67e18817 100644 --- a/R/post-block.R +++ b/R/post-block.R @@ -20,7 +20,7 @@ user_block <- function(user, unblock = FALSE, token = NULL) { - stopifnot(is.atomic(user), is_logical(unblock)) + stopifnot(is.atomic(user) || is.null(user), is_logical(unblock)) if (!unblock) { query <- "/1.1/blocks/create" diff --git a/R/post-favorite.R b/R/post-favorite.R index ba1cb2d9..50647d8a 100644 --- a/R/post-favorite.R +++ b/R/post-favorite.R @@ -14,7 +14,7 @@ #' } #' @family post #' @export -#' @references +#' @references #' Create: #' Destroy: post_favorite <- function(status_id, @@ -22,7 +22,7 @@ post_favorite <- function(status_id, include_entities = FALSE, token = NULL) { - stopifnot(is.atomic(status_id)) + stopifnot(is.atomic(status_id) && !is.null(status_id)) if (destroy) { query <- "/1.1/favorites/destroy" diff --git a/R/post-list.R b/R/post-list.R index d24b351d..c5275055 100644 --- a/R/post-list.R +++ b/R/post-list.R @@ -100,7 +100,8 @@ post_list_create <- function(name, private = FALSE, token = NULL) { - stopifnot(is.atomic(name), length(name) == 1, is_logical(private)) + stopifnot(is.atomic(name) && !is.null(name), length(name) == 1, + is_logical(private)) if (private) { mode <- "private" @@ -193,7 +194,7 @@ post_list_destroy_all <- function(users, my_list_params <- function(token, slug = NULL, list_id = NULL, ..., users = NULL) { params <- list(...) - if (!is.null(list_id) && is.null(slug)) { + if (!is.null(list_id) && !is.null(slug)) { stopifnot(is.atomic(list_id), length(list_id) == 1) params$list_id <- list_id diff --git a/R/post-user.R b/R/post-user.R index aec553c8..6133d7ab 100644 --- a/R/post-user.R +++ b/R/post-user.R @@ -30,7 +30,7 @@ post_follow <- function(user, retweets = TRUE, token = NULL) { - stopifnot(is.atomic(user), is_logical(notify)) + stopifnot(is.atomic(user) && !is.null(user), is_logical(notify)) if (all(!destroy, !retweets)) { query <- "/1.1/friendships/update" @@ -89,7 +89,7 @@ post_friendship <- function(user, retweets = FALSE, token = NULL) { - stopifnot(is.atomic(user), is_logical(device), + stopifnot(is.atomic(user) && !is.null(user), is_logical(device), is_logical(retweets)) params <- list( diff --git a/R/search_tweets.R b/R/search_tweets.R index a52d2ce5..6a81186d 100644 --- a/R/search_tweets.R +++ b/R/search_tweets.R @@ -125,7 +125,8 @@ search_params <- function(q, if (missing(q) && !is.null(geocode)) { q <- "" } - stopifnot(is.atomic(q), length(q) == 1L, is.atomic(max_id)) + stopifnot(is.atomic(q) && !is.null(q) && length(q) == 1L, + is.atomic(max_id) && length(max_id) <= 1L) type <- arg_match(type) ## validate query length–char count might not always be same here as with diff --git a/R/search_users.R b/R/search_users.R index 7cb0176a..6c98723e 100644 --- a/R/search_users.R +++ b/R/search_users.R @@ -1,11 +1,11 @@ #' Search for users #' -#' Search for Twitter users. The Twitter API limits the results to at most +#' Search for Twitter users. The Twitter API limits the results to at most #' 1,000 users. #' #' @inheritParams TWIT_paginate_max_id -#' @param q As string providing the search query. Try searching by interest, -#' full name, company name, or location. Exact match searches are not +#' @param q As string providing the search query. Try searching by interest, +#' full name, company name, or location. Exact match searches are not #' supported. #' @examples #' if (auth_has_default()) { @@ -24,8 +24,8 @@ search_users <- function(q, n = 100, parse = TRUE, token = NULL, verbose = TRUE) { - - stopifnot(is_n(n), is.atomic(q)) + + stopifnot(is_n(n), is.atomic(q) && !is.null(q)) if (n > 1000) { abort("`n` must be <= 1,000 (the maximum allowed by Twitter)") } @@ -37,23 +37,23 @@ search_users <- function(q, n = 100, pb <- progress::progress_bar$new( format = "Searching for users :bar", total = pages - ) + ) withr::defer(pb$terminate()) } - + params <- list(q = q, count = 20) for (i in seq_len(pages)) { if (verbose) { pb$tick() - } + } params$page <- i results[[i]] <- TWIT_get(token, "/1.1/users/search", params) } - + if (parse) { results <- users_with_tweets(results) results$created_at <- format_date(results$created_at) } - + results } diff --git a/R/stream.R b/R/stream.R index a80d7b4b..6a4b5f86 100644 --- a/R/stream.R +++ b/R/stream.R @@ -170,7 +170,7 @@ whole_lines <- function(text, fragment = "") { stream_prep <- function(token, q = "", ..., filter_level = "none") { token <- check_token(token) - stopifnot(is.atomic(q) || inherits(q, "coords")) + stopifnot(is.atomic(q) && !is.null(q) || inherits(q, "coords")) if (identical(q, "")) { path <- "1.1/statuses/sample.json" diff --git a/R/trends.R b/R/trends.R index 542dd0ec..f39bb26f 100644 --- a/R/trends.R +++ b/R/trends.R @@ -75,7 +75,7 @@ get_trends <- function(woeid = 1, stop("could not find woe id for provided lat/lng coordinates", call. = FALSE) } } else { - stopifnot(is.atomic(woeid), length(woeid) == 1) + stopifnot(is.atomic(woeid) && !is.null(woeid), length(woeid) == 1) if (!is_n(woeid)) { trends <- trends_available(token = token) woeid <- trends$woeid[grep(woeid, trends$name, ignore.case = TRUE)[1]] diff --git a/R/ts_plot.R b/R/ts_plot.R index f14c46da..b26c0ed0 100644 --- a/R/ts_plot.R +++ b/R/ts_plot.R @@ -79,7 +79,7 @@ ts_plot <- function(data, by = "days", trim = 0L, tz ="UTC", ...) { #' #' @export ts_data <- function(data, by = "days", trim = 0L, tz ="UTC") { - stopifnot(is.data.frame(data), is.atomic(by)) + stopifnot(is.data.frame(data), is.atomic(by) && !is.null(by)) if (has_name_(data, "created_at")) { dtvar <- "created_at" } else { @@ -183,7 +183,7 @@ ts_data <- function(data, by = "days", trim = 0L, tz ="UTC") { } parse_unit <- function(by) { - stopifnot(is.atomic(by)) + stopifnot(is.atomic(by) && !is.null(by)) if (is.numeric(by)) { return(by) } else if (grepl("year", by)) { From 20cbaa716d241a3d0d7339fcfbede095cd55cf60 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Sun, 8 Oct 2023 12:31:39 +0200 Subject: [PATCH 13/21] Change error message --- R/client.R | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/R/client.R b/R/client.R index b741138b..cfbbfb63 100644 --- a/R/client.R +++ b/R/client.R @@ -72,7 +72,7 @@ default_client <- function(client_id = NULL, client_secret = NULL) { # The sysdat file is in #./R and loaded automagically abort(c("The default rtweet client is no longer authorized.", i = "You'll need to register as developer in order to use the Twitter API."), - call = current_call()) + call = caller_env()) client_id <- decrypt(sysdat$e914c55d2f) client_secret <- decrypt(sysdat$d5571d4003) } else { @@ -132,11 +132,7 @@ client_list <- function() { find_client <- function(client = NULL) { if (is.null(client)) { - if (is_developing()) { - load_client("academic_dev") %||% no_client() - } else{ - default_cached_client() - } + no_client() } else if (is_client(client)) { client } else if (is_string(client)) { From a91e5c785371885e3f0bca1bdc3f01630c08e72c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Sun, 8 Oct 2023 12:32:23 +0200 Subject: [PATCH 14/21] Handle earlier the API v1.1 errors --- R/http.R | 36 ++++++++++++++++++++---------------- 1 file changed, 20 insertions(+), 16 deletions(-) diff --git a/R/http.R b/R/http.R index bd4ebaad..dde1db95 100644 --- a/R/http.R +++ b/R/http.R @@ -100,6 +100,7 @@ TWIT_method <- function(method, token, api, #' Twitter API. #' @param verbose Show progress bars and other messages indicating current #' progress? +#' @returns A list with the json output of the API. TWIT_paginate_max_id <- function(token, api, params, get_id = function(x) x$id_str, n = 1000, @@ -484,27 +485,30 @@ handle_error <- function(x, params) { } json <- from_js(x) error <- if (!is.null(json[["error"]])) json[["error"]] else json[["errors"]] - if (length(error) == 1) { - if (any(c("screen_name", "user_id") %in% names(params))) { - account <- params$screen_name - if (is.null(account)) account <- params$user_id - warn(paste0("Skipping unauthorized account: ", account)) + if (x$status_code %in% c("401", "403") && is_developing()) { + testthat::skip("API v1.1 no longer works") + if (length(error) == 1) { + if (any(c("screen_name", "user_id") %in% names(params))) { + account <- params$screen_name + if (is.null(account)) + account <- params$user_id + warn(paste0("Skipping unauthorized account: ", account)) + } else { + warn(paste0("Something went wrong with the authentication:\n\t", error)) + } + } else if (length(error) == 2) { + abort(c(paste0("Twitter API failed [", x$status_code, "]:"), + paste0(error$message, " (", error$code, ")")), + call. = caller_call()) } else { - warn(paste0("Something went wrong with the authentication:\n\t", error)) - } - } else if (length(error) == 2) { - abort(c(paste0("Twitter API failed [", x$status_code, "]:"), - paste0(error$message, " (", error$code, ")")), - call. = caller_call()) - } else { - if (is_testing()) { - testthat::skip("Something went wrong with the requests") + if (is_testing()) { + testthat::skip("Something went wrong with the requests") + } + warn("Something went wrong with the requests") } - warn("Something went wrong with the requests") } } - # I don't love this interface because it returns either a httr response object # or a condition object, but it's easy to understand and avoids having to do # anything exotic to break from the correct frame. From fd1328440dca80908fa953be706e123d33b1b203 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Sun, 8 Oct 2023 12:32:44 +0200 Subject: [PATCH 15/21] Fix CRAN note about no return value --- man/TWIT_paginate_max_id.Rd | 3 +++ 1 file changed, 3 insertions(+) diff --git a/man/TWIT_paginate_max_id.Rd b/man/TWIT_paginate_max_id.Rd index 03b4cab6..1c910d01 100644 --- a/man/TWIT_paginate_max_id.Rd +++ b/man/TWIT_paginate_max_id.Rd @@ -105,6 +105,9 @@ continue pagination from where it left off.} to return the "raw" list corresponding to the JSON returned from the Twitter API.} } +\value{ +A list with the json output of the API. +} \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} These are internal functions used for pagination inside of rtweet. From c31d0ee98c7d7f18ed7635563a564ccd0509996b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Sun, 8 Oct 2023 12:33:11 +0200 Subject: [PATCH 16/21] Update documentation --- NAMESPACE | 1 + R/api_v2_utils.R | 3 +-- R/auth.R | 1 + man/as_screenname.Rd | 4 ++-- man/bearer_token.Rd | 3 +++ man/invalidate_bearer.Rd | 3 +++ man/rtweet_bearer.Rd | 11 +++++++++++ 7 files changed, 22 insertions(+), 4 deletions(-) create mode 100644 man/rtweet_bearer.Rd diff --git a/NAMESPACE b/NAMESPACE index badb2f67..1fca53d6 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -119,6 +119,7 @@ export(rate_limit_wait) export(read_twitter_csv) export(round_time) export(rtweet_app) +export(rtweet_bearer) export(rtweet_bot) export(rtweet_client) export(rtweet_oauth2) diff --git a/R/api_v2_utils.R b/R/api_v2_utils.R index 4fad1930..c639789b 100644 --- a/R/api_v2_utils.R +++ b/R/api_v2_utils.R @@ -86,12 +86,11 @@ check_token_v2 <- function(token = NULL, mechanism = "bearer") { # Provides the required method for the token type req_auth <- function(req, token) { if (auth_is_bearer(token)) { - token <- token$token + httr2::req_auth_bearer_token(req, token$token) } else if (auth_is_pkce(token)) { token <- auth_renew(token) token <- token$access_token } - httr2::req_auth_bearer_token(req, token) } req_is_error <- function(resp) { diff --git a/R/auth.R b/R/auth.R index c0f067b4..8a3874d1 100644 --- a/R/auth.R +++ b/R/auth.R @@ -494,6 +494,7 @@ rtweet_oauth2 <- function(client = NULL, scopes = NULL) { auth_url = "https://twitter.com/i/oauth2/authorize", pkce = TRUE, scope = paste(scopes, collapse = " "), + # redirect_uri = "http://127.0.0.1:1410", host_name = "127.0.0.1", port = 1410 ) diff --git a/man/as_screenname.Rd b/man/as_screenname.Rd index 45ebf400..4de7f87c 100644 --- a/man/as_screenname.Rd +++ b/man/as_screenname.Rd @@ -29,8 +29,8 @@ not static and may change over longer periods of time. } \examples{ if (auth_has_default()) { -# Look up user with id -lookup_users("25594077") +# Look up user with id +lookup_users("25594077") # Look up user with name 25594077 lookup_users(as_screenname("123456")) diff --git a/man/bearer_token.Rd b/man/bearer_token.Rd index d3d15b95..7de4d6aa 100644 --- a/man/bearer_token.Rd +++ b/man/bearer_token.Rd @@ -15,4 +15,7 @@ in the bearer token directly from the \href{https://developer.twitter.com/en/portal/projects-and-apps}{Twitter developer portal}. See \code{vignette("auth", package = "rtweet")} for full details. } +\seealso{ +\code{\link[=rtweet_bearer]{rtweet_bearer()}} +} \keyword{internal} diff --git a/man/invalidate_bearer.Rd b/man/invalidate_bearer.Rd index 0783d182..2d1ff2d8 100644 --- a/man/invalidate_bearer.Rd +++ b/man/invalidate_bearer.Rd @@ -24,4 +24,7 @@ Not tested! \url{https://developer.twitter.com/en/docs/authentication/api-reference/invalidate_bearer_token} \url{https://developer.twitter.com/en/docs/authentication/api-reference/invalidate_access_token} } +\seealso{ +\code{\link[=rtweet_invalidate]{rtweet_invalidate()}} +} \keyword{internal} diff --git a/man/rtweet_bearer.Rd b/man/rtweet_bearer.Rd new file mode 100644 index 00000000..f7da3887 --- /dev/null +++ b/man/rtweet_bearer.Rd @@ -0,0 +1,11 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/auth.R +\name{rtweet_bearer} +\alias{rtweet_bearer} +\title{Generate a Bearer token from a client} +\usage{ +rtweet_bearer(client = NULL, scopes = set_scopes()) +} +\description{ +Generate a Bearer token from a client +} From 791903bfd1a3438de862878d7251f87af22223c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Mon, 20 Nov 2023 19:39:48 +0100 Subject: [PATCH 17/21] Minor changes in documentation --- man/TWIT_paginate_max_id.Rd | 3 --- man/auth_clean.Rd | 3 ++- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/man/TWIT_paginate_max_id.Rd b/man/TWIT_paginate_max_id.Rd index c67f4ebc..5b364009 100644 --- a/man/TWIT_paginate_max_id.Rd +++ b/man/TWIT_paginate_max_id.Rd @@ -104,9 +104,6 @@ continue pagination from where it left off.} \value{ A list with the json output of the API. } -\value{ -A list with the json output of the API. -} \description{ \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#experimental}{\figure{lifecycle-experimental.svg}{options: alt='[Experimental]'}}}{\strong{[Experimental]}} These are internal functions used for pagination inside of rtweet. diff --git a/man/auth_clean.Rd b/man/auth_clean.Rd index 881af04c..18db13d4 100644 --- a/man/auth_clean.Rd +++ b/man/auth_clean.Rd @@ -14,6 +14,7 @@ auth_clean(old = TRUE, new = FALSE) \value{ An invisible logical value showing the success of the operation. If no tokens need to be deleted it will return FALSE too. +\code{NULL} if there is nothing to do. } \description{ If there is a file with saved tokens it will delete it. @@ -23,5 +24,5 @@ This functions helps to comply with CRAN policy to remove files created by the package. } \examples{ -auth_clean() +auth_clean(FALSE, FALSE) } From 15e9c6950f33e8c3b182bbbcbc2d3a78e048f3ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Sun, 10 Dec 2023 23:36:02 +0100 Subject: [PATCH 18/21] Remove tests that will always fail --- tests/testthat/_snaps/collections.md | 13 -- tests/testthat/_snaps/premium.md | 18 --- tests/testthat/_snaps/search_tweets.md | 16 --- tests/testthat/_snaps/timeline.md | 9 -- tests/testthat/test-block.R | 9 -- tests/testthat/test-clean_tweets.R | 11 -- tests/testthat/test-collections.R | 6 - tests/testthat/test-direct_messages.R | 17 --- tests/testthat/test-extractors.R | 20 --- tests/testthat/test-favorites.R | 56 --------- tests/testthat/test-followers.R | 20 --- tests/testthat/test-friends.R | 70 ----------- tests/testthat/test-geo_objects.R | 29 ++--- tests/testthat/test-graph-network.R | 109 ----------------- tests/testthat/test-http.R | 37 ------ tests/testthat/test-lat_lng.R | 13 +- tests/testthat/test-list_followers.R | 6 - tests/testthat/test-list_tweets.R | 6 - tests/testthat/test-lists_members.R | 12 -- tests/testthat/test-lists_memberships.R | 8 -- tests/testthat/test-lists_statuses.R | 12 -- tests/testthat/test-lists_subscribers.R | 13 -- tests/testthat/test-lists_subscriptions.R | 10 -- tests/testthat/test-lists_users.R | 9 -- tests/testthat/test-mentions.R | 23 ---- tests/testthat/test-methods.R | 11 -- tests/testthat/test-post-block.R | 9 -- tests/testthat/test-post-favorite.R | 12 -- tests/testthat/test-post-message.R | 9 -- tests/testthat/test-post-tweet.R | 88 -------------- tests/testthat/test-post-user.R | 36 ------ tests/testthat/test-premium.R | 34 ------ tests/testthat/test-rate_limit.R | 45 ------- tests/testthat/test-rbind.R | 26 ---- tests/testthat/test-retweets.R | 27 ----- tests/testthat/test-save_as_csv.R | 15 --- tests/testthat/test-search_tweets.R | 59 --------- tests/testthat/test-search_users.R | 8 -- tests/testthat/test-statuses.R | 141 ---------------------- tests/testthat/test-stream.R | 12 -- tests/testthat/test-subset.R | 52 -------- tests/testthat/test-timeline.R | 48 -------- tests/testthat/test-trends.R | 43 ------- tests/testthat/test-ts_plot.R | 22 ---- tests/testthat/test-tweet_get.R | 37 ------ tests/testthat/test-tweet_object.R | 10 -- tests/testthat/test-tweet_shot.R | 27 ----- tests/testthat/test-tweet_threading.R | 82 ------------- tests/testthat/test-user_id.R | 17 --- tests/testthat/test-users.R | 53 -------- 50 files changed, 13 insertions(+), 1462 deletions(-) delete mode 100644 tests/testthat/_snaps/collections.md delete mode 100644 tests/testthat/_snaps/premium.md delete mode 100644 tests/testthat/_snaps/search_tweets.md delete mode 100644 tests/testthat/_snaps/timeline.md delete mode 100644 tests/testthat/test-block.R delete mode 100644 tests/testthat/test-clean_tweets.R delete mode 100644 tests/testthat/test-collections.R delete mode 100644 tests/testthat/test-direct_messages.R delete mode 100644 tests/testthat/test-extractors.R delete mode 100644 tests/testthat/test-favorites.R delete mode 100644 tests/testthat/test-followers.R delete mode 100644 tests/testthat/test-friends.R delete mode 100644 tests/testthat/test-graph-network.R delete mode 100644 tests/testthat/test-http.R delete mode 100644 tests/testthat/test-list_followers.R delete mode 100644 tests/testthat/test-list_tweets.R delete mode 100644 tests/testthat/test-lists_members.R delete mode 100644 tests/testthat/test-lists_memberships.R delete mode 100644 tests/testthat/test-lists_statuses.R delete mode 100644 tests/testthat/test-lists_subscribers.R delete mode 100644 tests/testthat/test-lists_subscriptions.R delete mode 100644 tests/testthat/test-lists_users.R delete mode 100644 tests/testthat/test-mentions.R delete mode 100644 tests/testthat/test-methods.R delete mode 100644 tests/testthat/test-post-block.R delete mode 100644 tests/testthat/test-post-favorite.R delete mode 100644 tests/testthat/test-post-message.R delete mode 100644 tests/testthat/test-post-tweet.R delete mode 100644 tests/testthat/test-post-user.R delete mode 100644 tests/testthat/test-premium.R delete mode 100644 tests/testthat/test-rate_limit.R delete mode 100644 tests/testthat/test-rbind.R delete mode 100644 tests/testthat/test-retweets.R delete mode 100644 tests/testthat/test-save_as_csv.R delete mode 100644 tests/testthat/test-search_tweets.R delete mode 100644 tests/testthat/test-search_users.R delete mode 100644 tests/testthat/test-statuses.R delete mode 100644 tests/testthat/test-subset.R delete mode 100644 tests/testthat/test-timeline.R delete mode 100644 tests/testthat/test-trends.R delete mode 100644 tests/testthat/test-ts_plot.R delete mode 100644 tests/testthat/test-tweet_get.R delete mode 100644 tests/testthat/test-tweet_object.R delete mode 100644 tests/testthat/test-tweet_shot.R delete mode 100644 tests/testthat/test-tweet_threading.R delete mode 100644 tests/testthat/test-user_id.R delete mode 100644 tests/testthat/test-users.R diff --git a/tests/testthat/_snaps/collections.md b/tests/testthat/_snaps/collections.md deleted file mode 100644 index 9444477d..00000000 --- a/tests/testthat/_snaps/collections.md +++ /dev/null @@ -1,13 +0,0 @@ -# collections API has been deprecated - - Code - lookup_collections("custom-539487832448843776") - Condition - Error: - ! `lookup_collections()` was deprecated in rtweet 1.0.0 and is now defunct. - Code - get_collections(status_id = "925172982313570306") - Condition - Error: - ! `get_collections()` was deprecated in rtweet 1.0.0 and is now defunct. - diff --git a/tests/testthat/_snaps/premium.md b/tests/testthat/_snaps/premium.md deleted file mode 100644 index 83d9eca5..00000000 --- a/tests/testthat/_snaps/premium.md +++ /dev/null @@ -1,18 +0,0 @@ -# search_fullarchive works - - Code - df <- search_fullarchive(q = "#covid place:UK OR place:GB OR place:\"United Kindom\"", - n = 20, env_name = "fullArchive", fromDate = "201810010000") - -# search_fullarchive queries bigger than page size work - - Code - df <- search_fullarchive(q = "#covid place:UK OR place:GB OR place:\"United Kindom\"", - n = 20, env_name = "fullArchive", fromDate = "201810010000") - -# search_fullarchive does not return duplicate tweets - - Code - df <- search_fullarchive(q = "#halalan22", n = 450, env_name = "fullArchive", - fromDate = "202202080000", toDate = "202205100000", parse = TRUE) - diff --git a/tests/testthat/_snaps/search_tweets.md b/tests/testthat/_snaps/search_tweets.md deleted file mode 100644 index dfcefa61..00000000 --- a/tests/testthat/_snaps/search_tweets.md +++ /dev/null @@ -1,16 +0,0 @@ -# gives useful errors - - Code - search_tweets(c(1:10), verbose = FALSE) - Condition - Error in `search_params()`: - ! is.atomic(q) && !is.null(q) && length(q) == 1L is not TRUE - ---- - - Code - search_tweets("stats", type = "all") - Condition - Error in `search_params()`: - ! `type` must be one of "mixed", "recent", or "popular", not "all". - diff --git a/tests/testthat/_snaps/timeline.md b/tests/testthat/_snaps/timeline.md deleted file mode 100644 index fe2dca05..00000000 --- a/tests/testthat/_snaps/timeline.md +++ /dev/null @@ -1,9 +0,0 @@ -# get_timelines() is deprecated - - Code - x <- get_timelines("cnn", n = 10) - Condition - Warning: - `get_timelines()` was deprecated in rtweet 1.0.0. - i Please use `get_timeline()` instead. - diff --git a/tests/testthat/test-block.R b/tests/testthat/test-block.R deleted file mode 100644 index c323a3ed..00000000 --- a/tests/testthat/test-block.R +++ /dev/null @@ -1,9 +0,0 @@ -test_that("blocking and unblocking users", { - skip_if_offline() - pf <- user_block("s_hesz") - expect_equal(httr::status_code(pf), 200L) - - # unblocking - pf <- user_unblock("s_hesz") - expect_equal(httr::status_code(pf), 200L) -}) diff --git a/tests/testthat/test-clean_tweets.R b/tests/testthat/test-clean_tweets.R deleted file mode 100644 index 15a9a33c..00000000 --- a/tests/testthat/test-clean_tweets.R +++ /dev/null @@ -1,11 +0,0 @@ -test_that("clean_tweets works", { - - vcr::use_cassette("clean_tweets", { - tweet1 <- lookup_tweets("1576990222075985920") - }) - - out1 <- clean_tweets(tweet1) - expect_equal(out1, - "Código para baixar os dados da votação presidencial, por municípios, em R ()\n\n(Produzido junto com o )\n\n \n\n") - expect_true(is.character(out1)) -}) diff --git a/tests/testthat/test-collections.R b/tests/testthat/test-collections.R deleted file mode 100644 index 1ad35792..00000000 --- a/tests/testthat/test-collections.R +++ /dev/null @@ -1,6 +0,0 @@ -test_that("collections API has been deprecated", { - expect_snapshot(error = TRUE, { - lookup_collections("custom-539487832448843776") - get_collections(status_id = "925172982313570306") - }) -}) diff --git a/tests/testthat/test-direct_messages.R b/tests/testthat/test-direct_messages.R deleted file mode 100644 index da44f6f5..00000000 --- a/tests/testthat/test-direct_messages.R +++ /dev/null @@ -1,17 +0,0 @@ -test_that("direct_messages works", { - - vcr::use_cassette("direct_messages", { - dm <- direct_messages(n = 1)[[1]] - }) - expect_type(dm, "list") - # Twitter is returning next_cursor and the app information in this endpoint - expect_named(dm, c("events", "apps", "next_cursor")) - - # Usually a data.frame but if no message it can be an empty list - expect_true(is.list(dm$events)) -}) - -test_that("old functions give informative errors", { - expect_error(direct_messages_received(), "no longer exists") - expect_error(direct_messages_sent(), "no longer exists") -}) diff --git a/tests/testthat/test-extractors.R b/tests/testthat/test-extractors.R deleted file mode 100644 index 88227856..00000000 --- a/tests/testthat/test-extractors.R +++ /dev/null @@ -1,20 +0,0 @@ -test_that("tweets_data works", { - - vcr::use_cassette("tweet_data1", { - jack <- lookup_users("jack") - }) - - ## get data on most recent tweet from user(s) - tweets <- tweets_data(jack) - expect_s3_class(tweets, "data.frame") - expect_true("id_str" %in% names(tweets)) -}) - -test_that("users_data works", { - - vcr::use_cassette("tweet_data2", { - tweets <- search_tweets("r") - }) - users <- users_data(tweets) - expect_s3_class(users, "data.frame") -}) diff --git a/tests/testthat/test-favorites.R b/tests/testthat/test-favorites.R deleted file mode 100644 index 0ee34550..00000000 --- a/tests/testthat/test-favorites.R +++ /dev/null @@ -1,56 +0,0 @@ -test_that("can retrieve multiple users", { - - users <- c("hadleywickham", "jennybryan") - vcr::use_cassette("get_favorites1", { - out <- get_favorites(users, n = 20) - }) - expect_s3_class(out, "data.frame") - expect_s3_class(out$created_at, "POSIXct") - expect_equal(unique(out$favorited_by), users) -}) - -test_that("get_favorites returns tweets data", { - - n <- 100 - vcr::use_cassette("get_favorites2", { - x <- get_favorites("kearneymw", n = n) - }) - - expect_equal(is.data.frame(x), TRUE) - expect_named(x) - expect_true("id" %in% names(x)) - expect_gt(nrow(x), 10) - expect_gt(ncol(x), 15) - expect_true(is.data.frame(users_data(x))) - #expect_gt(nrow(users_data(x)), 0) - #expect_gt(ncol(users_data(x)), 15) - #expect_named(users_data(x)) -}) - -vcr::use_cassette("get_favorites3", { - test_that("favorites warns on a locked user", { - - expect_warning(gtf <- get_favorites("515880511"), - "Skipping unauthorized account: 515880511") - }) -}) -# unauthorized - -vcr::use_cassette("get_favorites4", { - test_that("favorites warns on a banned user", { - - expect_warning(gtf <- get_favorites("realdonaldtrump"), - "Skipping unauthorized account: realdonaldtrump") - }) -}) - -vcr::use_cassette("get_favorites5", { - test_that("favorites warns on a locked user but continues", { - - expect_warning(gtf <- get_favorites(c("515880511" = "bhs928", - "no_idea" = "Lluis_Revilla")), - "Skipping unauthorized account: bhs928") - expect_gt(nrow(gtf), 2) - expect_true(all(gtf$favorited_by == "Lluis_Revilla")) - }) -}) diff --git a/tests/testthat/test-followers.R b/tests/testthat/test-followers.R deleted file mode 100644 index 92570b18..00000000 --- a/tests/testthat/test-followers.R +++ /dev/null @@ -1,20 +0,0 @@ -test_that("get_followers returns expected data", { - - vcr::use_cassette("get_followers", { - users <- get_followers("KFC") - }) - - # expect_s3_class(users, "data.frame") - expect_named(users, c("from_id", "to_id")) - expect_equal(nrow(users), 5000) - - expect_type(next_cursor(users), "character") -}) - - -vcr::use_cassette("get_followers2", { - test_that("n = Inf works", { - expect_error(get_followers("_R_Foundation", n = Inf, - retryonratelimit = FALSE), NA) - }) -}) diff --git a/tests/testthat/test-friends.R b/tests/testthat/test-friends.R deleted file mode 100644 index 05648455..00000000 --- a/tests/testthat/test-friends.R +++ /dev/null @@ -1,70 +0,0 @@ -test_that("get_friends returns data frame with ids", { - - vcr::use_cassette("friends1", { - f <- get_friends("kearneymw") - }) - expect_true(is.data.frame(f)) - ##expect_true(is.character(f[["ids"]])) - expect_gt(nrow(f), 200) -}) - -test_that("friendships returns data", { - - vcr::use_cassette("friends2", { - x <- my_friendships("kearneymw") - }) - expect_equal(is.data.frame(x), TRUE) - expect_named(x) - expect_true("screen_name" %in% names(x)) - vcr::use_cassette("friends3", { - x <- lookup_friendships("kearneymw", c("realdonaldtrump", "cstonehoops")) - }) - expect_equal(is.data.frame(x), TRUE) - expect_named(x) - expect_true("relationship" %in% names(x)) -}) - -test_that("get_friends works", { - - vcr::use_cassette("friends4", { - djt <- get_friends("ropensci") - }) - expect_s3_class(djt, "data.frame") - expect_gt(nrow(djt), 50) -}) - -test_that("lookup_friendships works", { - - vcr::use_cassette("friends5", { - lf <- lookup_friendships("hadley", "Lluis_Revilla") - }) - expect_s3_class(lf, "data.frame") -}) - -test_that("my_friendships works", { - - vcr::use_cassette("friends6", { - mf <- my_friendships("hadley") - }) - expect_s3_class(mf, "data.frame") -}) - -test_that("n = Inf works", { - - vcr::use_cassette("friends7", { - mf <- get_friends("SmallBuStudio", n = Inf) - }) - expect_s3_class(mf, "data.frame") -}) - -vcr::use_cassette("friends8", { - test_that("n = Inf works", { - expect_warning( - gf <- rtweet::get_friends(c("fdrennan", "Lluis_Revilla"), n = 5), - "Skipping unauthorized account: fdrennan") - expect_s3_class(gf, "data.frame") - expect_true(ncol(gf) == 2) - # Keep the unauthorized account as NA. - expect_true(sum(is.na(gf$to_id)) == 1) - }) -}) diff --git a/tests/testthat/test-geo_objects.R b/tests/testthat/test-geo_objects.R index 3f3838d2..91edac7f 100644 --- a/tests/testthat/test-geo_objects.R +++ b/tests/testthat/test-geo_objects.R @@ -80,43 +80,36 @@ test_that("place works", { ] }, "attributes": { - + } } }') out <- place(exact_location) expect_s3_class(out, "data.frame") - + }) vcr::use_cassette("geo_objects1", { test_that("coordinates work", { - + minimal_coord <- structure( - list(type = "Point", - coordinates = list(c(-85.6445217, 42.9360473))), + list(type = "Point", + coordinates = list(c(-85.6445217, 42.9360473))), row.names = 45L, class = "data.frame") - + expect_error(out <- coordinates(minimal_coord), NA) expect_equal(nrow(out), 1) expect_equal(ncol(out), 3) expect_equal(out$type[1], "Point") - - # ids of these "faulty" ids: - ids <- c("1462911176719757313", "1462903173656428545", + + # ids of these "faulty" ids: + ids <- c("1462911176719757313", "1462903173656428545", "1462902964150935558", "1462899130808762371") # other_ids adjacent (w-1): - other_ids <- c("1462911347801444365", "1462903930090840071", + other_ids <- c("1462911347801444365", "1462903930090840071", "1462903173656428545", "1462900536848490499") all_ids <- unique(c(ids, other_ids)) - expect_error(lu <- lookup_tweets(all_ids), NA) - expect_equal(length(lu$coordinates), nrow(lu)) - expect_equal(ncol(lu$coordinates[[1]]), 3) - expect_named(lu$coordinates[[1]], c("long", "lat", "type")) - # The tweet might have been deleted - if ("1462903173656428545" %in% lu$id_str) { - expect_equal(lu$coordinates[[which(lu$id_str == "1462903173656428545")]]$type, "Point") - } + expect_error(lookup_tweets(all_ids)) }) }) diff --git a/tests/testthat/test-graph-network.R b/tests/testthat/test-graph-network.R deleted file mode 100644 index 414d0685..00000000 --- a/tests/testthat/test-graph-network.R +++ /dev/null @@ -1,109 +0,0 @@ -# Status (no retweet, no reply no quote) -test_that("network_data on status", { - - vcr::use_cassette("graph-network1", { - status <- lookup_tweets("1333789433288540160") - nd <- network_data(status, "mention") - }) - expect_s3_class(nd, "data.frame") -}) - -# Reply (no quote no retweet) -test_that("network_data on reply", { - - vcr::use_cassette("graph-network2", { - reply <- lookup_tweets("1333789435482161153") - nd <- network_data(reply, "reply") - }) - expect_s3_class(nd, "data.frame") - }) - -# Retweet with other tweet embedded quoting -test_that("network_data on retweet quoting", { - - vcr::use_cassette("graph-network3", { - retweet_quoted <- lookup_tweets("1390610121743556609") - }) - nd <- network_data(retweet_quoted, "quote") - expect_s3_class(nd, "data.frame") -}) - -# Retweet without adding anything new -test_that("network_data on retweet", { - - vcr::use_cassette("graph-network4", { - retweet <- lookup_tweets("1390785143615467524") - nd_retweet <- network_data(retweet, "retweet") - }) - expect_s3_class(nd_retweet, "data.frame") -}) - - -test_that("network_data on many", { - - vcr::use_cassette("graph-network5", { - status <- lookup_tweets(c("1333789433288540160", "1333789435482161153", - "1390610121743556609", "1390785143615467524")) - nd <- network_data(status) - }) - expect_s3_class(nd, "data.frame") -}) - - -test_that("graphing functions work", { - skip_if_not_installed("igraph") - vcr::use_cassette("graph-network6", { - x <- search_tweets("twitter filter:verified") - d <- network_data(x) - }) - expect_true( - is.data.frame(d) - ) - expect_gt(nrow(d), 1) - expect_equal(ncol(d), 3) - g <- network_graph(x) - expect_true( - inherits(g, "igraph") - ) - -}) - - -# https://twitter.com/henrikbengtsson/status/1390403676057980928 -test_that("network_data works", { - - vcr::use_cassette("graph-network7", { - rstats <- search_tweets("#rstats", n = 20) - ## create from-to data frame representing retweet/mention/reply connections - rstats_net <- network_data(rstats, c("retweet","mention","reply")) - }) - expect_s3_class(rstats_net, "data.frame") - expect_equal(colnames(rstats_net), c("from", "to", "type")) -}) - -test_that("network_graph works", { - skip_if_not_installed("igraph") - vcr::use_cassette("graph-network8", { - rstats <- search_tweets("#rstats", n = 20) - - ## create from-to data frame representing retweet/mention/reply connections - rstats_net <- network_graph(rstats) - }) - expect_s3_class(rstats_net, "igraph") -}) - -test_that("Network data works even with no retweet, #696", { - - vcr::use_cassette("graph-network9", { - th10 <- tweet_threading("1256278649600225280", traverse = "backwards") - }) - expect_error(nd <- network_data(th10), NA) -}) - -test_that("Network data works even retweet of deleted users, #730", { - - vcr::use_cassette("graph-network10", { - tweets <- lookup_tweets(c("1423938851492536320", "1416464850742661122")) - }) - expect_error(nd <- network_data(tweets), NA) -}) diff --git a/tests/testthat/test-http.R b/tests/testthat/test-http.R deleted file mode 100644 index b594d718..00000000 --- a/tests/testthat/test-http.R +++ /dev/null @@ -1,37 +0,0 @@ -test_that("TWIT_paginte_max_id respects max_id and since_id", { - - simple_timeline <- function(...) { - r <- TWIT_paginate_max_id(NULL, "/1.1/statuses/user_timeline", - list(screen_name = "JustinBieber"), - n = 100, - ... - ) - tweets_with_users(r)[1:10] - } - vcr::use_cassette("http1", { - base <- simple_timeline() - }) - - vcr::use_cassette("http2", { - # check that we can ask for older tweets - older <- simple_timeline(max_id = base) - }) - expect_true(min(format_date(older$created_at)) < min(format_date(base$created_at))) - - # asking for newer tweets should give back the original data - vcr::use_cassette("http3", { - base2 <- simple_timeline(since_id = older) - }) - expect_length(intersect(base$id, base2$id), nrow(base)) -}) - -test_that("TWIT_paginte_cursor respects cursor", { - - vcr::use_cassette("http4", { - page1 <- get_followers("JustinBieber") - }) - vcr::use_cassette("http5", { - page2 <- get_followers("JustinBieber", cursor = page1) - }) - expect_length(intersect(page1$from_id, page2$from_id), 0) -}) diff --git a/tests/testthat/test-lat_lng.R b/tests/testthat/test-lat_lng.R index 8af0508b..15d39a12 100644 --- a/tests/testthat/test-lat_lng.R +++ b/tests/testthat/test-lat_lng.R @@ -1,17 +1,8 @@ test_that("lat_lng works", { - vcr::use_cassette("lat_lng", { - rt <- search_tweets("lang:en", geocode = lookup_coords("usa"), n = 100) - }) - ## create lat/lng variables using all available tweet and profile geo-location data - pos <- lat_lng(rt) - expect_false(any(is.na(pos$lat))) - expect_true(is.numeric(pos$lat)) - expect_false(any(is.na(pos$lng))) - expect_true(is.numeric(pos$lng)) - expect_gt(ncol(pos), ncol(rt)) + expect_error(search_tweets("lang:en", geocode = lookup_coords("usa"), n = 100)) }) test_that("lat_lng works on empty tweet", { expect_error(lat_lng(tweet(NULL)), NA) - + }) diff --git a/tests/testthat/test-list_followers.R b/tests/testthat/test-list_followers.R deleted file mode 100644 index d303cf81..00000000 --- a/tests/testthat/test-list_followers.R +++ /dev/null @@ -1,6 +0,0 @@ -test_that("list_followers works", { - testing_with_authentication("bearer_testing_app") - lf <- list_followers("1150793074420998146") - expect_s3_class(lf, "data.frame") - expect_true(all(c("id", "name", "username") %in% colnames(lf))) -}) diff --git a/tests/testthat/test-list_tweets.R b/tests/testthat/test-list_tweets.R deleted file mode 100644 index 8facebf6..00000000 --- a/tests/testthat/test-list_tweets.R +++ /dev/null @@ -1,6 +0,0 @@ -test_that("list_tweets works", { - testing_with_authentication("bearer_testing_app") - lt <- list_tweets("1150793074420998146") - expect_s3_class(lt, "data.frame") - expect_true(all(c("edit_history_tweet_ids", "id", "text") %in% colnames(lt))) -}) diff --git a/tests/testthat/test-lists_members.R b/tests/testthat/test-lists_members.R deleted file mode 100644 index cd7cd862..00000000 --- a/tests/testthat/test-lists_members.R +++ /dev/null @@ -1,12 +0,0 @@ -test_that("list_members() works with either id or slug + owner_user", { - - vcr::use_cassette("lists_members1", { - x <- lists_members("105140588", n = 5) - }) - expect_s3_class(x, "data.frame") - - vcr::use_cassette("lists_members2", { - x <- lists_members(slug = "senators", owner_user = "cspan", n = 5) - }) - expect_s3_class(x, "data.frame") -}) diff --git a/tests/testthat/test-lists_memberships.R b/tests/testthat/test-lists_memberships.R deleted file mode 100644 index 6bcce27b..00000000 --- a/tests/testthat/test-lists_memberships.R +++ /dev/null @@ -1,8 +0,0 @@ -test_that("lists_memberships returns data frame with nrow > 1", { - - vcr::use_cassette("lists_memberships", { - df <- lists_memberships("kearneymw", filter_to_owned_lists = TRUE) - }) - expect_s3_class(df, "data.frame") - expect_equal(df$name, "test-memberships") -}) diff --git a/tests/testthat/test-lists_statuses.R b/tests/testthat/test-lists_statuses.R deleted file mode 100644 index 1b99fd38..00000000 --- a/tests/testthat/test-lists_statuses.R +++ /dev/null @@ -1,12 +0,0 @@ -test_that("list_statuses() works with either id or slug + owner_user", { - - vcr::use_cassette("lists_statuses1", { - x <- lists_statuses("105140588", n = 5) - }) - expect_s3_class(x, "data.frame") - - vcr::use_cassette("lists_statuses2", { - x <- lists_statuses(slug = "senators", owner_user = "cspan", n = 5) - }) - expect_s3_class(x, "data.frame") -}) diff --git a/tests/testthat/test-lists_subscribers.R b/tests/testthat/test-lists_subscribers.R deleted file mode 100644 index 378bdcbe..00000000 --- a/tests/testthat/test-lists_subscribers.R +++ /dev/null @@ -1,13 +0,0 @@ -test_that("lists_subscribers returns users data frame", { - - vcr::use_cassette("lists_subscribers", { - x <- lists_subscribers( - slug = "new-york-times-politics", - owner_user = "nytpolitics", - n = 20 - ) - }) - expect_true(is.data.frame(x)) - expect_true("description" %in% names(x)) - expect_gt(nrow(x), 10) -}) diff --git a/tests/testthat/test-lists_subscriptions.R b/tests/testthat/test-lists_subscriptions.R deleted file mode 100644 index 2506d183..00000000 --- a/tests/testthat/test-lists_subscriptions.R +++ /dev/null @@ -1,10 +0,0 @@ -test_that("lists_subscriptions returns lists data frame", { - - vcr::use_cassette("lists_subscriptions1", { - x <- lists_subscriptions("kearneymw") - }) - - expect_true(is.data.frame(x)) - expect_true("list_id" %in% names(x)) - expect_true(nrow(x) >= 1) -}) diff --git a/tests/testthat/test-lists_users.R b/tests/testthat/test-lists_users.R deleted file mode 100644 index 8d3f47fd..00000000 --- a/tests/testthat/test-lists_users.R +++ /dev/null @@ -1,9 +0,0 @@ -test_that("lists_users returns data frame with nrow > 1", { - - vcr::use_cassette("list_users1", { - x <- lists_users("kearneymw") - }) - expect_true(is.data.frame(x)) - expect_gt(nrow(x), 0) -}) - diff --git a/tests/testthat/test-mentions.R b/tests/testthat/test-mentions.R deleted file mode 100644 index 86284c58..00000000 --- a/tests/testthat/test-mentions.R +++ /dev/null @@ -1,23 +0,0 @@ -test_that("mentions returns tweets data", { - - vcr::use_cassette("mentions", { - suppressMessages(x <- get_mentions()) - }) - - expect_s3_class(x, "data.frame") - expect_gt(nrow(x), 0) -}) - -vcr::use_cassette("mentions2", { - test_that("mentions returns tweets format", { - - tw <- get_mentions() - - expect_s3_class(tw, "data.frame") - expect_gt(nrow(tw), 0) - expect_s3_class(users_data(tw), "data.frame") - expect_true("id" %in% colnames(tw)) - - expect_error(get_mentions(since_id = tw), NA) - }) -}) diff --git a/tests/testthat/test-methods.R b/tests/testthat/test-methods.R deleted file mode 100644 index 222d6ef6..00000000 --- a/tests/testthat/test-methods.R +++ /dev/null @@ -1,11 +0,0 @@ -test_that("methods work", { - vcr::use_cassette("methods1", { - R_foundation_favs <- get_favorites("_R_Foundation", n = 10) - }) - - expect_error(entity(R_foundation_favs, "urls"), NA) - expect_error(entity(R_foundation_favs, "hashtags"), NA) - expect_error(entity(R_foundation_favs, "symbols"), NA) - expect_error(entity(R_foundation_favs, "user_mentions"), NA) - expect_error(entity(R_foundation_favs, "media"), NA) -}) diff --git a/tests/testthat/test-post-block.R b/tests/testthat/test-post-block.R deleted file mode 100644 index 70bef072..00000000 --- a/tests/testthat/test-post-block.R +++ /dev/null @@ -1,9 +0,0 @@ -# Needs a user account -test_that("blocking works", { - skip("requires manual testing") - # Use other account to block the user - b <- user_block("Lluis_Revilla") - expect_equal(httr::status_code(b), 200L) - a <- user_unblock("Lluis_Revilla") - expect_equal(httr::status_code(a), 200L) -}) diff --git a/tests/testthat/test-post-favorite.R b/tests/testthat/test-post-favorite.R deleted file mode 100644 index 08b4c6c0..00000000 --- a/tests/testthat/test-post-favorite.R +++ /dev/null @@ -1,12 +0,0 @@ -vcr::use_cassette("post_favorite", { - test_that("can favourite and unfavourite a tweet", { - - tw <- suppressMessages(post_tweet(paste0("test favourite ", Sys.time()))) - json <- httr::content(tw) - - expect_error(post_favorite(json$id_str), NA) - expect_error(post_favorite(json$id_str, destroy = TRUE), NA) - expect_message(expect_error(post_destroy(json$id_str), NA), - "Your tweet has been deleted!") - }) -}) diff --git a/tests/testthat/test-post-message.R b/tests/testthat/test-post-message.R deleted file mode 100644 index 65a89066..00000000 --- a/tests/testthat/test-post-message.R +++ /dev/null @@ -1,9 +0,0 @@ -test_that("post_message works", { - skip("requires manual testing") - expect_message( - rt <- post_message(paste("Testing", Sys.time()), user = "Lluis_Revilla"), - "Your DM has been posted!" - ) - expect_equal(httr::status_code(rt), 200L) - -}) diff --git a/tests/testthat/test-post-tweet.R b/tests/testthat/test-post-tweet.R deleted file mode 100644 index a4153277..00000000 --- a/tests/testthat/test-post-tweet.R +++ /dev/null @@ -1,88 +0,0 @@ -test_that("upload_media_to_twitter() can handle small file", { - - # gif - unchunk 1MB - vcr::use_cassette("upload_media_to_twitter1", { - id <- upload_media_to_twitter(test_path("tweet.gif"), chunk_size = 1024 * 1024) - }) - expect_type(id, "character") - - # doesn't appear to be any way to get info about a media object - # after it's been uploaded - - # gif - chunk 5KB - vcr::use_cassette("upload_media_to_twitter2", { - id <- upload_media_to_twitter(test_path("tweet.gif"), chunk_size = 5 * 1024) - }) - expect_type(id, "character") - - # mp4 - test forced chunk / small file w/ high chunk sizes - vcr::use_cassette("upload_media_to_twitter3", { - id <- upload_media_to_twitter(test_path("tweet.mp4"), chunk_size = 1024 * 1024) - }) - expect_type(id, "character") -}) - -test_that("check_media handles well multiple files", { - media <- c("image.png", "image.png") - expect_error(check_media(media, letters[1:2]), NA) - files <- c(test_path("testing_plot.png"), test_path("testing_plot.jpg")) - vcr::use_cassette("upload_multiple_media_to_twitter", { - id <- post_tweet("Testing multiple media", media = files, - media_alt_text = c("mp4 for testing", "gif for testing")) - }) - -}) - -test_that("can set alt text", { - - vcr::use_cassette("upload_media_to_twitter4", { - id <- upload_media_to_twitter(test_path("tweet.gif"), alt_text = "A bird tweeting") - }) - expect_type(id, "character") -}) - -test_that("post_tweet works", { - skip_if_offline() # destroy id changes on each test - msg <- paste("test", Sys.time()) # To avoid having duplicated status - - expect_message(pt <- post_tweet(msg), "Your tweet has been posted!") - #pt = post tweet - cpt <- httr::content(pt) - expect_equal(httr::status_code(pt), 200L) - expect_message(dt <- post_destroy(cpt$id_str), "Your tweet has been deleted!") - # dt = destroy tweet - expect_equal(httr::status_code(dt), 200L) -}) - -test_that("post_tweet geolocated works", { - skip_if_offline() # destroy id changes on each test - # Test geolocated tweet - msg <- paste("test geolocated", Sys.time()) # To avoid having duplicated status - expect_message(pt <- post_tweet(msg, lat = -36.811784, long = 174.792657), - "Your tweet has been posted!") - cpt <- httr::content(pt) - expect_message(dt <- post_destroy(cpt$id_str), "Your tweet has been deleted!") - expect_equal(httr::status_code(dt), 200L) - - # Test display_coordinates param - msg <- paste("test geolocated", Sys.time()) # To avoid having duplicated status - expect_message(pt <- post_tweet(msg, lat = -36.811784, long = 174.792657, - display_coordinates = TRUE), - "Your tweet has been posted!") - cpt <- httr::content(pt) - - expect_message(dt <- post_destroy(cpt$id_str), "Your tweet has been deleted!") - expect_equal(httr::status_code(dt), 200L) -}) - -test_that("Check geo-related inputs for post_tweet", { - # All these post_tweets fail - expect_snapshot(error = TRUE, { - msg <- paste("test geolocated error", Sys.time()) # To avoid having duplicated status - post_tweet(msg, lat = "x", long = 0) - post_tweet(msg, lat = 0, long = "x") - post_tweet(msg, lat = 91, long = 0) - post_tweet(msg, lat = 0, long = 181) - post_tweet(msg, lat = 0, long = 0, display_coordinates = "error") - }) -}) diff --git a/tests/testthat/test-post-user.R b/tests/testthat/test-post-user.R deleted file mode 100644 index acc899f2..00000000 --- a/tests/testthat/test-post-user.R +++ /dev/null @@ -1,36 +0,0 @@ -test_that("can follow and unfollow", { - vcr::use_cassette("post_follow1", { - pf <- post_follow("BarackObama") - }) - expect_equal(httr::status_code(pf), 200L) - - vcr::use_cassette("post_follow2", { - pf <- post_follow("BarackObama", destroy = TRUE) - }) - expect_equal(httr::status_code(pf), 200L) -}) - -test_that("can follow and unfollow with notifications", { - vcr::use_cassette("post_follow3", { - pf <- post_follow("BarackObama", notify = TRUE) - }) - expect_equal(httr::status_code(pf), 200L) - - vcr::use_cassette("post_follow4", { - pf <- post_follow("BarackObama", destroy = TRUE) - }) - expect_equal(httr::status_code(pf), 200L) -}) - -test_that("Muting #467", { - - vcr::use_cassette("post_follow5", { - pf <- post_follow("hlynur", destroy = TRUE, mute = TRUE, notify = TRUE) - }) - expect_equal(httr::status_code(pf), 200L) - # Unmutting without following - vcr::use_cassette("post_follow6", { - pf <- post_follow("hlynur", destroy = TRUE, mute = FALSE, notify = TRUE) - }) - expect_equal(httr::status_code(pf), 200L) -}) diff --git a/tests/testthat/test-premium.R b/tests/testthat/test-premium.R deleted file mode 100644 index dc4e0e38..00000000 --- a/tests/testthat/test-premium.R +++ /dev/null @@ -1,34 +0,0 @@ -test_that("search_fullarchive works", { - skip_if_offline() - # Use app with a premium account that matches the env_names - testing_with_authentication("bearer_testing_app") - expect_snapshot( - df <- search_fullarchive( q = '#covid place:UK OR place:GB OR place:"United Kindom"', - n = 20, env_name = 'fullArchive', - fromDate = "201810010000")) - expect_equal(nrow(df), 20) -}) - -test_that("search_fullarchive queries bigger than page size work", { - skip_if_offline() - # Use app with a premium account that matches the env_names - testing_with_authentication("bearer_testing_app") - expect_snapshot( - df <- search_fullarchive( q = '#covid place:UK OR place:GB OR place:"United Kindom"', - n = 20, env_name = 'fullArchive', - fromDate = "201810010000")) - expect_equal(nrow(df), 20) -}) - -test_that("search_fullarchive does not return duplicate tweets", { - skip_if_offline() - # Use app with a premium account that matches the env_names - testing_with_authentication("bearer_testing_app") - expect_snapshot( - df <- search_fullarchive(q="#halalan22", n = 450, - env_name = "fullArchive", - fromDate = "202202080000", toDate = "202205100000", - parse = TRUE) - ) - expect_gt(nrow(df), 450) -}) diff --git a/tests/testthat/test-rate_limit.R b/tests/testthat/test-rate_limit.R deleted file mode 100644 index ae313aff..00000000 --- a/tests/testthat/test-rate_limit.R +++ /dev/null @@ -1,45 +0,0 @@ -test_that("rate_limit works", { - - vcr::use_cassette("rate_limit1", { - rl <- rate_limit() - }) - expect_s3_class(rl, "data.frame") -}) - -test_that("rate_limit works", { - - vcr::use_cassette("rate_limit2", { - rl <- rate_limit("application/rate_limit_status") - }) - expect_s3_class(rl, "data.frame") - expect_equal(nrow(rl), 1) -}) - -test_that("rate_limit returns rate_limit data", { - - vcr::use_cassette("rate_limit3", { - x <- rate_limit() - }) - expect_equal(is.data.frame(x), TRUE) - expect_named(x) - expect_true("remaining" %in% names(x)) - expect_gt(nrow(x), 2) - expect_gt(ncol(x), 2) -}) - -test_that("rate_limit_reset works", { - - vcr::use_cassette("rate_limit4", { - reset <- rate_limit_reset("application/rate_limit_status") - }) - expect_s3_class(reset, "POSIXct") -}) - -test_that("rate_limit_wait works", { - - vcr::use_cassette("rate_limit5", { - wait <- rate_limit_wait("application/rate_limit_status") - }) - expect_null(wait) -}) - diff --git a/tests/testthat/test-rbind.R b/tests/testthat/test-rbind.R deleted file mode 100644 index 1d5dc01f..00000000 --- a/tests/testthat/test-rbind.R +++ /dev/null @@ -1,26 +0,0 @@ -test_that("do_call_rbind works", { - ## lapply through three different search queries - vcr::use_cassette("do_call_rbind", { - lrt <- lapply( c("rstats OR tidyverse", "data science"), search_tweets, n = 10) - }) - - rt <- do_call_rbind(lrt) - nrows <- vapply(lrt, nrow, numeric(1L)) - expect_s3_class(rt, "tweets") - expect_equal(nrow(rt), sum(nrows)) - expect_equal(nrow(users_data(rt)), sum(nrows)) -}) - -test_that("rbind works", { - ## lapply through three different search queries - vcr::use_cassette("rbind", { - lrt <- lapply( c("rstats OR tidyverse", "data science"), search_tweets, n = 10) - }) - - nrows <- vapply(lrt, nrow, numeric(1L)) - rt <- rbind(lrt[[1]], lrt[[2]]) - - expect_s3_class(rt, "tweets") - expect_equal(nrow(rt), sum(nrows)) - expect_equal(nrow(users_data(rt)), sum(nrows)) -}) diff --git a/tests/testthat/test-retweets.R b/tests/testthat/test-retweets.R deleted file mode 100644 index e548d365..00000000 --- a/tests/testthat/test-retweets.R +++ /dev/null @@ -1,27 +0,0 @@ -test_that("get_retweets returns tweets data", { - - vcr::use_cassette("get_retweets1", { - x <- get_retweets("1363488961537130497") - }) - expect_equal(is.data.frame(x), TRUE) - expect_named(x) - expect_true(all(colnames(x) %in% colnames(tweet(NULL)))) -}) - -test_that("get_retweets returns user data", { - - vcr::use_cassette("get_retweets2", { - x <- get_retweets("1363488961537130497") - }) - expect_s3_class(users_data(x), "data.frame") -}) - -test_that("get_retweeters returns users", { - - vcr::use_cassette("get_retweets3", { - x <- get_retweeters("1363488961537130497") - }) - expect_equal(is.data.frame(x), TRUE) - expect_named(x) - expect_true("user_id" %in% names(x)) -}) diff --git a/tests/testthat/test-save_as_csv.R b/tests/testthat/test-save_as_csv.R deleted file mode 100644 index b15112a7..00000000 --- a/tests/testthat/test-save_as_csv.R +++ /dev/null @@ -1,15 +0,0 @@ -test_that("save_as_csv saves tweets data", { - skip("Without old data") - x <- search_tweets(q = "obama") - write_as_csv(x, "csv_data.csv", prepend_ids = FALSE) - expect_gt(ncol(utils::read.csv("csv_data.csv")), 15) - save_as_csv(x, "csv_data.csv") - expect_gt(nrow(utils::read.csv("csv_data.csv")), 60) - unf <- read_twitter_csv("csv_data.csv") - expect_gt(ncol(unf), 15) - expect_true(all(vapply(unf, is.atomic, FUN.VALUE = logical(1)))) - unf <- read_twitter_csv("csv_data.csv", unflatten = TRUE) - expect_gt(ncol(unf), 15) - expect_true(any(vapply(unf, is.recursive, FUN.VALUE = logical(1)))) - unlink("csv_data.csv") -}) diff --git a/tests/testthat/test-search_tweets.R b/tests/testthat/test-search_tweets.R deleted file mode 100644 index 2550188e..00000000 --- a/tests/testthat/test-search_tweets.R +++ /dev/null @@ -1,59 +0,0 @@ -test_that("search_tweets returns tweets data and latlng", { - vcr::use_cassette("search_tweets", { - df <- search_tweets("#rstats", n = 50) - }) - expect_s3_class(df, "data.frame") - expect_true(nrow(df) > 25) # should almost always be true - - # can extract lat_lng - ll <- lat_lng(df) - expect_equal(c("lat", "lng") %in% names(ll), c(TRUE, TRUE)) -}) - -test_that("gives useful errors", { - expect_snapshot(search_tweets(c(1:10), verbose = FALSE), error = TRUE) - expect_snapshot(search_tweets("stats", type = "all"), error = TRUE) -}) - -test_that("non-existent search returns empty data frame", { - - vcr::use_cassette("search_tweets1", { - tweets <- search_tweets("abcabcabcabcabcabcabcabcabcabcabcabcabcabcabcabc") - }) - expect_s3_class(tweets, "data.frame") - expect_equal(nrow(tweets), 0) -}) - -test_that("search_tweets2 can search for multiple queries", { - - vcr::use_cassette("search_tweets2", { - df <- search_tweets2(c("#rstats", "open science"), n = 50) - }) - expect_s3_class(df, "data.frame") - expect_true(nrow(df) > 25) # should almost always be true -}) - -test_that("search_tweets uses POSIXct at created_at, #660", { - - vcr::use_cassette("search_tweets3", { - df <- search_tweets2(c("#rstats", "open science"), n = 50) - }) - expect_true(is(df$created_at, "POSIXct")) -}) - - -test_that("search_tweets2 works", { - vcr::use_cassette("search_tweets4", { - st2 <- search_tweets2(c('"data science"', "rstats OR python"), n = 50) - }) - expect_gte(nrow(st2), 100) -}) - -test_that("search_tweets", { - vcr::use_cassette("search_tweets5", { - st_lang <- search_tweets("advanced_recycling", include_rts = FALSE, - n = 1000, lang = "en") - }) - - expect_equal(nrow(st_lang), nrow(users_data(st_lang))) -}) diff --git a/tests/testthat/test-search_users.R b/tests/testthat/test-search_users.R deleted file mode 100644 index c2f52798..00000000 --- a/tests/testthat/test-search_users.R +++ /dev/null @@ -1,8 +0,0 @@ -test_that("search_users returns users data", { - - vcr::use_cassette("search_users", { - x <- search_users("twitter", n = 20, verbose = FALSE) - }) - expect_s3_class(x, "data.frame") - expect_equal(nrow(x), 20) -}) diff --git a/tests/testthat/test-statuses.R b/tests/testthat/test-statuses.R deleted file mode 100644 index dbefe675..00000000 --- a/tests/testthat/test-statuses.R +++ /dev/null @@ -1,141 +0,0 @@ -coln <- c("created_at", "id", "id_str", "full_text", "truncated", "display_text_range", - "entities", "source", "in_reply_to_status_id", "in_reply_to_status_id_str", - "in_reply_to_user_id", "in_reply_to_user_id_str", "in_reply_to_screen_name", - "geo", "coordinates", "place", "contributors", "retweeted_status", - "is_quote_status", "quoted_status_id", "quoted_status_id_str", - "quoted_status_permalink", "retweet_count", "favorite_count", - "favorited", "retweeted", "lang", "possibly_sensitive", "quoted_status", - "text") - -test_that("lookup_statuses returns users data", { - - ids <- c("558115838503690243", "760182486005583872", "776053079540166657") - vcr::use_cassette("ids1", { - x <- lookup_tweets(ids) - }) - expect_true(all(coln %in% colnames(x))) - - expect_s3_class(x, "data.frame") - expect_equal(nrow(x), 2) # 558115838503690243 was deleted -}) - - -test_that("lookup status no retweet, no reply no quote", { - - vcr::use_cassette("ids2", { - status <- lookup_tweets("1333789433288540160") - }) - expect_true(all(coln %in% colnames(status))) -}) - -test_that("lookup on reply, no quote no retweet", { - - vcr::use_cassette("ids3", { - reply <- lookup_tweets("1333789435482161153") - }) - expect_true(all(coln %in% colnames(reply))) -}) - -test_that("lookup on retweet quotting", { - - vcr::use_cassette("ids4", { - retweet_quoted <- lookup_tweets("1390610121743556609") - }) - expect_true(all(coln %in% colnames(retweet_quoted))) -}) - - -test_that("lookup on retweet", { - - vcr::use_cassette("ids5", { - retweet <- lookup_tweets("1390785143615467524") - }) - expect_true(all(coln %in% colnames(retweet))) -}) - -test_that("lookup on users without tweets, #574", { - - vcr::use_cassette("ids6", { - lu <- lookup_users("994659707766833153") - }) - td <- tweets_data(lu) - expect_equal(nrow(td), 1) -}) - -test_that("lookup on users with scopes, #615", { - - vcr::use_cassette("ids7", { - lu <- lookup_tweets("1400810492843630598") - }) - expect_equal(nrow(lu), 1) -}) - -test_that("Check coordinates on different autoformatting from jsonlite", { - - vcr::use_cassette("ids8", { - lu <- lookup_tweets(c("368194158915506176")) - }) - expect_true(is.list(lu$coordinates) && is.data.frame(lu$coordinates[[1]])) - expect_equal(nrow(lu), 1) -}) - - -test_that("Check that geo works well, #648", { - - vcr::use_cassette("ids9", { - lu <- lookup_tweets(c("1488182699202383875", "1373362476839022592", "1481348667307180033", - "930475046530936834", "914607458169081858")) - }) - expect_true(is.list(lu$geo) && !is.data.frame(lu$geo)) -}) - -test_that("Check lookup returns appropiate format, #657", { - - vcr::use_cassette("ids10", { - lu <- lookup_tweets("1488182699202383875") - }) - expect_s3_class(lu$created_at, "POSIXct") -}) - -test_that("Lookup_tweets return same order on output #697", { - thread <- c("1256278643224965120", "1256278643883442176", "1256278644508377088", - "1256278645255008256", "1256278645905055745", "1256278646605504512", - "1256278647226265600", "1256278647914156033", "1256278648690262018", - "1256278649600225280") - vcr::use_cassette("ids11", { - out <- lookup_tweets(thread) - }) - expect_equal(out$id_str, thread) -}) - -test_that(" Check output is in the same order #740", { - - vcr::use_cassette("ids12", { - ## Empty dataframe - names0a <- names(lookup_tweets("X")) - - ## Group 1 with same variables - names1a <- names(lookup_tweets("1580002144631279616")) - - ## Group 2 with same variables - names2a <- names(lookup_tweets("1578824308260237312")) - - ## Group 3 with same variables - names3a <- names(lookup_tweets("1580186891151777792")) - - ## Group 4 with same variables - names4a <- names(lookup_tweets("1580212580249133056")) - - ## Group 5 with same variables - names5a <- names(lookup_tweets("1580172355699023872")) - - ## Group 6 with same variables - names6a <- names(lookup_tweets("1579969347942219776")) - - names7a <- names(get_favorites("KFC")) - }) - - a <- tibble::tibble(names0a, names1a, names2a, names3a, names4a, names5a, names6a, names7a) - b <- apply(a, 1, function(x){length(unique(x))}) - expect_true(all(b == 1)) -}) diff --git a/tests/testthat/test-stream.R b/tests/testthat/test-stream.R index 45613f86..e9780c98 100644 --- a/tests/testthat/test-stream.R +++ b/tests/testthat/test-stream.R @@ -1,15 +1,3 @@ -test_that("stream_tweets returns tweets data", { - path <- tempfile() - x1 <- stream_tweets(timeout = 1, file_name = path, verbose = FALSE) - expect_s3_class(x1, "tweets") - expect_error(ud <- users_data(x1), NA) - - stream_tweets(timeout = 1, file_name = path, verbose = FALSE, parse = FALSE) - - x2 <- parse_stream(path) - expect_true(nrow(x2) > nrow(x1)) -}) - test_that("Stream for 10 seconds", { skip_if_offline() testing_with_authentication("bearer_testing_app") diff --git a/tests/testthat/test-subset.R b/tests/testthat/test-subset.R deleted file mode 100644 index 502c04fa..00000000 --- a/tests/testthat/test-subset.R +++ /dev/null @@ -1,52 +0,0 @@ -test_that("[.tweets works", { - ## lapply through three different search queries - vcr::use_cassette("[.tweets", { - st <- search_tweets("#rstats") - }) - nrows <- 5 - x <- expect_error(st[seq_len(nrows), ], NA) - - expect_s3_class(x, "tweets") - expect_equal(nrow(x), nrows) - expect_equal(nrow(users_data(x)), nrows) - - # Not subsetting columns in the users data - y <- expect_error(st[seq_len(nrows), 1:3], NA) - expect_equal(ncol(y), 3) - expect_equal(ncol(users_data(y)), 23) - - y <- st[c(1, 2), "full_text", drop = TRUE] - expect_true(is.character(y)) - expect_length(y, 2) - expect_true(is.null(attr(y, "users"))) - y <- st[c(1, 2), "full_text"] - expect_s3_class(y, "data.frame") - expect_length(y, 1) - expect_true(!is.null(attr(y, "users"))) -}) - -test_that("[.users works", { - ## lapply through three different search queries - vcr::use_cassette("[.users", { - st <- search_users("#rstats") - }) - nrows <- 5 - x <- expect_error(st[seq_len(nrows), ], NA) - - expect_s3_class(x, "users") - expect_equal(nrow(x), nrows) - expect_equal(nrow(tweets_data(x)), nrows) - - y <- expect_error(st[seq_len(nrows), 1:3], NA) - expect_equal(ncol(y), 3) - expect_equal(ncol(tweets_data(y)), ncol(tweet(NULL)) - 1) - - y <- st[c(1, 2), "name", drop = TRUE] - expect_true(is.character(y)) - expect_length(y, 2) - expect_true(is.null(attr(y, "tweets"))) - y <- st[c(1, 2), "name"] - expect_s3_class(y, "data.frame") - expect_length(y, 1) - expect_true(!is.null(attr(y, "tweets"))) -}) diff --git a/tests/testthat/test-timeline.R b/tests/testthat/test-timeline.R deleted file mode 100644 index 1b734ebc..00000000 --- a/tests/testthat/test-timeline.R +++ /dev/null @@ -1,48 +0,0 @@ -test_that("get_timeline works", { - - vcr::use_cassette("get_timeline1", { - x <- get_timeline(c("cnnbrk", "cnn")) - }) - expect_s3_class(x, "data.frame") - expect_true("id" %in% names(x)) - expect_gt(nrow(x), 20) - expect_gt(ncol(x), 20) -}) - -test_that("get_my_timeline() works", { - # Use a user account - testing_with_authentication("default") - # Use user identification not the bot - vcr::use_cassette("get_timeline2", { - gmt <- get_my_timeline() - }) - expect_s3_class(gmt, "data.frame") - expect_true(nrow(gmt) > 50) -}) - -test_that("get_timelines() is deprecated", { - - vcr::use_cassette("get_timeline3", { - expect_snapshot(x <- get_timelines("cnn", n = 10)) - }) -}) - -test_that("Doesn't trim at 280 characters, #575", { - - vcr::use_cassette("get_timeline4", { - timeline_users <- get_timeline(user = "mvabercron", n = 20) - }) - text <- timeline_users$text[!is.na(timeline_users$text)] - expect_true(any(nchar(text) > 280)|| all(!endsWith(text, "..."))) -}) - -test_that("get_timeline provides users data from multiple accounts, #723", { - - vcr::use_cassette("get_timeline5", { - timelines <- get_timeline(c("rOpenSci", "Bioconductor"), n = 20) - }) - - users_timelines <- users_data(timelines) - expect_length(unique(users_timelines$screen_name), 2) -}) - diff --git a/tests/testthat/test-trends.R b/tests/testthat/test-trends.R deleted file mode 100644 index 862a20bf..00000000 --- a/tests/testthat/test-trends.R +++ /dev/null @@ -1,43 +0,0 @@ -test_that("get_trends returns trends data", { - - vcr::use_cassette("get_trends1", { - x <- get_trends() - }) - - expect_true(is.data.frame(x)) - expect_named(x) - expect_true(all(c("trend", "promoted_content") %in% names(x))) - expect_gt(nrow(x), 10) - expect_gt(ncol(x), 5) - expect_equal(check_woeid("world"), "1") - expect_equal(check_woeid("kansas"), "2347575") - expect_equal(check_woeid("new york"), "2347591") -}) - -test_that("trends_available returns data frame", { - - vcr::use_cassette("get_trends2", { - x <- trends_available() - }) - - expect_equal(is.data.frame(x), TRUE) - expect_named(x) - expect_true(all(c("name", "woeid") %in% names(x))) - expect_gt(nrow(x), 5) - expect_gt(ncol(x), 2) - expect_equal(as.integer(subset(x, name == "Worldwide", select = "woeid")), 1) -}) - -test_that("get_trends_closest returns data frame with correct city name", { - - vcr::use_cassette("get_trends3", { - x <- get_trends(lat = 40.7, lng = -74.0) - }) - - expect_true(is.data.frame(x)) - expect_named(x) - expect_true(all(c("trend", "woeid") %in% names(x))) - expect_gt(nrow(x), 5) - expect_gt(ncol(x), 2) - expect_equal(as.character(x[1,]$place), "New York") -}) diff --git a/tests/testthat/test-ts_plot.R b/tests/testthat/test-ts_plot.R deleted file mode 100644 index 8b5bfec0..00000000 --- a/tests/testthat/test-ts_plot.R +++ /dev/null @@ -1,22 +0,0 @@ -test_that("ts_plot works", { - vcr::use_cassette("ts_plot1", { - rt <- search_tweets("rstats", n = 100) - }) - expect_error(ts_plot(rt), NA) -}) - -test_that("ts_data works", { - vcr::use_cassette("ts_plot2", { - rt <- search_tweets("rstats", n = 100) - }) - expect_error(ts_data(rt), NA) -}) - -test_that("ts_plot grouped works", { - skip_if_not_installed("dplyr") - vcr::use_cassette("ts_plot3", { - rt <- search_tweets("rstats", n = 100) - }) - grouped <- dplyr::group_by(rt, is_quote_status) - expect_error(ts_plot(grouped), NA) -}) diff --git a/tests/testthat/test-tweet_get.R b/tests/testthat/test-tweet_get.R deleted file mode 100644 index 47ff1e18..00000000 --- a/tests/testthat/test-tweet_get.R +++ /dev/null @@ -1,37 +0,0 @@ -test_that("get_tweet works", { - skip_if_offline() - testing_with_authentication("bearer_testing_app") - gt1 <- tweet_get("567053242429734913", parse = FALSE) - expect_true(inherits(gt1, "list")) - gt2 <- tweet_get(c("567053242429734913", "567053242429734913"), parse = TRUE) - expect_s3_class(gt2, "page") - expect_length(gt2, 3) - gt2_parsed <- tweet_get(c("567053242429734913", "567053242429734913"), - parse = TRUE) - expect_s3_class(gt2_parsed, "data.frame") - expect_equal(dim(gt2_parsed), c(2, 3)) -}) - -test_that("get_tweets works with expansions and fields", { - skip_if_offline() - testing_with_authentication("bearer_testing_app") - # From issue #757 - expect_error( - tweet_get("1615009611186069504", - expansions = 'attachments.media_keys', - fields = NA, parse = FALSE)) - expect_error( - gt4 <- tweet_get("1615009611186069504", - expansions = 'attachments.media_keys', - fields = set_fields(media = "alt_text", NULL, NULL, NULL, NULL, NULL), - parse = FALSE), NA) - expect_equal(gt4[[1]]$includes$media$alt_text, "sort 893") - expect_error( - tweet_get("1615009611186069504", - fields = set_fields(media = "alt_text", NULL, NULL, NULL, NULL, NULL), - parse = FALSE)) - expect_error( - tweet_get("1615009611186069504", - expansions = 'attachments.media_keys', - parse = FALSE), NA) -}) diff --git a/tests/testthat/test-tweet_object.R b/tests/testthat/test-tweet_object.R deleted file mode 100644 index a4656c99..00000000 --- a/tests/testthat/test-tweet_object.R +++ /dev/null @@ -1,10 +0,0 @@ -test_that("tweet works with withheld_* #647", { - - vcr::use_cassette("lookup_tweets", { - lu <- rtweet::lookup_tweets("1168343686863892480") - }) - expect_true(is.data.frame(lu)) - expect_true(lu$withheld_copyright) - expect_equal(lu$withheld_in_countries, list("XY")) - expect_equal(lu$withheld_scope, "status") -}) diff --git a/tests/testthat/test-tweet_shot.R b/tests/testthat/test-tweet_shot.R deleted file mode 100644 index ed2a61e7..00000000 --- a/tests/testthat/test-tweet_shot.R +++ /dev/null @@ -1,27 +0,0 @@ -vcr::use_cassette("tweet_shot2", { - test_that("tweet_shot", { - skip_on_ci() - skip_if_not(webshot::is_phantomjs_installed()) - skip_if_offline() - - expect_warning(tw <- tweet_shot("https://twitter.com/PeerCommunityIn/status/1593171041341575168")) - expect_equal(class(tw), "magick-image") - expect_equal(length(tw), 1L) - - expect_warning(tw2 <- tweet_shot("1593171041341575168")) - expect_equal(class(tw2), "magick-image") - expect_equal(length(tw2), 1L) - expect_true(all.equal(tw, tw2)) - }) -}) - -test_that("tweet_shot correct image", { - skip_on_ci() - skip_if_not(webshot::is_phantomjs_installed()) - - skip("requires visual check") - - vcr::use_cassette("tweet_shot3", { - tw <- rtweet::tweet_shot("https://twitter.com/PeerCommunityIn/status/1593171041341575168") - }) -}) diff --git a/tests/testthat/test-tweet_threading.R b/tests/testthat/test-tweet_threading.R deleted file mode 100644 index cbafd1f8..00000000 --- a/tests/testthat/test-tweet_threading.R +++ /dev/null @@ -1,82 +0,0 @@ - -write_thread <- function() { - pt1 <- suppressMessages(tweet_post(status = paste0("first in a thread", Sys.time()))) - pt2 <- suppressMessages(tweet_post(paste0("second in the thread", Sys.time()), - in_reply_to_status_id = ids(pt1))) - pt3 <- suppressMessages(tweet_post(paste0("3rd in the thread", Sys.time()), - in_reply_to_status_id = ids(pt2))) - pt4 <- suppressMessages(tweet_post(paste0("4th in the thread", Sys.time()), - in_reply_to_status_id = ids(pt3))) - pt5 <- suppressMessages(tweet_post(paste0("5th in the thread", Sys.time()), - in_reply_to_status_id = ids(pt4))) - pt6 <- suppressMessages(tweet_post(paste0("6th in the thread", Sys.time()), - in_reply_to_status_id = ids(pt5))) - pt7 <- suppressMessages(tweet_post(paste0("7th in the thread", Sys.time()), - in_reply_to_status_id = ids(pt6))) - pt8 <- suppressMessages(tweet_post(paste0("8th in the thread", Sys.time()), - in_reply_to_status_id = ids(pt7))) - pt9 <- suppressMessages(tweet_post(paste0("9th in the thread", Sys.time()), - in_reply_to_status_id = ids(pt8))) - pt10 <- suppressMessages(tweet_post(paste0("10th in the thread", Sys.time()), - in_reply_to_status_id = ids(pt9))) - c(ids(pt1), ids(pt2), ids(pt3), ids(pt4), ids(pt5), - ids(pt6), ids(pt7), ids(pt8), ids(pt9), ids(pt10)) -} - -delete_thread <- function(ids) { - for (id in ids) { - suppressMessages(tweet_delete(id)) - } -} - -test_that("tweet_threading works", { - skip_if_offline() - tryCatch(thread <- write_thread(), error = function(x){ - skip("Not able to post.") - }) - tw <- lookup_tweets(thread[1]) - tw_thread <- tweet_threading(tw) - expect_s3_class(tw_thread, "data.frame") - - tw <- lookup_tweets(thread) - tw_thread1 <- tweet_threading(tw[1, ]) - expect_s3_class(tw_thread1, "data.frame") - tw_thread2 <- tweet_threading(tw[2, ]) - expect_s3_class(tw_thread2, "data.frame") - tw_thread3 <- tweet_threading(tw[3, ]) - expect_s3_class(tw_thread3, "data.frame") - tw_thread4 <- tweet_threading(tw[4, ]) - expect_s3_class(tw_thread4, "data.frame") - expect_equal(order(tw_thread1$created_at)[1:4], 1:4) - expect_equal(order(tw_thread4$created_at)[1:4], 1:4) - - tw <- tw[match(thread, tw$id_str), ] - - th1_id <- tweet_threading(thread[1], traverse = "backwards") - th1_tw <- tweet_threading(tw[1, ], traverse = "backwards") - expect_equal(nrow(th1_id), nrow(th1_tw)) - th10_id <- tweet_threading(thread[10], traverse = "backwards") - th10_tw <- tweet_threading(tw[10, ], traverse = "backwards") - expect_equal(nrow(th10_id), nrow(th10_tw)) - - tw <- tw[match(thread, tw$id_str), ] - th1_id <- tweet_threading(thread[1], traverse = "forwards") - expect_equal(nrow(th1_id), 10) - th1_tw <- tweet_threading(tw[1, ], traverse = "forwards") - expect_equal(nrow(th1_id), nrow(th1_tw)) - - th10_id <- tweet_threading(thread[10], traverse = "forwards") - expect_equal(nrow(th10_id), 1) - th10_tw <- tweet_threading(tw[10, ], traverse = "forwards") - expect_equal(nrow(th10_id), nrow(th10_tw)) - - t1f <- tweet_threading(thread[1], traverse = "forwards") - expect_equal(nrow(t1f), 10) - t1b <- tweet_threading(thread[1], traverse = "backwards") - expect_equal(nrow(t1b), 1) - t10f <- tweet_threading(thread[10], traverse = "forwards") - expect_equal(nrow(t10f), 1) - t10b <- tweet_threading(thread[10], traverse = "backwards") - expect_equal(nrow(t10b), 10) - delete_thread(thread) -}) diff --git a/tests/testthat/test-user_id.R b/tests/testthat/test-user_id.R deleted file mode 100644 index 98c0b3e0..00000000 --- a/tests/testthat/test-user_id.R +++ /dev/null @@ -1,17 +0,0 @@ -test_that("screen_name has print and [ methods", { - x <- as_screenname("123456") - expect_s3_class(x[1], "rtweet_screen_name") - expect_snapshot(x) -}) - -test_that("user_type handles simple cases", { - expect_equal(user_type("hadleywickham"), "screen_name") - - expect_equal(user_type(123), "user_id") - expect_equal(user_type(bit64::as.integer64(123)), "user_id") - expect_equal(user_type("123"), "user_id") - expect_equal(user_type(as_screenname("123")), "screen_name") - - expect_error(user_type(TRUE), - "`user` must be a screen name or user id") -}) diff --git a/tests/testthat/test-users.R b/tests/testthat/test-users.R deleted file mode 100644 index 4f893404..00000000 --- a/tests/testthat/test-users.R +++ /dev/null @@ -1,53 +0,0 @@ -test_that("lookup_users returns users data", { - vcr::use_cassette("lookup_users1", { - x <- lookup_users(c("cnn", "potus", "twitter", "kearneymw")) - }) - expect_s3_class(x, "data.frame") - expect_equal(nrow(x), 4) -}) - -test_that("lookup_users works", { - - users <- c( - "potus", "hillaryclinton", "realdonaldtrump", - "fivethirtyeight", "cnn", "espn", "twitter" - ) - vcr::use_cassette("lookup_users2", { - usr_df <- lookup_users(users) - }) - expect_s3_class(usr_df, "data.frame") - expect_equal(nrow(usr_df), 6) - expect_equal(ncol(usr_df), 23) -}) - - -test_that("users with same information, #654", { - - vcr::use_cassette("lookup_users3", { - a <- lookup_users("alexpghayes") - }) - vcr::use_cassette("lookup_users4", { - d <- lookup_users("Corey_Yanofsky") - }) - - expect_length(setdiff(colnames(a), colnames(d)), 0) -}) - -test_that("Users with date formatting, #653", { - - vcr::use_cassette("lookup_users5", { - x <- lookup_users("alexpghayes") - }) - expect_s3_class(x$created_at, "POSIXct") -}) - -test_that("lookup_users only works with ids", { - vcr::use_cassette("lookup_users1", { - x <- lookup_users(c("cnn", "potus", "twitter", "kearneymw")) - }) - - twd <- tweets_data(x) - skip_if_offline() - expect_error(b <- lookup_tweets(twd), NA) - expect_s3_class(b, "tweets") -}) From 7b7db9f14ccd60e7f2ed46149e7239ecdad23983 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Mon, 11 Dec 2023 19:58:39 +0100 Subject: [PATCH 19/21] Fix errors from GHA --- R/coords.R | 4 +--- tests/testthat/test-geo_objects.R | 9 --------- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/R/coords.R b/R/coords.R index 4d418b1b..7f9ddfbb 100644 --- a/R/coords.R +++ b/R/coords.R @@ -56,9 +56,7 @@ #' @export lookup_coords <- function(address, components = NULL, apikey = NULL, ...) { if (missing(address)) stop("must supply address", call. = FALSE) - stopifnot(is.atomic(address) && !is.null(address), - is.atomic(components)) - stopifnot(is.atomic(address), is.atomic(components)) + stopifnot(is.atomic(address) && !is.null(address)) place <- address if (grepl("^us$|^usa$|^united states$|^u\\.s", address, ignore.case = TRUE)) { diff --git a/tests/testthat/test-geo_objects.R b/tests/testthat/test-geo_objects.R index 91edac7f..457f358c 100644 --- a/tests/testthat/test-geo_objects.R +++ b/tests/testthat/test-geo_objects.R @@ -102,14 +102,5 @@ vcr::use_cassette("geo_objects1", { expect_equal(nrow(out), 1) expect_equal(ncol(out), 3) expect_equal(out$type[1], "Point") - - # ids of these "faulty" ids: - ids <- c("1462911176719757313", "1462903173656428545", - "1462902964150935558", "1462899130808762371") - # other_ids adjacent (w-1): - other_ids <- c("1462911347801444365", "1462903930090840071", - "1462903173656428545", "1462900536848490499") - all_ids <- unique(c(ids, other_ids)) - expect_error(lookup_tweets(all_ids)) }) }) From 0d09ef1a545f8eaccff8a357ca1fd9b71fe2ce2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Mon, 11 Dec 2023 20:04:24 +0100 Subject: [PATCH 20/21] Commit everything before merge --- R/auth.R | 5 ++--- R/bearer_token.R | 1 - R/collections.R | 4 ++-- R/http.R | 3 +++ R/ts_plot.R | 2 ++ R/utils.R | 9 +++++++++ man/invalidate_bearer.Rd | 3 --- man/rtweet_bearer.Rd | 11 ----------- man/rtweet_user.Rd | 3 +++ 9 files changed, 21 insertions(+), 20 deletions(-) delete mode 100644 man/rtweet_bearer.Rd diff --git a/R/auth.R b/R/auth.R index 0ea0b1fa..72c2b577 100644 --- a/R/auth.R +++ b/R/auth.R @@ -173,9 +173,8 @@ ask_pass <- function(type) { val } -#' Generate a Bearer token from a client -#' #' @export +#' @rdname rtweet_user rtweet_bearer <- function(client = NULL, scopes = set_scopes()) { client <- client %||% client_get() @@ -200,7 +199,7 @@ rtweet_bearer <- function(client = NULL, scopes = set_scopes()) { token } -#' @seealso [invalidate_bearer()] +# @seealso [invalidate_bearer()] rtweet_invalidate <- function(api_key, api_secret, token = NULL) { if (missing(api_key)) { api_key <- ask_pass("API key") diff --git a/R/bearer_token.R b/R/bearer_token.R index 5ba89a2b..fe24ec76 100644 --- a/R/bearer_token.R +++ b/R/bearer_token.R @@ -26,7 +26,6 @@ bearer_token <- function(token = NULL) { #' @references #' #' @keywords internal -#' @seealso [rtweet_invalidate()] #' @export invalidate_bearer <- function(api_key, api_secret, client = NULL, token = NULL) { # See also rtweet_invalidate in auth.R diff --git a/R/collections.R b/R/collections.R index 92bd1928..ff5678c3 100644 --- a/R/collections.R +++ b/R/collections.R @@ -12,7 +12,7 @@ lookup_collections <- function(id, n = 200, parse = TRUE, token = NULL, ...) { - lifecycle::deprecate_stop("1.0.0", "lookup_collections()") + lifecycle::deprecate_stop("1.0.0", function_call()) } #' @export @@ -24,5 +24,5 @@ get_collections <- function(user = NULL, parse = TRUE, token = NULL) { - lifecycle::deprecate_stop("1.0.0", "get_collections()") + lifecycle::deprecate_stop("1.0.0", function_call()) } diff --git a/R/http.R b/R/http.R index 9f3b3fb7..73d22f40 100644 --- a/R/http.R +++ b/R/http.R @@ -27,6 +27,9 @@ TWIT_method <- function(method, token, api, retryonratelimit = NULL, verbose = TRUE, ...) { + lifecycle::deprecate_stop("2.0.0", function_caller(), + details = c("The removal of API v1.1 made this function obsolete.", + "See the new vignette about the new requirements and functions.")) # need scipen to ensure large IDs are not displayed in scientific notation # need ut8-encoding for the comma separated IDs withr::local_options(scipen = 14, encoding = "UTF-8") diff --git a/R/ts_plot.R b/R/ts_plot.R index b26c0ed0..58c03c2c 100644 --- a/R/ts_plot.R +++ b/R/ts_plot.R @@ -31,6 +31,7 @@ #' @family ts_data #' @export ts_plot <- function(data, by = "days", trim = 0L, tz ="UTC", ...) { + lifecycle::deprecate_stop("2.0.0", function_call()) data <- ts_data(data, by, trim, tz) check_installed("ggplot2") @@ -79,6 +80,7 @@ ts_plot <- function(data, by = "days", trim = 0L, tz ="UTC", ...) { #' #' @export ts_data <- function(data, by = "days", trim = 0L, tz ="UTC") { + lifecycle::deprecate_stop("2.0.0", function_call()) stopifnot(is.data.frame(data), is.atomic(by) && !is.null(by)) if (has_name_(data, "created_at")) { dtvar <- "created_at" diff --git a/R/utils.R b/R/utils.R index 4e1e5b74..6b944fb9 100644 --- a/R/utils.R +++ b/R/utils.R @@ -92,3 +92,12 @@ release_bullets <- function() { "Check spelling with: `spelling::spell_check_package()`", "Run manual tests.") } + + +function_call <- function() { + paste0(as.character(sys.call(sys.parent(1)))[1L], "()") +} + +function_caller <- function() { + paste0(as.character(sys.call(1))[1L], "()") +} diff --git a/man/invalidate_bearer.Rd b/man/invalidate_bearer.Rd index 2d1ff2d8..0783d182 100644 --- a/man/invalidate_bearer.Rd +++ b/man/invalidate_bearer.Rd @@ -24,7 +24,4 @@ Not tested! \url{https://developer.twitter.com/en/docs/authentication/api-reference/invalidate_bearer_token} \url{https://developer.twitter.com/en/docs/authentication/api-reference/invalidate_access_token} } -\seealso{ -\code{\link[=rtweet_invalidate]{rtweet_invalidate()}} -} \keyword{internal} diff --git a/man/rtweet_bearer.Rd b/man/rtweet_bearer.Rd deleted file mode 100644 index f7da3887..00000000 --- a/man/rtweet_bearer.Rd +++ /dev/null @@ -1,11 +0,0 @@ -% Generated by roxygen2: do not edit by hand -% Please edit documentation in R/auth.R -\name{rtweet_bearer} -\alias{rtweet_bearer} -\title{Generate a Bearer token from a client} -\usage{ -rtweet_bearer(client = NULL, scopes = set_scopes()) -} -\description{ -Generate a Bearer token from a client -} diff --git a/man/rtweet_user.Rd b/man/rtweet_user.Rd index 1197079f..c38e94f9 100644 --- a/man/rtweet_user.Rd +++ b/man/rtweet_user.Rd @@ -4,6 +4,7 @@ \alias{rtweet_user} \alias{rtweet_bot} \alias{rtweet_app} +\alias{rtweet_bearer} \alias{rtweet_oauth2} \title{Authentication options} \usage{ @@ -18,6 +19,8 @@ rtweet_bot(api_key, api_secret, access_token, access_secret, app = "rtweet") rtweet_app(bearer_token) +rtweet_bearer(client = NULL, scopes = set_scopes()) + rtweet_oauth2(client = NULL, scopes = NULL) } \arguments{ From ba947e9520b34312eb1d892a1e001e9d68fe96ac Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Llu=C3=ADs?= Date: Sat, 16 Dec 2023 19:05:45 +0100 Subject: [PATCH 21/21] Remove examples and tests for API v1 --- NAMESPACE | 2 -- R/api_v2_utils.R | 2 +- R/auth.R | 4 +-- R/clean_tweets.R | 10 +------ R/client.R | 2 ++ R/coords.R | 6 ---- R/direct_messages.R | 15 ++-------- R/do_call_rbind.R | 24 +--------------- R/entities.R | 13 --------- R/extractors.R | 12 -------- R/favorites.R | 13 ++------- R/followers.R | 9 ++---- R/friends.R | 7 ++--- R/graph-network.R | 25 +--------------- R/ids.R | 9 ------ R/lat_lng.R | 15 +--------- R/links.R | 9 ------ R/lists_members.R | 13 --------- R/lists_memberships.R | 23 ++++----------- R/lists_statuses.R | 5 ---- R/lists_subscribers.R | 6 ---- R/lists_subscriptions.R | 12 ++------ R/lists_users.R | 8 ------ R/mentions.R | 10 +------ R/next_cursor.R | 23 ++------------- R/post-block.R | 7 +---- R/post-favorite.R | 6 +--- R/post-list.R | 41 +-------------------------- R/post-tweet.R | 39 ++----------------------- R/post-user.R | 6 +--- R/post_destroy.R | 8 ++---- R/premium.R | 16 ++--------- R/rate_limit.R | 36 +++++++++++------------ R/save_as_csv.R | 10 +------ R/search_tweets.R | 42 +++------------------------ R/search_users.R | 12 ++------ R/statuses.R | 23 ++------------- R/stream.R | 19 ++----------- R/timeline.R | 18 ++---------- R/trends.R | 41 ++------------------------- R/ts_plot.R | 34 +++------------------- R/tweet_shot.R | 1 + R/tweet_threading.R | 6 +--- R/user_id.R | 8 ------ R/users.R | 6 +--- man/as_screenname.Rd | 9 ------ man/clean_tweets.Rd | 11 +------- man/direct_messages.Rd | 7 ++--- man/direct_messages_received.Rd | 8 ------ man/do_call_rbind.Rd | 25 +--------------- man/entity.Rd | 14 --------- man/get_favorites.Rd | 13 ++------- man/get_followers.Rd | 9 ++---- man/get_friends.Rd | 7 ++--- man/get_mentions.Rd | 11 +------- man/get_timeline.Rd | 21 ++------------ man/get_trends.Rd | 34 +--------------------- man/ids.Rd | 10 ------- man/lat_lng.Rd | 15 +--------- man/links.Rd | 10 ------- man/lists_members.Rd | 14 --------- man/lists_memberships.Rd | 12 -------- man/lists_statuses.Rd | 6 ---- man/lists_subscribers.Rd | 7 ----- man/lists_subscriptions.Rd | 7 ----- man/lists_users.Rd | 9 ------ man/lookup_coords.Rd | 6 ---- man/lookup_tweets.Rd | 18 ++---------- man/lookup_users.Rd | 6 +--- man/max_id.Rd | 12 -------- man/network_data.Rd | 26 +---------------- man/next_cursor.Rd | 6 ---- man/parse_stream.Rd | 1 + man/post_destroy.Rd | 11 +++----- man/post_favorite.Rd | 8 +----- man/post_follow.Rd | 8 +----- man/post_list.Rd | 41 +-------------------------- man/post_tweet.Rd | 42 ++------------------------- man/rate_limit.Rd | 6 ++-- man/read_twitter_csv.Rd | 10 +------ man/rtweet_client.Rd | 2 ++ man/rtweet_user.Rd | 2 -- man/search_fullarchive.Rd | 17 ++--------- man/search_tweets.Rd | 44 ++++------------------------- man/search_users.Rd | 14 ++------- man/stream_tweets.Rd | 19 ++----------- man/trends_available.Rd | 11 +------- man/ts_data.Rd | 20 ++----------- man/ts_plot.Rd | 16 ++--------- man/tweet_delete.Rd | 8 ------ man/tweet_quoted.Rd | 3 -- man/tweet_shot.Rd | 1 + man/tweet_threading.Rd | 7 +---- man/user_block.Rd | 8 +----- man/users_data.Rd | 13 --------- tests/testthat/_snaps/post-tweet.md | 29 ------------------- tests/testthat/_snaps/user_id.md | 8 ------ 97 files changed, 143 insertions(+), 1195 deletions(-) delete mode 100644 tests/testthat/_snaps/post-tweet.md delete mode 100644 tests/testthat/_snaps/user_id.md diff --git a/NAMESPACE b/NAMESPACE index 18b343f2..3c3d1094 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -72,7 +72,6 @@ export(get_tokens) export(get_trends) export(ids) export(invalidate_bearer) -export(lat_lng) export(links) export(list_expansions) export(list_fields) @@ -108,7 +107,6 @@ export(post_destroy) export(post_favorite) export(post_follow) export(post_friendship) -export(post_list) export(post_message) export(post_mute) export(post_tweet) diff --git a/R/api_v2_utils.R b/R/api_v2_utils.R index c639789b..04b9bf67 100644 --- a/R/api_v2_utils.R +++ b/R/api_v2_utils.R @@ -99,7 +99,7 @@ req_is_error <- function(resp) { } else { r <- resp } - has_name_(r, "errors") + has_name_(r, "errors") || httr2::resp_is_error(resp) } req_errors <- function(resp) { diff --git a/R/auth.R b/R/auth.R index 72c2b577..29320100 100644 --- a/R/auth.R +++ b/R/auth.R @@ -84,8 +84,6 @@ auth_setup_default <- function() { #' @export #' @examples #' \dontrun{ -#' rtweet_user() -#' rtweet_bot() #' rtweet_app() #' } rtweet_user <- function(client_id = NULL, client_secret = NULL, @@ -195,7 +193,7 @@ rtweet_bearer <- function(client = NULL, scopes = set_scopes()) { token_params = list(client_secret = client$secret, client_type = "third_party_app", grant_type = "refresh_token")) - attr(token, "app", TRUE) <- client + attr(token, "app") <- client token } diff --git a/R/clean_tweets.R b/R/clean_tweets.R index 35b561c6..eb157041 100644 --- a/R/clean_tweets.R +++ b/R/clean_tweets.R @@ -2,19 +2,11 @@ #' #' Removes from the text, users mentions, hashtags, urls and media. #' Some urls or other text might remain if it is not recognized as an entity by -#' the API. +#' the API. `r lifecycle::badge("deprecated")` #' @param x Tweets #' @param clean Type of elements to be removed. #' @return A vector with the text without the entities selected #' @export -#' @examples -#' if (auth_has_default()) { -#' tweets <- search_tweets("weather") -#' tweets -#' -#' # tweets -#' clean_tweets(tweets) -#' } clean_tweets <- function(x, clean = c("users", "hashtags", "urls", "media")) { if (is.character(x)) { abort("You should provide tweets with all the users and hashtags information", diff --git a/R/client.R b/R/client.R index 825e4eb0..b09101f9 100644 --- a/R/client.R +++ b/R/client.R @@ -183,9 +183,11 @@ no_client <- function(call = caller_env()) { #' @seealso scopes #' @export #' @examples +#' \donttest{ #' if (interactive()) { #' rtweet_client() #' } +#' } rtweet_client <- function(client_id, client_secret, app, scopes = NULL) { if (missing(client_id) && missing(client_secret) ) { diff --git a/R/coords.R b/R/coords.R index 7f9ddfbb..31bdd04e 100644 --- a/R/coords.R +++ b/R/coords.R @@ -44,12 +44,6 @@ #' lnd <- lookup_coords("london") #' bz <- lookup_coords("brazil") #' -#' ## pass a returned coords object to search_tweets -#' bztw <- search_tweets(geocode = bz) -#' -#' ## or stream tweets -#' ustw <- stream_tweets(usa, timeout = 10) -#' #' } #' #' @family geo diff --git a/R/direct_messages.R b/R/direct_messages.R index 7de6a402..238509a9 100644 --- a/R/direct_messages.R +++ b/R/direct_messages.R @@ -3,7 +3,7 @@ #' #' Returns all Direct Message events (both sent and received) within the last 30 #' days. Sorted in reverse-chronological order. Includes detailed information -#' about the sender and recipient. +#' about the sender and recipient. `r lifecycle::badge("deprecated")` #' #' @inheritParams TWIT_paginate_cursor #' @inheritParams stream @@ -13,10 +13,7 @@ #' \dontrun{ #' #' ## get my direct messages -#' dms <- direct_messages() -#' -#' ## inspect data structure -#' str(dms) +#' direct_messages() #' #' } #' @export @@ -62,16 +59,8 @@ direct_messages <- function(n = 50, #' #' ## get my direct messages #' dms <- direct_messages_received() -#' -#' ## inspect data structure -#' str(dms) -#' #' ## get direct messages I've sent #' sdms <- direct_messages_sent() -#' -#' ## inspect data structure -#' str(dms) -#' #' } #' #' @details Includes detailed information about the sender and diff --git a/R/do_call_rbind.R b/R/do_call_rbind.R index 85501af7..a9c1a756 100644 --- a/R/do_call_rbind.R +++ b/R/do_call_rbind.R @@ -2,7 +2,7 @@ #' Binds list of data frames while preserving attribute (tweets or users) data. #' #' Row bind lists of tweets/users data whilst also preserving and binding -#' users/tweets attribute data. +#' users/tweets attribute data. `r lifecycle::badge("deprecated")` #' #' @param x List of parsed tweets data or users data, each of which #' presumably contains an attribute of the other (i.e., users data @@ -13,28 +13,6 @@ #' [users_data()] or [tweets_data()] extractor #' functions. #' @family parsing -#' @examples -#' -#' if (auth_has_default()) { -#' -#' ## lapply through three different search queries -#' lrt <- lapply( -#' c("rstats OR tidyverse", "data science", "python"), -#' search_tweets, -#' n = 100 -#' ) -#' -#' ## convert list object into single parsed data rame -#' rt <- do_call_rbind(lrt) -#' -#' ## preview tweets data -#' rt -#' -#' ## preview users data -#' users_data(rt) -#' -#' } -#' #' @export do_call_rbind <- function(x) { do.call(rbind, x) diff --git a/R/entities.R b/R/entities.R index 0c7de29c..b4908c37 100644 --- a/R/entities.R +++ b/R/entities.R @@ -10,19 +10,6 @@ #' for users mentions the ids of the mentioned users are "user_id", "user_id_str" #' (not "id_str") #' @export -#' @examples -#' if (auth_has_default()) { -#' statuses <- c( -#' "567053242429734913", -#' "266031293945503744", -#' "440322224407314432" -#' ) -#' -#' ## lookup tweets data for given statuses -#' tw <- lookup_tweets(statuses) -#' entity(tw, "urls") -#' -#' } entity <- function(x, entity, ...) { UseMethod("entity") } diff --git a/R/extractors.R b/R/extractors.R index f5dbc221..8adcacf0 100644 --- a/R/extractors.R +++ b/R/extractors.R @@ -6,18 +6,6 @@ #' rtweet instead stores in special attributes and allows you to show them #' with the `user_data()` and `tweets_data()` helpers. #' -#' @examples -#' if (auth_has_default()) { -#' # find users from tweets -#' tweets <- search_tweets("r") -#' users_data(tweets) -#' full_search <- cbind(tweets, users_data(tweets)) -#' -#' # from tweets from users -#' users <- search_users("r") -#' tweets_data(users) -#' full_users <- cbind(users, tweets_data(users)) -#' } #' @return `user_data()` returns a data frame of users; `tweets_data()` #' returns a data frame of tweets. #' @param tweets A data frame of tweets. diff --git a/R/favorites.R b/R/favorites.R index eb70c7f0..d5fc0eeb 100644 --- a/R/favorites.R +++ b/R/favorites.R @@ -1,22 +1,15 @@ #' Get tweets liked/favorited by one or more users #' #' Returns up to 3,000 tweets liked/favorited for each `user`. +#' `r lifecycle::badge("deprecated")` #' #' @inheritParams TWIT_paginate_max_id #' @inheritParams get_timeline #' @inheritParams stream #' @return A tibble with one row for each tweet. #' @examples -#' if (auth_has_default()) { -#' # get likes for a single user -#' kfc <- get_favorites("KFC") -#' kfc -#' # get newer likes since last request -#' newer <- get_favorites("KFC", since_id = kfc) -#' -#' # get likes from multiple users -#' favs <- get_favorites(c("Lesdoggg", "pattonoswalt", "meganamram")) -#' favs +#' if (FALSE) { +#' get_favorites("KFC") #' } #' @family tweets #' @references diff --git a/R/followers.R b/R/followers.R index 8ff82127..0b997f06 100644 --- a/R/followers.R +++ b/R/followers.R @@ -1,7 +1,7 @@ #' Get user IDs for accounts following target user. #' #' Returns a list of user IDs for the accounts following specified -#' user. +#' user. `r lifecycle::badge("deprecated")` #' #' @inheritParams TWIT_paginate_cursor #' @inheritParams get_timeline @@ -9,13 +9,8 @@ #' @param page `r lifecycle::badge("deprecated")` Please use `cursor` instead. #' @references #' @examples -#' if (auth_has_default()) { +#' if (FALSE) { #' users <- get_followers("_R_Foundation") -#' users -#' -#' # use `cursor` to find the next "page" of results -#' more_users <- get_followers("_R_Foundation", cursor = users) -#' #' } #' @return A tibble data frame with one column named "from_id" with the #' followers and another one "to_id" with the user used as input. diff --git a/R/friends.R b/R/friends.R index d0df522b..d3e1fd27 100644 --- a/R/friends.R +++ b/R/friends.R @@ -1,7 +1,7 @@ #' Get user IDs of accounts followed by target user(s). #' #' Returns a list of user IDs for the accounts following BY one or -#' more specified users. +#' more specified users. `r lifecycle::badge("deprecated")` #' #' Generally, you should not need to set `n` to more than 5,000 since Twitter #' limits the number of people that you can follow (i.e. to follow more than @@ -18,9 +18,8 @@ #' retrieved. #' @references #' @examples -#' if (auth_has_default()) { -#' users <- get_friends("ropensci") -#' users +#' if (FALSE) { +#' get_friends("ropensci") #' } #' @return A tibble data frame with two columns, "from_id" for name or ID of target #' user and "to_id" for accounts ID they follow. diff --git a/R/graph-network.R b/R/graph-network.R index 6500ff10..01093cf9 100644 --- a/R/graph-network.R +++ b/R/graph-network.R @@ -1,6 +1,7 @@ #' Network data #' #' Retrieve data to know which users are connected to which users. +#' `r lifecycle::badge("deprecated")` #' #' @description #' * `network_data()` returns a data frame that can easily be converted to @@ -16,30 +17,6 @@ #' default value of `c("mention", "retweet", "reply", "quote")` #' @return A from/to data edge data frame #' @seealso network_graph -#' @examples -#' if (auth_has_default()) { -#' ## search for #rstats tweets -#' rstats <- search_tweets("#rstats", n = 200) -#' -#' ## create from-to data frame representing retweet/mention/reply connections -#' rstats_net <- network_data(rstats, c("retweet","mention","reply")) -#' -#' ## view edge data frame -#' rstats_net -#' -#' ## view user_id->screen_name index -#' attr(rstats_net, "idsn") -#' -#' ## if igraph is installed... -#' if (requireNamespace("igraph", quietly = TRUE)) { -#' -#' ## (1) convert directly to graph object representing semantic network -#' rstats_net <- network_graph(rstats) -#' -#' ## (2) plot graph via igraph.plotting -#' plot(rstats_net) -#' } -#' } #' @export network_data <- function(x, e = c("mention", "retweet", "reply", "quote")) { if (isTRUE(e) || (length(e) == 1 && e %in% c("semantics", "all"))) { diff --git a/R/ids.R b/R/ids.R index de6faa37..766b385d 100644 --- a/R/ids.R +++ b/R/ids.R @@ -5,15 +5,6 @@ #' @param x An object of the rtweet package. #' @param ... Other arguments currently unused. #' @export -#' @examples -#' if (auth_has_default()) { -#' users <- lookup_users(c("twitter", "rladiesglobal", "_R_Foundation")) -#' ids(users) -#' followers <- get_followers("_R_Foundation") -#' head(ids(followers)) -#' friends <- get_friends("_R_Foundation") -#' head(ids(friends)) -#' } ids <- function(x, ...) { UseMethod("ids") } diff --git a/R/lat_lng.R b/R/lat_lng.R index 8e83c32e..6d2fede0 100644 --- a/R/lat_lng.R +++ b/R/lat_lng.R @@ -5,7 +5,7 @@ #' Adds single-point latitude and longitude variables to tweets data. #' #' Appends parsed Twitter data with latitude and longitude variables -#' using all available geolocation information. +#' using all available geolocation information. `r lifecycle::badge("deprecated")` #' #' @param x Parsed Twitter data as returned by various rtweet #' functions. This should be a data frame with variables such as @@ -28,19 +28,6 @@ #' @return Returns updated data object with full information latitude #' and longitude vars. #' @family geo -#' @examples -#' -#' if (auth_has_default()) { -#' -#' ## stream tweets sent from the US -#' rt <- search_tweets(geocode = lookup_coords("usa")) -#' -#' ## use lat_lng to recover full information geolocation data -#' rtl_loc <- lat_lng(rt) -#' rtl_loc -#' } -#' -#' @export lat_lng <- function(x, coords = c("coords_coords", "bbox_coords", "geo_coords"), prefs = "bbox_coords") { stopifnot(is.data.frame(x)) coords <- match.arg(coords, several.ok = TRUE) diff --git a/R/links.R b/R/links.R index 4ff26eb5..bc2c543f 100644 --- a/R/links.R +++ b/R/links.R @@ -5,15 +5,6 @@ #' @param x An object of the rtweet package. #' @param ... Other arguments currently unused. #' @export -#' @examples -#' if (auth_has_default()) { -#' users <- lookup_users(c("twitter", "rladiesglobal", "_R_Foundation")) -#' links(users) -#' followers <- get_followers("_R_Foundation") -#' head(links(followers)) -#' friends <- get_friends("_R_Foundation") -#' head(links(friends)) -#' } links <- function(x, ...) { UseMethod("links") } diff --git a/R/lists_members.R b/R/lists_members.R index 8dcef4a2..10006068 100644 --- a/R/lists_members.R +++ b/R/lists_members.R @@ -9,19 +9,6 @@ #' @param owner_user optional The screen name or user ID of the user #' @param ... Other arguments used as parameters in query composition. #' @inheritParams stream -#' @examples -#' if (auth_has_default()) { -#' -#' ## get list members for a list of rstats experts using list_id -#' (rstats <- lists_members("1260528710559694850")) -#' -#' ## get list members for an rstats list using list topic slug -#' ## list owner's screen name -#' rstats <- lists_members(slug = "r-people", owner_user = "Lluis_Revilla") -#' rstats -#' -#' } -#' #' @family lists #' @export #' @references diff --git a/R/lists_memberships.R b/R/lists_memberships.R index 5995441e..938b82c6 100644 --- a/R/lists_memberships.R +++ b/R/lists_memberships.R @@ -3,24 +3,13 @@ #' Due to deleted or removed lists, the returned number of memberships #' is often less than the provided n value. This is a reflection of the API and #' not a unique quirk of rtweet. -#' +#' #' @inheritParams TWIT_paginate_cursor #' @inheritParams get_timeline #' @param filter_to_owned_lists When `TRUE`, will return only lists that #' authenticating user owns. -#' @param previous_cursor `r lifecycle::badge("deprecated")` Please use +#' @param previous_cursor `r lifecycle::badge("deprecated")` Please use #' `cursor` instead. -#' @examples -#' if (auth_has_default()) { -#' -#' ## get up to 1000 Twitter lists that include Nate Silver -#' R_foundation <- lists_memberships("_R_Foundation", n = 1000) -#' -#' ## view data -#' R_foundation -#' -#' } -#' #' @references #' @export lists_memberships <- function(user = NULL, @@ -40,15 +29,15 @@ lists_memberships <- function(user = NULL, params$filter_to_owned_lists <- TRUE } - r <- TWIT_paginate_cursor(token, "/1.1/lists/memberships", params, + r <- TWIT_paginate_cursor(token, "/1.1/lists/memberships", params, n = n, - cursor = cursor, + cursor = cursor, retryonratelimit = retryonratelimit, verbose = verbose, page_size = if (n >= 1000) 1000 else n, get_id = function(x) x$lists$id_str ) - + if (parse) { r <- parse_lists_list(r) } @@ -61,6 +50,6 @@ parse_lists_list <- function(x) { dfs <- lapply(lists, wrangle_into_clean_data, type = "list") dfs <- lapply(dfs, tibble::as_tibble) df <- do.call(rbind, dfs) - + copy_cursor(df, x) } diff --git a/R/lists_statuses.R b/R/lists_statuses.R index c3a045d2..f57e3179 100644 --- a/R/lists_statuses.R +++ b/R/lists_statuses.R @@ -17,11 +17,6 @@ #' @family lists #' @family tweets #' @return data -#' @examples -#' if (auth_has_default()) { -#' (rladies <- lists_statuses(list_id = "839186302968848384")) -#' (rladies <- lists_statuses(slug = "rladies1", owner_user = "RLadiesGlobal")) -#' } #' @export lists_statuses <- function(list_id = NULL, slug = NULL, diff --git a/R/lists_subscribers.R b/R/lists_subscribers.R index 3d6cbb48..c746a124 100644 --- a/R/lists_subscribers.R +++ b/R/lists_subscribers.R @@ -4,12 +4,6 @@ #' @inheritParams stream #' @param list_id required The numerical id of the list. #' @param slug,owner_user The list name (slug) and owner. -#' @examples -#' if (auth_has_default()) { -#' ## get subscribers of rladies list -#' rstats <- lists_subscribers(slug = "rladies1", owner_user = "rladiesglobal") -#' } -#' #' @family lists #' @family users #' @export diff --git a/R/lists_subscriptions.R b/R/lists_subscriptions.R index e5a14c65..6844f755 100644 --- a/R/lists_subscriptions.R +++ b/R/lists_subscriptions.R @@ -1,14 +1,8 @@ -#' Get list subscriptions of a given user but does not include the user's own +#' Get list subscriptions of a given user but does not include the user's own #' lists. #' #' @inheritParams TWIT_paginate_cursor #' @inheritParams get_timeline -#' @examples -#' if (auth_has_default()) { -#' ## get ropensci subscriptions -#' rstats <- lists_subscriptions(user = "rladiesglobal", n = 1000) -#' } -#' #' @family lists #' @references #' @export @@ -19,7 +13,7 @@ lists_subscriptions <- function(user, retryonratelimit = NULL, verbose = TRUE, token = NULL) { - + params <- list( count = n, cursor = cursor @@ -33,7 +27,7 @@ lists_subscriptions <- function(user, page_size = if (n >= 1000) 1000 else n, get_id = function(x) x$user_id ) - + if (parse) { out <- parse_lists_list(r) } diff --git a/R/lists_users.R b/R/lists_users.R index 35df258d..ca31c586 100644 --- a/R/lists_users.R +++ b/R/lists_users.R @@ -5,14 +5,6 @@ #' to be returned first. See description above for information on #' how this parameter works. #' @return data -#' @examples -#' if (auth_has_default()) { -#' -#' ## get lists subscribed to by R_Foundation -#' lists_users("ropensci") -#' -#' } -#' #' @family lists #' @export lists_users <- function(user = NULL, reverse = FALSE, token = NULL, parse = TRUE) { diff --git a/R/mentions.R b/R/mentions.R index 9798a4d0..7a1a31e7 100644 --- a/R/mentions.R +++ b/R/mentions.R @@ -3,7 +3,7 @@ #' Returns data on up to 200 of the most recent mentions (Tweets #' containing a users' screen_name) of the authenticating user. #' The timeline returned is the equivalent of the one seen when you view -#' your mentions on twitter.com. +#' your mentions on twitter.com. `r lifecycle::badge("deprecated")` #' #' @inheritParams TWIT_paginate_max_id #' @inheritParams stream @@ -11,14 +11,6 @@ #' query. #' @return Tibble of mentions data. #' @family tweets -#' @examples -#' if (auth_has_default()) { -#' tw <- get_mentions() -#' tw -#' -#' # newer mentions -#' get_mentions(since_id = tw) -#' } #' @references #' @export get_mentions <- function(n = 200, diff --git a/R/next_cursor.R b/R/next_cursor.R index b690a9cf..f48c7a1b 100644 --- a/R/next_cursor.R +++ b/R/next_cursor.R @@ -4,12 +4,6 @@ #' `cursor` argument of the functions that use [TWIT_paginate_cursor()]. #' #' @keywords internal -#' @examples -#' if (auth_has_default()) { -#' page1 <- get_followers("_R_Foundation") -#' page2 <- get_followers("_R_Foundation", cursor = page1) -#' } -#' @keywords internal #' @export next_cursor <- function(x) { if (is_string(x) || is_null(x)) { @@ -35,7 +29,7 @@ copy_cursor <- function(to, from) { #' Previous cursor #' -#' @description +#' @description #' `r lifecycle::badge("deprecated")` #' Reverse pagination is no longer supported. #' @@ -46,24 +40,13 @@ previous_cursor <- function(x) { } #' Extract min/max id (for id based pagination) -#' +#' #' These internal helpers extract the ids passed on to the `max_id` #' and `since_id` arguments to functions that use [TWIT_paginate_max_id()]. -#' +#' #' @keywords internal #' @param x Either a data frame of tweets or a character vector of status ids. #' @export -#' @examples -#' if (auth_has_default()) { -#' tw <- search_tweets("#rstats") -#' -#' # retrieve older tweets -#' older <- search_tweets("#rstats", max_id = tw) -#' even_older <- search_tweets("#rstats", max_id = older) -#' -#' # retrieve newer tweets -#' newer <- search_tweets("#rstats", since_id = tw) -#' } max_id <- function(x) { id <- find_id(x, "max_id") as.character(min(bit64::as.integer64(id)) - 1L) diff --git a/R/post-block.R b/R/post-block.R index 67e18817..339508fb 100644 --- a/R/post-block.R +++ b/R/post-block.R @@ -2,6 +2,7 @@ #' #' `user_block(...)` blocks or unblocks a target twitter user. #' `user_unblock(...)` is synonymous to `user_block(..., unblock=TRUE)`. +#' `r lifecycle::badge("deprecated")` #' #' @inheritParams get_timeline #' @param unblock Logical indicating whether to unblock the intended @@ -10,12 +11,6 @@ #' @export #' @references #' Block: -#' @examples -#' if (auth_has_default()) { -#' user_block("rtweet") -#' user_unblock("rtweet") -#' user_block("rtweet", unblock=TRUE) #<-same as the above -#' } user_block <- function(user, unblock = FALSE, token = NULL) { diff --git a/R/post-favorite.R b/R/post-favorite.R index 50647d8a..94b71708 100644 --- a/R/post-favorite.R +++ b/R/post-favorite.R @@ -1,5 +1,6 @@ #' Favorites target status id. #' +#' `r lifecycle::badge("deprecated")` #' @inheritParams lookup_users #' @param status_id Status id of target tweet. #' @param destroy Logical indicating whether to post (add) or @@ -7,11 +8,6 @@ #' @param include_entities Logical indicating whether to #' include entities object in return. #' @aliases post_favourite favorite_tweet -#' @examples -#' if (auth_has_default()) { -#' rt <- search_tweets("#rstats", n = 1) -#' post_favorite(rt$id_str) -#' } #' @family post #' @export #' @references diff --git a/R/post-list.R b/R/post-list.R index c5275055..8c4f4d16 100644 --- a/R/post-list.R +++ b/R/post-list.R @@ -1,6 +1,6 @@ #' Manage Twitter lists #' -#' Create, add users, and destroy Twitter lists +#' Create, add users, and destroy Twitter lists. `r lifecycle::badge("deprecated")` #' #' @inheritParams lookup_users #' @param users Character vectors of users to be added to list. @@ -14,45 +14,6 @@ #' @param list_id Optional, numeric ID of list. #' @param slug Optional, list slug. #' @return Response object from HTTP request. -#' @examples -#' \dontrun{ -#' -#' ## R related Twitter accounts -#' users <- c("_R_Foundation", "R_dev_news", "rweekly_live", "RConsortium", "rstats4ds", -#' "icymi_r", "rstatstweet", "RLadiesGlobal") -#' -#' ## create r-accounts list with 8 total users -#' (r_lst <- post_list(users, -#' "r-accounts", description = "R related accounts")) -#' -#' ## view list in browser at https://twitter.com//lists/r-accounts -#' -#' ## search for more rstats users -#' r_users <- search_users("rstats", n = 200) -#' -#' ## filter and select more users to add to list -#' more_users <- r_users$screen_name[r_users$verified] -#' -#' ## add more users to list- note: can only add up to 100 at a time -#' post_list(users = more_users, slug = "r-accounts") -#' -#' ## view updated list in browser (should be around 100 users) -#' ## view list in browser at https://twitter.com//lists/r-accounts -#' -#' drop_users <- "icymi_r" -#' -#' ## drop these users from the R list -#' post_list(users = drop_users, slug = "r-accounts", -#' destroy = TRUE) -#' -#' ## view updated list in browser (should be around 100 users) -#' ## view list in browser at https://twitter.com//lists/r-accounts -#' -#' ## delete list entirely -#' post_list(slug = "r-accounts", destroy = TRUE) -#' -#' } -#' @export #' @references #' Create: #' Destroy: diff --git a/R/post-tweet.R b/R/post-tweet.R index 837d4bbb..1b09aabb 100644 --- a/R/post-tweet.R +++ b/R/post-tweet.R @@ -1,5 +1,6 @@ #' Posts status update to user's Twitter account #' +#' `r lifecycle::badge("deprecated")` #' @inheritParams lookup_users #' @param status Character, tweet status. Must be 280 characters or less. #' @param media Length 1 character vector with a file path to video media **OR** @@ -34,45 +35,9 @@ #' @param display_coordinates Put a pin on the exact coordinates a tweet has #' been sent from. Value should be TRUE or FALSE. This parameter would apply #' only if you have provided a valid `lat/long` pair of valid values. -#' @examples -#' if (auth_has_default()) { -#' ## generate data to make/save plot (as a .png file) -#' x <- rnorm(300) -#' y <- x + rnorm(300, 0, .75) -#' col <- c(rep("#002244aa", 50), rep("#440000aa", 50)) -#' bg <- c(rep("#6699ffaa", 50), rep("#dd6666aa", 50)) -#' -#' ## create temporary file name -#' tmp <- tempfile(fileext = ".png") -#' -#' ## save as png -#' png(tmp, 6, 6, "in", res = 127.5) -#' par(tcl = -.15, family = "Inconsolata", -#' font.main = 2, bty = "n", xaxt = "l", yaxt = "l", -#' bg = "#f0f0f0", mar = c(3, 3, 2, 1.5)) -#' plot(x, y, xlab = NULL, ylab = NULL, pch = 21, cex = 1, -#' bg = bg, col = col, -#' main = "This image was uploaded by rtweet") -#' grid(8, lwd = .15, lty = 2, col = "#00000088") -#' dev.off() -#' -#' ## post tweet with media attachment -#' post_tweet("a tweet with media attachment", media = tmp, -#' media_alt_text = "Random points example of rtweet::post_tweet. -#' rtweet requires alt text with all media") -#' -#' # example of replying within a thread -#' ## first post -#' pt <- post_tweet(status="first in a thread") -#' -#' reply_id <- ids(pt) -#' -#' ## post reply -#' post_tweet("second in the thread", -#' in_reply_to_status_id = reply_id) -#' } #' @family post #' @aliases post_status +#' @seealso [tweet_post()] #' @export #' @references #' Tweet: diff --git a/R/post-user.R b/R/post-user.R index 6133d7ab..af4b4133 100644 --- a/R/post-user.R +++ b/R/post-user.R @@ -1,5 +1,6 @@ #' Follows target Twitter user. #' +#' `r lifecycle::badge("deprecated")` #' @inheritParams get_timeline #' @param destroy Logical indicating whether to post (add) or #' remove (delete) target tweet as favorite. @@ -11,11 +12,6 @@ #' @param retweets Logical indicating whether to enable retweets #' for target user. Defaults to true. #' @aliases follow_user -#' @examples -#' if (auth_has_default()) { -#' post_follow("_R_Foundation") -#' post_follow("rtweet", mute = TRUE) # Mute -#' } #' @family post #' @export #' @references diff --git a/R/post_destroy.R b/R/post_destroy.R index 03970304..95b26aaa 100644 --- a/R/post_destroy.R +++ b/R/post_destroy.R @@ -1,14 +1,10 @@ #' Delete status of user's Twitter account #' -#' Deletes a status of user's profile. +#' Deletes a status of user's profile. `r lifecycle::badge("deprecated")` #' @inheritParams post_tweet #' @export #' @references -#' @examples -#' if (auth_has_default()) { -#' pt <- post_tweet("Running #rtweet examples") -#' post_destroy(ids(pt)) -#' } +#' @seealso [tweet_delete()] post_destroy <- function(destroy_id, token = NULL) { stopifnot(is.character(destroy_id) && length(destroy_id) == 1) diff --git a/R/premium.R b/R/premium.R index ca21b4e5..d3fb0f67 100644 --- a/R/premium.R +++ b/R/premium.R @@ -7,6 +7,7 @@ #' See the info provided by Twitter and the "Developer Account" section. #' #' Note: The `env_name` must match the ones you set up for the token you are using. +#' `r lifecycle::badge("deprecated")` #' #' @inheritParams TWIT_paginate_max_id #' @inheritParams stream @@ -81,20 +82,7 @@ #' #' @return A tibble data frame of Twitter data. #' @family premium endpoints -#' @examples -#' -#' \dontrun{ -#' ## search fullarchive for up to 300 rstats tweets sent in Jan 2014 -#' rt <- search_fullarchive("#rstats", n = 300, env_name = "SetYourLabel", -#' fromDate = "201401010000", toDate = "201401312359") -#' -#' toDate <- format(Sys.time() - 60 * 60 * 24 * 7, "%Y%m%d%H%M") -#' -#' ## search 30day for up to 300 rstats tweets sent before the last week -#' rt <- search_30day("#rstats", n = 300, -#' env_name = "SetYourLabel", toDate = toDate) -#' } -#' +#' @seealso [tweet_search_recent()], [tweet_search_all()] #' @export search_fullarchive <- function(q, n = 100, fromDate = NULL, toDate = NULL, continue = NULL, diff --git a/R/rate_limit.R b/R/rate_limit.R index ee5cf535..c48d5e4b 100644 --- a/R/rate_limit.R +++ b/R/rate_limit.R @@ -1,29 +1,27 @@ #' Rate limit helpers #' -#' @description +#' `r lifecycle::badge("deprecated")` +#' +#' @description #' * `rate_limit()` returns a tibble of info about all rate limits #' * `rate_limit_reset()` returns the next reset for a endpoint #' * `rate_limit_wait()` waits for the next reset for an endpoint -#' +#' #' You should not need to use these function in the usual operation of rtweet -#' because all paginated functions will wait on your behalf if you set +#' because all paginated functions will wait on your behalf if you set #' `retryonratelimit = TRUE`. #' #' @inheritParams lookup_users -#' @param resource_match An optional regular expression used to filter the +#' @param resource_match An optional regular expression used to filter the #' resources listed in returned rate limit data. #' @param endpoint Name of Twitter endpoint like `"lookup/users"`, #' `"/media/upload"`, or `"/feedback/show/:id"`. -#' @examples -#' if (auth_has_default()) { -#' rate_limit() -#' } #' @family tokens #' @export #' @references rate_limit <- function(resource_match = NULL, token = NULL) { json <- TWIT_get(token, "/1.1/application/rate_limit_status") - + resources <- unlist(unname(json$resources), recursive = FALSE) df <- tibble::tibble( resource = names(resources), @@ -33,11 +31,11 @@ rate_limit <- function(resource_match = NULL, token = NULL) { ) df$reset_at <- .POSIXct(df$reset_at) df$reset <- round(difftime(df$reset_at, Sys.time(), units = "mins")) - + if (!is.null(resource_match)) { df <- df[grepl(resource_match, df$resource), ] } - + df } @@ -45,24 +43,24 @@ rate_limit <- function(resource_match = NULL, token = NULL) { #' @rdname rate_limit rate_limit_reset <- function(endpoint, token = NULL) { endpoint <- gsub("^/", "", endpoint) - + resource <- strsplit(endpoint, "/")[[1]][[1]] params <- list(resource = resource) json <- TWIT_get(token, "/1.1/application/rate_limit_status", params) - + info <- json$resources[[resource]][[paste0("/", endpoint)]] if (is.null(info)) { stop("Unrecognised endpoint '", endpoint, "'", call. = FALSE) } - + if (info$remaining > 0) { Sys.time() } else { - .POSIXct(info$reset) + .POSIXct(info$reset) } } -#' @export +#' @export #' @rdname rate_limit rate_limit_wait <- function(endpoint, token = NULL) { reset <- unclass(rate_limit_reset(endpoint, token)) @@ -79,11 +77,11 @@ wait_until <- function(until, api, fps = 8, verbose = TRUE) { Sys.sleep(ceiling(seconds)) return() } - + if (seconds < 0) { return(invisible()) } - + pb <- progress::progress_bar$new( total = seconds * fps, format = paste0( @@ -92,7 +90,7 @@ wait_until <- function(until, api, fps = 8, verbose = TRUE) { ) ) withr::defer(pb$terminate()) - + while(Sys.time() < until) { Sys.sleep(1 / fps) mins <- round((until - unclass(Sys.time())) / 60) diff --git a/R/save_as_csv.R b/R/save_as_csv.R index ad514034..dce35626 100644 --- a/R/save_as_csv.R +++ b/R/save_as_csv.R @@ -184,20 +184,12 @@ unx_ids <- function(x) { #' Read comma separated value Twitter data. #' #' Reads Twitter data that was previously saved as a CSV file. -#' +#' `r lifecycle::badge("deprecated")` #' @param file Name of CSV file. #' @param unflatten Logical indicating whether to unflatten (separate hasthags #' and mentions columns on space, converting characters to lists), defaults #' to FALSE. #' @return A tbl data frame of Twitter data -#' @examples -#' -#' \dontrun{ -#' -#' ## read in data.csv -#' rt <- read_twitter_csv("data.csv") -#' -#' } #' @family datafiles #' @export read_twitter_csv <- function(file, unflatten = FALSE) { diff --git a/R/search_tweets.R b/R/search_tweets.R index 1d3923b0..49e54147 100644 --- a/R/search_tweets.R +++ b/R/search_tweets.R @@ -1,7 +1,7 @@ #' Get tweets data on statuses identified via search query. #' #' Returns Twitter statuses matching a user provided search -#' query. ONLY RETURNS DATA FROM THE PAST 6-9 DAYS. +#' query. `r lifecycle::badge("deprecated")` #' #' @param q Query to be searched, used to filter and select tweets to #' return from Twitter's REST API. Must be a character string not to @@ -58,26 +58,10 @@ #' It should also be noted Twitter's search API does not consist of #' an index of all Tweets. At the time of searching, the search API #' index includes between only 6-9 days of Tweets. -#' @examples -#' if (auth_has_default()) { -#' tweets <- search_tweets("weather") -#' tweets -#' -#' # data about the users who made those tweets -#' users_data(tweets) -#' -#' # Retrieve all the tweets made since the previous request -#' # (there might not be any if people aren't tweeting about the weather) -#' newer <- search_tweets("weather", since_id = tweets) -#' # Retrieve tweets made before the previous request -#' older <- search_tweets("weather", max_id = tweets) -#' -#' # Restrict to English only, and ignore retweets -#' tweets2 <- search_tweets("weather", lang = "en", include_rts = FALSE) -#' } #' @return List object with tweets and users each returned as a #' data frame. #' @family tweets +#' @seealso [tweet_search_recent()], [tweet_search_all()] #' @export #' @references search_tweets <- function(q, n = 100, @@ -166,29 +150,11 @@ search_params <- function(q, #' #' search_tweets2 Passes all arguments to search_tweets. Returns data from #' one OR MORE search queries. +#' `r lifecycle::badge("deprecated")` #' #' @return A tbl data frame with additional "query" column. #' @rdname search_tweets -#' @examples -#' if (auth_has_default()) { -#' -#' ## search using multiple queries -#' st2 <- search_tweets2( -#' c("\"data science\"", "rstats OR python"), -#' n = 500 -#' ) -#' -#' ## preview tweets data -#' st2 -#' -#' ## preview users data -#' users_data(st2) -#' -#' ## check breakdown of results by search query -#' table(st2$query) -#' -#' } -#' +#' @seealso [tweet_search_recent()] #' @export search_tweets2 <- function(...) { dots <- match_fun(list(...), "search_tweets") diff --git a/R/search_users.R b/R/search_users.R index 235266ec..bc1172ab 100644 --- a/R/search_users.R +++ b/R/search_users.R @@ -1,24 +1,16 @@ #' Search for users #' #' Search for Twitter users. The Twitter API limits the results to at most -#' 1,000 users. +#' 1,000 users. `r lifecycle::badge("deprecated")` #' #' @inheritParams TWIT_paginate_max_id #' @inheritParams stream #' @param q As string providing the search query. Try searching by interest, #' full name, company name, or location. Exact match searches are not #' supported. -#' @examples -#' if (auth_has_default()) { -#' users <- search_users("#rstats", n = 300) -#' users -#' -#' # latest tweet from each user -#' tweets_data(users) -#' } -#' #' @return Data frame with one row for each matching user. #' @family users +#' @seealso [user_search()] #' @export #' @references search_users <- function(q, n = 100, diff --git a/R/statuses.R b/R/statuses.R index 5b427c59..1f4d8357 100644 --- a/R/statuses.R +++ b/R/statuses.R @@ -1,24 +1,13 @@ #' Get tweets data for given statuses (status IDs). #' +#' `r lifecycle::badge("deprecated")` #' @inheritParams lookup_users #' @inheritParams stream #' @param statuses User id or screen name of target user. #' @references -#' @examples -#' -#' if (auth_has_default()) { -#' statuses <- c( -#' "567053242429734913", -#' "266031293945503744", -#' "440322224407314432" -#' ) -#' -#' ## lookup tweets data for given statuses -#' tw <- lookup_tweets(statuses) -#' tw -#' } #' @return A tibble of tweets data. #' @family tweets +#' @seealso [tweet_search_recent()] #' @export lookup_tweets <- function(statuses, parse = TRUE, token = NULL, retryonratelimit = NULL, verbose = TRUE) { @@ -176,13 +165,6 @@ check_reply_settings <- function(options) { #' @seealso [tweet_post()], [tweet_search_recent()], [user_timeline()] #' @export #' @references -#' @examples -#' if (FALSE) { -#' # It requires Oauth authentication -#' tp <- tweet_post("Running examples of #rtweet") -#' td <- tweet_delete(tp$id) -#' } -#' tweet_delete <- function(id, verbose = FALSE, token = NULL) { stopifnot("Requires valid ids." = is_id(id)) if (length(id) == 1) { @@ -211,7 +193,6 @@ tweet_delete <- function(id, verbose = FALSE, token = NULL) { #' @inheritParams tweet_get #' @inheritParams tweet_search_recent #' @param id At least a tweet id. -#' @seealso [lookup_tweets()] [tweet_get()] #' @references #' One tweet: #' @export diff --git a/R/stream.R b/R/stream.R index 6a4b5f86..1c6957dd 100644 --- a/R/stream.R +++ b/R/stream.R @@ -1,5 +1,6 @@ #' Collect a live stream of Twitter data #' +#' `r lifecycle::badge("deprecated")` #' @description #' Streams public statuses to a file via one of the following four methods: #' @@ -35,24 +36,9 @@ #' @param verbose If `TRUE`, display a progress bar. #' @param parse Use `FALSE` to opt-out of parsing the tweets. #' @param ... Other arguments passed in to query parameters. -#' @seealso [parse_stream()]. +#' @seealso [filtered_stream()]. #' @references #' They were removed from the website. -#' @examples -#' \dontrun{ -#' # stream tweets mentioning "#rstats" for 10 seconds -#' rstats1 <- stream_tweets("#rstats", timeout = 10, file_name = "rstats.json") -#' rstats1 -#' -#' # Download another 10s worth of data to the same file -#' rstats2 <- stream_tweets("#rstats", timeout = 10, file_name = "rstats.json", -#' append = TRUE) -#' -#' # stream tweets about continental USA for 10 seconds -#' usa <- stream_tweets(location = lookup_coords("usa"), file_name = "usa.json", -#' timeout = 10) -#' -#' } #' @return A tibble with one row per tweet #' @export #' @references @@ -214,6 +200,7 @@ stream_params <- function(stream, ...) { #' Parser of stream #' #' Converts Twitter stream data (JSON file) into parsed data frame. +#' `r lifecycle::badge("deprecated")` #' @param path Character, name of JSON file with data collected by #' [stream_tweets()]. #' @param ... Unused, keeping it for back compatibility. diff --git a/R/timeline.R b/R/timeline.R index fdeb5891..c12674a0 100644 --- a/R/timeline.R +++ b/R/timeline.R @@ -3,7 +3,7 @@ #' `get_timeline()` returns the timeline of any Twitter user (i.e. what they #' have tweeted). `get_my_timeline()` returns the home timeline for the #' authenticated user (i.e. the tweets you see when you log into Twitter). -#' +#' `r lifecycle::badge("deprecated")` #' At most up to 3,200 of a user's most recent Tweets can be retrieved. #' #' @inheritParams TWIT_paginate_max_id @@ -17,22 +17,8 @@ #' @param ... Further arguments passed on as parameters in API query. #' @return A tbl data frame of tweets data with users data attribute. #' @references -#' @examples -#' if (auth_has_default()) { -#' tw <- get_timeline("_R_Foundation") -#' tw -#' -#' # get tweets that arrived since the last request -#' get_timeline("_R_Foundation", since_id = tw) -#' # get earlier tweets -#' get_timeline("_R_Foundation", max_id = tw) -#' -#' # get timelines for multiple users -#' tw <- get_timeline(c("_R_Foundation", "rOpenSci", "Bioconductor")) -#' tw -#' } -#' #' @family tweets +#' @seealso [user_timeline()] #' @export get_timeline <- function(user = NULL, n = 100, diff --git a/R/trends.R b/R/trends.R index 3f38bb6f..4ee8d67b 100644 --- a/R/trends.R +++ b/R/trends.R @@ -1,5 +1,6 @@ #' Get Twitter trends data. #' +#' `r lifecycle::badge("deprecated")` #' @inheritParams lookup_users #' @param woeid Numeric, WOEID (Yahoo! Where On Earth ID) or character #' string of desired town or country. Users may also supply latitude @@ -19,37 +20,6 @@ #' exclude hashtags. Defaults to FALSE--meaning, hashtags are #' included in returned trends. #' @inheritParams stream -#' @examples -#' if (auth_has_default()) { -#' -#' ## Retrieve available trends -#' trends <- trends_available() -#' trends -#' -#' ## Store WOEID for Worldwide trends -#' worldwide <- trends$woeid[grep("world", trends$name, ignore.case = TRUE)[1]] -#' -#' ## Retrieve worldwide trends datadata -#' ww_trends <- get_trends(worldwide) -#' -#' ## Preview trends data -#' ww_trends -#' -#' ## Retrieve trends data using latitude, longitude near New York City -#' nyc_trends <- get_trends(lat = 40.7, lng = -74.0) -#' -#' ## should be same result if lat/long supplied as first argument -#' nyc_trends <- get_trends(c(40.7, -74.0)) -#' -#' ## Preview trends data -#' nyc_trends -#' -#' ## Provide a city or location name using a regular expression string to -#' ## have the function internals do the WOEID lookup/matching for you -#' (luk <- get_trends("london")) -#' -#' } -#' #' @return Tibble data frame of trends data for a given geographical area. #' @family trends #' @export @@ -144,16 +114,9 @@ format_trend_date <- function(x) { #' Available Twitter trends along with associated WOEID. #' +#' `r lifecycle::badge("deprecated")` #' @inheritParams lookup_users #' -#' @examples -#' if (auth_has_default()) { -#' ## Retrieve available trends -#' trends <- trends_available() -#' trends -#' -#' } -#' #' @return Data frame with WOEID column. WOEID is a Yahoo! Where On #' Earth ID. #' @family trends diff --git a/R/ts_plot.R b/R/ts_plot.R index 58c03c2c..530fc4d3 100644 --- a/R/ts_plot.R +++ b/R/ts_plot.R @@ -1,7 +1,7 @@ #' Plots tweets data as a time series-like data object. #' #' Creates a ggplot2 plot of the frequency of tweets over a specified -#' interval of time. +#' interval of time. `r lifecycle::badge("deprecated")` #' #' @param data Data frame or grouped data frame. #' @param by Desired interval of time expressed as numeral plus one of @@ -16,19 +16,8 @@ #' @return If #' [ggplot2](https://cran.r-project.org/package=ggplot2) is #' installed then a [ggplot2::ggplot()] plot object. -#' @examples -#' -#' if (auth_has_default()) { -#' ## search for tweets containing "rstats" -#' rt <- search_tweets("rstats", n = 100) -#' -#' ## plot frequency in 1 min intervals -#' ts_plot(rt, "mins") -#' -#' ## examine all Twitter activity using weekly intervals -#' ts_plot(rt, "hours") -#' } #' @family ts_data +#' @keywords internal #' @export ts_plot <- function(data, by = "days", trim = 0L, tz ="UTC", ...) { lifecycle::deprecate_stop("2.0.0", function_call()) @@ -51,7 +40,7 @@ ts_plot <- function(data, by = "days", trim = 0L, tz ="UTC", ...) { #' Converts tweets data into time series-like data object. #' #' Returns data containing the frequency of tweets over a specified -#' interval of time. +#' interval of time. `r lifecycle::badge("deprecated")` #' #' @param data Data frame or grouped data frame. #' @param by Desired interval of time expressed as numeral plus one of @@ -62,22 +51,7 @@ ts_plot <- function(data, by = "days", trim = 0L, tz ="UTC", ...) { #' each time series #' @param tz Time zone to be used, defaults to "UTC" (Twitter default) #' @return Data frame with time, n, and grouping column if applicable. -#' @examples -#' if (auth_has_default()) { -#' -#' ## handles of women senators -#' orgs <- c("_R_Foundation", "ropensci") -#' -#' ## get timelines for each -#' orgs_tml <- get_timeline(orgs, n = 100) -#' -#' ## get single time series for tweets -#' ts_data(orgs_tml) -#' -#' ## using weekly intervals -#' ts_data(orgs_tml, "weeks") -#' } -#' +#' @keywords internal #' @export ts_data <- function(data, by = "days", trim = 0L, tz ="UTC") { lifecycle::deprecate_stop("2.0.0", function_call()) diff --git a/R/tweet_shot.R b/R/tweet_shot.R index df5c3f37..91c7f15f 100644 --- a/R/tweet_shot.R +++ b/R/tweet_shot.R @@ -3,6 +3,7 @@ #' Provide a status id or a full Twitter link to a tweet and this function #' will capture an image of the tweet --- or tweet + thread (if there are #' Twitter-linked replies) --- from the mobile version of said tweet/thread. +#' `r lifecycle::badge("deprecated")` #' #' For this to work, you will need to ensure the packages in `Suggests:` are #' installed as they will be loaded upon the first invocation of this function. diff --git a/R/tweet_threading.R b/R/tweet_threading.R index 4f588000..e77accdc 100644 --- a/R/tweet_threading.R +++ b/R/tweet_threading.R @@ -4,6 +4,7 @@ #' own tweets). By default the function traverses first backwards from the #' origin status_id of the thread up to the root, then checks if there are any #' child statuses that were posted after the origin status. +#' `r lifecycle::badge("deprecated")` #' #' The backwards method looks up the tweet which is replying to, so it works if #' starting from the last tweet of the thread. @@ -16,11 +17,6 @@ #' It is not recommended to change the default if you don't know at which point of a thread you are starting. #' @param verbose logical, output to console status of traverse. #' @return Tweets in a structure like [lookup_tweets()]. -#' @examples -#' if (auth_has_default()) { -#' tw_thread <- tweet_threading("1461776330584956929") -#' tw_thread -#' } #' @export tweet_threading <- function(tw, traverse = c("backwards", "forwards"), verbose = FALSE) { diff --git a/R/user_id.R b/R/user_id.R index e4a71118..94ffa1b9 100644 --- a/R/user_id.R +++ b/R/user_id.R @@ -18,14 +18,6 @@ #' not static and may change over longer periods of time. #' #' @param x A character vector of Twitter screen names. -#' @examples -#' if (auth_has_default()) { -#' # Look up user with id -#' lookup_users("25594077") -#' -#' # Look up user with name 25594077 -#' lookup_users(as_screenname("123456")) -#' } #' @family users #' @rdname as_screenname #' @export diff --git a/R/users.R b/R/users.R index add0d92c..4f57c313 100644 --- a/R/users.R +++ b/R/users.R @@ -7,13 +7,9 @@ #' #' @examples #' -#' if (auth_has_default()) { +#' if (FALSE) { #' users <- c("twitter", "rladiesglobal", "_R_Foundation") #' users <- lookup_users(users) -#' users -#' -#' # latest tweet from each user -#' tweets_data(users) #' } #' #' @return A tibble of users data. diff --git a/man/as_screenname.Rd b/man/as_screenname.Rd index 4de7f87c..0c811888 100644 --- a/man/as_screenname.Rd +++ b/man/as_screenname.Rd @@ -27,15 +27,6 @@ tell rtweet that it's actually a screen name. Note that in general, you are best off using user ids; screen names are not static and may change over longer periods of time. } -\examples{ -if (auth_has_default()) { -# Look up user with id -lookup_users("25594077") - -# Look up user with name 25594077 -lookup_users(as_screenname("123456")) -} -} \seealso{ Other users: \code{\link{lists_subscribers}()}, diff --git a/man/clean_tweets.Rd b/man/clean_tweets.Rd index 3ecbe0cf..88939a81 100644 --- a/man/clean_tweets.Rd +++ b/man/clean_tweets.Rd @@ -17,14 +17,5 @@ A vector with the text without the entities selected \description{ Removes from the text, users mentions, hashtags, urls and media. Some urls or other text might remain if it is not recognized as an entity by -the API. -} -\examples{ -if (auth_has_default()) { -tweets <- search_tweets("weather") -tweets - -# tweets -clean_tweets(tweets) -} +the API. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } diff --git a/man/direct_messages.Rd b/man/direct_messages.Rd index b75da920..8a545105 100644 --- a/man/direct_messages.Rd +++ b/man/direct_messages.Rd @@ -65,16 +65,13 @@ A list with one element for each page of results. \description{ Returns all Direct Message events (both sent and received) within the last 30 days. Sorted in reverse-chronological order. Includes detailed information -about the sender and recipient. +about the sender and recipient. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ \dontrun{ ## get my direct messages -dms <- direct_messages() - -## inspect data structure -str(dms) +direct_messages() } } diff --git a/man/direct_messages_received.Rd b/man/direct_messages_received.Rd index 0ba20f2a..4fa96ef9 100644 --- a/man/direct_messages_received.Rd +++ b/man/direct_messages_received.Rd @@ -43,16 +43,8 @@ this endpoint. ## get my direct messages dms <- direct_messages_received() - -## inspect data structure -str(dms) - ## get direct messages I've sent sdms <- direct_messages_sent() - -## inspect data structure -str(dms) - } } diff --git a/man/do_call_rbind.Rd b/man/do_call_rbind.Rd index 5206cbf9..ea6c2b4b 100644 --- a/man/do_call_rbind.Rd +++ b/man/do_call_rbind.Rd @@ -20,29 +20,6 @@ functions. } \description{ Row bind lists of tweets/users data whilst also preserving and binding -users/tweets attribute data. -} -\examples{ - -if (auth_has_default()) { - -## lapply through three different search queries -lrt <- lapply( - c("rstats OR tidyverse", "data science", "python"), - search_tweets, - n = 100 -) - -## convert list object into single parsed data rame -rt <- do_call_rbind(lrt) - -## preview tweets data -rt - -## preview users data -users_data(rt) - -} - +users/tweets attribute data. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \concept{parsing} diff --git a/man/entity.Rd b/man/entity.Rd index 34bc44ce..8f9ad203 100644 --- a/man/entity.Rd +++ b/man/entity.Rd @@ -24,17 +24,3 @@ Extract entities of the tweets linked to a tweet id. \details{ The position of where does this occur is not provided. } -\examples{ -if (auth_has_default()) { - statuses <- c( - "567053242429734913", - "266031293945503744", - "440322224407314432" - ) - - ## lookup tweets data for given statuses - tw <- lookup_tweets(statuses) - entity(tw, "urls") - -} -} diff --git a/man/get_favorites.Rd b/man/get_favorites.Rd index 8ca2d50a..37634555 100644 --- a/man/get_favorites.Rd +++ b/man/get_favorites.Rd @@ -67,18 +67,11 @@ A tibble with one row for each tweet. } \description{ Returns up to 3,000 tweets liked/favorited for each \code{user}. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ -if (auth_has_default()) { -# get likes for a single user -kfc <- get_favorites("KFC") -kfc -# get newer likes since last request -newer <- get_favorites("KFC", since_id = kfc) - -# get likes from multiple users -favs <- get_favorites(c("Lesdoggg", "pattonoswalt", "meganamram")) -favs +if (FALSE) { + get_favorites("KFC") } } \references{ diff --git a/man/get_followers.Rd b/man/get_followers.Rd index 32c9aa7f..f9fc94d8 100644 --- a/man/get_followers.Rd +++ b/man/get_followers.Rd @@ -68,16 +68,11 @@ followers and another one "to_id" with the user used as input. } \description{ Returns a list of user IDs for the accounts following specified -user. +user. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ -if (auth_has_default()) { +if (FALSE) { users <- get_followers("_R_Foundation") - users - - # use `cursor` to find the next "page" of results - more_users <- get_followers("_R_Foundation", cursor = users) - } } \references{ diff --git a/man/get_friends.Rd b/man/get_friends.Rd index 9b421418..ece450d2 100644 --- a/man/get_friends.Rd +++ b/man/get_friends.Rd @@ -69,7 +69,7 @@ user and "to_id" for accounts ID they follow. } \description{ Returns a list of user IDs for the accounts following BY one or -more specified users. +more specified users. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \details{ Generally, you should not need to set \code{n} to more than 5,000 since Twitter @@ -81,9 +81,8 @@ If a user is protected the API will omit all requests so you'll need to find which user is protected. rtweet will warn you and the output will be \code{NA}. } \examples{ -if (auth_has_default()) { -users <- get_friends("ropensci") -users +if (FALSE) { + get_friends("ropensci") } } \references{ diff --git a/man/get_mentions.Rd b/man/get_mentions.Rd index 5d81da89..051047a5 100644 --- a/man/get_mentions.Rd +++ b/man/get_mentions.Rd @@ -69,16 +69,7 @@ Tibble of mentions data. Returns data on up to 200 of the most recent mentions (Tweets containing a users' screen_name) of the authenticating user. The timeline returned is the equivalent of the one seen when you view -your mentions on twitter.com. -} -\examples{ -if (auth_has_default()) { - tw <- get_mentions() - tw - - # newer mentions - get_mentions(since_id = tw) -} +your mentions on twitter.com. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/overview} diff --git a/man/get_timeline.Rd b/man/get_timeline.Rd index bbbba3ba..6add5c4f 100644 --- a/man/get_timeline.Rd +++ b/man/get_timeline.Rd @@ -94,30 +94,15 @@ A tbl data frame of tweets data with users data attribute. \code{get_timeline()} returns the timeline of any Twitter user (i.e. what they have tweeted). \code{get_my_timeline()} returns the home timeline for the authenticated user (i.e. the tweets you see when you log into Twitter). -} -\details{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} At most up to 3,200 of a user's most recent Tweets can be retrieved. -} -\examples{ -if (auth_has_default()) { -tw <- get_timeline("_R_Foundation") -tw - -# get tweets that arrived since the last request -get_timeline("_R_Foundation", since_id = tw) -# get earlier tweets -get_timeline("_R_Foundation", max_id = tw) - -# get timelines for multiple users -tw <- get_timeline(c("_R_Foundation", "rOpenSci", "Bioconductor")) -tw -} - } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/tweets/timelines/overview} } \seealso{ +\code{\link[=user_timeline]{user_timeline()}} + Other tweets: \code{\link{get_favorites}()}, \code{\link{get_mentions}()}, diff --git a/man/get_trends.Rd b/man/get_trends.Rd index 3c7d44b5..1c369952 100644 --- a/man/get_trends.Rd +++ b/man/get_trends.Rd @@ -47,39 +47,7 @@ Twitter API.} Tibble data frame of trends data for a given geographical area. } \description{ -Get Twitter trends data. -} -\examples{ -if (auth_has_default()) { - -## Retrieve available trends -trends <- trends_available() -trends - -## Store WOEID for Worldwide trends -worldwide <- trends$woeid[grep("world", trends$name, ignore.case = TRUE)[1]] - -## Retrieve worldwide trends datadata -ww_trends <- get_trends(worldwide) - -## Preview trends data -ww_trends - -## Retrieve trends data using latitude, longitude near New York City -nyc_trends <- get_trends(lat = 40.7, lng = -74.0) - -## should be same result if lat/long supplied as first argument -nyc_trends <- get_trends(c(40.7, -74.0)) - -## Preview trends data -nyc_trends - -## Provide a city or location name using a regular expression string to -## have the function internals do the WOEID lookup/matching for you -(luk <- get_trends("london")) - -} - +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \seealso{ Other trends: diff --git a/man/ids.Rd b/man/ids.Rd index f57a681f..9f282335 100644 --- a/man/ids.Rd +++ b/man/ids.Rd @@ -15,13 +15,3 @@ ids(x, ...) Extract the ids of the rtweet data if present. Depending on the object type it returns either users ids, tweet ids or rules ids. } -\examples{ -if (auth_has_default()) { - users <- lookup_users(c("twitter", "rladiesglobal", "_R_Foundation")) - ids(users) - followers <- get_followers("_R_Foundation") - head(ids(followers)) - friends <- get_friends("_R_Foundation") - head(ids(friends)) -} -} diff --git a/man/lat_lng.Rd b/man/lat_lng.Rd index 53a2ef2c..9e1f9562 100644 --- a/man/lat_lng.Rd +++ b/man/lat_lng.Rd @@ -31,7 +31,7 @@ and longitude vars. } \description{ Appends parsed Twitter data with latitude and longitude variables -using all available geolocation information. +using all available geolocation information. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \details{ On occasion values may appear to be outliers given a @@ -41,19 +41,6 @@ tweets returned a large bounding box that overlapped with the area of interest. This function converts boxes into their geographical midpoints, which works well in the vast majority of cases, but sometimes includes an otherwise puzzling result. -} -\examples{ - -if (auth_has_default()) { - -## stream tweets sent from the US -rt <- search_tweets(geocode = lookup_coords("usa")) - -## use lat_lng to recover full information geolocation data -rtl_loc <- lat_lng(rt) -rtl_loc -} - } \seealso{ Other geo: diff --git a/man/links.Rd b/man/links.Rd index b766e90f..f85f6eb5 100644 --- a/man/links.Rd +++ b/man/links.Rd @@ -15,13 +15,3 @@ links(x, ...) create the links from the rtweet data present. Depending on the object type it returns either users links, tweet links or rules links. } -\examples{ -if (auth_has_default()) { - users <- lookup_users(c("twitter", "rladiesglobal", "_R_Foundation")) - links(users) - followers <- get_followers("_R_Foundation") - head(links(followers)) - friends <- get_friends("_R_Foundation") - head(links(friends)) -} -} diff --git a/man/lists_members.Rd b/man/lists_members.Rd index d0d441c3..4b74af98 100644 --- a/man/lists_members.Rd +++ b/man/lists_members.Rd @@ -72,20 +72,6 @@ Twitter API.} } \description{ Get Twitter list members (users on a given list). -} -\examples{ -if (auth_has_default()) { - -## get list members for a list of rstats experts using list_id -(rstats <- lists_members("1260528710559694850")) - -## get list members for an rstats list using list topic slug -## list owner's screen name -rstats <- lists_members(slug = "r-people", owner_user = "Lluis_Revilla") -rstats - -} - } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-members} diff --git a/man/lists_memberships.Rd b/man/lists_memberships.Rd index ba29c12c..6ea1998a 100644 --- a/man/lists_memberships.Rd +++ b/man/lists_memberships.Rd @@ -71,18 +71,6 @@ progress?} Due to deleted or removed lists, the returned number of memberships is often less than the provided n value. This is a reflection of the API and not a unique quirk of rtweet. -} -\examples{ -if (auth_has_default()) { - -## get up to 1000 Twitter lists that include Nate Silver -R_foundation <- lists_memberships("_R_Foundation", n = 1000) - -## view data -R_foundation - -} - } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-memberships} diff --git a/man/lists_statuses.Rd b/man/lists_statuses.Rd index 9021201b..68c17516 100644 --- a/man/lists_statuses.Rd +++ b/man/lists_statuses.Rd @@ -84,12 +84,6 @@ data \description{ Get a timeline of tweets authored by members of a specified list. } -\examples{ -if (auth_has_default()) { - (rladies <- lists_statuses(list_id = "839186302968848384")) - (rladies <- lists_statuses(slug = "rladies1", owner_user = "RLadiesGlobal")) -} -} \seealso{ Other lists: \code{\link{lists_members}()}, diff --git a/man/lists_subscribers.Rd b/man/lists_subscribers.Rd index 6b10ab31..1e5b69fc 100644 --- a/man/lists_subscribers.Rd +++ b/man/lists_subscribers.Rd @@ -64,13 +64,6 @@ default for all calls. See \code{\link[=auth_as]{auth_as()}} for details.} } \description{ Get subscribers of a specified list. -} -\examples{ -if (auth_has_default()) { - ## get subscribers of rladies list - rstats <- lists_subscribers(slug = "rladies1", owner_user = "rladiesglobal") -} - } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscribers} diff --git a/man/lists_subscriptions.Rd b/man/lists_subscriptions.Rd index 797c8480..7cd251c6 100644 --- a/man/lists_subscriptions.Rd +++ b/man/lists_subscriptions.Rd @@ -63,13 +63,6 @@ default for all calls. See \code{\link[=auth_as]{auth_as()}} for details.} \description{ Get list subscriptions of a given user but does not include the user's own lists. -} -\examples{ -if (auth_has_default()) { -## get ropensci subscriptions -rstats <- lists_subscriptions(user = "rladiesglobal", n = 1000) -} - } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/get-lists-subscriptions} diff --git a/man/lists_users.Rd b/man/lists_users.Rd index 0bd9414f..c28daba1 100644 --- a/man/lists_users.Rd +++ b/man/lists_users.Rd @@ -27,15 +27,6 @@ data } \description{ Get all lists a specified user subscribes to, including their own. -} -\examples{ -if (auth_has_default()) { - -## get lists subscribed to by R_Foundation -lists_users("ropensci") - -} - } \seealso{ Other lists: diff --git a/man/lookup_coords.Rd b/man/lookup_coords.Rd index 749ef5da..92593b58 100644 --- a/man/lookup_coords.Rd +++ b/man/lookup_coords.Rd @@ -58,12 +58,6 @@ usa <- lookup_coords("usa") lnd <- lookup_coords("london") bz <- lookup_coords("brazil") -## pass a returned coords object to search_tweets -bztw <- search_tweets(geocode = bz) - -## or stream tweets -ustw <- stream_tweets(usa, timeout = 10) - } } diff --git a/man/lookup_tweets.Rd b/man/lookup_tweets.Rd index 2688aedd..148fbb7f 100644 --- a/man/lookup_tweets.Rd +++ b/man/lookup_tweets.Rd @@ -43,26 +43,14 @@ progress?} A tibble of tweets data. } \description{ -Get tweets data for given statuses (status IDs). -} -\examples{ - -if (auth_has_default()) { - statuses <- c( - "567053242429734913", - "266031293945503744", - "440322224407314432" - ) - - ## lookup tweets data for given statuses - tw <- lookup_tweets(statuses) - tw -} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/get-statuses-lookup} } \seealso{ +\code{\link[=tweet_search_recent]{tweet_search_recent()}} + Other tweets: \code{\link{get_favorites}()}, \code{\link{get_mentions}()}, diff --git a/man/lookup_users.Rd b/man/lookup_users.Rd index 0d892dd4..7323d103 100644 --- a/man/lookup_users.Rd +++ b/man/lookup_users.Rd @@ -46,13 +46,9 @@ Get Twitter users data for given users (user IDs or screen names). } \examples{ -if (auth_has_default()) { +if (FALSE) { users <- c("twitter", "rladiesglobal", "_R_Foundation") users <- lookup_users(users) - users - - # latest tweet from each user - tweets_data(users) } } diff --git a/man/max_id.Rd b/man/max_id.Rd index b6a7b85f..24b5dd0a 100644 --- a/man/max_id.Rd +++ b/man/max_id.Rd @@ -13,16 +13,4 @@ max_id(x) These internal helpers extract the ids passed on to the \code{max_id} and \code{since_id} arguments to functions that use \code{\link[=TWIT_paginate_max_id]{TWIT_paginate_max_id()}}. } -\examples{ -if (auth_has_default()) { -tw <- search_tweets("#rstats") - -# retrieve older tweets -older <- search_tweets("#rstats", max_id = tw) -even_older <- search_tweets("#rstats", max_id = older) - -# retrieve newer tweets -newer <- search_tweets("#rstats", since_id = tw) -} -} \keyword{internal} diff --git a/man/network_data.Rd b/man/network_data.Rd index 93ae2dda..ddc3643f 100644 --- a/man/network_data.Rd +++ b/man/network_data.Rd @@ -33,31 +33,7 @@ various network classes. } \details{ Retrieve data to know which users are connected to which users. -} -\examples{ -if (auth_has_default()) { - ## search for #rstats tweets - rstats <- search_tweets("#rstats", n = 200) - - ## create from-to data frame representing retweet/mention/reply connections - rstats_net <- network_data(rstats, c("retweet","mention","reply")) - - ## view edge data frame - rstats_net - - ## view user_id->screen_name index - attr(rstats_net, "idsn") - - ## if igraph is installed... - if (requireNamespace("igraph", quietly = TRUE)) { - - ## (1) convert directly to graph object representing semantic network - rstats_net <- network_graph(rstats) - - ## (2) plot graph via igraph.plotting - plot(rstats_net) - } -} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \seealso{ network_graph diff --git a/man/next_cursor.Rd b/man/next_cursor.Rd index deaa66a5..7c7bc002 100644 --- a/man/next_cursor.Rd +++ b/man/next_cursor.Rd @@ -13,10 +13,4 @@ since_id(x) This internal helper extracts the cursor from the object passed to the \code{cursor} argument of the functions that use \code{\link[=TWIT_paginate_cursor]{TWIT_paginate_cursor()}}. } -\examples{ -if (auth_has_default()) { -page1 <- get_followers("_R_Foundation") -page2 <- get_followers("_R_Foundation", cursor = page1) -} -} \keyword{internal} diff --git a/man/parse_stream.Rd b/man/parse_stream.Rd index b1448c0b..3fc4e61a 100644 --- a/man/parse_stream.Rd +++ b/man/parse_stream.Rd @@ -14,6 +14,7 @@ parse_stream(path, ...) } \description{ Converts Twitter stream data (JSON file) into parsed data frame. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \examples{ \dontrun{ diff --git a/man/post_destroy.Rd b/man/post_destroy.Rd index 740b547e..3ccb835c 100644 --- a/man/post_destroy.Rd +++ b/man/post_destroy.Rd @@ -16,14 +16,11 @@ a single API call. In many cases you are better off changing the default for all calls. See \code{\link[=auth_as]{auth_as()}} for details.} } \description{ -Deletes a status of user's profile. -} -\examples{ -if (auth_has_default()) { - pt <- post_tweet("Running #rtweet examples") - post_destroy(ids(pt)) -} +Deletes a status of user's profile. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-destroy-id} } +\seealso{ +\code{\link[=tweet_delete]{tweet_delete()}} +} diff --git a/man/post_favorite.Rd b/man/post_favorite.Rd index 1bc32081..ddbe6928 100644 --- a/man/post_favorite.Rd +++ b/man/post_favorite.Rd @@ -27,13 +27,7 @@ a single API call. In many cases you are better off changing the default for all calls. See \code{\link[=auth_as]{auth_as()}} for details.} } \description{ -Favorites target status id. -} -\examples{ -if (auth_has_default()) { - rt <- search_tweets("#rstats", n = 1) - post_favorite(rt$id_str) -} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ Create: \url{https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-favorites-create} diff --git a/man/post_follow.Rd b/man/post_follow.Rd index 0c1798f2..f9dacc45 100644 --- a/man/post_follow.Rd +++ b/man/post_follow.Rd @@ -44,13 +44,7 @@ a single API call. In many cases you are better off changing the default for all calls. See \code{\link[=auth_as]{auth_as()}} for details.} } \description{ -Follows target Twitter user. -} -\examples{ -if (auth_has_default()) { - post_follow("_R_Foundation") - post_follow("rtweet", mute = TRUE) # Mute -} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ Update: \url{https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/post-friendships-update} diff --git a/man/post_list.Rd b/man/post_list.Rd index dbcf0d4e..b6559ce8 100644 --- a/man/post_list.Rd +++ b/man/post_list.Rd @@ -41,46 +41,7 @@ default for all calls. See \code{\link[=auth_as]{auth_as()}} for details.} Response object from HTTP request. } \description{ -Create, add users, and destroy Twitter lists -} -\examples{ -\dontrun{ - -## R related Twitter accounts -users <- c("_R_Foundation", "R_dev_news", "rweekly_live", "RConsortium", "rstats4ds", - "icymi_r", "rstatstweet", "RLadiesGlobal") - -## create r-accounts list with 8 total users -(r_lst <- post_list(users, - "r-accounts", description = "R related accounts")) - -## view list in browser at https://twitter.com//lists/r-accounts - -## search for more rstats users -r_users <- search_users("rstats", n = 200) - -## filter and select more users to add to list -more_users <- r_users$screen_name[r_users$verified] - -## add more users to list- note: can only add up to 100 at a time -post_list(users = more_users, slug = "r-accounts") - -## view updated list in browser (should be around 100 users) -## view list in browser at https://twitter.com//lists/r-accounts - -drop_users <- "icymi_r" - -## drop these users from the R list -post_list(users = drop_users, slug = "r-accounts", - destroy = TRUE) - -## view updated list in browser (should be around 100 users) -## view list in browser at https://twitter.com//lists/r-accounts - -## delete list entirely -post_list(slug = "r-accounts", destroy = TRUE) - -} +Create, add users, and destroy Twitter lists. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ Create: \url{https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/create-manage-lists/api-reference/post-lists-create} diff --git a/man/post_tweet.Rd b/man/post_tweet.Rd index 3cb3ac29..6c52f502 100644 --- a/man/post_tweet.Rd +++ b/man/post_tweet.Rd @@ -68,45 +68,7 @@ been sent from. Value should be TRUE or FALSE. This parameter would apply only if you have provided a valid \code{lat/long} pair of valid values.} } \description{ -Posts status update to user's Twitter account -} -\examples{ -if (auth_has_default()) { -## generate data to make/save plot (as a .png file) -x <- rnorm(300) -y <- x + rnorm(300, 0, .75) -col <- c(rep("#002244aa", 50), rep("#440000aa", 50)) -bg <- c(rep("#6699ffaa", 50), rep("#dd6666aa", 50)) - -## create temporary file name -tmp <- tempfile(fileext = ".png") - -## save as png -png(tmp, 6, 6, "in", res = 127.5) -par(tcl = -.15, family = "Inconsolata", - font.main = 2, bty = "n", xaxt = "l", yaxt = "l", - bg = "#f0f0f0", mar = c(3, 3, 2, 1.5)) -plot(x, y, xlab = NULL, ylab = NULL, pch = 21, cex = 1, - bg = bg, col = col, - main = "This image was uploaded by rtweet") -grid(8, lwd = .15, lty = 2, col = "#00000088") -dev.off() - -## post tweet with media attachment -post_tweet("a tweet with media attachment", media = tmp, - media_alt_text = "Random points example of rtweet::post_tweet. - rtweet requires alt text with all media") - -# example of replying within a thread -## first post -pt <- post_tweet(status="first in a thread") - -reply_id <- ids(pt) - -## post reply -post_tweet("second in the thread", - in_reply_to_status_id = reply_id) -} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ Tweet: \url{https://developer.twitter.com/en/docs/twitter-api/v1/tweets/post-and-engage/api-reference/post-statuses-update} @@ -115,6 +77,8 @@ Media: \url{https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-me Alt-text: \url{https://developer.twitter.com/en/docs/twitter-api/v1/media/upload-media/api-reference/post-media-metadata-create} } \seealso{ +\code{\link[=tweet_post]{tweet_post()}} + Other post: \code{\link{post_favorite}()}, \code{\link{post_follow}()}, diff --git a/man/rate_limit.Rd b/man/rate_limit.Rd index c6ce259a..a401875f 100644 --- a/man/rate_limit.Rd +++ b/man/rate_limit.Rd @@ -34,10 +34,8 @@ You should not need to use these function in the usual operation of rtweet because all paginated functions will wait on your behalf if you set \code{retryonratelimit = TRUE}. } -\examples{ -if (auth_has_default()) { -rate_limit() -} +\details{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/developer-utilities/rate-limit-status} diff --git a/man/read_twitter_csv.Rd b/man/read_twitter_csv.Rd index 7972230a..ccde4200 100644 --- a/man/read_twitter_csv.Rd +++ b/man/read_twitter_csv.Rd @@ -18,15 +18,7 @@ A tbl data frame of Twitter data } \description{ Reads Twitter data that was previously saved as a CSV file. -} -\examples{ - -\dontrun{ - -## read in data.csv -rt <- read_twitter_csv("data.csv") - -} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \seealso{ Other datafiles: diff --git a/man/rtweet_client.Rd b/man/rtweet_client.Rd index 0cfd7573..93119041 100644 --- a/man/rtweet_client.Rd +++ b/man/rtweet_client.Rd @@ -22,10 +22,12 @@ Leave \code{NULL} to allow everything or choose yours with \code{set_scopes()}.} Set up your client mechanism for the Twitter API. } \examples{ +\donttest{ if (interactive()) { rtweet_client() } } +} \seealso{ scopes } diff --git a/man/rtweet_user.Rd b/man/rtweet_user.Rd index c38e94f9..23fa6ab9 100644 --- a/man/rtweet_user.Rd +++ b/man/rtweet_user.Rd @@ -87,8 +87,6 @@ since the default behaviour is to use ask_pass that if possible uses \examples{ \dontrun{ -rtweet_user() -rtweet_bot() rtweet_app() } } diff --git a/man/search_fullarchive.Rd b/man/search_fullarchive.Rd index f6221190..18797f96 100644 --- a/man/search_fullarchive.Rd +++ b/man/search_fullarchive.Rd @@ -90,6 +90,7 @@ See the info provided by Twitter and the "Developer Account" section. } \details{ Note: The \code{env_name} must match the ones you set up for the token you are using. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \section{Developer Account}{ @@ -154,19 +155,7 @@ followed by a word or quoted phrase (if appropriate)–e.g.,} \code{lang:en} } } -\examples{ - -\dontrun{ -## search fullarchive for up to 300 rstats tweets sent in Jan 2014 -rt <- search_fullarchive("#rstats", n = 300, env_name = "SetYourLabel", - fromDate = "201401010000", toDate = "201401312359") - -toDate <- format(Sys.time() - 60 * 60 * 24 * 7, "\%Y\%m\%d\%H\%M") - -## search 30day for up to 300 rstats tweets sent before the last week -rt <- search_30day("#rstats", n = 300, - env_name = "SetYourLabel", toDate = toDate) -} - +\seealso{ +\code{\link[=tweet_search_recent]{tweet_search_recent()}}, \code{\link[=tweet_search_all]{tweet_search_all()}} } \concept{premium endpoints} diff --git a/man/search_tweets.Rd b/man/search_tweets.Rd index d3868f99..b8891044 100644 --- a/man/search_tweets.Rd +++ b/man/search_tweets.Rd @@ -120,10 +120,11 @@ A tbl data frame with additional "query" column. } \description{ Returns Twitter statuses matching a user provided search -query. ONLY RETURNS DATA FROM THE PAST 6-9 DAYS. +query. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} search_tweets2 Passes all arguments to search_tweets. Returns data from one OR MORE search queries. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \details{ Twitter API documentation recommends limiting searches to @@ -132,48 +133,15 @@ errors preventing recovery of information related to the query. It should also be noted Twitter's search API does not consist of an index of all Tweets. At the time of searching, the search API index includes between only 6-9 days of Tweets. -} -\examples{ -if (auth_has_default()) { -tweets <- search_tweets("weather") -tweets - -# data about the users who made those tweets -users_data(tweets) - -# Retrieve all the tweets made since the previous request -# (there might not be any if people aren't tweeting about the weather) -newer <- search_tweets("weather", since_id = tweets) -# Retrieve tweets made before the previous request -older <- search_tweets("weather", max_id = tweets) - -# Restrict to English only, and ignore retweets -tweets2 <- search_tweets("weather", lang = "en", include_rts = FALSE) -} -if (auth_has_default()) { - -## search using multiple queries -st2 <- search_tweets2( - c("\"data science\"", "rstats OR python"), - n = 500 -) - -## preview tweets data -st2 - -## preview users data -users_data(st2) - -## check breakdown of results by search query -table(st2$query) - -} - } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/tweets/search/api-reference/get-search-tweets} } \seealso{ +\code{\link[=tweet_search_recent]{tweet_search_recent()}}, \code{\link[=tweet_search_all]{tweet_search_all()}} + +\code{\link[=tweet_search_recent]{tweet_search_recent()}} + Other tweets: \code{\link{get_favorites}()}, \code{\link{get_mentions}()}, diff --git a/man/search_users.Rd b/man/search_users.Rd index dbf729b4..9b0eee31 100644 --- a/man/search_users.Rd +++ b/man/search_users.Rd @@ -41,22 +41,14 @@ Data frame with one row for each matching user. } \description{ Search for Twitter users. The Twitter API limits the results to at most -1,000 users. -} -\examples{ -if (auth_has_default()) { -users <- search_users("#rstats", n = 300) -users - -# latest tweet from each user -tweets_data(users) -} - +1,000 users. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/follow-search-get-users/api-reference/get-users-search} } \seealso{ +\code{\link[=user_search]{user_search()}} + Other users: \code{\link{as_screenname}()}, \code{\link{lists_subscribers}()}, diff --git a/man/stream_tweets.Rd b/man/stream_tweets.Rd index 361ce1a4..78bda90a 100644 --- a/man/stream_tweets.Rd +++ b/man/stream_tweets.Rd @@ -66,21 +66,8 @@ Streams public statuses to a file via one of the following four methods: Learn more in \code{vignette("stream", package = "rtweet")} } -\examples{ -\dontrun{ -# stream tweets mentioning "#rstats" for 10 seconds -rstats1 <- stream_tweets("#rstats", timeout = 10, file_name = "rstats.json") -rstats1 - -# Download another 10s worth of data to the same file -rstats2 <- stream_tweets("#rstats", timeout = 10, file_name = "rstats.json", - append = TRUE) - -# stream tweets about continental USA for 10 seconds -usa <- stream_tweets(location = lookup_coords("usa"), file_name = "usa.json", - timeout = 10) - -} +\details{ +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ They were removed from the website. @@ -88,5 +75,5 @@ They were removed from the website. The webpages describing how it used to work were removed. } \seealso{ -\code{\link[=parse_stream]{parse_stream()}}. +\code{\link[=filtered_stream]{filtered_stream()}}. } diff --git a/man/trends_available.Rd b/man/trends_available.Rd index 458bab67..e4aab285 100644 --- a/man/trends_available.Rd +++ b/man/trends_available.Rd @@ -20,16 +20,7 @@ Data frame with WOEID column. WOEID is a Yahoo! Where On Earth ID. } \description{ -Available Twitter trends along with associated WOEID. -} -\examples{ -if (auth_has_default()) { -## Retrieve available trends -trends <- trends_available() -trends - -} - +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/v1/trends/locations-with-trending-topics/api-reference/get-trends-available} diff --git a/man/ts_data.Rd b/man/ts_data.Rd index 13b05b31..d2c9caaf 100644 --- a/man/ts_data.Rd +++ b/man/ts_data.Rd @@ -24,22 +24,6 @@ Data frame with time, n, and grouping column if applicable. } \description{ Returns data containing the frequency of tweets over a specified -interval of time. -} -\examples{ -if (auth_has_default()) { - -## handles of women senators -orgs <- c("_R_Foundation", "ropensci") - -## get timelines for each -orgs_tml <- get_timeline(orgs, n = 100) - -## get single time series for tweets -ts_data(orgs_tml) - -## using weekly intervals -ts_data(orgs_tml, "weeks") -} - +interval of time. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } +\keyword{internal} diff --git a/man/ts_plot.Rd b/man/ts_plot.Rd index 3fe10f85..d7bb0897 100644 --- a/man/ts_plot.Rd +++ b/man/ts_plot.Rd @@ -29,19 +29,7 @@ installed then a \code{\link[ggplot2:ggplot]{ggplot2::ggplot()}} plot object. } \description{ Creates a ggplot2 plot of the frequency of tweets over a specified -interval of time. -} -\examples{ - -if (auth_has_default()) { -## search for tweets containing "rstats" -rt <- search_tweets("rstats", n = 100) - -## plot frequency in 1 min intervals -ts_plot(rt, "mins") - -## examine all Twitter activity using weekly intervals -ts_plot(rt, "hours") -} +interval of time. \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \concept{ts_data} +\keyword{internal} diff --git a/man/tweet_delete.Rd b/man/tweet_delete.Rd index 9bb4618b..841d8f9e 100644 --- a/man/tweet_delete.Rd +++ b/man/tweet_delete.Rd @@ -17,14 +17,6 @@ created via \code{\link[=rtweet_oauth2]{rtweet_oauth2()}}) or a bearer token (ca } \description{ Will delete a tweet -} -\examples{ -if (FALSE) { - # It requires Oauth authentication - tp <- tweet_post("Running examples of #rtweet") - td <- tweet_delete(tp$id) -} - } \references{ \url{https://developer.twitter.com/en/docs/twitter-api/tweets/manage-tweets/api-reference/delete-tweets-id} diff --git a/man/tweet_quoted.Rd b/man/tweet_quoted.Rd index a8c569ae..532dd697 100644 --- a/man/tweet_quoted.Rd +++ b/man/tweet_quoted.Rd @@ -50,6 +50,3 @@ if (FALSE){ \references{ One tweet: \url{https://developer.twitter.com/en/docs/twitter-api/tweets/quote-tweets/api-reference/get-tweets-id-quote_tweets} } -\seealso{ -\code{\link[=lookup_tweets]{lookup_tweets()}} \code{\link[=tweet_get]{tweet_get()}} -} diff --git a/man/tweet_shot.Rd b/man/tweet_shot.Rd index 283c7274..ed45581f 100644 --- a/man/tweet_shot.Rd +++ b/man/tweet_shot.Rd @@ -23,6 +23,7 @@ own image manipulation.} Provide a status id or a full Twitter link to a tweet and this function will capture an image of the tweet --- or tweet + thread (if there are Twitter-linked replies) --- from the mobile version of said tweet/thread. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \details{ For this to work, you will need to ensure the packages in \verb{Suggests:} are diff --git a/man/tweet_threading.Rd b/man/tweet_threading.Rd index 218c7196..12610a17 100644 --- a/man/tweet_threading.Rd +++ b/man/tweet_threading.Rd @@ -23,6 +23,7 @@ Return all statuses that are part of a thread (Replies from a user to their own tweets). By default the function traverses first backwards from the origin status_id of the thread up to the root, then checks if there are any child statuses that were posted after the origin status. +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \details{ The backwards method looks up the tweet which is replying to, so it works if @@ -31,9 +32,3 @@ starting from the last tweet of the thread. The forwards method looks for newer replies to the tweet provided. If the tweet doesn't have a reply it won't be able to find anything. The forwards method is limited by the timeline API (See \code{\link[=get_timeline]{get_timeline()}}). } -\examples{ -if (auth_has_default()) { -tw_thread <- tweet_threading("1461776330584956929") -tw_thread -} -} diff --git a/man/user_block.Rd b/man/user_block.Rd index a1d77ca9..291eb75d 100644 --- a/man/user_block.Rd +++ b/man/user_block.Rd @@ -23,13 +23,7 @@ default for all calls. See \code{\link[=auth_as]{auth_as()}} for details.} \description{ \code{user_block(...)} blocks or unblocks a target twitter user. \code{user_unblock(...)} is synonymous to \code{user_block(..., unblock=TRUE)}. -} -\examples{ -if (auth_has_default()) { - user_block("rtweet") - user_unblock("rtweet") - user_block("rtweet", unblock=TRUE) #<-same as the above -} +\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} } \references{ Block: \url{https://developer.twitter.com/en/docs/twitter-api/v1/accounts-and-users/mute-block-report-users/api-reference/post-blocks-create} diff --git a/man/users_data.Rd b/man/users_data.Rd index 076e0fe2..4e6dc7e3 100644 --- a/man/users_data.Rd +++ b/man/users_data.Rd @@ -25,16 +25,3 @@ Showing these additional columns would clutter the default display, so rtweet instead stores in special attributes and allows you to show them with the \code{user_data()} and \code{tweets_data()} helpers. } -\examples{ -if (auth_has_default()) { - # find users from tweets - tweets <- search_tweets("r") - users_data(tweets) - full_search <- cbind(tweets, users_data(tweets)) - - # from tweets from users - users <- search_users("r") - tweets_data(users) - full_users <- cbind(users, tweets_data(users)) -} -} diff --git a/tests/testthat/_snaps/post-tweet.md b/tests/testthat/_snaps/post-tweet.md deleted file mode 100644 index fcf4088f..00000000 --- a/tests/testthat/_snaps/post-tweet.md +++ /dev/null @@ -1,29 +0,0 @@ -# Check geo-related inputs for post_tweet - - Code - msg <- paste("test geolocated error", Sys.time()) - post_tweet(msg, lat = "x", long = 0) - Condition - Error in `post_tweet()`: - ! `lat` must be numeric. - Code - post_tweet(msg, lat = 0, long = "x") - Condition - Error in `post_tweet()`: - ! `long` must be numeric. - Code - post_tweet(msg, lat = 91, long = 0) - Condition - Error in `post_tweet()`: - ! `lat` must be between -90 and 90 degrees. - Code - post_tweet(msg, lat = 0, long = 181) - Condition - Error in `post_tweet()`: - ! `long` must be between -180 and 180 degrees. - Code - post_tweet(msg, lat = 0, long = 0, display_coordinates = "error") - Condition - Error in `post_tweet()`: - ! `display_coordinates` must be TRUE/FALSE. - diff --git a/tests/testthat/_snaps/user_id.md b/tests/testthat/_snaps/user_id.md deleted file mode 100644 index dab6cdae..00000000 --- a/tests/testthat/_snaps/user_id.md +++ /dev/null @@ -1,8 +0,0 @@ -# screen_name has print and [ methods - - Code - x - Output - - [1] "123456" -