Add filter, n args for all list methods (#48)

closes #44
This commit is contained in:
Hong Ooi 2021-04-30 11:49:34 +10:00 коммит произвёл GitHub
Родитель 3d07d20f19
Коммит dbf2ddfdb6
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
31 изменённых файлов: 320 добавлений и 130 удалений

Просмотреть файл

@ -14,7 +14,7 @@ Depends:
R (>= 3.3)
Imports:
AzureAuth,
AzureGraph (>= 1.2.2),
AzureGraph (>= 1.3.0),
utils,
curl,
httr,

Просмотреть файл

@ -1,5 +1,6 @@
# Microsoft365R 2.1.0.9000
- All `list_*` class methods now have `filter` and `n` arguments to filter the result set and cap the number of results, following the pattern in AzureGraph 1.3.0. The default values are `filter=NULL` and `n=Inf`. If `n=NULL`, an `ms_graph_pager` iterator object is returned instead to allow manual iteration over the results. Note that support for filtering in the underlying Graph API is somewhat uneven at the moment.
- Add a `list_shared_items()` method for the `ms_drive` class to access files and folders shared with you (#45).
- Add `list_members()` and `get_member()` methods for teams and channels.
- Add support for @mentions in Teams channel messages (#26).

Просмотреть файл

@ -38,6 +38,21 @@ utils::globalVariables(c("self", "private"))
register_graph_class("attachment", ms_outlook_attachment,
function(props) "isInline" %in% names(props))
register_graph_class("fileAttachment", ms_outlook_attachment,
function(props) "isInline" %in% names(props))
register_graph_class("referenceAttachment", ms_outlook_attachment,
function(props) "isInline" %in% names(props))
register_graph_class("itemAttachment", ms_outlook_attachment,
function(props) "isInline" %in% names(props))
register_graph_class("aadUserConversationMember", ms_team_member,
function(props) "roles" %in% names(props))
register_graph_class("listItem", ms_list_item,
function(props) !is_empty(props$contentType$name))
add_graph_methods()
add_user_methods()
add_group_methods()
@ -53,6 +68,14 @@ utils::globalVariables(c("self", "private"))
error_message <- get("error_message", getNamespace("AzureGraph"))
get_confirmation <- get("get_confirmation", getNamespace("AzureGraph"))
make_basic_list <- function(object, op, filter, n, ...)
{
opts <- list(`$filter`=filter)
hdrs <- if(!is.null(filter)) httr::add_headers(consistencyLevel="eventual")
pager <- object$get_list_pager(object$do_operation(op, options=opts, hdrs), ...)
extract_list_values(pager, n)
}
# dummy mention to keep CRAN happy
# we need to ensure that vctrs is loaded so that AzureGraph will use vec_rbind
# to combine paged results into a single data frame: individual pages can have

Просмотреть файл

@ -123,10 +123,9 @@ add_graph_methods <- function()
add_user_methods <- function()
{
az_user$set("public", "list_drives", overwrite=TRUE,
function()
function(filter=NULL, n=Inf)
{
res <- private$get_paged_list(self$do_operation("drives"))
private$init_list_objects(res, "drive")
make_basic_list(self, "drives", filter, n)
})
az_user$set("public", "get_drive", overwrite=TRUE,
@ -139,19 +138,21 @@ add_user_methods <- function()
})
az_user$set("public", "list_sharepoint_sites", overwrite=TRUE,
function(filter=NULL)
function(filter=NULL, n=Inf)
{
opts <- if(!is.null(filter)) list(`$filter`=filter)
res <- private$get_paged_list(self$do_operation("followedSites", options=opts))
lapply(private$init_list_objects(res, "site"), function(site) site$sync_fields())
lst <- make_basic_list(self, "followedSites", filter, n)
if(!is.null(n))
lapply(lst, function(site) site$sync_fields()) # result from endpoint is incomplete
else lst
})
az_user$set("public", "list_teams", overwrite=TRUE,
function(filter=NULL)
function(filter=NULL, n=Inf)
{
opts <- if(!is.null(filter)) list(`$filter`=filter)
res <- private$get_paged_list(self$do_operation("joinedTeams", options=opts))
lapply(private$init_list_objects(res, "team"), function(team) team$sync_fields())
lst <- make_basic_list(self, "joinedTeams", filter, n)
if(!is.null(n))
lapply(lst, function(team) team$sync_fields()) # result from endpoint only contains ID and displayname
else lst
})
az_user$set("public", "get_outlook", overwrite=TRUE,
@ -171,10 +172,9 @@ add_group_methods <- function()
})
az_group$set("public", "list_drives", overwrite=TRUE,
function()
function(filter=NULL, n=Inf)
{
res <- private$get_paged_list(self$do_operation("drives"))
private$init_list_objects(res, "drive")
make_basic_list(self, "drives", filter, n)
})
az_group$set("public", "get_drive", overwrite=TRUE,

Просмотреть файл

@ -16,14 +16,14 @@
#' - `do_operation(...)`: Carry out an arbitrary operation on the channel.
#' - `sync_fields()`: Synchronise the R object with the channel metadata in Microsoft Graph.
#' - `send_message(body, content_type, attachments)`: Sends a new message to the channel. See below.
#' - `list_messages(n=50)`: Retrieves the messages in the channel. By default, this is limited to the 50 most recent messages; set the `n` argument to change this.
#' - `list_messages(filter=NULL, n=50)`: Retrieves the messages in the channel. By default, this is limited to the 50 most recent messages; set the `n` argument to change this.
#' - `get_message(message_id)`: Retrieves a specific message in the channel.
#' - `delete_message(message_id, confirm=TRUE)`: Deletes a message. Currently the Graph API does not support deleting Teams messages, so this method is disabled.
#' - `list_files()`: List the files for the channel. See [`ms_drive`] for the arguments available for this and the file upload/download methods.
#' - `upload_file()`: Uploads a file to the channel.
#' - `download_file()`: Downloads a file from the channel.
#' - `get_folder()`: Retrieves the files folder for the channel, as a [`ms_drive_item`] object.
#' - `list_members()`: Retrieves the members of the channel, as a list of [`ms_team_member`] objects.
#' - `list_members(filter=NULL, n=Inf)`: Retrieves the members of the channel, as a list of [`ms_team_member`] objects.
#' - `get_member(name, email, id)`: Retrieve a specific member of the channel, as a `ms_team_member` object. Supply only one of the member name, email address or ID.
#'
#' @section Initialization:
@ -39,6 +39,10 @@
#'
#' Note that message attachments are actually uploaded to the channel's file listing (a directory in the team's primary shared document folder). Support for attachments is somewhat experimental, so if you want to be sure that it works, upload the file separately using the `upload_file()` method.
#'
#' @section List methods:
#' All `list_*` methods have `filter` and `n` arguments to limit the number of results. The former should be an [OData expression](https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter) as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are `filter=NULL` and `n=Inf`. If `n=NULL`, the `ms_graph_pager` iterator object is returned instead to allow manual iteration over the results.
#'
#' Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
#' @seealso
#' [`ms_team`], [`ms_drive`], [`ms_chat_message`]
#'
@ -113,10 +117,9 @@ public=list(
ms_chat_message$new(self$token, self$tenant, res)
},
list_messages=function(n=50)
list_messages=function(filter=NULL, n=50)
{
lst <- private$get_paged_list(self$do_operation("messages"), n=n)
private$init_list_objects(lst, "chatMessage")
make_basic_list(self, "messages", filter, n)
},
get_message=function(message_id)
@ -152,11 +155,9 @@ public=list(
private$folder
},
list_members=function()
list_members=function(filter=NULL, n=Inf)
{
res <- private$get_paged_list(self$do_operation("members"))
private$init_list_objects(res, default_generator=ms_team_member,
parent_id=self$properties$id, parent_type="channel")
make_basic_list(self, "members", filter, n, parent_id=self$properties$id, parent_type="channel")
},
get_member=function(name=NULL, email=NULL, id=NULL)
@ -173,11 +174,10 @@ public=list(
filter <- if(!is.null(name))
sprintf("displayName eq '%s'", name)
else sprintf("microsoft.graph.aadUserConversationMember/email eq '%s'", email)
res <- private$get_paged_list(self$do_operation("members", options=list(`$filter`=filter)))
res <- self$list_members(filter=filter)
if(length(res) != 1)
stop("Invalid name or email address", call.=FALSE)
ms_team_member$new(self$token, self$tenant, res[[1]],
parent_id=self$properties$id, parent_type="channel")
res[[1]]
}
},

Просмотреть файл

@ -15,7 +15,7 @@
#' - `do_operation(...)`: Carry out an arbitrary operation on the message.
#' - `sync_fields()`: Synchronise the R object with the message metadata in Microsoft Graph.
#' - `send_reply(body, content_type, attachments)`: Sends a reply to the message. See below.
#' - `list_replies(n=50)`: List the replies to this message. By default, this is limited to the 50 most recent replies; set the `n` argument to change this.
#' - `list_replies(filter=NULL, n=50)`: List the replies to this message. By default, this is limited to the 50 most recent replies; set the `n` argument to change this.
#' - `get_reply(message_id)`: Retrieves a specific reply to the message.
#' - `delete_reply(message_id, confirm=TRUE)`: Deletes a reply to the message. Currently the Graph API does not support deleting Teams messages, so this method is disabled.
#'
@ -34,6 +34,10 @@
#'
#' Note that message attachments are actually uploaded to the channel's file listing (a directory in the team's primary shared document folder). Support for attachments is somewhat experimental, so if you want to be sure that it works, upload the file separately using the channel's `upload_file()` method.
#'
#' @section List methods:
#' All `list_*` methods have `filter` and `n` arguments to limit the number of results. The former should be an [OData expression](https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter) as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are `filter=NULL` and `n=Inf`. If `n=NULL`, the `ms_graph_pager` iterator object is returned instead to allow manual iteration over the results.
#'
#' Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
#' @seealso
#' [`ms_team`], [`ms_channel`]
#'
@ -76,11 +80,10 @@ public=list(
ms_chat_message$new(self$token, self$tenant, res)
},
list_replies=function(n=50)
list_replies=function(filter=NULL, n=50)
{
private$assert_not_nested_reply()
res <- private$get_paged_list(self$do_operation("replies"), n=n)
private$init_list_objects(res, "chatMessage")
make_basic_list(self, "replies", filter, n)
},
get_reply=function(message_id)

Просмотреть файл

@ -24,7 +24,7 @@
#' - `get_item(path)`: Get an item representing a file or folder.
#' - `get_item_properties(path)`: Get the properties (metadata) for a file or folder.
#' - `set_item_properties(path, ...)`: Set the properties for a file or folder.
#' - `list_shared_items(...)`: List the drive items shared with you. See 'Shared items' below.
#' - `list_shared_items(...), list_shared_files(...)`: List the drive items shared with you. See 'Shared items' below.
#'
#' @section Initialization:
#' Creating new objects of this class should be done via the `get_drive` methods of the [`ms_graph`], [`az_user`] or [`ms_site`] classes. 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 drive.
@ -56,12 +56,17 @@
#' The `list_shared_items` method lists the files and folders that have been shared with you. This is similar to `list_items`, modified to handle the fact that the listed items reside on another drive or document library. The arguments are:
#' - `info`: The information to return: either "partial", "items" or "all". If "partial", a data frame is returned containing the name, size, whether the item is a file or folder, and a list of drive item objects. If "items", only the list of drive items is returned. If "all", a data frame is returned containing all the properties for each item.
#' - `allow_external`: Whether to include items that were shared from outside tenants. The default is FALSE.
#' - `filter, 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.
#'
#' The returned object will contain a list of drive items, that you can use to access the shared files/folders. If `info` is "item", the returned object is the list; if "partial" or "all" it is the `remoteItem` column in the data frame.
#'
#' `list_shared_files` is a synonym for `list_shared_items`.
#'
#' @section List methods:
#' All `list_*` methods have `filter` and `n` arguments to limit the number of results. The former should be an [OData expression](https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter) as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are `filter=NULL` and `n=Inf`. If `n=NULL`, the `ms_graph_pager` iterator object is returned instead to allow manual iteration over the results.
#'
#' Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
#' @seealso
#' [`get_personal_onedrive`], [`get_business_onedrive`], [`ms_site`], [`ms_drive_item`]
#'
@ -119,10 +124,9 @@ public=list(
super$initialize(token, tenant, properties)
},
list_items=function(path="/", info=c("partial", "name", "all"), full_names=FALSE, pagesize=1000)
list_items=function(path="/", ...)
{
info <- match.arg(info)
private$get_root()$list_items(path, info, full_names, pagesize)
private$get_root()$list_items(path, ...)
},
upload_file=function(src, dest, blocksize=32768000)
@ -177,16 +181,21 @@ public=list(
self$get_item(path)$update(...)
},
list_shared_items=function(info=c("partial", "items", "all"), allow_external=FALSE, pagesize=1000)
list_shared_items=function(info=c("partial", "items", "all"), allow_external=FALSE,
filter=NULL, n=Inf, pagesize=1000)
{
info <- match.arg(info)
opts <- list(`$top`=pagesize)
if(allow_external)
opts$allowExternal <- "true"
if(!is.null(filter))
opts$`filter` <- filter
children <- self$do_operation("sharedWithMe", options=opts, simplify=TRUE)
# get remote file list as a data frame
df <- private$get_paged_list(children, simplify=TRUE)
# get file list as a data frame, or return the iterator immediately if n is NULL
df <- extract_list_values(self$get_list_pager(children), n)
if(is.null(n))
return(df)
if(is_empty(df))
df <- data.frame(name=character(), size=numeric(), isdir=logical(), remoteItem=I(list()))

Просмотреть файл

@ -31,10 +31,11 @@
#'
#' `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, 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, 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).
#' - `full_names`: Whether to prefix the folder path to the names of the items.
#' - `filter, 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`.
@ -58,6 +59,10 @@
#'
#' This method returns a URL to access the item, for `type="view"` or "`type=edit"`. For `type="embed"`, it returns a list with components `webUrl` containing the URL, and `webHtml` containing a HTML fragment to embed the link in an IFRAME. The default is a viewable link, expiring in 7 days.
#'
#' @section List methods:
#' All `list_*` methods have `filter` and `n` arguments to limit the number of results. The former should be an [OData expression](https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter) as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are `filter=NULL` and `n=Inf`. If `n=NULL`, the `ms_graph_pager` iterator object is returned instead to allow manual iteration over the results.
#'
#' Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
#' @seealso
#' [`ms_graph`], [`ms_site`], [`ms_drive`]
#'
@ -175,7 +180,7 @@ public=list(
else res$link$webUrl
},
list_items=function(path="", info=c("partial", "name", "all"), full_names=FALSE, pagesize=1000)
list_items=function(path="", info=c("partial", "name", "all"), full_names=FALSE, filter=NULL, n=Inf, pagesize=1000)
{
private$assert_is_folder()
if(path == "/")
@ -186,12 +191,16 @@ public=list(
name=list(`$select`="name", `$top`=pagesize),
list(`$top`=pagesize)
)
if(!is.null(filter))
opts$`filter` <- filter
op <- sub("::", "", paste0(private$make_absolute_path(path), ":/children"))
children <- call_graph_endpoint(self$token, op, options=opts, simplify=TRUE)
# get file list as a data frame
df <- private$get_paged_list(children, simplify=TRUE)
# get file list as a data frame, or return the iterator immediately if n is NULL
df <- extract_list_values(self$get_list_pager(children), n)
if(is.null(n))
return(df)
if(is_empty(df))
df <- data.frame(name=character(), size=numeric(), isdir=logical(), id=character())
@ -243,7 +252,6 @@ public=list(
on.exit(close(con))
op <- paste0(private$make_absolute_path(dest), ":/createUploadSession")
# print(op)
upload_dest <- call_graph_endpoint(self$token, op, http_verb="POST")$uploadUrl
size <- file.size(src)

Просмотреть файл

@ -27,7 +27,8 @@
#'
#' @section List querying:
#' `list_items` supports the following arguments to customise results returned by the query.
#' - `filter`: A string giving a logical expression to filter the rows to return. Note that column names used in the expression must be prefixed with `fields/` to distinguish them from item metadata.
#' - `filter`: A string giving an [OData expression](https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter) to filter the rows to return. Note that column names used in the expression must be prefixed with `fields/` to distinguish them from item metadata.
#' - `n`: The maximum number of (filtered) results to return. If this is NULL, the `ms_graph_pager` iterator object is returned instead to allow manual iteration over the results.
#' - `select`: A string containing comma-separated column names to include in the returned data frame. If not supplied, includes all columns.
#' - `all_metadata`: If TRUE, the returned data frame will contain extended metadata as separate columns, while the data fields will be in a nested data frame named `fields`.
#' - `as_data_frame`: If FALSE, return the result as a list of individual `ms_list_item` objects, rather than a data frame. The `all_metadata` argument is ignored if `as_data_frame=FALSE`.
@ -77,7 +78,7 @@ public=list(
super$initialize(token, tenant, properties)
},
list_items=function(filter=NULL, select=NULL, all_metadata=FALSE, as_data_frame=TRUE, pagesize=5000)
list_items=function(filter=NULL, select=NULL, all_metadata=FALSE, as_data_frame=TRUE, n=Inf, pagesize=5000)
{
select <- if(is.null(select))
"fields"
@ -85,13 +86,16 @@ public=list(
options <- list(expand=select, `$filter`=filter, `$top`=pagesize)
headers <- httr::add_headers(Prefer="HonorNonIndexedQueriesWarningMayFailRandomly")
items <- self$do_operation("items", options=options, headers, simplify=as_data_frame)
df <- private$get_paged_list(items, simplify=as_data_frame)
if(!as_data_frame)
lapply(df, function(item) ms_list_item$new(self$token, self$tenant, item,
site_id=self$properties$parentReference$siteId,
list_id=self$properties$id))
else if(!all_metadata)
pager <- self$get_list_pager(self$do_operation("items", options=options, headers, simplify=as_data_frame),
site_id=self$properties$parentReference$siteId,
list_id=self$properties$id)
# get item list, or return the iterator immediately if n is NULL
df <- extract_list_values(pager, n)
if(is.null(n))
return(df)
if(as_data_frame && !all_metadata)
df$fields
else df
},

Просмотреть файл

@ -16,7 +16,7 @@
#' - `create_email(...)`: Creates a new email in the Drafts folder, optionally sending it as well. See 'Creating and sending emails'.
#' - `list_inbox_emails(...)`: List the emails in the Inbox folder. See 'Listing emails'.
#' - `get_inbox(),get_drafts(),get_sent_items(),get_deleted_items()`: Gets the special folder of that name. These folders are created by Outlook and exist in every email account.
#' - `list_folders()`: List all folders in this account.
#' - `list_folders(filter=NULL, n=Inf)`: List all folders in this account.
#' - `get_folder(folder_name, folder_id)`: Get a folder, either by the name or ID.
#' - `create_folder(folder_name)`: Create a new folder.
#' - `delete_folder(folder_name, folder_id, confirm=TRUE)`: Delete a folder. By default, ask for confirmation first. Note that special folders cannot be deleted.
@ -48,9 +48,13 @@
#' list_emails(by = "received desc", n = 100, pagesize = 10)
#' ```
#' - `by`: The sorting order of the message list. The possible fields are "received" (received date, the default), "from" and "subject". To sort in descending order, add a " desc". You can specify multiple sorting fields, with later fields used to break ties in earlier ones. The last sorting field is always "received desc" unless it appears earlier.
#' - `n`: The total number of emails to retrieve. The default is 100.
#' - `filter, n`: See below.
#' - `pagesize`: The number of emails per page. You can change this to a larger number to increase throughput, at the risk of running into timeouts.
#'
#' @section List methods generally:
#' All `list_*` methods have `filter` and `n` arguments to limit the number of results. The former should be an [OData expression](https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter) as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are `filter=NULL` and `n=100` for listing emails, and `n=Inf` for listing folders. If `n=NULL`, the `ms_graph_pager` iterator object is returned instead to allow manual iteration over the results.
#'
#' Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
#' @seealso
#' [`ms_outlook_folder`], [`ms_outlook_email`]
#'
@ -155,10 +159,9 @@ public=list(
stop("Cannot delete this object", call.=FALSE)
},
list_folders=function()
list_folders=function(filter=NULL, n=Inf)
{
lst <- private$get_paged_list(self$do_operation("mailFolders"))
private$init_list_objects(lst, default_generator=ms_outlook_folder, user_id=self$properties$id)
make_basic_list(self, "mailFolders", filter, n, user_id=self$properties$id)
},
get_folder=function(folder_name=NULL, folder_id=NULL)
@ -180,11 +183,10 @@ public=list(
return(ms_outlook_folder$new(self$token, self$tenant, self$do_operation(op), user_id=self$properties$id))
}
folders <- self$list_folders()
wch <- which(sapply(folders, function(f) f$properties$displayName == folder_name))
if(length(wch) != 1)
folders <- self$list_folders(filter=sprintf("displayName eq '%s'", folder_name))
if(length(folders) != 1)
stop("Invalid folder name '", folder_name, "'", call.=FALSE)
else folders[[wch]]
else folders[[1]]
},
create_folder=function(folder_name)

Просмотреть файл

@ -22,7 +22,7 @@
#' - `add_attachment(object, ...)`: Adds an attachment to the email. See 'Attachments' below.
#' - `add_image(object)`: Adds an inline image to the email.
#' - `get_attachment(attachment_name=NULL, attachment_id=NULL)`: Gets an attachment, either by name or ID. Note that attachments don't need to have unique names; if multiple attachments share the same name, the method throws an error.
#' - `list_attachments()`: Lists the current attachments for the email.
#' - `list_attachments(filter=NULL, n=Inf)`: Lists the current attachments for the email.
#' - `remove_attachment(attachment_name=NULL, attachment_id=NULL, confirm=TRUE)`: Removes an attachment from the email. By default, ask for confirmation first.
#' - `download_attachment(attachment_name=NULL, attachment_id=NULL, ...)`: Downloads an attachment. This is only supported for file attachments (not URLs).
#' - `send()`: Sends an email. See 'Sending, replying and forwarding'.
@ -75,6 +75,10 @@
#'
#' The `get_message_headers()` method retrieves the Internet message headers for the email, as a named character vector.
#'
#' @section List methods:
#' All `list_*` methods have `filter` and `n` arguments to limit the number of results. The former should be an [OData expression](https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter) as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are `filter=NULL` and `n=Inf`. If `n=NULL`, the `ms_graph_pager` iterator object is returned instead to allow manual iteration over the results.
#'
#' Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
#' @seealso
#' [`ms_outlook`], [`ms_outlook_folder`], [`ms_outlook_attachment`]
#'
@ -292,6 +296,7 @@ public=list(
assert_one_arg(attachment_name, attachment_id, msg="Supply exactly one of attachment name or ID")
if(is.null(attachment_id))
{
# filter arg not working with attachments?
atts <- self$list_attachments()
att_names <- sapply(atts, function(a) a$properties$name)
wch <- which(att_names == attachment_name)
@ -309,12 +314,15 @@ public=list(
user_id=self$user_id, message_id=self$properties$id)
},
list_attachments=function()
list_attachments=function(filter=NULL, n=Inf)
{
fields <- c("id", "name", "contentType", "size", "isInline", "lastModifiedDateTime")
res <- self$do_operation("attachments", options=list(select=paste(fields, collapse=",")))
private$init_list_objects(private$get_paged_list(res), default_generator=ms_outlook_attachment,
opts <- list(select=paste(fields, collapse=","))
if(!is.null(filter))
opts$`filter` <- filter
pager <- self$get_list_pager(self$do_operation("attachments", options=opts),
user_id=self$user_id, message_id=self$properties$id)
extract_list_values(pager, n)
},
remove_attachment=function(attachment_name=NULL, attachment_id=NULL, confirm=TRUE)

Просмотреть файл

@ -19,7 +19,7 @@
#' - `get_email(message_id)`: Get the email with the specified ID.
#' - `create_email(...)`: Creates a new draft email in this folder, optionally sending it as well. See 'Creating and sending emails'.
#' - `delete_email(message_id, confim=TRUE)`: Deletes the specified email. By default, ask for confirmation first.
#' - `list_folders()`: List subfolders of this folder.
#' - `list_folders(filter=NULL, n=Inf)`: List subfolders of this folder.
#' - `get_folder(folder_name, folder_id)`: Get a subfolder, either by the name or ID.
#' - `create_folder(folder_name)`: Create a new subfolder of this folder.
#' - `delete_folder(folder_name, folder_id, confirm=TRUE)`: Delete a subfolder. By default, ask for confirmation first.
@ -49,14 +49,18 @@
#' @section Listing emails:
#' To list the emails in a folder, call the `list_emails()` method. This returns a list of objects of class [`ms_outlook_email`], and has the following signature:
#' ```
#' list_emails(by = "received desc", n = 100, pagesize = 10)
#' list_emails(by = "received desc", filter = NULL, n = 100, pagesize = 10)
#' ```
#' - `by`: The sorting order of the message list. The possible fields are "received" (received date, the default), "from" and "subject". To sort in descending order, add a " desc". You can specify multiple sorting fields, with later fields used to break ties in earlier ones. The last sorting field is always "received desc" unless it appears earlier.
#' - `n`: The total number of emails to retrieve. The default is 100.
#' - `filter, n`: See below.
#' - `pagesize`: The number of emails per page. You can change this to a larger number to increase throughput, at the risk of running into timeouts.
#'
#' This returns a list of objects of class [`ms_outlook_email`].
#'
#' @section List methods generally:
#' All `list_*` methods have `filter` and `n` arguments to limit the number of results. The former should be an [OData expression](https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter) as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are `filter=NULL` and `n=100` for listing emails, and `n=Inf` for listing folders. If `n=NULL`, the `ms_graph_pager` iterator object is returned instead to allow manual iteration over the results.
#'
#' Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
#' @seealso
#' [`ms_outlook`], [`ms_outlook_email`]
#'
@ -148,12 +152,13 @@ public=list(
super$initialize(token, tenant, properties)
},
list_emails=function(by="received desc", n=100, pagesize=10)
list_emails=function(by="received desc", filter=NULL, n=100, pagesize=10)
{
order_by <- email_list_order(by)
opts <- list(`$orderby`=order_by, `$top`=pagesize)
lst <- private$get_paged_list(self$do_operation("messages", options=opts), n=n)
private$init_list_objects(lst, default_generator=ms_outlook_email, user_id=self$user_id)
# by only works with no filter
order_by <- if(is.null(filter)) email_list_order(by)
opts <- list(`$orderby`=order_by, `$filter`=filter, `$top`=pagesize)
pager <- self$get_list_pager(self$do_operation("messages", options=opts), user_id=self$user_id)
extract_list_values(pager, n)
},
get_email=function(message_id)
@ -183,10 +188,9 @@ public=list(
self$get_email(message_id)$delete(confirm=confirm)
},
list_folders=function()
list_folders=function(filter=NULL, n=Inf)
{
lst <- private$get_paged_list(self$do_operation("childFolders"))
private$init_list_objects(lst, default_generator=ms_outlook_folder, user_id=self$user_id)
make_basic_list(self, "childFolders", filter, n, user_id=self$user_id)
},
get_folder=function(folder_name=NULL, folder_id=NULL)
@ -200,11 +204,10 @@ public=list(
return(ms_outlook_folder$new(self$token, self$tenant, res, user_id=self$properties$id))
}
folders <- self$list_folders()
wch <- which(sapply(folders, function(f) f$properties$displayName == folder_name))
if(length(wch) != 1)
folders <- self$list_folders(filter=sprintf("displayName eq '%s'", folder_name))
if(length(folders) != 1)
stop("Invalid folder name '", folder_name, "'", call.=FALSE)
else folders[[wch]]
else folders[[1]]
},
create_folder=function(folder_name)

Просмотреть файл

@ -14,16 +14,20 @@
#' - `update(...)`: Update the site metadata in Microsoft Graph.
#' - `do_operation(...)`: Carry out an arbitrary operation on the site.
#' - `sync_fields()`: Synchronise the R object with the site metadata in Microsoft Graph.
#' - `list_drives()`: List the drives (shared document libraries) associated with this site.
#' - `list_drives(filter=NULL, n=Inf)`: List the drives (shared document libraries) associated with this site.
#' - `get_drive(drive_id)`: Retrieve a shared document library for this site. If the ID is not specified, this returns the default document library.
#' - `list_subsites()`: List the subsites of this site.
#' - `get_lists()`: Returns the lists that are part of this site.
#' - `list_subsites(filter=NULL, n=Inf)`: List the subsites of 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.
#'
#' @section Initialization:
#' Creating new objects of this class should be done via the `get_sharepoint_site` method of the [`ms_graph`] or [`az_group`] classes. 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 site.
#'
#' @section List methods:
#' All `list_*` methods have `filter` and `n` arguments to limit the number of results. The former should be an [OData expression](https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter) as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are `filter=NULL` and `n=Inf`. If `n=NULL`, the `ms_graph_pager` iterator object is returned instead to allow manual iteration over the results.
#'
#' Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
#' @seealso
#' [`ms_graph`], [`ms_drive`], [`az_user`]
#'
@ -51,10 +55,9 @@ public=list(
super$initialize(token, tenant, properties)
},
list_drives=function()
list_drives=function(filter=NULL, n=Inf)
{
res <- private$get_paged_list(self$do_operation("drives"))
private$init_list_objects(res, "drive")
make_basic_list(self, "drives", filter, n)
},
get_drive=function(drive_id=NULL)
@ -65,16 +68,14 @@ public=list(
ms_drive$new(self$token, self$tenant, self$do_operation(op))
},
list_subsites=function()
list_subsites=function(filter=NULL, n=Inf)
{
res <- private$get_paged_list(self$do_operation("sites"))
private$init_list_objects(res, "site")
make_basic_list(self, "sites", filter, n)
},
get_lists=function()
get_lists=function(filter=NULL, n=Inf)
{
res <- private$get_paged_list(self$do_operation("lists"))
private$init_list_objects(res, "list")
make_basic_list(self, "lists", filter, n)
},
get_list=function(list_name=NULL, list_id=NULL)

Просмотреть файл

@ -14,20 +14,24 @@
#' - `update(...)`: Update the team metadata in Microsoft Graph.
#' - `do_operation(...)`: Carry out an arbitrary operation on the team.
#' - `sync_fields()`: Synchronise the R object with the team metadata in Microsoft Graph.
#' - `list_channels(filter=NULL)`: List the channels for this team. Optionally, supply an OData expression to filter the list.
#' - `list_channels(filter=NULL, n=Inf)`: List the channels for this team.
#' - `get_channel(channel_name, channel_id)`: Retrieve a channel. If the name and ID are not specified, returns the primary channel.
#' - `create_channel(channel_name, description, membership)`: Create a new channel. Optionally, you can specify a short text description of the channel, and the type of membership: either standard or private (invitation-only).
#' - `delete_channel(channel_name, channel_id, confirm=TRUE)`: Delete a channel; by default, ask for confirmation first. You cannot delete the primary channel of a team. Note that Teams keeps track of all channels ever created, even if you delete them (you can see the deleted channels by going to the "Manage team" pane for a team, then the "Channels" tab, and expanding the "Deleted" entry); therefore, try not to create and delete channels unnecessarily.
#' - `list_drives()`: List the drives (shared document libraries) associated with this team.
#' - `list_drives(filter=NULL, n=Inf)`: List the drives (shared document libraries) associated with this team.
#' - `get_drive(drive_id)`: Retrieve a shared document library for this team. If the ID is not specified, this returns the default document library.
#' - `get_sharepoint_site()`: Get the SharePoint site associated with the team.
#' - `get_group()`: Retrieve the Microsoft 365 group associated with the team.
#' - `list_members()`: Retrieves the members of the team, as a list of [`ms_team_member`] objects.
#' - `list_members(filter=NULL, n=Inf)`: Retrieves the members of the team, as a list of [`ms_team_member`] objects.
#' - `get_member(name, email, id)`: Retrieve a specific member of the channel, as a `ms_team_member` object. Supply only one of the member name, email address or ID.
#'
#' @section Initialization:
#' Creating new objects of this class should be done via the `get_team` and `list_teams` methods of the [`ms_graph`], [`az_user`] or [`az_group`] classes. 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 team.
#'
#' @section List methods:
#' All `list_*` methods have `filter` and `n` arguments to limit the number of results. The former should be an [OData expression](https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter) as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are `filter=NULL` and `n=Inf`. If `n=NULL`, the `ms_graph_pager` iterator object is returned instead to allow manual iteration over the results.
#'
#' Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
#' @seealso
#' [`ms_graph`], [`az_group`], [`ms_channel`], [`ms_site`], [`ms_drive`]
#'
@ -64,11 +68,9 @@ public=list(
super$initialize(token, tenant, properties)
},
list_channels=function(filter=NULL)
list_channels=function(filter=NULL, n=Inf)
{
opts <- if(!is.null(filter)) list(`$filter`=filter)
res <- private$get_paged_list(self$do_operation("channels", options=opts))
private$init_list_objects(res, "channel", team_id=self$properties$id)
make_basic_list(self, "channels", filter, n, team_id=self$properties$id)
},
get_channel=function(channel_name=NULL, channel_id=NULL)
@ -107,10 +109,9 @@ public=list(
self$get_channel(channel_name, channel_id)$delete(confirm=confirm)
},
list_drives=function()
list_drives=function(filter=NULL, n=Inf)
{
res <- private$get_paged_list(private$do_group_operation("drives"))
private$init_list_objects(res, "drive")
make_basic_list(self$get_group(), "drives", filter, n)
},
get_drive=function(drive_id=NULL)
@ -132,11 +133,9 @@ public=list(
az_group$new(self$token, self$tenant, private$do_group_operation())
},
list_members=function()
list_members=function(filter=NULL, n=Inf)
{
res <- private$get_paged_list(self$do_operation("members"))
private$init_list_objects(res, default_generator=ms_team_member,
parent_id=self$properties$id, parent_type="team")
make_basic_list(self, "members", filter, n, parent_id=self$properties$id, parent_type="team")
},
get_member=function(name=NULL, email=NULL, id=NULL)
@ -153,11 +152,10 @@ public=list(
filter <- if(!is.null(name))
sprintf("displayName eq '%s'", name)
else sprintf("microsoft.graph.aadUserConversationMember/email eq '%s'", email)
res <- private$get_paged_list(self$do_operation("members", options=list(`$filter`=filter)))
res <- self$list_members(filter=filter)
if(length(res) != 1)
stop("Invalid name or email address", call.=FALSE)
ms_team_member$new(self$token, self$tenant, res[[1]],
parent_id=self$properties$id, parent_type="team")
res[[1]]
}
},

Просмотреть файл

@ -30,14 +30,14 @@ Class representing a Microsoft Teams channel.
\item \code{do_operation(...)}: Carry out an arbitrary operation on the channel.
\item \code{sync_fields()}: Synchronise the R object with the channel metadata in Microsoft Graph.
\item \code{send_message(body, content_type, attachments)}: Sends a new message to the channel. See below.
\item \code{list_messages(n=50)}: Retrieves the messages in the channel. By default, this is limited to the 50 most recent messages; set the \code{n} argument to change this.
\item \code{list_messages(filter=NULL, n=50)}: Retrieves the messages in the channel. By default, this is limited to the 50 most recent messages; set the \code{n} argument to change this.
\item \code{get_message(message_id)}: Retrieves a specific message in the channel.
\item \code{delete_message(message_id, confirm=TRUE)}: Deletes a message. Currently the Graph API does not support deleting Teams messages, so this method is disabled.
\item \code{list_files()}: List the files for the channel. See \code{\link{ms_drive}} for the arguments available for this and the file upload/download methods.
\item \code{upload_file()}: Uploads a file to the channel.
\item \code{download_file()}: Downloads a file from the channel.
\item \code{get_folder()}: Retrieves the files folder for the channel, as a \code{\link{ms_drive_item}} object.
\item \code{list_members()}: Retrieves the members of the channel, as a list of \code{\link{ms_team_member}} objects.
\item \code{list_members(filter=NULL, n=Inf)}: Retrieves the members of the channel, as a list of \code{\link{ms_team_member}} objects.
\item \code{get_member(name, email, id)}: Retrieve a specific member of the channel, as a \code{ms_team_member} object. Supply only one of the member name, email address or ID.
}
}
@ -61,6 +61,13 @@ To send a message to a channel, use the \code{send_message()} method. This has a
Note that message attachments are actually uploaded to the channel's file listing (a directory in the team's primary shared document folder). Support for attachments is somewhat experimental, so if you want to be sure that it works, upload the file separately using the \code{upload_file()} method.
}
\section{List methods}{
All \verb{list_*} methods have \code{filter} and \code{n} arguments to limit the number of results. The former should be an \href{https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter}{OData expression} as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are \code{filter=NULL} and \code{n=Inf}. If \code{n=NULL}, the \code{ms_graph_pager} iterator object is returned instead to allow manual iteration over the results.
Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
}
\examples{
\dontrun{

Просмотреть файл

@ -29,7 +29,7 @@ Class representing a message in a Teams channel. Currently Microsoft365R only su
\item \code{do_operation(...)}: Carry out an arbitrary operation on the message.
\item \code{sync_fields()}: Synchronise the R object with the message metadata in Microsoft Graph.
\item \code{send_reply(body, content_type, attachments)}: Sends a reply to the message. See below.
\item \code{list_replies(n=50)}: List the replies to this message. By default, this is limited to the 50 most recent replies; set the \code{n} argument to change this.
\item \code{list_replies(filter=NULL, n=50)}: List the replies to this message. By default, this is limited to the 50 most recent replies; set the \code{n} argument to change this.
\item \code{get_reply(message_id)}: Retrieves a specific reply to the message.
\item \code{delete_reply(message_id, confirm=TRUE)}: Deletes a reply to the message. Currently the Graph API does not support deleting Teams messages, so this method is disabled.
}
@ -56,6 +56,13 @@ Teams channels don't support nested replies, so any methods dealing with replies
Note that message attachments are actually uploaded to the channel's file listing (a directory in the team's primary shared document folder). Support for attachments is somewhat experimental, so if you want to be sure that it works, upload the file separately using the channel's \code{upload_file()} method.
}
\section{List methods}{
All \verb{list_*} methods have \code{filter} and \code{n} arguments to limit the number of results. The former should be an \href{https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter}{OData expression} as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are \code{filter=NULL} and \code{n=Inf}. If \code{n=NULL}, the \code{ms_graph_pager} iterator object is returned instead to allow manual iteration over the results.
Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
}
\examples{
\dontrun{

Просмотреть файл

@ -38,7 +38,7 @@ Class representing a personal OneDrive or SharePoint document library.
\item \code{get_item(path)}: Get an item representing a file or folder.
\item \code{get_item_properties(path)}: Get the properties (metadata) for a file or folder.
\item \code{set_item_properties(path, ...)}: Set the properties for a file or folder.
\item \code{list_shared_items(...)}: List the drive items shared with you. See 'Shared items' below.
\item \verb{list_shared_items(...), list_shared_files(...)}: List the drive items shared with you. See 'Shared items' below.
}
}
@ -78,6 +78,7 @@ The \code{list_shared_items} method lists the files and folders that have been s
\itemize{
\item \code{info}: The information to return: either "partial", "items" or "all". If "partial", a data frame is returned containing the name, size, whether the item is a file or folder, and a list of drive item objects. If "items", only the list of drive items is returned. If "all", a data frame is returned containing all the properties for each item.
\item \code{allow_external}: Whether to include items that were shared from outside tenants. The default is FALSE.
\item \verb{filter, 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.
}
@ -86,6 +87,13 @@ The returned object will contain a list of drive items, that you can use to acce
\code{list_shared_files} is a synonym for \code{list_shared_items}.
}
\section{List methods}{
All \verb{list_*} methods have \code{filter} and \code{n} arguments to limit the number of results. The former should be an \href{https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter}{OData expression} as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are \code{filter=NULL} and \code{n=Inf}. If \code{n=NULL}, the \code{ms_graph_pager} iterator object is returned instead to allow manual iteration over the results.
Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
}
\examples{
\dontrun{

Просмотреть файл

@ -50,11 +50,12 @@ 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, 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, 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{full_names}: Whether to prefix the folder path to the names of the items.
\item \verb{filter, 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.
}
@ -82,6 +83,13 @@ It is an error to try to upload to a file item, or to upload a source directory.
This method returns a URL to access the item, for \code{type="view"} or "\verb{type=edit"}. For \code{type="embed"}, it returns a list with components \code{webUrl} containing the URL, and \code{webHtml} containing a HTML fragment to embed the link in an IFRAME. The default is a viewable link, expiring in 7 days.
}
\section{List methods}{
All \verb{list_*} methods have \code{filter} and \code{n} arguments to limit the number of results. The former should be an \href{https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter}{OData expression} as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are \code{filter=NULL} and \code{n=Inf}. If \code{n=NULL}, the \code{ms_graph_pager} iterator object is returned instead to allow manual iteration over the results.
Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
}
\examples{
\dontrun{

Просмотреть файл

@ -47,7 +47,8 @@ Creating new objects of this class should be done via the \code{get_list} method
\code{list_items} supports the following arguments to customise results returned by the query.
\itemize{
\item \code{filter}: A string giving a logical expression to filter the rows to return. Note that column names used in the expression must be prefixed with \verb{fields/} to distinguish them from item metadata.
\item \code{filter}: A string giving an \href{https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter}{OData expression} to filter the rows to return. Note that column names used in the expression must be prefixed with \verb{fields/} to distinguish them from item metadata.
\item \code{n}: The maximum number of (filtered) results to return. If this is NULL, the \code{ms_graph_pager} iterator object is returned instead to allow manual iteration over the results.
\item \code{select}: A string containing comma-separated column names to include in the returned data frame. If not supplied, includes all columns.
\item \code{all_metadata}: If TRUE, the returned data frame will contain extended metadata as separate columns, while the data fields will be in a nested data frame named \code{fields}.
\item \code{as_data_frame}: If FALSE, return the result as a list of individual \code{ms_list_item} objects, rather than a data frame. The \code{all_metadata} argument is ignored if \code{as_data_frame=FALSE}.

Просмотреть файл

@ -30,7 +30,7 @@ Class representing a user's Outlook email account.
\item \code{create_email(...)}: Creates a new email in the Drafts folder, optionally sending it as well. See 'Creating and sending emails'.
\item \code{list_inbox_emails(...)}: List the emails in the Inbox folder. See 'Listing emails'.
\item \verb{get_inbox(),get_drafts(),get_sent_items(),get_deleted_items()}: Gets the special folder of that name. These folders are created by Outlook and exist in every email account.
\item \code{list_folders()}: List all folders in this account.
\item \code{list_folders(filter=NULL, n=Inf)}: List all folders in this account.
\item \code{get_folder(folder_name, folder_id)}: Get a folder, either by the name or ID.
\item \code{create_folder(folder_name)}: Create a new folder.
\item \code{delete_folder(folder_name, folder_id, confirm=TRUE)}: Delete a folder. By default, ask for confirmation first. Note that special folders cannot be deleted.
@ -68,11 +68,18 @@ To list the emails in the Inbox, call the \code{list_emails()} method. This retu
}
\itemize{
\item \code{by}: The sorting order of the message list. The possible fields are "received" (received date, the default), "from" and "subject". To sort in descending order, add a " desc". You can specify multiple sorting fields, with later fields used to break ties in earlier ones. The last sorting field is always "received desc" unless it appears earlier.
\item \code{n}: The total number of emails to retrieve. The default is 100.
\item \verb{filter, n}: See below.
\item \code{pagesize}: The number of emails per page. You can change this to a larger number to increase throughput, at the risk of running into timeouts.
}
}
\section{List methods generally}{
All \verb{list_*} methods have \code{filter} and \code{n} arguments to limit the number of results. The former should be an \href{https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter}{OData expression} as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are \code{filter=NULL} and \code{n=100} for listing emails, and \code{n=Inf} for listing folders. If \code{n=NULL}, the \code{ms_graph_pager} iterator object is returned instead to allow manual iteration over the results.
Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
}
\examples{
\dontrun{

Просмотреть файл

@ -36,7 +36,7 @@ Class representing an Outlook mail message. The one class represents both sent a
\item \code{add_attachment(object, ...)}: Adds an attachment to the email. See 'Attachments' below.
\item \code{add_image(object)}: Adds an inline image to the email.
\item \code{get_attachment(attachment_name=NULL, attachment_id=NULL)}: Gets an attachment, either by name or ID. Note that attachments don't need to have unique names; if multiple attachments share the same name, the method throws an error.
\item \code{list_attachments()}: Lists the current attachments for the email.
\item \code{list_attachments(filter=NULL, n=Inf)}: Lists the current attachments for the email.
\item \code{remove_attachment(attachment_name=NULL, attachment_id=NULL, confirm=TRUE)}: Removes an attachment from the email. By default, ask for confirmation first.
\item \code{download_attachment(attachment_name=NULL, attachment_id=NULL, ...)}: Downloads an attachment. This is only supported for file attachments (not URLs).
\item \code{send()}: Sends an email. See 'Sending, replying and forwarding'.
@ -103,6 +103,13 @@ The \code{copy()} and \code{move()} methods copy and move an email to a differen
The \code{get_message_headers()} method retrieves the Internet message headers for the email, as a named character vector.
}
\section{List methods}{
All \verb{list_*} methods have \code{filter} and \code{n} arguments to limit the number of results. The former should be an \href{https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter}{OData expression} as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are \code{filter=NULL} and \code{n=Inf}. If \code{n=NULL}, the \code{ms_graph_pager} iterator object is returned instead to allow manual iteration over the results.
Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
}
\examples{
\dontrun{

Просмотреть файл

@ -33,7 +33,7 @@ Class representing a folder in Outlook.
\item \code{get_email(message_id)}: Get the email with the specified ID.
\item \code{create_email(...)}: Creates a new draft email in this folder, optionally sending it as well. See 'Creating and sending emails'.
\item \code{delete_email(message_id, confim=TRUE)}: Deletes the specified email. By default, ask for confirmation first.
\item \code{list_folders()}: List subfolders of this folder.
\item \code{list_folders(filter=NULL, n=Inf)}: List subfolders of this folder.
\item \code{get_folder(folder_name, folder_id)}: Get a subfolder, either by the name or ID.
\item \code{create_folder(folder_name)}: Create a new subfolder of this folder.
\item \code{delete_folder(folder_name, folder_id, confirm=TRUE)}: Delete a subfolder. By default, ask for confirmation first.
@ -68,17 +68,24 @@ To reply to or forward an email, first retrieve it using \code{get_email()} or \
\section{Listing emails}{
To list the emails in a folder, call the \code{list_emails()} method. This returns a list of objects of class \code{\link{ms_outlook_email}}, and has the following signature:\preformatted{list_emails(by = "received desc", n = 100, pagesize = 10)
To list the emails in a folder, call the \code{list_emails()} method. This returns a list of objects of class \code{\link{ms_outlook_email}}, and has the following signature:\preformatted{list_emails(by = "received desc", filter = NULL, n = 100, pagesize = 10)
}
\itemize{
\item \code{by}: The sorting order of the message list. The possible fields are "received" (received date, the default), "from" and "subject". To sort in descending order, add a " desc". You can specify multiple sorting fields, with later fields used to break ties in earlier ones. The last sorting field is always "received desc" unless it appears earlier.
\item \code{n}: The total number of emails to retrieve. The default is 100.
\item \verb{filter, n}: See below.
\item \code{pagesize}: The number of emails per page. You can change this to a larger number to increase throughput, at the risk of running into timeouts.
}
This returns a list of objects of class \code{\link{ms_outlook_email}}.
}
\section{List methods generally}{
All \verb{list_*} methods have \code{filter} and \code{n} arguments to limit the number of results. The former should be an \href{https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter}{OData expression} as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are \code{filter=NULL} and \code{n=100} for listing emails, and \code{n=Inf} for listing folders. If \code{n=NULL}, the \code{ms_graph_pager} iterator object is returned instead to allow manual iteration over the results.
Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
}
\examples{
\dontrun{

Просмотреть файл

@ -28,10 +28,10 @@ Class representing a SharePoint site.
\item \code{update(...)}: Update the site metadata in Microsoft Graph.
\item \code{do_operation(...)}: Carry out an arbitrary operation on the site.
\item \code{sync_fields()}: Synchronise the R object with the site metadata in Microsoft Graph.
\item \code{list_drives()}: List the drives (shared document libraries) associated with this site.
\item \code{list_drives(filter=NULL, n=Inf)}: List the drives (shared document libraries) associated with this site.
\item \code{get_drive(drive_id)}: Retrieve a shared document library for this site. If the ID is not specified, this returns the default document library.
\item \code{list_subsites()}: List the subsites of this site.
\item \code{get_lists()}: Returns the lists that are part of this site.
\item \code{list_subsites(filter=NULL, n=Inf)}: List the subsites of 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.
}
@ -42,6 +42,13 @@ Class representing a SharePoint site.
Creating new objects of this class should be done via the \code{get_sharepoint_site} method of the \code{\link{ms_graph}} or \code{\link{az_group}} classes. Calling the \code{new()} method for this class only constructs the R object; it does not call the Microsoft Graph API to retrieve or create the actual site.
}
\section{List methods}{
All \verb{list_*} methods have \code{filter} and \code{n} arguments to limit the number of results. The former should be an \href{https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter}{OData expression} as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are \code{filter=NULL} and \code{n=Inf}. If \code{n=NULL}, the \code{ms_graph_pager} iterator object is returned instead to allow manual iteration over the results.
Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
}
\examples{
\dontrun{

Просмотреть файл

@ -28,15 +28,15 @@ Class representing a team in Microsoft Teams.
\item \code{update(...)}: Update the team metadata in Microsoft Graph.
\item \code{do_operation(...)}: Carry out an arbitrary operation on the team.
\item \code{sync_fields()}: Synchronise the R object with the team metadata in Microsoft Graph.
\item \code{list_channels(filter=NULL)}: List the channels for this team. Optionally, supply an OData expression to filter the list.
\item \code{list_channels(filter=NULL, n=Inf)}: List the channels for this team.
\item \code{get_channel(channel_name, channel_id)}: Retrieve a channel. If the name and ID are not specified, returns the primary channel.
\item \code{create_channel(channel_name, description, membership)}: Create a new channel. Optionally, you can specify a short text description of the channel, and the type of membership: either standard or private (invitation-only).
\item \code{delete_channel(channel_name, channel_id, confirm=TRUE)}: Delete a channel; by default, ask for confirmation first. You cannot delete the primary channel of a team. Note that Teams keeps track of all channels ever created, even if you delete them (you can see the deleted channels by going to the "Manage team" pane for a team, then the "Channels" tab, and expanding the "Deleted" entry); therefore, try not to create and delete channels unnecessarily.
\item \code{list_drives()}: List the drives (shared document libraries) associated with this team.
\item \code{list_drives(filter=NULL, n=Inf)}: List the drives (shared document libraries) associated with this team.
\item \code{get_drive(drive_id)}: Retrieve a shared document library for this team. If the ID is not specified, this returns the default document library.
\item \code{get_sharepoint_site()}: Get the SharePoint site associated with the team.
\item \code{get_group()}: Retrieve the Microsoft 365 group associated with the team.
\item \code{list_members()}: Retrieves the members of the team, as a list of \code{\link{ms_team_member}} objects.
\item \code{list_members(filter=NULL, n=Inf)}: Retrieves the members of the team, as a list of \code{\link{ms_team_member}} objects.
\item \code{get_member(name, email, id)}: Retrieve a specific member of the channel, as a \code{ms_team_member} object. Supply only one of the member name, email address or ID.
}
}
@ -46,6 +46,13 @@ Class representing a team in Microsoft Teams.
Creating new objects of this class should be done via the \code{get_team} and \code{list_teams} methods of the \code{\link{ms_graph}}, \code{\link{az_user}} or \code{\link{az_group}} classes. Calling the \code{new()} method for this class only constructs the R object; it does not call the Microsoft Graph API to retrieve or create the actual team.
}
\section{List methods}{
All \verb{list_*} methods have \code{filter} and \code{n} arguments to limit the number of results. The former should be an \href{https://docs.microsoft.com/en-us/graph/query-parameters#filter-parameter}{OData expression} as a string to filter the result set on. The latter should be a number setting the maximum number of (filtered) results to return. The default values are \code{filter=NULL} and \code{n=Inf}. If \code{n=NULL}, the \code{ms_graph_pager} iterator object is returned instead to allow manual iteration over the results.
Support in the underlying Graph API for OData queries is patchy. Not all endpoints that return lists of objects support filtering, and if they do, they may not allow all of the defined operators. If your filtering expression results in an error, you can carry out the operation without filtering and then filter the results on the client side.
}
\examples{
\dontrun{

Просмотреть файл

@ -37,6 +37,12 @@ test_that("OneDrive personal works",
item <- od$get_item(dest)
expect_is(item, "ms_drive_item")
pager <- od$list_files(newfolder, filter=sprintf("name eq '%s'", basename(src)), n=NULL)
expect_is(pager, "ms_graph_pager")
lst1 <- pager$value
expect_is(lst1, "data.frame")
expect_identical(nrow(lst1), 1L)
expect_silent(od$set_item_properties(dest, name="newname"))
expect_silent(item$sync_fields())
expect_identical(item$properties$name, "newname")

Просмотреть файл

@ -29,8 +29,8 @@ test_that("OneDrive for Business works",
od2 <- get_business_onedrive(tenant=tenant, app=app)
expect_is(od2, "ms_drive")
ls <- od$list_items()
expect_is(ls, "data.frame")
lst <- od$list_items()
expect_is(lst, "data.frame")
newfolder <- make_name()
expect_silent(od$create_folder(newfolder))
@ -46,6 +46,12 @@ test_that("OneDrive for Business works",
item <- od$get_item(dest)
expect_is(item, "ms_drive_item")
pager <- od$list_files(newfolder, filter=sprintf("name eq '%s'", basename(src)), n=NULL)
expect_is(pager, "ms_graph_pager")
lst1 <- pager$value
expect_is(lst1, "data.frame")
expect_identical(nrow(lst1), 1L)
expect_silent(od$set_item_properties(dest, name="newname"))
expect_silent(item$sync_fields())
expect_identical(item$properties$name, "newname")

Просмотреть файл

@ -55,11 +55,18 @@ test_that("SharePoint methods work",
site <- get_sharepoint_site(site_name, tenant=tenant, app=app)
expect_is(site, "ms_site")
# drive -- functionality tested in test02
# drive functionality tested in test02
drives <- site$list_drives()
expect_is(drives, "list")
expect_true(all(sapply(drives, inherits, "ms_drive")))
# filtering not yet supported for drives
# drvpager <- site$list_drives(filter="name eq 'Documents'", n=NULL)
# expect_is(drvpager, "ms_graph_pager")
# drv0 <- drvpager$value
# expect_is(drv0, "list")
# expect_true(length(drv0) == 1 && inherits(drv0[[1]], "ms_drive"))
drv <- site$get_drive()
expect_is(drv, "ms_drive")
@ -71,6 +78,12 @@ test_that("SharePoint methods work",
expect_is(lists, "list")
expect_true(all(sapply(lists, inherits, "ms_list")))
# filtering not yet supported
# lstpager <- site$get_lists(filter=sprintf("displayName eq '%s'", list_name), n=NULL)
# expect_is(lstpager, "ms_graph_pager")
# lst0 <- lstpager$value
# expect_true(length(lst0) == 1 && inherits(lst0[[1]], "ms_list"))
lst <- site$get_list(list_name=list_name)
lst2 <- site$get_list(list_id=list_id)
expect_is(lst, "ms_list")
@ -91,6 +104,11 @@ test_that("SharePoint methods work",
expect_is(items3, "list")
expect_true(all(sapply(items3, inherits, "ms_list_item")))
itpager <- lst$list_items(filter=sprintf("fields/Title eq '%s'", items3[[1]]$properties$fields$Title), n=NULL)
expect_is(itpager, "ms_graph_pager")
items0 <- itpager$value
expect_true(is.data.frame(items0) && nrow(items0) == 1)
item_id <- items3[[1]]$properties$id
item <- lst$get_item(item_id)
expect_is(item, "ms_list_item")

Просмотреть файл

@ -65,6 +65,11 @@ test_that("Teams methods work",
expect_is(chans, "list")
expect_true(all(sapply(chans, inherits, "ms_channel")))
chanpager <- team$list_channels(filter=sprintf("displayName eq '%s'", channel_name), n=NULL)
expect_is(chanpager, "ms_graph_pager")
chans0 <- chanpager$value
expect_true(length(chans0) == 1 && inherits(chans0[[1]], "ms_channel"))
expect_error(team$get_channel(channel_name, channel_id))
chan0 <- team$get_channel()
@ -97,6 +102,11 @@ test_that("Team member methods work",
expect_true(all(sapply(mlst, inherits, "ms_team_member")))
expect_true(all(sapply(mlst, function(obj) obj$type == "team member")))
mpager <- team$list_members(filter=sprintf("displayName eq '%s'", mlst[[1]]$properties$displayName), n=NULL)
expect_is(mpager, "ms_graph_pager")
mlst0 <- mpager$value
expect_true(length(mlst0) == 1 && inherits(mlst0[[1]], "ms_team_member"))
usr <- mlst[[1]]
usrname <- usr$properties$displayName
usremail <- usr$properties$email

Просмотреть файл

@ -28,10 +28,22 @@ test_that("Outlook client works",
expect_is(folders, "list")
expect_true(all(sapply(folders, inherits, "ms_outlook_folder")))
f1 <- folders[[1]]$properties$displayName
fpager <- outl$list_folders(filter=sprintf("displayName eq '%s'", f1), n=NULL)
expect_is(fpager, "ms_graph_pager")
folders1 <- fpager$value
expect_true(length(folders1) ==1 && inherits(folders1[[1]], "ms_outlook_folder"))
emails <- outl$list_emails()
expect_is(emails, "list")
expect_true(all(sapply(emails, inherits, "ms_outlook_email")))
subj1 <- emails[[1]]$properties$subject
empager <- outl$list_emails(filter=sprintf("subject eq '%s'", subj1), n=NULL)
expect_is(empager, "ms_graph_pager")
emails1 <- empager$value
expect_true(length(emails1) == 1 && inherits(emails1[[1]], "ms_outlook_email"))
f1name <- make_name()
f1 <- outl$create_folder(f1name)
expect_is(f1, "ms_outlook_folder")

Просмотреть файл

@ -68,6 +68,12 @@ test_that("Outlook folder methods work",
expect_is(flist, "list")
expect_true(all(sapply(flist, inherits, "ms_outlook_folder")))
f1 <- flist[[1]]$properties$displayName
fpager <- outl$list_folders(filter=sprintf("displayName eq '%s'", f1), n=NULL)
expect_is(fpager, "ms_graph_pager")
flist1 <- fpager$value
expect_true(length(flist1) ==1 && inherits(flist1[[1]], "ms_outlook_folder"))
expect_silent(folder$delete_folder(fname2, confirm=FALSE))
expect_silent(folder$delete(confirm=FALSE))
})

Просмотреть файл

@ -35,6 +35,12 @@ test_that("Outlook email attachment methods work",
expect_is(atts, "list")
expect_true(!is_empty(atts) && all(sapply(atts, inherits, "ms_outlook_attachment")))
name1 <- atts[[1]]$properties$name
attpager <- em$list_attachments(filter=sprintf("name eq '%s'", name1), n=NULL)
expect_is(attpager, "ms_graph_pager")
atts1 <- attpager$value
expect_true(length(atts1) ==1 && inherits(atts1[[1]], "ms_outlook_attachment"))
id1 <- atts[[1]]$properties$id
att1 <- em$get_attachment("logo_small.jpg")
expect_is(att1, "ms_outlook_attachment")