Skip to content

Instantly share code, notes, and snippets.

@jimjam-slam
Last active June 10, 2021 02:01
Show Gist options
  • Save jimjam-slam/0a18edbdd6626b94557d8d108358039d to your computer and use it in GitHub Desktop.
Save jimjam-slam/0a18edbdd6626b94557d8d108358039d to your computer and use it in GitHub Desktop.
Google Drive folder migration
# this script recursively transfers the contents of a folder to another
# (including a team/shared drive)
# configure it with the ids of your source and target folders below!
# james goldie, june 2021
library(tidyverse)
library(googledrive)
library(collateral)
library(tictoc)
# login (must be someone with whom the original files are shared and who has
# access to the target shared drive)
drive_auth()
# confirm that the user has access to the root of the shared folder and the
# shared drive
root_folder <- as_id("XXXXXXXXXXXXXXXXXXXXXXX")
target_drive <- as_id("XXXXXXXXXXXXXXXXXXXXXXX")
if (!(target_drive %in% drive_get(root_folder)$id)) {
stop(
"This user doesn't appear to have access to the folder with the ID: ",
root_folder
)
}
if (!(target_drive %in% team_drive_find()$id)) {
stop(
"This user doesn't appear to have access to the Shared Drive with ",
"the ID: ", target_drive
)
}
message(
"Note that this script can only copy files and folders in the root ",
"folder that have been shared with you!"
)
copy_and_notify <- function(id, name, target_id) {
drive_cp(as_id(id), path = as_id(target_id), name = name)
message(" πŸ“„ Attempted to copy ", name)
}
create_and_notify <- function(name, target_id) {
mkdir_result <- drive_mkdir(name, path = as_id(target_id))
message(" πŸ“‚ Attempted to create ", name)
return(mkdir_result)
}
# inside a given folder:
# - get the listing of child files and folders;
# - copy each of the files;
# - recreate each of the folders;
# - recurse into each of the folders
transfer_folder <- function(source_id, target_id) {
source_id <- as_id(source_id)
target_id <- as_id(target_id)
message(
"πŸ“‚πŸ”½ Recursing into folder ", source_id, " (",
drive_get(source_id)$name, ")"
)
# 1. get folder contents and split into files/folders
contents <-
drive_ls(source_id) %>%
drive_reveal("mime_type") %>%
split(.$mime_type == "application/vnd.google-apps.folder")
child_folders <- contents$`TRUE`
child_files <- contents$`FALSE`
message(
" - Received folder contents. ",
(nrow(child_folders) %||% 0), " folders and ",
(nrow(child_files) %||% 0), " files."
)
# 2. recreate each of the folders, then recurse into each of them
if (!(is_empty(child_folders) || nrow(child_folders) < 1)) {
child_folders %>%
mutate(
mk_result = map(name, create_and_notify, target_id = target_id),
target_child_id = map_chr(mk_result, "id")) %>%
select(name, id, target_child_id) ->
child_folders
message(" - Attempted to create target child folders.")
# recurse into each folder
walk2(child_folders$id, child_folders$target_child_id, transfer_folder)
} else {
message(" - No child folders to create/recurse over.")
child_folders <- tibble(
name = character(0), id = character(0),
target_child_id = character(0)
)
}
# 3. copy each of the files
if (!(is_empty(child_files) || nrow(child_files) < 1)) {
message(" - Attempting to copy files...")
map2(
child_files$id, child_files$name, copy_and_notify, target_id = target_id)
message(" - Attempted to copy files.")
} else {
message(" - No files to copy.")
}
}
# do the thing!
tic()
transfer_folder(root_folder, target_drive)
toc()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment