Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Overdue pull request with added playlist functions and fixed oauth. #134

Merged
merged 15 commits into from
Jul 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Generated by roxygen2: do not edit by hand

export("%>%")
export(add_video_to_playlist)
export(change_playlist_title)
export(create_playlist)
export(delete_captions)
export(delete_channel_sections)
export(delete_comments)
Expand All @@ -13,6 +16,8 @@ export(get_captions)
export(get_channel_stats)
export(get_comment_threads)
export(get_comments)
export(get_playlist_item_ids)
export(get_playlist_item_videoids)
export(get_playlist_items)
export(get_playlists)
export(get_related_videos)
Expand All @@ -33,6 +38,7 @@ export(list_regions)
export(list_videocats)
export(list_videos)
export(read_sbv)
export(update_video_metadata)
export(upload_caption)
export(upload_video)
export(yt_authorized)
Expand Down
51 changes: 51 additions & 0 deletions R/add_video_to_playlist.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
#' Add Video to Playlist
#'
#' @param playlist_id string; Required. The ID of the playlist.
#' @param video_id string; Required. The ID of the video to add.
#' @param ... Additional arguments passed to \code{\link{tuber_POST_json}}.
#'
#' @return Details of the added video in the playlist.
#'
#' @export
#' @references \url{https://developers.google.com/youtube/v3/docs/playlistItems/insert}
#'
#' @examples
#' \dontrun{
#'
#' # Set API token via yt_oauth() first
#'
#' add_video_to_playlist(playlist_id = "YourPlaylistID", video_id = "2_gLD1jarfU")
#' }

add_video_to_playlist <- function(playlist_id, video_id, position = NULL, ...) {

# Prepare the request body
if(is.null(position)){
body <- list(
snippet = list(
playlistId = playlist_id,
resourceId = list(
kind = "youtube#video",
videoId = video_id
)
)
)
} else {
body <- list(
snippet = list(
playlistId = playlist_id,
position = position,
resourceId = list(
kind = "youtube#video",
videoId = video_id
)
)
)
}

# Make the POST request using tuber_POST_json
raw_res <- tuber_POST_json(path = "playlistItems", query = list(part = "snippet"), body = body, ...)

# Return the response
return(raw_res)
}
49 changes: 49 additions & 0 deletions R/change_playlist_title.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
#' Change the title of a YouTube playlist.
#'
#' This function updates the title of an existing YouTube playlist using the YouTube Data API.
#'
#' @param playlist_id A character string specifying the ID of the playlist you want to update.
#' @param new_title A character string specifying the new title for the playlist.
#'
#' @return A list containing the server response after the update attempt.
#' @export
#'
#' @examples
#' \dontrun{
#' change_playlist_title(playlist_id = "YourPlaylistID", new_title = "New Playlist Title")
#' }
#'

change_playlist_title <- function(playlist_id, new_title) {
# Check for a valid token
yt_check_token()

# Define the body for the PUT request
body <- list(
id = playlist_id,
snippet = list(title = new_title)
)

body_json <- jsonlite::toJSON(body, auto_unbox = TRUE)

# Use the existing tuber infrastructure to send the PUT request
req <- httr::PUT(
url = "https://www.googleapis.com/youtube/v3/playlists",
query = list(key = getOption("google_key"), part = "snippet"),
config = httr::config(token = getOption("google_token")),
body = body_json,
httr::add_headers(
`Accept` = "application/json",
`Content-Type` = "application/json"
)
)

# Check for errors
tuber_check(req)

# Extract and return the content
return(httr::content(req))
}

