diff --git a/DESCRIPTION b/DESCRIPTION index 9dca2bf..6602cbd 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -3,38 +3,50 @@ Title: Interface to the 'Microsoft 365' Suite of Cloud Services Version: 2.4.1 Authors@R: c( person("Hong", "Ooi", , "hongooi73@gmail.com", role = c("aut", "cre")), - person("Roman", "Zenka", role="ctb"), - person("Robert", "Ashton", role="ctb"), - person("Philip", "Zheng", role="ctb"), - person("Microsoft", role="cph") - ) -Description: An interface to the 'Microsoft 365' (formerly known as 'Office 365') suite of cloud services, building on the framework supplied by the 'AzureGraph' package. Enables access from R to data stored in 'Teams', 'SharePoint Online' and 'OneDrive', including the ability to list drive folder contents, upload and download files, send messages, and retrieve data lists. Also provides a full-featured 'Outlook' email client, with the ability to send emails and manage emails and mail folders. -URL: https://github.com/Azure/Microsoft365R https://github.com/Azure/AzureR -BugReports: https://github.com/Azure/Microsoft365R/issues + person("Roman", "Zenka", role = "ctb"), + person("Robert", "Ashton", role = "ctb"), + person("Philip", "Zheng", role = "ctb"), + person("Eli", "Pousson", , "eli.pousson@gmail.com", role = "ctb", + comment = c(ORCID = "0000-0001-8280-1706")), + person("Microsoft", role = "cph") + ) +Description: An interface to the 'Microsoft 365' (formerly known as + 'Office 365') suite of cloud services, building on the framework + supplied by the 'AzureGraph' package. Enables access from R to data + stored in 'Teams', 'SharePoint Online' and 'OneDrive', including the + ability to list drive folder contents, upload and download files, send + messages, and retrieve data lists. Also provides a full-featured + 'Outlook' email client, with the ability to send emails and manage + emails and mail folders. License: MIT + file LICENSE -VignetteBuilder: knitr +URL: https://github.com/Azure/Microsoft365R + https://github.com/Azure/AzureR +BugReports: https://github.com/Azure/Microsoft365R/issues Depends: R (>= 3.3) Imports: AzureAuth, AzureGraph (>= 1.3.1), - utils, - parallel, - tools, curl, httr, jsonlite, + mime, + parallel, R6, - vctrs, - mime + tools, + utils, + vctrs Suggests: - openssl, - knitr, - rmarkdown, - testthat, blastula, emayili, + knitr, + openssl, readr, - readxl + readxl, + rmarkdown, + testthat +VignetteBuilder: + knitr +Encoding: UTF-8 Roxygen: list(markdown=TRUE, r6=FALSE) -RoxygenNote: 7.2.1 +RoxygenNote: 7.3.2 diff --git a/NAMESPACE b/NAMESPACE index 6c48147..1ba6a82 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -31,3 +31,8 @@ export(ms_team_member) export(personal_onedrive) export(sharepoint_site) import(AzureGraph) +importFrom(curl,curl_escape) +importFrom(parallel,makeCluster) +importFrom(parallel,parLapply) +importFrom(parallel,stopCluster) +importFrom(tools,file_ext) diff --git a/NEWS.md b/NEWS.md index bec2711..bf2ba2e 100644 --- a/NEWS.md +++ b/NEWS.md @@ -1,3 +1,13 @@ +# Microsoft365R development + +- Expose `select` argument for `ms_drive$list_items()` method (ignored when `info="name"`). +- Expose `simplify` argument for `ms_list$get_column_info()` method. +- Add `ms_list$create_link()` method for creating a shared link to a list item. +- Add `ms_list$create_column()` method. +- Add `ms_site$get_pages()` method (#190) +- Add `ms_site$get_analytics()`, `ms_site$list_permissions()`, and `ms_site$list_content_types()` methods. (#209) +- Add `ms_drive$list_activities()` (#209) + # Microsoft365R 2.4.1 ## OneDrive/SharePoint @@ -17,6 +27,7 @@ ## Other +- Add Eli Pousson to contributors. - Remove references to the Microsoft365 CLI, as this no longer has a multi-tenant app registration and hence cannot be used for authentication. This means you'll have to either allow the Microsoft365R app ID within your tenant or create your own app registration (both of which will require Azure admin access). (#215) diff --git a/R/Microsoft365R.R b/R/Microsoft365R.R index 18e5c29..89a2271 100644 --- a/R/Microsoft365R.R +++ b/R/Microsoft365R.R @@ -111,3 +111,7 @@ get_confirmation <- get("get_confirmation", getNamespace("AzureGraph")) # to combine paged results into a single data frame: individual pages can have # different structures, which will break base::rbind vctrs::vec_rbind + + +#' @importFrom R6 R6Class + diff --git a/R/build_chatmessage_body.R b/R/build_chatmessage_body.R index 17d4dcb..ebe551c 100644 --- a/R/build_chatmessage_body.R +++ b/R/build_chatmessage_body.R @@ -72,13 +72,13 @@ build_chatmessage_body <- function(channel, body, content_type, attachments, inl call_body } - +#' @noRd make_mention <- function(object, i) { UseMethod("make_mention") } - +#' @noRd make_mention.az_user <- function(object, i) { name <- if(!is.null(object$properties$displayName)) @@ -99,7 +99,7 @@ make_mention.az_user <- function(object, i) ) } - +#' @noRd make_mention.ms_team <- function(object, i) { list( @@ -115,7 +115,7 @@ make_mention.ms_team <- function(object, i) ) } - +#' @noRd make_mention.ms_channel <- function(object, i) { list( @@ -131,7 +131,7 @@ make_mention.ms_channel <- function(object, i) ) } - +#' @noRd make_mention.ms_team_member <- function(object, i) { make_mention(object$get_aaduser(), i) diff --git a/R/build_email_request.R b/R/build_email_request.R index f9012bd..4d173b6 100644 --- a/R/build_email_request.R +++ b/R/build_email_request.R @@ -1,11 +1,12 @@ # methods for different email formats: default, blastula, emayili +#' @noRd build_email_request <- function(body, ...) { UseMethod("build_email_request") } - +#' @noRd build_email_request.character <- function(body, content_type, subject=NULL, to=NA, cc=NA, bcc=NA, reply_to=NA, token=NULL, user_id=NULL, ...) { @@ -21,7 +22,7 @@ build_email_request.character <- function(body, content_type, utils::modifyList(req, build_email_recipients(to, cc, bcc, reply_to)) } - +#' @noRd build_email_request.blastula_message <- function(body, content_type, subject=NULL, to=NA, cc=NA, bcc=NA, reply_to=NA, token=NULL, user_id=NULL, ...) { @@ -37,7 +38,7 @@ build_email_request.blastula_message <- function(body, content_type, utils::modifyList(req, build_email_recipients(to, cc, bcc, reply_to)) } - +#' @noRd build_email_request.envelope <- function(body, token=NULL, user_id=NULL, ...) { require_emayili_0.6() diff --git a/R/make_email_attachments.R b/R/make_email_attachments.R index 17baa46..220fd87 100644 --- a/R/make_email_attachments.R +++ b/R/make_email_attachments.R @@ -1,9 +1,10 @@ +#' @noRd add_external_attachments <- function(object, email) { UseMethod("add_external_attachments") } - +#' @noRd add_external_attachments.blastula_message <- function(object, email) { for(a in object$attachments) @@ -28,7 +29,7 @@ add_external_attachments.blastula_message <- function(object, email) } } - +#' @noRd add_external_attachments.envelope <- function(object, email) { require_emayili_0.6() @@ -60,7 +61,7 @@ add_external_attachments.envelope <- function(object, email) } } - +#' @noRd add_external_attachments.default <- function(object, email) { # do nothing if message object is not a recognised class (from blastula or emayili) diff --git a/R/ms_drive.R b/R/ms_drive.R index b79d820..21f4ef9 100644 --- a/R/ms_drive.R +++ b/R/ms_drive.R @@ -62,6 +62,8 @@ #' #' `list_files` is a synonym for `list_items`. #' +#' `list_activities` returns a list of activities for a drive. +#' #' `download_file` and `upload_file` transfer files between the local machine and the drive. For `download_file`, the default destination folder is the current (working) directory of your R session. For `upload_file`, there is no default destination folder; make sure you specify the destination explicitly. #' #' `download_folder` and `upload_folder` transfer all the files in a folder. If `recursive` is TRUE, all subfolders will also be transferred recursively. The `parallel` argument can have the following values: @@ -158,6 +160,7 @@ #' } #' @format An R6 object of class `ms_drive`, inheriting from `ms_object`. #' @export +#' @importFrom curl curl_escape ms_drive <- R6::R6Class("ms_drive", inherit=ms_object, public=list( @@ -174,6 +177,10 @@ public=list( private$get_root()$list_items(path, ...) }, + list_activites=function() { + self$do_operation("activities") + }, + upload_file=function(src, dest, blocksize=32768000) { private$get_root()$upload(src, dest, blocksize) diff --git a/R/ms_drive_item.R b/R/ms_drive_item.R index f82a52b..a7e0f7d 100644 --- a/R/ms_drive_item.R +++ b/R/ms_drive_item.R @@ -41,15 +41,21 @@ #' #' `open` opens this file or folder in your browser. If the file has an unrecognised type, most browsers will attempt to download it. #' -#' `list_items(path, info, full_names, filter, n, pagesize)` lists the items under the specified path. It is the analogue of base R's `dir`/`list.files`. Its arguments are +#' `list_items(path, info, full_names, filter, select, n, pagesize)` lists the items under the specified path. It is the analogue of base R's `dir`/`list.files`. Its arguments are #' - `path`: The path. -#' - `info`: The information to return: either "partial", "name" or "all". If "partial", a data frame is returned containing the name, size, ID and whether the item is a file or folder. If "name", a vector of file/folder names is returned. If "all", a data frame is returned containing _all_ the properties for each item (this can be large). +#' - `info`: The information to return: either "partial", "name" or "all". If "partial", a data frame is returned containing the name, size, ID and whether the item is a file or folder. If "name", a vector of file/folder names is returned (and any value passed to `select` is ignored). If "all", a data frame is returned containing _all_ the properties for each item (this can be large). If `select` is supplied and `info` is "partial" or "all", only the specified columns are included in the returned data frame. #' - `full_names`: Whether to prefix the folder path to the names of the items. -#' - `filter, n`: See 'List methods' below. +#' - `filter, select, n`: See 'List methods' below. #' - `pagesize`: The number of results to return for each call to the REST endpoint. You can try reducing this argument below the default of 1000 if you are experiencing timeouts. #' #' `list_files` is a synonym for `list_items`. #' +#' `list_permissions` returns a list of permissions for a drive item. +#' +#' `list_versions` returns a list of drive item versions. +#' +#' `list_activities` returns a list of activities for a drive item. +#' #' `download` downloads the item to the local machine. If this is a file, it is downloaded; in this case, the `dest` argument can be the path to the destination file, or NULL to return the downloaded content in a raw vector. If the item is a folder, all its files are downloaded, including subfolders if the `recursive` argument is TRUE. #' #' `upload` uploads a file or folder from the local machine into the folder item. The `src` argument can be the path to the source file, a [rawConnection] or a [textConnection] object. If `src` is a folder, all its files are uploaded, including subfolders if the `recursive` argument iS TRUE. An `ms_drive_item` object is returned invisibly. @@ -62,8 +68,9 @@ #' - A cluster object, created via the parallel package #' - FALSE: The transfer is done serially #' -#' `get_item` retrieves the file or folder with the given path, as another object of class `ms_drive_item`. -#' +#' `get_item(expand)` retrieves the file or folder with the given path, as another object of class `ms_drive_item`. +#' - `expand`: If `expand="fields"` include custom column values associated with the item. + #' - `copy` and `move` can take the destination location as either a full pathname (in the `dest` argument), or a name plus a drive item object (in the `dest_folder_item` argument). If the latter is supplied, any path in `dest` is ignored with a warning. Note that copying is an _asynchronous_ operation, meaning the method returns before the copy is complete. #' #' For copying and moving, the destination folder must exist beforehand. When copying/moving a large number of files, it's much more efficient to supply the destination folder in the `dest_folder_item` argument rather than as a path. @@ -152,6 +159,8 @@ #' } #' @format An R6 object of class `ms_drive_item`, inheriting from `ms_object`. #' @export +#' @importFrom parallel makeCluster stopCluster parLapply +#' @importFrom tools file_ext ms_drive_item <- R6::R6Class("ms_drive_item", inherit=ms_object, public=list( @@ -211,6 +220,21 @@ public=list( httr::BROWSE(self$properties$webUrl) }, + # https://learn.microsoft.com/en-us/graph/api/driveitem-list-permissions + list_permissions=function() { + self$do_operation("permissions") + }, + + # https://learn.microsoft.com/en-us/graph/api/driveitem-list-versions + list_versions=function() { + self$do_operation("versions") + }, + + # https://learn.microsoft.com/en-us/graph/api/activities-list + list_activities=function() { + self$do_operation("activities") + }, + create_share_link=function(type=c("view", "edit", "embed"), expiry="7 days", password=NULL, scope=NULL) { type <- match.arg(type) @@ -233,7 +257,7 @@ public=list( else res$link$webUrl }, - list_items=function(path="", info=c("partial", "name", "all"), full_names=FALSE, filter=NULL, n=Inf, pagesize=1000) + list_items=function(path="", info=c("partial", "name", "all"), full_names=FALSE, filter=NULL, select=NULL, n=Inf, pagesize=1000) { private$assert_is_folder() if(path == "/") @@ -244,6 +268,10 @@ public=list( name=list(`$select`="name", `$top`=pagesize), list(`$top`=pagesize) ) + + if (!is.null(select) && info != "name") + opts$`$select` <- paste0(select, collapse = ",") + if(!is.null(filter)) opts$`filter` <- filter @@ -272,6 +300,11 @@ public=list( if(full_names) df$name <- file.path(sub("^/", "", path), df$name) + + if (!is.null(select)) { + return(df) + } + switch(info, partial=df[c("name", "size", "isdir", "id")], name=df$name, @@ -283,10 +316,10 @@ public=list( ) }, - get_item=function(path) + get_item=function(path, expand = NULL) { private$assert_is_folder() - op <- private$make_absolute_path(path) + op <- private$make_absolute_path(path, expand = expand) ms_drive_item$new(self$token, self$tenant, call_graph_endpoint(self$token, op)) }, @@ -657,7 +690,7 @@ private=list( # dest = . or '' --> this item # dest = .. --> parent folder # dest = (childname) --> path to named child - make_absolute_path=function(dest=".", use_itemid=getOption("microsoft365r_use_itemid_in_path")) + make_absolute_path=function(dest=".", use_itemid=getOption("microsoft365r_use_itemid_in_path"), expand=NULL) { if(use_itemid == "remote") use_itemid <- !is.null(private$remoteItem) @@ -692,6 +725,10 @@ private=list( } if(dest != "..") op <- file.path(op, dest) + + if (!is.null(expand)) + op <- sprintf("%s?$expand=%s", op, expand) + utils::URLencode(enc2utf8(sub(":?/?$", "", op))) }, diff --git a/R/ms_list.R b/R/ms_list.R index 54b261d..186fd93 100644 --- a/R/ms_list.R +++ b/R/ms_list.R @@ -15,7 +15,8 @@ #' - `do_operation(...)`: Carry out an arbitrary operation on the list. #' - `sync_fields()`: Synchronise the R object with the list metadata in Microsoft Graph. #' - `list_items(filter, select, all_metadata, as_data_frame, pagesize)`: Queries the list and returns items as a data frame. See 'List querying' below. -#' - `get_column_info()`: Return a data frame containing metadata on the columns (fields) in the list. +#' - `get_column_info(simplify=TRUE)`: Return a list or data frame containing metadata on the columns (fields) in the list. +#' - `create_column(...)`: Create a new column in the list. #' - `get_item(id)`: Get an individual list item. #' - `create_item(...)`: Create a new list item, using the named arguments as fields. #' - `update_item(id, ...)`: Update the _data_ fields in the given item, using the named arguments. To update the item's metadata, use `get_item()` to retrieve the item object, then call its `update()` method. @@ -134,12 +135,18 @@ public=list( invisible(lapply(seq_len(nrow(data)), function(i) do.call(self$create_item, data[i, , drop=FALSE]))) }, - get_column_info=function() + get_column_info=function(simplify=TRUE) { - res <- self$do_operation(options=list(expand="columns"), simplify=TRUE) + res <- self$do_operation(options=list(expand="columns"), simplify=simplify) res$columns }, + create_column=function(...) + { + res <- self$do_operation("columns", encode="json", body=list(...), http_verb="POST") + res + }, + print=function(...) { cat("\n", sep="") diff --git a/R/ms_list_item.R b/R/ms_list_item.R index 349ea95..36f4a3b 100644 --- a/R/ms_list_item.R +++ b/R/ms_list_item.R @@ -14,6 +14,7 @@ #' - `update(...)`: Update the item's properties (metadata) in Microsoft Graph. To update the list _data_, update the `fields` property. See the examples below. #' - `do_operation(...)`: Carry out an arbitrary operation on the item. #' - `sync_fields()`: Synchronise the R object with the item data and metadata in Microsoft Graph. +#' - `create_link()`: Create a shared link to a list item. #' #' @section Initialization: #' Creating new objects of this class should be done via the `get_item` method of the [`ms_list`] class. Calling the `new()` method for this class only constructs the R object; it does not call the Microsoft Graph API to retrieve or create the actual item. @@ -62,6 +63,15 @@ public=list( super$initialize(token, tenant, properties) }, + # https://learn.microsoft.com/en-us/graph/api/listitem-createlink + create_link = function() { + self$do_operation("createLink", http_verb = "POST") + }, + + # delete = function() { + # self$do_operation(http_verb = "DELETE") + # }, + print=function(...) { cat("\n", sep="") diff --git a/R/ms_outlook_email.R b/R/ms_outlook_email.R index 2006bca..52f288a 100644 --- a/R/ms_outlook_email.R +++ b/R/ms_outlook_email.R @@ -527,24 +527,26 @@ format_email_date <- function(datestr) } +#' @noRd make_reply_comment <- function(comment) { UseMethod("make_reply_comment") } +#' @noRd make_reply_comment.default <- function(comment) { as.character(comment) } - +#' @noRd make_reply_comment.blastula_message <- function(comment) { comment$html_str } - +#' @noRd make_reply_comment.envelope <- function(comment) { parts <- comment$parts diff --git a/R/ms_site.R b/R/ms_site.R index f2c9116..89aa377 100644 --- a/R/ms_site.R +++ b/R/ms_site.R @@ -17,6 +17,7 @@ #' - `list_drives(filter=NULL, n=Inf)`: List the drives (shared document libraries) associated with this site. #' - `get_drive(drive_name, drive_id)`: Retrieve a shared document library for this site. If the name and ID are not specified, this returns the default document library. #' - `list_subsites(filter=NULL, n=Inf)`: List the subsites of this site. +#' - `get_pages(type = c("sitePage", "page"))`: Returns SharePoint pages for this site. #' - `get_lists(filter=NULL, n=Inf)`: Returns the lists that are part of this site. #' - `get_list(list_name, list_id)`: Returns a specific list, either by name or ID. #' - `get_group()`: Retrieve the Microsoft 365 group associated with the site, if it exists. A site that backs a private Teams channel will not have a group associated with it. @@ -44,6 +45,7 @@ #' } #' @format An R6 object of class `ms_site`, inheriting from `ms_object`. #' @export +#' @importFrom curl curl_escape ms_site <- R6::R6Class("ms_site", inherit=ms_object, public=list( @@ -109,6 +111,43 @@ public=list( az_group$new(self$token, self$tenant, res[[1]]) }, + get_analytics=function() + { + self$do_operation("analytics") + }, + + get_pages=function(type=c("sitePage", "page")) + { + type <- match.arg(type) + + op <- switch(type, + page = "pages", + sitePage = "pages/microsoft.graph.sitePage" + ) + + self$do_operation(op) + }, + + # https://learn.microsoft.com/en-us/graph/api/site-list-columns + # FIXME: Add support for OData parameters + list_columns=function() + { + self$do_operation("columns") + }, + + # https://learn.microsoft.com/en-us/graph/api/site-list-permissions?view=graph-rest-beta&tabs=http + # FIXME: Add support for OData parameters + list_permissions=function() + { + self$do_operation("permissions") + }, + + # https://learn.microsoft.com/en-us/graph/api/site-list-contenttypes?view=graph-rest-beta&tabs=http + list_content_types=function() + { + self$do_operation("contentTypes") + }, + print=function(...) { cat("\n", sep="") diff --git a/R/normalize_src.R b/R/normalize_src.R index ba0e12f..2d53403 100644 --- a/R/normalize_src.R +++ b/R/normalize_src.R @@ -1,9 +1,10 @@ +#' @noRd normalize_src <- function(src) { UseMethod("normalize_src") } - +#' @noRd normalize_src.character <- function(src) { con <- file(src, open="rb") @@ -11,7 +12,7 @@ normalize_src.character <- function(src) list(con=con, size=size) } - +#' @noRd normalize_src.textConnection <- function(src) { # convert to raw connection @@ -21,7 +22,7 @@ normalize_src.textConnection <- function(src) list(con=con, size=size) } - +#' @noRd normalize_src.rawConnection <- function(src) { # need to read the data to get object size (!) diff --git a/man/ms_drive.Rd b/man/ms_drive.Rd index 7fe3b83..08311de 100644 --- a/man/ms_drive.Rd +++ b/man/ms_drive.Rd @@ -82,6 +82,8 @@ For copying and moving, the destination folder must exist beforehand. When copyi \code{list_files} is a synonym for \code{list_items}. +\code{list_activities} returns a list of activities for a drive. + \code{download_file} and \code{upload_file} transfer files between the local machine and the drive. For \code{download_file}, the default destination folder is the current (working) directory of your R session. For \code{upload_file}, there is no default destination folder; make sure you specify the destination explicitly. \code{download_folder} and \code{upload_folder} transfer all the files in a folder. If \code{recursive} is TRUE, all subfolders will also be transferred recursively. The \code{parallel} argument can have the following values: diff --git a/man/ms_drive_item.Rd b/man/ms_drive_item.Rd index 4cb99ea..edee556 100644 --- a/man/ms_drive_item.Rd +++ b/man/ms_drive_item.Rd @@ -60,17 +60,23 @@ This class exposes methods for carrying out common operations on files and folde \code{open} opens this file or folder in your browser. If the file has an unrecognised type, most browsers will attempt to download it. -\code{list_items(path, info, full_names, filter, n, pagesize)} lists the items under the specified path. It is the analogue of base R's \code{dir}/\code{list.files}. Its arguments are +\code{list_items(path, info, full_names, filter, select, n, pagesize)} lists the items under the specified path. It is the analogue of base R's \code{dir}/\code{list.files}. Its arguments are \itemize{ \item \code{path}: The path. -\item \code{info}: The information to return: either "partial", "name" or "all". If "partial", a data frame is returned containing the name, size, ID and whether the item is a file or folder. If "name", a vector of file/folder names is returned. If "all", a data frame is returned containing \emph{all} the properties for each item (this can be large). +\item \code{info}: The information to return: either "partial", "name" or "all". If "partial", a data frame is returned containing the name, size, ID and whether the item is a file or folder. If "name", a vector of file/folder names is returned (and any value passed to \code{select} is ignored). If "all", a data frame is returned containing \emph{all} the properties for each item (this can be large). If \code{select} is supplied and \code{info} is "partial" or "all", only the specified columns are included in the returned data frame. \item \code{full_names}: Whether to prefix the folder path to the names of the items. -\item \verb{filter, n}: See 'List methods' below. +\item \verb{filter, select, n}: See 'List methods' below. \item \code{pagesize}: The number of results to return for each call to the REST endpoint. You can try reducing this argument below the default of 1000 if you are experiencing timeouts. } \code{list_files} is a synonym for \code{list_items}. +\code{list_permissions} returns a list of permissions for a drive item. + +\code{list_versions} returns a list of drive item versions. + +\code{list_activities} returns a list of activities for a drive item. + \code{download} downloads the item to the local machine. If this is a file, it is downloaded; in this case, the \code{dest} argument can be the path to the destination file, or NULL to return the downloaded content in a raw vector. If the item is a folder, all its files are downloaded, including subfolders if the \code{recursive} argument is TRUE. \code{upload} uploads a file or folder from the local machine into the folder item. The \code{src} argument can be the path to the source file, a \link{rawConnection} or a \link{textConnection} object. If \code{src} is a folder, all its files are uploaded, including subfolders if the \code{recursive} argument iS TRUE. An \code{ms_drive_item} object is returned invisibly. @@ -85,8 +91,9 @@ Uploading and downloading folders can be done in parallel, which can result in s \item FALSE: The transfer is done serially } -\code{get_item} retrieves the file or folder with the given path, as another object of class \code{ms_drive_item}. +\code{get_item(expand)} retrieves the file or folder with the given path, as another object of class \code{ms_drive_item}. \itemize{ +\item \code{expand}: If \code{expand="fields"} include custom column values associated with the item. \item \code{copy} and \code{move} can take the destination location as either a full pathname (in the \code{dest} argument), or a name plus a drive item object (in the \code{dest_folder_item} argument). If the latter is supplied, any path in \code{dest} is ignored with a warning. Note that copying is an \emph{asynchronous} operation, meaning the method returns before the copy is complete. } diff --git a/man/ms_list.Rd b/man/ms_list.Rd index 6e2470a..cf1eff5 100644 --- a/man/ms_list.Rd +++ b/man/ms_list.Rd @@ -29,7 +29,8 @@ Class representing a list in a SharePoint site. \item \code{do_operation(...)}: Carry out an arbitrary operation on the list. \item \code{sync_fields()}: Synchronise the R object with the list metadata in Microsoft Graph. \item \code{list_items(filter, select, all_metadata, as_data_frame, pagesize)}: Queries the list and returns items as a data frame. See 'List querying' below. -\item \code{get_column_info()}: Return a data frame containing metadata on the columns (fields) in the list. +\item \code{get_column_info(simplify=TRUE)}: Return a list or data frame containing metadata on the columns (fields) in the list. +\item \code{create_column(...)}: Create a new column in the list. \item \code{get_item(id)}: Get an individual list item. \item \code{create_item(...)}: Create a new list item, using the named arguments as fields. \item \code{update_item(id, ...)}: Update the \emph{data} fields in the given item, using the named arguments. To update the item's metadata, use \code{get_item()} to retrieve the item object, then call its \code{update()} method. diff --git a/man/ms_list_item.Rd b/man/ms_list_item.Rd index 4284e94..5dd051d 100644 --- a/man/ms_list_item.Rd +++ b/man/ms_list_item.Rd @@ -28,6 +28,7 @@ Class representing an item in a SharePoint list. \item \code{update(...)}: Update the item's properties (metadata) in Microsoft Graph. To update the list \emph{data}, update the \code{fields} property. See the examples below. \item \code{do_operation(...)}: Carry out an arbitrary operation on the item. \item \code{sync_fields()}: Synchronise the R object with the item data and metadata in Microsoft Graph. +\item \code{create_link()}: Create a shared link to a list item. } } diff --git a/man/ms_site.Rd b/man/ms_site.Rd index f5c1e95..731f835 100644 --- a/man/ms_site.Rd +++ b/man/ms_site.Rd @@ -31,6 +31,7 @@ Class representing a SharePoint site. \item \code{list_drives(filter=NULL, n=Inf)}: List the drives (shared document libraries) associated with this site. \item \code{get_drive(drive_name, drive_id)}: Retrieve a shared document library for this site. If the name and ID are not specified, this returns the default document library. \item \code{list_subsites(filter=NULL, n=Inf)}: List the subsites of this site. +\item \code{get_pages(type = c("sitePage", "page"))}: Returns SharePoint pages for this site. \item \code{get_lists(filter=NULL, n=Inf)}: Returns the lists that are part of this site. \item \code{get_list(list_name, list_id)}: Returns a specific list, either by name or ID. \item \code{get_group()}: Retrieve the Microsoft 365 group associated with the site, if it exists. A site that backs a private Teams channel will not have a group associated with it.