# Example usage:
# change_playlist_title(playlist_id = "PLOfOyOpiu5saim7DsJmz61uCf8igQiTpF", new_title = "Lil' Casey's Top 40 Countdown 2023-09-29")
32 changes: 32 additions & 0 deletions R/create_playlist.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#' Create New Playlist
#'
#' @param title string; Required. The title of the playlist.
#' @param description string; Optional. The description of the playlist.
#' @param status string; Optional. Default: 'public'. Can be one of: 'private', 'public', or 'unlisted'.
#' @param ... Additional arguments passed to \code{\link{tuber_POST}}.
#'
#' @return The created playlist's details.
#'
#' @export
#' @references \url{https://developers.google.com/youtube/v3/docs/playlists/insert}
#'
#' @examples
#' \dontrun{
#'
#' # Set API token via yt_oauth() first
#'
#' create_playlist(title = "My New Playlist", description = "This is a test playlist.")
#' }
create_playlist <- function(title, description, status, ...) {
# Prepare the request body
body <- list(
snippet = list(title = title, description = description),
status = list(privacyStatus = status)
)

# Make the POST request using tuber_POST_json
raw_res <- tuber_POST_json(path = "playlists", query = list(part = "snippet,status"), body = body, ...)

# Return the response
return(raw_res)
}
2 changes: 1 addition & 1 deletion R/delete_playlist_items.R
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
#'
#' # Set API token via yt_oauth() first
#'
#' delete_playlist_items(id = "y3ElXcEME3lSISz6izkWVT5GvxjPu8pA")
#' delete_playlist_items(id = "YourPlaylistItemID")
#' }

delete_playlist_items <- function(id = NULL, ...) {
Expand Down
2 changes: 1 addition & 1 deletion R/get_all_channel_video_stats.R
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ get_all_channel_video_stats <- function(channel_id = NULL, mine = FALSE, ...) {
channel_resources <- list_channel_resources(filter = list(channel_id = channel_id), part = "contentDetails")
playlist_id <- channel_resources$items$contentDetails$relatedPlaylists$uploads

playlist_items <- get_playlist_items(filter = list(playlist_id = playlist_id), max_results = 100)
playlist_items <- get_playlist_items(filter = list(playlist_id = playlist_id), max_results = 50)
vid_ids <- playlist_items$contentDetails$videoId

res <- lapply(vid_ids, get_stats)
Expand Down
74 changes: 74 additions & 0 deletions R/get_playlist_item_ids.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#' Get Playlist Item IDs
#'
#' @param filter string; Required.
#' named vector of length 1
#' potential names of the entry in the vector:
#' \code{item_id}: comma-separated list of one or more unique playlist item IDs.
#' \code{playlist_id}: YouTube playlist ID.
#'
#' @param part Required. Comma separated string including one or more of the
#' following: \code{contentDetails, id, snippet, status}. Default:
#' \code{contentDetails}.
#' @param max_results Maximum number of items that should be returned.
#' Integer. Optional. Default is 50.
#' If over 50, all the results are returned.
#' @param simplify returns a data.frame rather than a list.
#' @param page_token specific page in the result set that should be
#' returned, optional
#' @param video_id Optional. request should return only the playlist
#' items that contain the specified video.
#' @param \dots Additional arguments passed to \code{\link{tuber_GET}}.
#'
#' @return playlist items
#' @export
#' @references \url{https://developers.google.com/youtube/v3/docs/playlists/list}
#'
#' @examples
#' \dontrun{
#'
#' # Set API token via yt_oauth() first
#'
#' get_playlist_items(filter =
#' c(playlist_id = "PLrEnWoR732-CN09YykVof2lxdI3MLOZda"))
#' get_playlist_items(filter =
#' c(playlist_id = "PL0fOlXVeVW9QMO3GoESky4yDgQfK2SsXN"),
#' max_results = 51)
#' }

get_playlist_item_ids <- function(filter = NULL, part = "contentDetails",
max_results = 50, video_id = NULL,
page_token = NULL, simplify = TRUE, ...) {

if (max_results < 0 || max_results > 50) {
stop("max_results must be a value between 0 and 50.")
}

valid_filters <- c("item_id", "playlist_id")
if (!(names(filter) %in% valid_filters)) {
stop("filter can only take one of the following values: item_id, playlist_id.")
}

if (length(filter) != 1) {
stop("filter must be a vector of length 1.")
}

translate_filter <- c(item_id = "id", playlist_id = "playlistId")
filter_name <- translate_filter[names(filter)]
names(filter) <- filter_name

querylist <- list(part = part,
maxResults = max(min(max_results, 50), 1),
pageToken = page_token, videoId = video_id)
querylist <- c(querylist, filter)

res <- tuber_GET("playlistItems", querylist, ...)
res_items <- res$items

item_ids <- rep("", length(res_items))
for(i in 1:length(res_items)){
item_ids[i] <- res_items[[i]]$id
}
return(item_ids)
}


74 changes: 74 additions & 0 deletions R/get_playlist_item_videoids.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
#' Get Playlist Item Video IDs
#'
#' @param filter string; Required.
#' named vector of length 1
#' potential names of the entry in the vector:
#' \code{item_id}: comma-separated list of one or more unique playlist item IDs.
#' \code{playlist_id}: YouTube playlist ID.
#'
#' @param part Required. Comma separated string including one or more of the
#' following: \code{contentDetails, id, snippet, status}. Default:
#' \code{contentDetails}.
#' @param max_results Maximum number of items that should be returned.
#' Integer. Optional. Default is 50.
#' If over 50, all the results are returned.
#' @param simplify returns a data.frame rather than a list.
#' @param page_token specific page in the result set that should be
#' returned, optional
#' @param video_id Optional. request should return only the playlist
#' items that contain the specified video.
#' @param \dots Additional arguments passed to \code{\link{tuber_GET}}.
#'
#' @return playlist items
#' @export
#' @references \url{https://developers.google.com/youtube/v3/docs/playlists/list}
#'
#' @examples
#' \dontrun{
#'
#' # Set API token via yt_oauth() first
#'
#' get_playlist_items(filter =
#' c(playlist_id = "YourPlaylistID"))
#' get_playlist_items(filter =
#' c(playlist_id = "YourPlaylistID"),
#' max_results = 51)
#' }

get_playlist_item_videoids <- function(filter = NULL, part = "contentDetails",
max_results = 50, video_id = NULL,
page_token = NULL, simplify = TRUE, ...) {

if (max_results < 0 || max_results > 50) {
stop("max_results must be a value between 0 and 50.")
}

valid_filters <- c("item_id", "playlist_id")
if (!(names(filter) %in% valid_filters)) {
stop("filter can only take one of the following values: item_id, playlist_id.")
}

if (length(filter) != 1) {
stop("filter must be a vector of length 1.")
}

translate_filter <- c(item_id = "id", playlist_id = "playlistId")
filter_name <- translate_filter[names(filter)]
names(filter) <- filter_name

querylist <- list(part = part,
maxResults = max(min(max_results, 50), 1),
pageToken = page_token, videoId = video_id)
querylist <- c(querylist, filter)

res <- tuber_GET("playlistItems", querylist, ...)
res_items <- res$items

item_ids <- rep("", length(res_items))
for(i in 1:length(res_items)){
item_ids[i] <- res_items[[i]]$contentDetails$videoId
}
return(item_ids)
}


2 changes: 2 additions & 0 deletions R/get_video_details.R
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ conditional_unnest_wider <- function(data_input, var) {
}
}

# Added to squash notes on devtools check.
utils::globalVariables(c("kind", "etag", "items", "snippet"))

json_to_df <- function(res) {
intermediate <- res %>%
Expand Down
25 changes: 25 additions & 0 deletions R/tuber.R
Original file line number Diff line number Diff line change
Expand Up @@ -214,6 +214,31 @@ tuber_POST <- function(path, query, body = "", ...) {
res
}

#'
#' POST encoded in json
#'
#' @param path path to specific API request URL
#' @param query query list
#' @param body passing image through body
#' @param \dots Additional arguments passed to \code{\link[httr]{GET}}.
#'
#' @return list

tuber_POST_json <- function(path, query, body = "", ...) {

yt_check_token()

req <- httr::POST("https://www.googleapis.com", path = paste0("youtube/v3/", path),
body = body, query = query,
config(token = getOption("google_token")),
encode = "json", ...)

tuber_check(req)
res <- content(req)

res
}

#'
#' DELETE
#'
Expand Down
Loading
Loading