diff --git a/.Rbuildignore b/.Rbuildignore index 850104d..b6bfdf0 100644 --- a/.Rbuildignore +++ b/.Rbuildignore @@ -11,6 +11,7 @@ ^_pkgdown\.yml$ ^config\.yml$ ^cran-comments\.md$ +^docker$ ^docs$ ^pkgdown$ ^renv$ diff --git a/.github/workflows/test-coverage.yaml b/.github/workflows/test-coverage.yaml index 056da9e..b732d91 100644 --- a/.github/workflows/test-coverage.yaml +++ b/.github/workflows/test-coverage.yaml @@ -44,7 +44,7 @@ jobs: - name: Upload test results if: failure() - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: coverage-test-failures path: ${{ runner.temp }}/package diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index bd4e3f3..aad02aa 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,36 +1,11 @@ -image: rocker/r-ver:4.4.0 +image: images.sbgenomics.com/marko_trifunovic/sevenbridges2-ci-docker:v1 stages: - - build - - document - - check - - sonar - - publish - - deploy - -variables: - APT_DEPS: "git libssl-dev libcurl4-openssl-dev libcurl4-openssl-dev libssl-dev libfreetype6-dev libfribidi-dev libharfbuzz-dev git libxml2-dev libfontconfig1-dev libgit2-dev libssl-dev pandoc libicu-dev libz-dev libcurl4-openssl-dev libjpeg-dev libpng-dev libtiff-dev make zlib1g-dev git libgit2-dev libssl-dev libcurl4-openssl-dev git libicu-dev pandoc make make zlib1g-dev libssl-dev libcurl4-openssl-dev pandoc libssl-dev libfreetype6-dev libfribidi-dev libharfbuzz-dev libxml2-dev libfontconfig1-dev libssl-dev pandoc libicu-dev libcurl4-openssl-dev libjpeg-dev libpng-dev libtiff-dev make libfreetype6-dev libfribidi-dev libharfbuzz-dev libfontconfig1-dev libjpeg-dev libpng-dev libtiff-dev libxml2-dev libicu-dev pandoc make libxml2-dev libcurl4-openssl-dev libssl-dev libicu-dev libfontconfig1-dev libfreetype6-dev libfreetype6-dev libfribidi-dev libharfbuzz-dev libfontconfig1-dev git libgit2-dev libssl-dev libcurl4-openssl-dev make libxml2-dev" - IMAGE: dockerhub.sbgenomics.com/$CI_PROJECT_NAME - RENV_PATHS_CACHE: ${CI_PROJECT_DIR}/cache - RENV_PATHS_LIBRARY: ${CI_PROJECT_DIR}/renv/library - RENV_CONFIG_REPOS_OVERRIDE: http://cran.r-project.org - LIBRARY_NAME: examplePackage - -cache: - key: $CI_JOB_NAME - paths: - - ${RENV_PATHS_CACHE} - - ${RENV_PATHS_LIBRARY} - -before_script: - - mkdir -p ${RENV_PATHS_CACHE} ${RENV_PATHS_LIBRARY} - - apt-get -qq update; - - apt-get -y install ${APT_DEPS} - - apt-get install -y nodejs - - apt-get install -y npm - - R -e "install.packages(c('remotes', 'devtools', 'covr'), repos = 'http://cran.r-project.org')" - - R -e "if (!requireNamespace('renv', quietly = TRUE)) remotes::install_version('renv', version = '1.0.7')" - - R -e "renv::restore(lockfile = 'renv.lock')" + - build # Build the R package binaries + - document # Generate package documentation using 'roxygen2' + - check # Run various checks (linting, coverage) on the codebase + - sonar # Perform SonarQube analysis to report code quality + - deploy # Deploy the package site using pkgdown buildbinary: stage: build @@ -71,7 +46,6 @@ sonar: dependencies: - coverage image: emeraldsquad/sonar-scanner:2.2.0 - before_script: [] script: - infinity sonar scanner allow_failure: true diff --git a/CRAN-SUBMISSION b/CRAN-SUBMISSION index 0a7f50b..201a98a 100644 --- a/CRAN-SUBMISSION +++ b/CRAN-SUBMISSION @@ -1,3 +1,3 @@ -Version: 0.2.0 -Date: 2024-07-01 15:42:36 UTC -SHA: 7735af228579c33a30ba0a9f2b18bd0d27a60576 +Version: 0.3.0 +Date: 2025-02-24 21:33:09 UTC +SHA: 0c4d015b5d88819b3776910d84a2bd82991de8ce diff --git a/DESCRIPTION b/DESCRIPTION index 4b69a85..397682b 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -1,7 +1,7 @@ Package: sevenbridges2 Type: Package Title: The 'Seven Bridges Platform' API Client -Version: 0.2.0 +Version: 0.4.0 Authors@R: c( person("Marko", "Trifunovic", email = "marko.trifunovic@velsera.com", role = c("aut", "cre")), person("Marija", "Gacic", email = "marija.jovanovic@velsera.com", role = c("aut")), @@ -20,7 +20,7 @@ URL: https://www.sevenbridges.com, https://sbg.github.io/sevenbridges2/, https://github.com/sbg/sevenbridges2 Depends: R (>= 4.2.0) -RoxygenNote: 7.3.1 +RoxygenNote: 7.3.2 Imports: httr, R6, diff --git a/NAMESPACE b/NAMESPACE index 2e7dbdc..22db9d6 100644 --- a/NAMESPACE +++ b/NAMESPACE @@ -2,9 +2,12 @@ export(App) export(Apps) +export(AsyncJob) export(Auth) export(Billing_groups) export(Collection) +export(Division) +export(Divisions) export(Export) export(Exports) export(File) @@ -16,6 +19,8 @@ export(Part) export(Projects) export(Task) export(Tasks) +export(Team) +export(Teams) export(Upload) export(Volume) export(VolumeContentCollection) @@ -28,6 +33,7 @@ export(prepare_items_for_bulk_import) importFrom(DescTools,StripAttr) importFrom(R6,R6Class) importFrom(checkmate,assert_character) +importFrom(checkmate,assert_choice) importFrom(checkmate,assert_int) importFrom(checkmate,assert_integer) importFrom(checkmate,assert_list) diff --git a/NEWS.md b/NEWS.md index aeee57e..e9ad353 100644 --- a/NEWS.md +++ b/NEWS.md @@ -2,26 +2,137 @@ * Initial CRAN submission. +--- + # sevenbridges2 0.2.0 -## Breaking changes +## New features -* The package now includes support for another category of API calls: bulk actions. -* Bulk actions allow users to perform actions on multiple items with a single call. The following bulk API methods have been added: - - `bulk_submit_import()` in the `Auth$imports` path allows you to import multiple volume files or folders into a project using a single API call. - - `bulk_get()` in the `Auth$imports` path retrieves details about a bulk import job. - - `bulk_submit_export()` in the `Auth$exports` path enables you to export multiple project files into a volume using a single API call. - - `bulk_get()` in the `Auth$exports` path fetches details about a bulk export job. - - `bulk_get()` in the `Auth$files` path retrieves details of multiple specified files, including file names and metadata. - - `bulk_update()` in the `Auth$files` path updates the details for multiple specified files, replacing existing information and clearing omitted parameters. - - `bulk_edit()` in the `Auth$files` path modifies existing information or adds new information for multiple specified files, while preserving omitted parameters. - - `bulk_delete()` in the `Auth$files` path deletes multiple specified files in a single API call. - - `bulk_get()` in the `Auth$tasks` path retrieves details of multiple tasks in a single API call. -* Additionally, the package includes two utility functions: `prepare_items_for_bulk_import()` and `prepare_items_for_bulk_export()`. These functions are designed to facilitate the creation of item lists for bulk import and export operations. +* The package now includes support for another category of API calls: bulk +actions. +* Bulk actions allow users to perform actions on multiple items with a single +call. The following bulk API methods have been added: + - `bulk_submit_import()` in the `Auth$imports` path allows you to import + multiple volume files or folders into a project using a single API call. + - `bulk_get()` in the `Auth$imports` path retrieves details about a bulk + import job. + - `bulk_submit_export()` in the `Auth$exports` path enables you to export + multiple project files into a volume using a single API call. + - `bulk_get()` in the `Auth$exports` path fetches details about a bulk export + job. + - `bulk_get()` in the `Auth$files` path retrieves details of multiple + specified files, including file names and metadata. + - `bulk_update()` in the `Auth$files` path updates the details for multiple + specified files, replacing existing information and clearing omitted + parameters. + - `bulk_edit()` in the `Auth$files` path modifies existing information or + adds new information for multiple specified files, while preserving omitted + parameters. + - `bulk_delete()` in the `Auth$files` path deletes multiple specified files + in a single API call. + - `bulk_get()` in the `Auth$tasks` path retrieves details of multiple tasks + in a single API call. +* Additionally, the package includes two utility functions: +`prepare_items_for_bulk_import()` and `prepare_items_for_bulk_export()`. These +functions are designed to facilitate the creation of item lists for bulk import +and export operations. ## Enhancements and fixes -* Fix error handling checkers in the core `api()` function to ensure compatibility with newer versions of R. The `setequal()` function has been replaced with the custom `list_eq()` function. -* Fix logic for setting API request header when using Seven Bridges single sign-on token for authentication. -* Set the default value of the `fields` parameter in the core `api()` function to "_all", ensuring that all available fields are included in the API response for each resource. +* Fix error handling checkers in the core `api()` function to ensure +compatibility with newer versions of R. The `setequal()` function has been +replaced with the custom `list_eq()` function. +* Fix logic for setting API request header when using Seven Bridges single +sign-on token for authentication. +* Set the default value of the `fields` parameter in the core `api()` function +to "_all", ensuring that all available fields are included in the API response +for each resource. + +--- + +# sevenbridges2 0.3.0 + +## New features + +* Introduced support for **asynchronous bulk actions**, enabling asynchronous +operations on multiple items without blocking execution. +* The following **async bulk API methods** have been added: + - `async_bulk_copy()` in the `Auth$files` path: Copies multiple files and + folders while preserving the folder structure. Supports: + - Copying to a subfolder within the same project. + - Copying to another project. + - Copying to a subfolder in a different project. + - `async_bulk_delete()` in the `Auth$files` path: Deletes multiple files or + folders asynchronously. Empty and non-empty folders can be deleted. + - `async_bulk_move()` in the `Auth$files` path: Moves multiple files and + folders. Supports: + - Moving to the root folder of a project. + - Moving to a subfolder within the same project or a different project. + - `async_get_copy_job()` in the `Auth$files` path: Retrieves details of an + asynchronous bulk copy job. + - `async_get_delete_job()` in the `Auth$files` path: Retrieves details of an + asynchronous bulk deletion job. + - `async_get_move_job()` in the `Auth$files` path: Retrieves details of an + asynchronous bulk move job. + - `async_list_file_jobs()`in the `Auth$files` path: Lists all active and + completed asynchronous bulk jobs initiated by the user. + +## Enhancements and fixes + +* Updated the **quickstart.Rmd vignette**: + - Replaced the example app illustrating the `Auth$apps$copy()` method, as the + previous example was outdated. + - Updated example input files for improved clarity and consistency. + - Fixed typos and improved wording for better readability. + +--- + +# sevenbridges2 0.4.0 + +## New features + +* Introduced support for **Enterprise API actions**, enabling users to manage +organizational structures such as divisions and teams on the Seven Bridges +Platform. + +* The following Enterprise API classes and methods have been added: + - **Division-related methods**: + - `query()` and `get()` in the `Auth$divisions` path allow listing all + divisions and retrieving a division by ID. + - Fetched Division objects support additional methods: + - `list_teams()` lists all teams within a division. + - `list_members()` retrieves division members, with optional filtering by + role. + - `remove_member()` removes a member from the division. + + - **Team-related methods**: + - `query()`, `get()`, `create()`, and `delete()` in the `Auth$teams` path + allow managing teams within divisions. + - Fetched Team objects support the following actions: + - `list_members()`, `add_member()`, and `remove_member()` for managing + team membership. + - `rename()` and `delete()` for modifying or removing a team. + + - **Added support for managing volume access using Enterprise members:** + - New methods in the Volume class: + - `add_member_team()` and `add_member_division()` allow adding entire + teams or divisions as volume members (for users with appropriate + `ADMIN` privileges). + - Introduced an internal method `add_member_general()`, which handles + the underlying logic for adding volume members. All three public methods + — `add_member()`, `add_member_team()`, and `add_member_division()` — now + use `add_member_general()` internally to ensure consistency and reduce + duplication. + +* Added a new vignette `Enterprise_actions.Rmd` covering the full set of +Enterprise API actions. + +* Updated the `Files_upload_and_Volumes.Rmd` vignette to document volume +sharing with teams and divisions. + +## Enhancements and fixes + +Fixed typos and refined wording across documentation and code comments for +improved readability and maintainability. + diff --git a/R/api-utils.R b/R/api-utils.R index 590b19d..4fe7bb8 100644 --- a/R/api-utils.R +++ b/R/api-utils.R @@ -712,7 +712,7 @@ find_type <- function(type) { #' #' @noRd is_required <- function(x) { - !((checkmate::test_list(x$type) && x$type[[1]] == "null") || (checkmate::test_string(x$type) && grepl(pattern = "?", x = x$type, fixed = TRUE))) # nolint + !((checkmate::test_list(x$type) && checkmate::test_list(x$type[[1]]) && x$type[[1]]$type == "array") || (checkmate::test_list(x$type) && x$type[[1]] == "null") || (checkmate::test_string(x$type) && grepl(pattern = "?", x = x$type, fixed = TRUE))) # nolint } #' @description Compare two lists. diff --git a/R/class-AsyncJob.R b/R/class-AsyncJob.R new file mode 100644 index 0000000..a4aaa9e --- /dev/null +++ b/R/class-AsyncJob.R @@ -0,0 +1,145 @@ +# nolint start +#' @title R6 Class representing an AsyncJob +#' +#' @description +#' R6 Class representing a resource for managing asynchronous jobs. +#' +#' @importFrom R6 R6Class +#' @export +AsyncJob <- R6::R6Class( + # nolint end + "AsyncJob", + inherit = Item, + portable = FALSE, + public = list( + #' @field id Asynchronous job ID. + id = NULL, + #' @field type The type of job. Can be one of: COPY, DELETE, MOVE. + type = NULL, + #' @field state The following states are available: SUBMITTED, RESOLVING, + #' RUNNING and FINISHED. + state = NULL, + #' @field result The result of the job. + result = NULL, + #' @field total_files The total number of files that were processed for + #' the job. + total_files = NULL, + #' @field completed_files The number of files that were successfully + #' completed. + completed_files = NULL, + #' @field failed_files The number of files that failed. + failed_files = NULL, + #' @field started_on The time and date the job started. + started_on = NULL, + #' @field finished_on The time and date the job finished. + finished_on = NULL, + + # Initialize AsyncJob object ---------------------------------------------- + #' @description Create a new AsyncJob object. + #' + #' @param res Response containing AsyncJob object information. + #' + #' @param ... Other response arguments. + #' + #' @return A new `AsyncJob` object. + initialize = function(res = NA, ...) { + # Initialize Item class + super$initialize(...) + + self$id <- res$id + self$type <- res$type + self$state <- res$state + self$result <- res$result + self$total_files <- res$total_files + self$completed_files <- res$completed_files + self$failed_files <- res$failed_files + self$started_on <- res$started_on + self$finished_on <- res$finished_on + }, + + # nocov start + # Print AsyncJob object --------------------------------------------------- + #' @description Print method for AsyncJob class. + #' + #' @importFrom purrr discard + #' @importFrom glue glue_col + #' @importFrom cli cli_h1 cli_li cli_end + #' + #' @examples + #' \dontrun{ + #' # x is API response when app is requested + #' asyncjob_object <- AsyncJob$new( + #' res = x, + #' href = x$href, + #' auth = auth, + #' response = attr(x, "response") + #' ) + #' asyncjob_object$print() + #' } + print = function() { + x <- as.list(self) + + # Extract all except 'raw' + x$raw <- NULL + + x <- purrr::discard(x, .p = is.function) + x <- purrr::discard(x, .p = is.environment) + x <- purrr::discard(x, .p = is.null) + x <- purrr::discard(x, .p = is.list) + + # Remove copy_of field if it's empty (NA) + x <- purrr::discard(x, .p = is.na) + + string <- glue::glue_col("{green {names(x)}}: {x}") + + cli::cli_h1("Asynchronous Job") + + cli::cli_li(string) + + # Close container elements + cli::cli_end() + }, + + # Reload AsyncJob object -------------------------------------------------- + #' @description Reloads AsyncJob object information. + #' + #' @param ... Other arguments that can be passed to core `api()` function + #' like 'fields', etc. + #' + #' @examples + #' \dontrun{ + #' # x is API response when AsyncJob is requested + #' asyncjob_object <- AsyncJob$new( + #' res = x, + #' href = x$href, + #' auth = auth, + #' response = attr(x, "response") + #' ) + #' asyncjob_object$reload() + #' } + #' @return \code{\link{AsyncJob}} object. + reload = function(...) { + super$reload( + cls = self, + ... + ) + rlang::inform("AsyncJob object is refreshed!") + } + ) +) + +# Helper functions for creating AsyncJob objects ------------------------------ +asAsyncJob <- function(x = NULL, auth = NULL) { + AsyncJob$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) +} + +asAsyncJobList <- function(x, auth) { + obj <- lapply(x$items, asAsyncJob, auth = auth) + obj +} +# nocov end diff --git a/R/class-VolumeFile.R b/R/class-VolumeFile.R index 2613d82..5ffba99 100644 --- a/R/class-VolumeFile.R +++ b/R/class-VolumeFile.R @@ -24,7 +24,7 @@ VolumeFile <- R6::R6Class( type = NULL, #' @field volume Volume id. volume = NULL, - #' @field metadata File's metadata if exists. + #' @field metadata File metadata, if it exists. metadata = NULL, # Initialize VolumeFile object ------------------------------------------- @@ -110,7 +110,7 @@ VolumeFile <- R6::R6Class( #' volume_file_object$reload() #' } #' - #' @return \code{\link{VolumeFile}} object. + #' @return A \code{\link{VolumeFile}} object. reload = function(...) { reload_url <- "" if (!is_missing(self$href)) { @@ -141,8 +141,8 @@ VolumeFile <- R6::R6Class( }, # nocov end # Start new file import job ----------------------------------------------- - #' @description This call lets you queue a job to import this file or folder - #' from a volume into a project on the Platform. \cr + #' @description This call lets you queue a job to import this file or + #' folder from a volume into a project on the Platform. \cr #' Essentially, you are importing an item from your cloud storage provider #' (Amazon Web Services, Google Cloud Storage, Azure or Ali Cloud) via the #' volume onto the Platform. \cr diff --git a/R/class-VolumePrefix.R b/R/class-VolumePrefix.R index f101a20..7a9eb38 100644 --- a/R/class-VolumePrefix.R +++ b/R/class-VolumePrefix.R @@ -25,7 +25,7 @@ VolumePrefix <- R6::R6Class( # Initialize VolumePrefix object ------------------------------------------ #' @description Create a new VolumePrefix object. #' - #' @param res Response containing VolumePrefix object info. + #' @param res Response containing VolumePrefix object information. #' @param ... Other response arguments. initialize = function(res = NA, ...) { # Initialize Item class @@ -56,7 +56,7 @@ VolumePrefix <- R6::R6Class( #' response = attr(x, "response") #' ) #' - #' # Print volume prefix object + #' # Print the Volume Prefix object #' volume_prefix_object$print() #' } #' @@ -87,7 +87,7 @@ VolumePrefix <- R6::R6Class( }, # Reload VolumePrefix object --------------------------------------------- - #' @description Reload VolumePrefix object information. + #' @description Reload the VolumePrefix object information. #' #' @examples #' \dontrun{ @@ -110,7 +110,7 @@ VolumePrefix <- R6::R6Class( }, # nocov end # List volume folder content --------------------------------------------- - #' @description List volume folder contents. + #' @description List the contents of a volume folder. #' This call lists the contents of a specific volume folder. #' #' @param limit The maximum number of collection items to return @@ -167,8 +167,8 @@ VolumePrefix <- R6::R6Class( }, # nocov end # Start new import job --------------------------------------------------- - #' @description This call lets you queue a job to import this file or folder - #' from a volume into a project on the Platform. \cr + #' @description This call lets you queue a job to import this file or + #' folder from a volume into a project on the Platform. \cr #' Essentially, you are importing an item from your cloud storage provider #' (Amazon Web Services, Google Cloud Storage, Azure or Ali Cloud) via the #' volume onto the Platform. \cr @@ -192,8 +192,9 @@ VolumePrefix <- R6::R6Class( #' #' Segments are considered to be separated with forward slashes /. #' Allowed characters in file names are all alphanumeric and special - #' characters except forward slash /, while folder names can contain - #' alphanumeric and special characters _, - and .. + #' characters except forward slash (/), while folder names can contain + #' alphanumeric and special characters underscores (_), hyphens (-), and + #' dots (.). #' #' @param overwrite Set to `TRUE` if you want to overwrite the item if #' another one with the same name already exists at the destination. diff --git a/R/class-app.R b/R/class-app.R index b37c393..d9ef849 100644 --- a/R/class-app.R +++ b/R/class-app.R @@ -144,8 +144,7 @@ App <- R6::R6Class( #' `/` format, e.g. \cr #' `rfranklin/my-project`, or as `/` #' depending on the account \cr type. - #' @param name The new name the app will have in the target project. - #' Optional. + #' @param name The new name for the app in the target project (optional). #' @param strategy The method for copying the app. Supported strategies: #' \itemize{ #' \item `clone` - copy all revisions; get updates from the same app as @@ -157,8 +156,8 @@ App <- R6::R6Class( #' app as the copied app. #' } #' @param use_revision Parameter specifying which app's revision should be - #' copied. If set to `FALSE` (default), the latest revision of the app will - #' be copied. + #' copied. If set to `FALSE` (default), the latest revision of the app + #' will be copied. #' @param ... Other arguments that can be passed to core `api()` function #' like 'fields', etc. #' @@ -314,10 +313,10 @@ App <- R6::R6Class( #' [here](https://docs.sevenbridges.com/reference/add-an-app-using-raw-cwl). #' @param raw A list containing a raw CWL for the app revision you are #' about to create. To generate such a list, you might want to load some - #' existing JSON / YAML file. In case that your CWL file is in JSON format, - #' please use the `fromJSON` function from the `jsonlite` package to - #' minimize potential problems with parsing the JSON file. If you want to - #' load a CWL file in YAML format, it is highly recommended to use the + #' existing JSON / YAML file. In case that your CWL file is in JSON + #' format, please use the `fromJSON` function from the `jsonlite` package + #' to minimize potential problems with parsing the JSON file. If you want + #' to load a CWL file in YAML format, it is highly recommended to use the #' `read_yaml` function from the `yaml` package. Keep in mind that this #' parameter should not be used together with the `file_path` parameter. #' @param from_path A path to a file containing the raw CWL for the app @@ -479,9 +478,8 @@ App <- R6::R6Class( }, # Get inputs info --------------------------------------------------------- - #' @description Get inputs matrix for the app - what are expected inputs - #' required or not, with their details about the expected types, - #' descriptions etc. + #' @description Get an input matrix for the app, listing expected inputs + #' (required or optional) along with their types, descriptions, etc. #' #' @return Data frame. input_matrix = function() { @@ -492,9 +490,8 @@ App <- R6::R6Class( }, # Get outputs info -------------------------------------------------------- - #' @description Get outputs matrix for the app - what are the expected - #' outputs of the task running this app, with their details about the - #' expected types, descriptions etc. + #' @description Get an output matrix for the app, listing expected outputs + #' of tasks that run this app, along with their types, descriptions, etc. #' #' @return Data frame. output_matrix = function() { @@ -505,11 +502,11 @@ App <- R6::R6Class( }, # Create task ------------------------------------------------------------ - #' @description This call creates a new task. You can create either a single - #' task or a batch task by using the app's default batching, override - #' batching, or disable batching completely. A parent task is a task that - #' specifies criteria by which to batch its inputs into a series of further - #' sub-tasks, called child tasks. The documentation on + #' @description This call creates a new task. You can create either a + #' single task or a batch task by using the app's default batching, + #' override batching, or disable batching completely. A parent task is a + #' task that specifies criteria by which to batch its inputs into a series + #' of further sub-tasks, called child tasks. The documentation on # nolint start #' [batching tasks](https://docs.sevenbridges.com/docs/about-batch-analyses) # nolint end @@ -579,8 +576,8 @@ App <- R6::R6Class( #' See below for more details. #' \itemize{ #' \item `main_location` - Defines the output location for all - #' output nodes in the task. Can be a string path within the project in - #' which the task is created, for example \cr + #' output nodes in the task. Can be a string path within the project + #' in which the task is created, for example \cr #' `/Analysis/_/` #' or a path on an attached volume, \cr such as #' `volumes://volume_name//html`. @@ -588,10 +585,10 @@ App <- R6::R6Class( #' dynamically replaced with corresponding values during task #' execution. #' \item `main_location_alias`: The string location (path) in the - #' project that will point to the actual location where the outputs are - #' stored. Used if main_location is defined as a volume path (starting - #' with volumes://), to provide an easy way of accessing output data - #' directly from project files. + #' project that will point to the actual location where the outputs + #' are stored. Used if main_location is defined as a volume path + #' (starting with volumes://), to provide an easy way of accessing + #' output data directly from project files. #' \item `nodes_override`: Enables defining of output locations #' for output nodes individually through nodes_location (see below). #' Set to `TRUE` to be able to define individual locations per output @@ -615,9 +612,9 @@ App <- R6::R6Class( #' "output_location_alias" = "/rfranklin/tasks/picard" #' ) #' ``` - #' In the example above, b64html is the ID of the output node for which - #' you want to define the output location, while the parameters are - #' defined as follows: + #' In the example above, b64html is the ID of the output node for + #' which you want to define the output location, while the parameters + #' are defined as follows: #' \itemize{ #' \item `output_location` - Can be a path within the project in which #' the task is created, for example \cr @@ -677,7 +674,7 @@ App <- R6::R6Class( description = NULL, execution_settings = NULL, inputs = NULL, - output_location = output_location, + output_location = NULL, batch = NULL, batch_input = NULL, batch_by = NULL, diff --git a/R/class-apps.R b/R/class-apps.R index 0616b75..4e3f708 100644 --- a/R/class-apps.R +++ b/R/class-apps.R @@ -1,8 +1,8 @@ # nolint start -#' @title R6 Class representing apps endpoint +#' @title R6 Class representing the apps endpoint #' #' @description -#' R6 Class representing apps resource endpoint. +#' R6 Class representing the apps resource endpoint. #' #' @importFrom R6 R6Class #' @@ -25,7 +25,7 @@ Apps <- R6::R6Class( ), # Initialize Apps object -------------------------------------------------- - #' @description Create new Apps resource object. + #' @description Create a new Apps resource object. #' #' @param ... Other response arguments. initialize = function(...) { @@ -42,11 +42,17 @@ Apps <- R6::R6Class( #' to restrict the results to apps from that project only. #' @param visibility Set this to `public` to see all public apps on #' the Seven Bridges Platform. - #' @param query_terms Enter one or more search terms to query apps. - #' Read more about how to use the query_terms parameter in our - # nolint start - #' [API documentation](https://docs.sevenbridges.com/reference/list-all-apps-available-to-you#query-apps). - # nolint end + #' @param query_terms A list of search terms used to filter apps based on + #' their details. Each term is case-insensitive and can relate to the + #' app's name, label, toolkit, toolkit version, category, tagline, or + #' description. + #' You can provide a single term (e.g., `list("Compressor")`) or multiple + #' terms (e.g., `list("Expression", "Abundance")`) to search for apps + #' that match all the specified terms. If a term matches any part of the + #' app's details, the app will be included in the results. + #' Search terms can also include phrases + #' (e.g., `list("Abundance estimates input")`), which will search for + #' exact matches within app descriptions or other fields. #' @param id Use this parameter to query apps based on their ID. #' @param limit The maximum number of collection items to return #' for a single request. Minimum value is `1`. @@ -56,13 +62,13 @@ Apps <- R6::R6Class( #' of the first item to return. The default value is `0`. #' This is a pagination-specific attribute. #' @param fields Selector specifying a subset of fields to include in the - #' response. For querying apps it is set to return all fields except 'raw' - #' which stores CWL in form of a list. Please be careful when setting to - #' return all fields, since the execution of this API request could be - #' time-consuming. + #' response. For querying apps, it is set to return all fields except + #' 'raw' which stores CWL as a list. Be cautious when requesting all + #' fields, as this API request may take a long time to execute. #' @param ... Other arguments that can be passed to core `api()` function. #' - #' @importFrom checkmate assert_list + #' @importFrom checkmate assert_list assert_string + #' @importFrom utils URLencode #' #' @examples #' \dontrun{ @@ -97,10 +103,16 @@ Apps <- R6::R6Class( checkmate::assert_string(id, null.ok = TRUE) - # Collapse query terms to a string with space between values + # Collapse query terms to a URL-encoded string with space between values if (!is.null(query_terms)) { - query_terms <- paste(query_terms, collapse = " ") + query_terms <- paste( + lapply(query_terms, utils::URLencode, + reserved = TRUE + ), + collapse = "%20" + ) } + # nocov start res <- super$query( path = self$URL[["query"]], @@ -121,11 +133,10 @@ Apps <- R6::R6Class( # Get app ---------------------------------------------------------------- #' @description This call returns information about the specified app. - #' The app should be one in a project that you can access; - #' this could be an app that has been uploaded to the Seven Bridges - #' Platform by a project member, or a publicly available app that has - #' been copied to the project. \cr - #' More about this operation you can find in our + #' The app must be in a project you can access. It could be an app + #' uploaded to the Seven Bridges Platform by a project member or a public + #' app copied into the project. \cr + #' You can find more details about this operation in our # nolint start #' [API documentation](https://docs.sevenbridges.com/reference/get-details-of-an-app). # nolint end @@ -170,10 +181,10 @@ Apps <- R6::R6Class( }, # Copy app ---------------------------------------------------------------- - #' @description This call copies the specified app to the specified project. - #' The app should be one in a project that you can access; this could be an - #' app that has been uploaded to the Seven Bridges Platform by a project - #' member, or a publicly available app that has been copied to the project. + #' @description This call copies the specified app to the specified + #' project. The app must be in a project you can access. It could be an + #' app uploaded to the Seven Bridges Platform by a project member or a + #' public app copied into the project. #' #' @param app App object or the short name of the app you are copying. #' Optionally, to copy a specific revision of the app, use the @@ -187,7 +198,8 @@ Apps <- R6::R6Class( #' \itemize{ #' \item `clone` : copy all revisions; get updates from the same app #' as the copied app (default); - #' \item `direct`: copy latest revision; get updates from the copied app; + #' \item `direct`: copy latest revision; get updates from the copied + #' app; #' \item `clone_direct`: copy all revisions; get updates from the #' copied app; #' \item `transient`: copy latest revision; get updates from the same @@ -259,8 +271,9 @@ Apps <- R6::R6Class( #' #' @param raw The body of the request should be a CWL app description saved #' as a `JSON` or `YAML` file. For a template of this description, try - #' making the call to get raw CWL for an app about an app already in one of - #' your projects. Shouldn't be used together with `from_path` parameter. + #' making the call to get raw CWL for an app about an app already in one + #' of your projects. Shouldn't be used together with `from_path` + #' parameter. #' @param from_path File containing CWL app description. Shouldn't be used #' together with raw parameter. #' @param project String project ID or Project object in which you want to diff --git a/R/class-auth.R b/R/class-auth.R index f056af0..15be269 100644 --- a/R/class-auth.R +++ b/R/class-auth.R @@ -1,7 +1,7 @@ # nolint start #' @title R6 Class Representing Authentication Object #' -#' @description Authentication object with methods to access API endpoints. +#' @description Authentication object with methods for accessing API endpoints. #' Every object could be requested from this Auth object and any action #' could start from this object using cascading style. Please check #' `vignette("Authentication_and_Billing", package = "sevenbridges2")` @@ -42,7 +42,8 @@ Auth <- R6::R6Class( #' @field profile_name Profile name in the user configuration file. profile_name = NULL, - #' @field fs FS (FileSystem) object, for mount and unmount file system. + #' @field fs FS (FileSystem) object, for mounting and unmounting the file + #' system. fs = NULL, #' @field authorization Is the `token` an API @@ -65,7 +66,7 @@ Auth <- R6::R6Class( #' platform. volumes = NULL, - #' @field tasks Tasks object, for accessing volumes resources on the + #' @field tasks Tasks object, for accessing tasks resources on the #' platform. tasks = NULL, @@ -81,10 +82,18 @@ Auth <- R6::R6Class( #' platform. invoices = NULL, - #' @field billing_groups Billing_groups object, for accessing billing groups - #' resources on the platform. + #' @field billing_groups Billing_groups object, for accessing billing + #' groups resources on the platform. billing_groups = NULL, + #' @field divisions Divisions object, for accessing divisions resources on + #' the platform. + divisions = NULL, + + #' @field teams Teams object, for accessing teams resources on + #' the platform. + teams = NULL, + # Initialize Auth object ------------------------------------------------- #' @description #' Create a new Seven Bridges API Authentication object. @@ -100,7 +109,7 @@ Auth <- R6::R6Class( #' Default is `"direct"`. #' #' @param platform The platform to use. - #' If `platform` and `url` are both not specified, + #' If neither `platform` nor `url` is specified #' the default is `"aws-us"` (Seven Bridges Platform - US). #' Other possible values include: #' \itemize{ @@ -112,7 +121,7 @@ Auth <- R6::R6Class( #' } #' @param url Base URL for API. Please only use this when you #' want to specify a platform that is not in the `platform` list - #' above, and also leaving `platform` unspecified. + #' above, while leaving `platform` unspecified. #' #' @param token API authentication token or `access_token` for #' Seven Bridges single sign-on. Authentication token uniquely identifies @@ -345,8 +354,14 @@ Auth <- R6::R6Class( # Invoices resource self$invoices <- Invoices$new(self) - # Billng_groups resousrce + # Billing_groups resource self$billing_groups <- Billing_groups$new(self) + + # Divisions resource + self$divisions <- Divisions$new(self) + + # Teams resource + self$teams <- Teams$new(self) }, # Get token -------------------------------------------------------------- @@ -379,8 +394,8 @@ Auth <- R6::R6Class( #' pass arguments to core `api()` function. #' #' @param limit The maximum number of collection items to return for a - #' single request. Minimum value is `1`. The maximum value is `100` and the - #' default value is `50`. + #' single request. Minimum value is `1`. The maximum value is `100` and + #' the default value is `50`. #' This is a pagination-specific attribute. #' @param offset The zero-based starting index in the entire collection of #' the first item to return. The default value is `0`. @@ -468,9 +483,9 @@ Auth <- R6::R6Class( # Get rate limit info ---------------------------------------------------- #' @description Get information about current rate limit. \cr \cr - #' This call returns information about your current rate limit. This is the - #' number of API calls you can make in one hour. This call also returns - #' information about your current instance limit. + #' This call returns information about your current rate limit. This is + #' the number of API calls you can make in one hour. This call also + #' returns information about your current instance limit. #' @examples #' \dontrun{ #' # Authenticate using authentication token @@ -508,8 +523,8 @@ Auth <- R6::R6Class( #' specified Platform folder, within the project to which the folder #' belongs. If project is used, the call will upload the file to the root #' of the project's files. - #' @param filename Optional new file name. By default the uploaded file will - #' have the same name as the original file provided with the `path` + #' @param filename Optional new file name. By default the uploaded file + #' will have the same name as the original file provided with the `path` #' parameter. If its name will not change, omit this key. #' @param overwrite In case there is already a file with the same name in #' the selected platform project or folder, this option allows you to @@ -517,9 +532,9 @@ Auth <- R6::R6Class( #' If overwrite is set to `TRUE` and a file already exists under the name #' specified in the request, the existing file will be deleted and a new #' one created in its place. - #' @param part_size The preferred size for upload parts in bytes. If omitted - #' or set to a value that is incompatible with the cloud storage provider, - #' a default value will be used. + #' @param part_size The preferred size for upload parts in bytes. If + #' omitted or set to a value that is incompatible with the cloud storage + #' provider, a default value will be used. #' @param init If `TRUE`, the method will initialize and return the Upload #' object and stop. If `FALSE`, the method will return the Upload object #' and start the upload process immediately. @@ -700,8 +715,9 @@ Auth <- R6::R6Class( # Send feedback ---------------------------------------------------------- #' @description Send feedback to Seven Bridges. \cr \cr - #' Send feedback on ideas, thoughts, and problems via the sevenbridges2 API - #' package with three available types: `idea`, `thought`, and `problem`. + #' Send feedback on ideas, thoughts, and problems via the sevenbridges2 + #' API package with three available types: `idea`, `thought`, and + #' `problem`. #' You can send one feedback item per minute. #' #' @param text Specifies the content for the feedback i.e. feedback text. diff --git a/R/class-billing.R b/R/class-billing.R index 8256574..a3543c8 100644 --- a/R/class-billing.R +++ b/R/class-billing.R @@ -6,7 +6,7 @@ #' @importFrom R6 R6Class #' #' @details -#' This is main object for Billing +#' This is the main object for Billing # nolint start Billing <- R6::R6Class( # nolint end @@ -27,7 +27,7 @@ Billing <- R6::R6Class( owner = NULL, #' @field name Billing group name. name = NULL, - #' @field type Billing group type + #' @field type Billing group type. type = NULL, #' @field pending Billing group approval status. pending = NULL, @@ -56,7 +56,7 @@ Billing <- R6::R6Class( # nocov start # Print Billing object -------------------------------------------------- - #' @description Print billing group information as a bullet list. + #' @description Prints billing group information as a bullet list. #' #' @importFrom purrr discard #' @importFrom glue glue @@ -134,7 +134,8 @@ Billing <- R6::R6Class( }, # Get analysis breakdown -------------------------------------------------- - #' @description Method for getting a analysis breakdown for a billing group. + #' @description Method for getting an analysis breakdown for a billing + #' group. #' #' @param offset The zero-based starting index in the entire collection #' of the first item to return. The default value is `0`. diff --git a/R/class-billing_groups.R b/R/class-billing_groups.R index 551d2ef..b659e3a 100644 --- a/R/class-billing_groups.R +++ b/R/class-billing_groups.R @@ -70,7 +70,7 @@ Billing_groups <- R6::R6Class( }, # nocov end # Get billing group ------------------------------------------------------- - #' @description Retrieve a single billing group, specified by its id. + #' @description Retrieve a single billing group, specified by its ID. #' To find the `billing_group`, use the call `Billing_groups$query()` #' to list all your billing groups. The information returned #' includes the billing group owner, the total balance, and the status of diff --git a/R/class-collection.R b/R/class-collection.R index e94c90f..203b73e 100644 --- a/R/class-collection.R +++ b/R/class-collection.R @@ -3,7 +3,7 @@ #' #' @description #' R6 Class representing a resource for managing collections. -#' Wrapper for Seven Bridges pageable resources. +#' A wrapper for Seven Bridges pageable resources. #' Among the actual collection items it contains information regarding #' the total number of entries available on the server and #' resource API request URL (href). @@ -101,7 +101,7 @@ Collection <- R6::R6Class( }, # nocov end # Get next page of results ------------------------------------------------ - #' @description Return next page of results. + #' @description Returns the next page of results. #' #' @param ... Other arguments that can be passed to core `api()` function #' like 'advanced_access', 'fields', etc. @@ -149,7 +149,7 @@ Collection <- R6::R6Class( }, # nocov end # Get previous page of results -------------------------------------------- - #' @description Return previous page of results. + #' @description Returns the previous page of results. #' #' @param ... Other arguments that can be passed to core `api()` function #' like 'advanced_access', 'fields', etc. diff --git a/R/class-division.R b/R/class-division.R new file mode 100644 index 0000000..f500082 --- /dev/null +++ b/R/class-division.R @@ -0,0 +1,282 @@ +#' @title R6 Class representing a Division +#' +#' @description +#' R6 Class representing a central resource for managing divisions. +#' +#' @importFrom R6 R6Class +#' +#' @export +Division <- R6::R6Class( + "Division", + inherit = Item, + portable = FALSE, + public = list( + #' @field URL List of URL endpoints for this resource. + URL = list( + "list_teams" = "divisions/{id}/teams", + "list_members" = "users", + "remove_member" = "users/{username}" + ), + #' @field id The ID of the division. + id = NULL, + #' @field name Division's name. + name = NULL, + + # Initialize Division object ---------------------------------------------- + #' @description Create a new Division object. + #' + #' @param res Response containing the Division object information. + #' + #' @param ... Other response arguments. + initialize = function(res = NA, ...) { + # Initialize Item class + super$initialize(...) + + self$id <- res$id + self$name <- res$name + }, + + # nocov start + # Print Division object --------------------------------------------------- + #' @description Print method for Division class. + #' + #' @importFrom purrr discard + #' @importFrom glue glue_col + #' @importFrom cli cli_h1 cli_li cli_end + #' + #' @examples + #' \dontrun{ + #' division_object <- Division$new( + #' res = x, + #' href = x$href, + #' auth = auth, + #' response = attr(x, "response") + #' ) + #' division_object$print() + #' } + print = function() { + x <- as.list(self) + + x <- purrr::discard(x, .p = is.list) + x <- purrr::discard(x, .p = is.function) + x <- purrr::discard(x, .p = is.environment) + x <- purrr::discard(x, .p = is.null) + x <- purrr::discard(x, .p = ~ .x == "") + + string <- glue::glue_col("{green {names(x)}}: {x}") + + cli::cli_h1("Division") + cli::cli_li(string) + + # Close container elements + cli::cli_end() + }, + + # Reload Division object -------------------------------------------------- + #' @description Reload Division object information. + #' + #' @param ... Other arguments that can be passed to core `api()` function + #' like 'fields', etc. + #' + #' @importFrom rlang inform + #' + #' @examples + #' \dontrun{ + #' division_object <- Division$new( + #' res = x, + #' href = x$href, + #' auth = auth, + #' response = attr(x, "response") + #' ) + #' division_object$reload() + #' } + #' + #' @return \code{\link{Division}} object. + reload = function(...) { + super$reload( + cls = self, + ... + ) + rlang::inform("Division object is refreshed!") + }, + # nocov end + + # List all teams in a division -------------------------------------------- + #' @description This call retrieves a list of all teams in a division that + #' you are a member of. Each team's ID and name will be returned. + #' + #' @param list_all Boolean. Set this field to `TRUE` if you want to list + #' all teams within the division (regardless of whether you are a member + #' of a team or not). Default value is `FALSE`. + #' @param ... Other arguments that can be passed to core `api()` function + #' like 'fields', etc. + #' + #' @importFrom checkmate assert_logical + #' @importFrom glue glue + #' + #' @examples + #' \dontrun{ + #' # Get details of a specific division + #' division_obj <- a$divisions$get(id = "division-id") + #' + #' # Retrieve a list of division teams you are a member of + #' division_obj$list_teams() + #' + #' # Retrieve a list of all teams within the division regardless of + #' # whether you are a member of a team or not + #' division_obj$list_teams(list_all = TRUE) + #' } + #' + #' @return A \code{\link{Collection}} of \code{\link{Team}} objects. + list_teams = function(list_all = FALSE, ...) { + checkmate::assert_logical(list_all) + + list_all <- ifelse(isTRUE(list_all), "true", "false") + # nocov start + res <- self$auth$api( + path = glue::glue(self$URL[["list_teams"]]), + method = "GET", + query = list("_all" = list_all), + ... + ) + + res$items <- asTeamList(res, self$auth) + + return(asCollection(res, auth = self$auth)) + }, + # nocov end + + # List division members --------------------------------------------------- + #' @description This call retrieves a list of all members of a division. In + #' addition, you can list members with a specific role, e.g. all + #' administrators within a division. + #' + #' @param role Filter members by role. Supported roles are `ADMIN`, + #' `MEMBER`, and `EXTERNAL_COLLABORATOR`. If `NULL` (default), members of + #' all roles will be retrieved. + #' @param limit The maximum number of collection items to return + #' for a single request. Minimum value is `1`. + #' The maximum value is `100` and the default value is `50`. + #' This is a pagination-specific attribute. + #' @param offset The zero-based starting index in the entire collection + #' of the first item to return. The default value is `0`. + #' This is a pagination-specific attribute. + #' @param ... Other arguments that can be passed to core `api()` function + #' like other query parameters or 'fields', etc. + #' + #' @importFrom checkmate assert_choice + #' @importFrom glue glue + #' + #' @examples + #' \dontrun{ + #' # Get details of a specific division + #' division_obj <- a$divisions$get(id = "division-id") + #' + #' # Retrieve a list of all division members + #' division_obj$list_members() + #' + #' # Or filter members by role. The following roles are supported: + #' # "MEMBER", "ADMIN", and "EXTERNAL_COLLABORATOR" + #' division_obj$list_members(role = "ADMIN") + #' } + #' + #' @return A \code{\link{Collection}} of \code{\link{User}} objects. + list_members = function(role = NULL, + limit = getOption("sevenbridges2")$limit, + offset = getOption("sevenbridges2")$offset, + ...) { + checkmate::assert_choice(role, + c("MEMBER", "ADMIN", "EXTERNAL_COLLABORATOR"), + null.ok = TRUE + ) + # nocov start + res <- self$auth$api( + path = glue::glue(self$URL[["list_members"]]), + method = "GET", + query = list(division = self$id, role = role), + limit = limit, + offset = offset, + ... + ) + + res$items <- asUserList(res, self$auth) + + return(asCollection(res, auth = self$auth)) + }, + # nocov end + + # Remove a member from a division ----------------------------------------- + #' @description Removes a specified user from a division. This action + #' revokes the user's membership in the division but does not delete their + #' Platform account. Note that only users with the `ADMIN` role in the + #' division can perform this action. + #' + #' @param user The Seven Bridges Platform username of the user to be + #' removed, specified in the format `division-name/username`, or an object + #' of class `User` that contains the username. + #' + #' @importFrom rlang abort inform + #' @importFrom glue glue glue_col + #' + #' @examples + #' \dontrun{ + #' # Retrieve details of a specific division + #' division_obj <- a$divisions$get(id = "division-id") + #' + #' # Remove a member using their username + #' division_obj$remove_member(user = "division-name/username") + #' + #' # Remove a member using a User object + #' members <- division_obj$list_members(role = "MEMBER") + #' member_to_remove <- members$items[[1]] + #' division_obj$remove_member(user = member_to_remove) + #' } + remove_member = function(user) { + if (self$auth$user()$role != "ADMIN") { + rlang::abort( + "You don't have the required permissions to remove members from this division. Only users with the 'ADMIN' role can perform this action." # nolint + ) + } + + if (is_missing(user)) { + rlang::abort( + "Please provide a username or a User object to remove the member from the division." # nolint + ) + } + + username <- check_and_transform_id(user, + class_name = "User", + field_name = "username" + ) + # nocov start + res <- self$auth$api( + path = glue::glue(self$URL[["remove_member"]]), + method = "DELETE" + ) + + rlang::inform( + message = glue::glue_col( + "User {green {username}} has been removed + from the {green {self$id}} division.", + .literal = TRUE + ) + ) + } + # nocov end + ) +) + +# Helper functions for creating Division objects ------------------------------ +asDivision <- function(x = NULL, auth = NULL) { + Division$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) +} + +asDivisionList <- function(x, auth) { + obj <- lapply(x$items, asDivision, auth = auth) + obj +} diff --git a/R/class-divisions.R b/R/class-divisions.R new file mode 100644 index 0000000..b06219a --- /dev/null +++ b/R/class-divisions.R @@ -0,0 +1,98 @@ +# nolint start +#' @title R6 Class representing divisions endpoints. +#' +#' @description +#' R6 Class representing Divisions resource. +#' +#' @importFrom R6 R6Class +#' @export +Divisions <- R6::R6Class( + # nolint end + "Divisions", + inherit = Resource, + portable = FALSE, + public = list( + #' @field URL List of URL endpoints for this resource. + URL = list( + "query" = "divisions", + "get" = "divisions/{id}" + ), + + # Initialize Divisions object --------------------------------------------- + #' @description Create new Divisions resource object. + #' + #' @param ... Other response arguments. + initialize = function(...) { + # Initialize Resource class + super$initialize(...) + }, + + # List divisions ---------------------------------------------------------- + #' @description This call retrieves a list of all divisions you are a + #' member of. Each division's ID, name and URL on platform will be + #' returned. + #' + #' @importFrom glue glue + #' + #' @return A \code{\link{Collection}} of \code{\link{Division}} objects. + #' + #' @examples + #' \dontrun{ + #' # Retrieve a list of all divisions you are a member of + #' a$Divisions$query() + #' } + query = function() { + # nocov start + params_list <- list( + path = glue::glue(self$URL[["query"]]) + ) + + res <- do.call( + super$query, + params_list + ) + + res$items <- asDivisionList(res, auth = self$auth) + + return(asCollection(res, auth = self$auth)) + # nocov end + }, + + # Get details of a division ----------------------------------------------- + #' @description This call returns the details of a specified division. + #' + #' @param id The ID of the division you are querying. The function + #' also accepts a Division object and extracts the ID. + #' @param ... Other arguments that can be passed to core `api()` function + #' like 'fields', etc. + #' + #' @return \code{\link{Division}} object. + #' + #' @examples + #' \dontrun{ + #' # Retrieve details of a specified division + #' a$Divisions$get(id = "division-id") + #' } + get = function(id, ...) { + if (is_missing(id)) { + rlang::abort( + "Please provide the 'id' parameter." + ) + } + + id <- check_and_transform_id(id, + class_name = "Division" + ) + + # nocov start + res <- super$get( + cls = self, + id = id, + ... + ) + + return(asDivision(res, auth = self$auth)) + # nocov end + } + ) +) diff --git a/R/class-export.R b/R/class-export.R index b70ef16..4004500 100644 --- a/R/class-export.R +++ b/R/class-export.R @@ -27,15 +27,15 @@ Export <- R6::R6Class( #' \item `FAILED`: the export has failed. #' } state = NULL, - #' @field source List containing source file id that is being exported to - #' the volume. + #' @field source List containing the source file ID that is being exported + #' to the volume. source = NULL, - #' @field destination List containing destination volume id and location - #' (file name) on the volume where the file is being exported. + #' @field destination List containing the destination volume ID and + #' location (file name) on the volume where the file is being exported. destination = NULL, - #' @field overwrite Whether the exported file name was - #' overwritten or not, if another one with the same name had already - #' existed on the volume. + #' @field overwrite Indicates whether the exported file name was + #' overwritten if another file with the same name already existed on the + #' volume. overwrite = NULL, #' @field started_on Time when the export job started. started_on = NULL, @@ -110,7 +110,7 @@ Export <- R6::R6Class( x <- x[elements_subset] x <- purrr::discard(x, .p = is.null) - # Remove it's empty (NA) + # Remove if it's empty (NA) x <- purrr::discard(x, .p = is.na) if (length(x) == 0) { @@ -126,7 +126,7 @@ Export <- R6::R6Class( }, # Reload Export object ---------------------------------------------------- - #' @description Reload Export object information. + #' @description Refresh the Export object with updated information. #' #' @param ... Other arguments that can be passed to core `api()` function #' like 'fields', etc. diff --git a/R/class-exports-utils.R b/R/class-exports-utils.R index 921ae13..be34af9 100644 --- a/R/class-exports-utils.R +++ b/R/class-exports-utils.R @@ -18,15 +18,15 @@ #' However, keep in mind that there are certain constraints: #' \itemize{ #' \item The same `destination_volume` applies to all items in the -#' . resulting list. +#' resulting list. #' \item The same applies to `overwrite` and `properties` #' parameters. #' \item By default, the `destination_location` field is populated with #' the source file name. Upon retrieval of the list of items for bulk -#' export, you can manually update the `destination_location` field -#' for each element of the list as needed. Additionally, you have the -#' flexibility to manually modify any other fields in the list if -#' required. +#' export, you can manually update the \cr +#' `destination_location` field for each element of the list as needed. +#' Additionally, you have the flexibility to manually modify any other +#' fields in the list if required. #' } #' #' @param files A list of \code{\link{File}} objects or list of strings @@ -58,7 +58,7 @@ #' exporting to this bucket. Supported values: #' `AES256` (SSE-S3 encryption), `aws:kms`, `null` #' (no server-side encryption). Default: `AES256`. -#' \item `sse_aws_kms_key_id`: Applies to type: `s3`. +#' \item `sse_aws_kms_key_Id`: Applies to type: `s3`. #' If AWS KMS encryption is used, this should be set to the required #' KMS key. If not set and `aws:kms` is set as `sse_algorithm`, #' default KMS key is used. @@ -81,7 +81,7 @@ # nolint end #' @importFrom purrr map #' -#' @return List of body params items for for staring an export job. +#' @return List of body params items for starting an export job. #' #' @export #' diff --git a/R/class-exports.R b/R/class-exports.R index 271aa36..df74cdb 100644 --- a/R/class-exports.R +++ b/R/class-exports.R @@ -31,7 +31,7 @@ Exports <- R6::R6Class( }, # List export jobs -------------------------------------------------------- - #' @description This call lists export jobs initiated by particular user. + #' @description This call lists export jobs initiated by a particular user. #' Note that when you export a file from a project on the Platform into a #' volume, you write to your cloud storage bucket. #' @@ -133,9 +133,10 @@ Exports <- R6::R6Class( # Start new export job ---------------------------------------------------- #' @description This call lets you queue a job to export a file from a - #' project on the Platform into a volume. The file selected for export must - #' not be a public file or an alias. Aliases are objects stored in your - #' cloud storage bucket which have been made available on the Platform. + #' project on the Platform into a volume. The file selected for export + #' must not be a public file or an alias. Aliases are objects stored in + #' your cloud storage bucket which have been made available on the + #' Platform. #' The volume you are exporting to must be configured for #' read-write access. To do this, set the `access_mode` parameter to #' `RW` when creating or modifying a volume. \cr @@ -172,8 +173,8 @@ Exports <- R6::R6Class( #' prepended to location before attempting to create the file on the #' volume. #' - #' If you would like to export the file into some folder on the volume, - #' please add folder name as prefix before file name in form + #' If you would like to export the file into a folder on the volume, + #' please add the folder name as a prefix before the file name in the form #' `/`. #' @param overwrite Set to `TRUE` if you want to overwrite the item #' if another one with the same name already exists at the destination. @@ -185,7 +186,7 @@ Exports <- R6::R6Class( #' exporting to this bucket. Supported values: #' `AES256` (SSE-S3 encryption), `aws:kms`, `null` #' (no server-side encryption). Default: `AES256`. - #' \item `sse_aws_kms_key_id`: Applies to type: `s3`. + #' \item `sse_aws_kms_key_Id`: Applies to type: `s3`. #' If AWS KMS encryption is used, this should be set to the required #' KMS key. If not set and `aws:kms` is set as `sse_algorithm`, #' default KMS key is used. @@ -280,7 +281,7 @@ Exports <- R6::R6Class( }, # Delete export job ------------------------------------------------------- - #' @description Deleting export jobs is not possible. + #' @description Export jobs cannot be deleted. #' #' @importFrom rlang inform delete = function() { @@ -393,7 +394,7 @@ Exports <- R6::R6Class( #' exporting to this bucket. Supported values: #' `AES256` (SSE-S3 encryption), `aws:kms`, `null` #' (no server-side encryption). Default: `AES256`. - #' \item `sse_aws_kms_key_id`: Applies to type: `s3`. + #' \item `sse_aws_kms_key_Id`: Applies to type: `s3`. #' If AWS KMS encryption is used, this should be set to the #' required KMS key. If not set and `aws:kms` is set as #' `sse_algorithm`, default KMS key is used. @@ -563,7 +564,7 @@ Exports <- R6::R6Class( } if (length(failed_export_tries) == length(res$items)) { - rlang::abort("None of the files can be exported. Please check file export limitations in the API documentation.") # nolint + rlang::abort("None of the files could be exported. Please check file export limitations in the API documentation.") # nolint } res$items <- asExportList(res, auth = self$auth, bulk = TRUE) diff --git a/R/class-file.R b/R/class-file.R index 8526dc0..2536a3f 100644 --- a/R/class-file.R +++ b/R/class-file.R @@ -41,7 +41,7 @@ File <- R6::R6Class( origin = NULL, #' @field tags List of tags associated with the file. tags = NULL, - #' @field metadata List for metadata associated with the file. + #' @field metadata List of metadata associated with the file. metadata = NULL, #' @field url File download URL. url = NULL, @@ -49,7 +49,8 @@ File <- R6::R6Class( parent = NULL, #' @field type This can be of type `file` or `folder`. type = NULL, - #' @field secondary_files Secondary files linked to the file if exist. + #' @field secondary_files Secondary files linked to the file, if they + #' exist. secondary_files = NULL, # Initialize File object ----------------------------------------------- @@ -259,13 +260,13 @@ File <- R6::R6Class( # nocov end # Update file ------------------------------------------------------------ - #' @description Updates the name, the full set metadata, and tags + #' @description Updates the name, the full set of metadata, and tags #' for a specified file. - #' . + #' #' @param name The new name of the file. #' @param metadata The metadata fields and their values that you want to - #' update. This is a named list of key-value pairs. The keys and values are - #' strings. + #' update. This is a named list of key-value pairs. The keys and values + #' are strings. #' @param tags The tags you want to update, represented as unnamed list of #' values to add as tags. #' @param ... Other arguments that can be passed to core `api()` function @@ -455,11 +456,11 @@ File <- R6::R6Class( #' @description This method returns a URL that you can use to download #' the specified file. #' - #' @importFrom glue glue - #' #' @param ... Other arguments that can be passed to core `api()` function #' like 'fields', etc. #' + #' @importFrom glue glue + #' #' @examples #' \dontrun{ #' # x is API response when file is requested @@ -533,8 +534,8 @@ File <- R6::R6Class( #' [API documentation](https://docs.sevenbridges.com/reference/modify-a-files-metadata). # nolint end #' - #' @param metadata_fields Enter a list of key-value pairs of metadata fields - #' and metadata values. + #' @param metadata_fields Enter a list of key-value pairs of metadata + #' fields and metadata values. #' @param overwrite Set to `TRUE` if you want to overwrite existing tags. #' Default: `FALSE`. #' @param ... Other arguments that can be passed to core `api()` function @@ -699,7 +700,6 @@ File <- R6::R6Class( #' @importFrom glue glue #' @importFrom cli cli_h1 cli_li cli_ul cli_end cli_bullets #' @importFrom rlang inform abort - #' @importFrom glue glue #' #' @examples #' \dontrun{ @@ -726,7 +726,7 @@ File <- R6::R6Class( # nocov end # Download file from platform --------------------------------------------- - #' @description Download method for File objects. It allows download a + #' @description Download method for File objects. It allows downloading a #' platform file to your local computer. To specify the destination for #' your download, you should provide the path to the destination directory #' as `directory_path` parameter. @@ -832,9 +832,10 @@ File <- R6::R6Class( # Export file into a volume --------------------------------------------- #' @description This call lets you queue a job to export this file from a - #' project on the Platform into a volume. The file selected for export must - #' not be a public file or an alias. Aliases are objects stored in your - #' cloud storage bucket which have been made available on the Platform. + #' project on the Platform into a volume. The file selected for export + #' must not be a public file or an alias. Aliases are objects stored in + #' your cloud storage bucket which have been made available on the + #' Platform. #' The volume you are exporting to must be configured for read-write #' access. To do this, set the `access_mode` parameter to `RW` when #' creating or modifying a volume. \cr @@ -870,7 +871,7 @@ File <- R6::R6Class( #' If you would like to export the file into some folder on the volume, #' please add folder name as prefix before file name in form #' `/`. - #' @param overwrite Set to `TRUE` of you want to overwrite the item that + #' @param overwrite Set to `TRUE` if you want to overwrite the item that #' already exists at the destination. Default: `FALSE`. #' @param copy_only If `TRUE`, file will be copied to a volume but #' source file will remain on the Platform. @@ -880,7 +881,7 @@ File <- R6::R6Class( #' exporting to this bucket. Supported values: #' `AES256` (SSE-S3 encryption), `aws:kms`, `null` #' (no server-side encryption). Default: `AES256`. - #' \item `sse_aws_kms_key_id`: Applies to type: `s3`. + #' \item `sse_aws_kms_key_Id`: Applies to type: `s3`. #' If AWS KMS encryption is used, this should be set to the required #' KMS key. If not set and `aws:kms` is set as `sse_algorithm`, #' default KMS key is used. diff --git a/R/class-files.R b/R/class-files.R index cff86d9..78da13d 100644 --- a/R/class-files.R +++ b/R/class-files.R @@ -21,7 +21,14 @@ Files <- R6::R6Class( "bulk_get" = "bulk/files/get", "bulk_update" = "bulk/files/update", "bulk_edit" = "bulk/files/edit", - "bulk_delete" = "bulk/files/delete" + "bulk_delete" = "bulk/files/delete", + "async_bulk_copy" = "async/files/copy", + "async_bulk_delete" = "async/files/delete", + "async_bulk_move" = "async/files/move", + "async_get_copy_job" = "async/files/copy/{job_id}", + "async_get_delete_job" = "async/files/delete/{job_id}", + "async_get_move_job" = "async/files/move/{job_id}", + "async_list_file_jobs" = "async/files" ), # Initialize Files object ----------------------------------------------- @@ -45,7 +52,7 @@ Files <- R6::R6Class( #' of the subdirectories. \cr #' To list the contents of a subdirectory, make a new call #' and specify the subdirectory ID as the `parent` parameter. \cr - #' More information you can find in our + #' For more details, see our # nolint start #' [API documentation](https://docs.sevenbridges.com/reference/list-files-primary-method). # nolint end @@ -71,9 +78,11 @@ Files <- R6::R6Class( #' metadata fields are represented as a named list. You can also define #' multiple instances of the same metadata field. #' @param origin Task object. List only files produced by task. - #' @param tag List files containing this tag. Note that the tag must be an - #' exact complete string for the results to match. Multiple tags can be - #' represented by vector of values. + #' @param tag Filters the files based on the specified tag(s). Each tag + #' must be an exact, complete match, for the results to match. Tags may + #' include spaces. Multiple tags should be provided as a vector of + #' strings. The method will return files that have any of the specified + #' tags. #' @param limit The maximum number of collection items to return #' for a single request. Minimum value is `1`. #' The maximum value is `100` and the default value is `50`. @@ -84,7 +93,7 @@ Files <- R6::R6Class( #' @param ... Other arguments that can be passed to core `api()` function #' as 'fields', etc. #' - #' @importFrom checkmate assert_string assert_character + #' @importFrom checkmate assert_character #' @importFrom rlang abort #' #' @examples @@ -125,7 +134,7 @@ Files <- R6::R6Class( origin_task_id <- NULL } if (!is_missing(tag)) { - checkmate::assert_character(tag, null.ok = TRUE) + check_tags(tag) # Transform into a list with name 'tag' tag_list <- list("tag" = lapply(tag, c)) tag <- transform_multiple_vals(tag_list) @@ -236,7 +245,7 @@ Files <- R6::R6Class( #' you to copy files between projects. Unlike the call to copy a file #' between projects, this call lets you batch the copy operation and copy #' a list of files at a time. \cr - #' More information you may find + #' More information can be found here # nolint start #' [here](https://docs.sevenbridges.com/reference/copy-files-between-projects). # nolint end @@ -374,8 +383,7 @@ Files <- R6::R6Class( # nocov end }, - # Bulk deletion of files - #' + # Bulk deletion of files -------------------------------------------------- #' @description This method facilitates bulk file deletion. It accepts #' either a list of \code{\link{File}} objects or a list containing #' files' IDs. @@ -429,8 +437,7 @@ Files <- R6::R6Class( # nocov end }, - # Get details of multiple files - #' + # Get details of multiple files ------------------------------------------- #' @description This call returns the details of multiple specified files, #' including file names and file metadata. The maximum number of files you #' can retrieve the details for per call is 100. @@ -481,8 +488,7 @@ Files <- R6::R6Class( # nocov end }, - # Update details of multiple files - #' + # Update details of multiple files ---------------------------------------- #' @description A method that sets new information for specified files, #' replacing all existing information and erasing omitted parameters. #' @@ -554,8 +560,7 @@ Files <- R6::R6Class( # nocov end }, - # Edit details of multiple files - #' + # Edit details of multiple files ------------------------------------------ #' @description This method modifies the existing information for specified #' files or adds new information while preserving omitted parameters. #' @@ -623,6 +628,588 @@ Files <- R6::R6Class( res$items <- asFileList(res, auth = self$auth, bulk = TRUE) + return(asCollection(res, auth = self$auth)) + # nocov end + }, + + # Asynchronous (bulk) action for copying multiple files -------------------- + #' @description This call lets you perform a bulk copy of files and + #' folders. Any underlying folder structure will be preserved. + #' You can copy: + #' \itemize{ + #' \item to a folder within the same project, + #' \item to another project, + #' \item to a folder in another project. + #' } + #' + #' @param items Nested list of elements containing information about each + #' file/folder to be copied. For each element, you must provide: + #' + # nolint start + #' \itemize{ + #' \item `file` - The ID of the file or folder you are copying. + #' Copying the project root folder is not allowed. + #' Use the API call for listing all files to obtain the ID. + #' \item `parent` - The ID of the folder you are copying files to. + #' It should not be used together with `project`. If `project` is + #' used, the items will be imported to the root of the project + #' files. If `parent` is used, the import will take place into the + #' specified folder, within the project to which the folder belongs. + #' \item `project` - The project you are copying the file to. + #' It should not be used together with `parent`. If `parent` is + #' used, the import will take place into the specified folder, + #' within the project to which the folder belongs. If `project` is + #' used, the items will be imported to the root of the project + #' files. + #' \item `name` - Enter the new name for the file if you want to + #' rename it in the destination folder. + #' } + # nolint end + #' Example of the list: + #' ```{r} + #' items <- list( + #' list( + #' file = '', + #' parent = '' + #' ), + #' list( + #' file = '', + #' project = '', + #' name = 'copied_file.txt' + #' ), + #' list( + #' file = '', + #' parent = '', + #' name = 'copied_file2.txt' + #' ) + #' ) + #' ``` + # nolint start + #' Read more on how to [perform async copy action on multiple files](https://docs.sevenbridges.com/reference/copy-multiple-files). + # nolint end + #' + #' + #' @importFrom rlang abort inform + #' @importFrom checkmate assert_list test_r6 + #' @importFrom glue glue + #' + #' @return \code{\link{AsyncJob}} object. + #' + #' @examples + #' \dontrun{ + #' # Copy multiple files + #' a$files$async_bulk_copy( + #' items = list( + #' list( + #' file = '', + #' parent = '' + #' ), + #' list( + #' file = '', + #' project = '', + #' name = 'copied_file.txt' + #' ), + #' list( + #' file = '', + #' parent = '', + #' name = 'copied_file2.txt' + #' ) + #' ) + #' ) + #' } + #' + async_bulk_copy = function(items) { + if (is_missing(items)) { + rlang::abort("The items parameter should be a nested list containing information about the files and folders to be copied.") # nolint + } + checkmate::assert_list(items) + + body_elements <- list() + + for (i in seq_along(items)) { + item <- items[[i]] + checkmate::assert_list(item) + body_element <- list() + + if (is_missing(item[["file"]])) { + rlang::abort( + glue::glue("The file ID must be provided as a string or a File object in the element {i}."), # nolint + ) + } else { + body_element$file <- check_and_transform_id(item[["file"]], + class_name = "File" + ) + } + + if (is_missing(item[["project"]]) && + is_missing(item[["parent"]])) { + rlang::abort( + glue::glue("Please provide either the destination project or the parent parameter in the element {i}.") # nolint + ) + } + if (!is_missing(item[["project"]]) && + !is_missing(item[["parent"]])) { + rlang::abort( + glue::glue("Either the destination project or the parent parameter must be provided in the element {i}, but not both.") # nolint + ) + } + if (!is_missing(item[["project"]])) { + body_element$project <- check_and_transform_id( + item[["project"]], + class_name = "Project" + ) + } + if (!is_missing(item[["parent"]])) { + if (checkmate::test_r6( + item[["parent"]], + classes = "File" + ) && + tolower(item[["parent"]]$type) != "folder") { + rlang::abort( + glue::glue("The destination parent directory parameter must contain either a folder ID or a File object with type = 'folder' in the element {i}.") # nolint + ) + } + body_element$parent <- check_and_transform_id( + x = item[["parent"]], + class_name = "File" + ) + } + if (!is_missing(item[["name"]])) { + checkmate::assert_string(item[["name"]], null.ok = TRUE) + body_element$name <- item[["name"]] + } + body_elements <- append(body_elements, list(body_element)) + } + + # Build body + # nocov start + body <- list( + items = body_elements + ) + + path <- glue::glue(self$URL[["async_bulk_copy"]]) + + res <- self$auth$api( + path = path, + method = "POST", + body = body + ) + + rlang::inform(glue::glue("New asynchronous job for copying files has started.")) # nolint + + return(asAsyncJob(res, auth = self$auth)) + # nocov end + }, + + # Asynchronous (bulk) action for deleting multiple files ------------------ + #' @description This call lets you perform an asynchronous bulk + #' deletion of files or folders. Deleting folders which aren't empty is + #' allowed. + #' + #' @param items List of File objects (both `file` or `folder` type) or list + #' of IDs of files/folders you want to delete. + # nolint start + #' Read more on how to [perform async delete action on multiple files](https://docs.sevenbridges.com/reference/delete-multiple-files-and-folders). + # nolint end + #' + #' + #' @importFrom rlang abort inform + #' @importFrom checkmate assert_list + #' @importFrom glue glue + #' + #' @return \code{\link{AsyncJob}} object. + #' + #' @examples + #' \dontrun{ + #' # Delete multiple files + #' a$files$async_bulk_delete( + #' items = list(file_obj1, file_obj2, "", "") + #' ) + #' } + #' + async_bulk_delete = function(items) { + if (is_missing(items)) { + rlang::abort("The 'items' parameter should be a list of file/folder IDs or File objects you want to delete.") # nolint + } + checkmate::assert_list(items) + + body_elements <- list() + + for (i in seq_along(items)) { + item <- items[[i]] + file_id <- check_and_transform_id(item, class_name = "File") + element <- list("file" = file_id) + body_elements <- append(body_elements, list(element)) + } + + # Build body + # nocov start + body <- list( + items = body_elements + ) + + path <- glue::glue(self$URL[["async_bulk_delete"]]) + + res <- self$auth$api( + path = path, + method = "POST", + body = body + ) + + rlang::inform(glue::glue("New asynchronous job for deleting files has started.")) # nolint + + return(asAsyncJob(res, auth = self$auth)) + # nocov end + }, + + # Asynchronous (bulk) action for moving multiple files -------------------- + #' @description This call lets you perform a bulk move operation of files + #' and folders. + #' You can move: + #' \itemize{ + #' \item to a root project folder, + #' \item to a subfolder within the same project or a different + #' project. + #' } + #' + #' @details + #' Rules for moving files and folders: + #' \itemize{ + #' \item The file ID is preserved after the move. + #' \item The folder ID is changed after the move. + #' \item The destination must be an existing folder. + #' \item If the target folder contains a folder with the same + #' name, the contents of both folders will be merged. + #' \item If a file with the same name already exists, the source + #' file will be automatically renamed (by adding a numeric + #' prefix). + #' \item You need to have WRITE permissions for both source + #' and destination folders. + #' } + #' + #' @param items Nested list of elements containing information about each + #' file/folder to be moved. For each element, you must provide: + #' + # nolint start + #' \itemize{ + #' \item `file` - The ID of the file or folder you are moving. Use the + #' API call for listing all files or folders to obtain the ID. + #' \item `parent` - The ID of the folder you are moving the files to, + #' which should not be used along with `project`. If `project` is + #' used, the items will be imported to the root of the project files. + #' If `parent` is used, the import will take place into the + #' specified folder, within the project to which the folder belongs. + #' \item `project` - The project you are moving the files to. It + #' should not be used together with `parent`. If `parent` is used, + #' the import will take place into the specified folder, within the + #' project to which the folder belongs. If `project` is used, the + #' items will be imported to the root of the project files. + #' \item `name` - Enter the new name for the file or folder if you + #' want to rename at the destination. + #' } + # nolint end + #' Example of the list: + #' ```{r} + #' items <- list( + #' list( + #' file = '', + #' parent = '' + #' ), + #' list( + #' file = '', + #' project = '', + #' name = 'moved_file.txt' + #' ), + #' list( + #' file = '', + #' parent = '', + #' name = 'moved_file2.txt' + #' ) + #' ) + #' ``` + # nolint start + #' Read more on how to [perform async move action on multiple files](https://docs.sevenbridges.com/reference/move-multiple-files-or-folders). + # nolint end + #' + #' + #' @importFrom rlang abort inform + #' @importFrom checkmate assert_list test_r6 + #' @importFrom glue glue + #' + #' @return \code{\link{AsyncJob}} object. + #' + #' @examples + #' \dontrun{ + #' # Move multiple files + #' a$files$async_bulk_move( + #' items = list( + #' list( + #' file = '', + #' parent = '' + #' ), + #' list( + #' file = '', + #' project = '', + #' name = 'moved_file.txt' + #' ), + #' list( + #' file = '', + #' parent = '', + #' name = 'moved_file2.txt' + #' ) + #' ) + #' ) + #' } + #' + async_bulk_move = function(items) { + if (is_missing(items)) { + rlang::abort("The items parameter should be a nested list containing information about the files and folders to be moved.") # nolint + } + checkmate::assert_list(items) + + body_elements <- list() + + for (i in seq_along(items)) { + item <- items[[i]] + checkmate::assert_list(item) + body_element <- list() + + if (is_missing(item[["file"]])) { + rlang::abort( + glue::glue("The file ID must be provided as a string or a File object in the element {i}."), # nolint + ) + } else { + body_element$file <- check_and_transform_id(item[["file"]], + class_name = "File" + ) + } + + if (is_missing(item[["project"]]) && + is_missing(item[["parent"]])) { + rlang::abort( + glue::glue("Please provide either the destination project or the parent parameter in the element {i}.") # nolint + ) + } + if (!is_missing(item[["project"]]) && + !is_missing(item[["parent"]])) { + rlang::abort( + glue::glue("Either the destination project or the parent parameter must be provided in the element {i}, but not both.") # nolint + ) + } + if (!is_missing(item[["project"]])) { + body_element$project <- check_and_transform_id( + item[["project"]], + class_name = "Project" + ) + } + if (!is_missing(item[["parent"]])) { + if (checkmate::test_r6( + item[["parent"]], + classes = "File" + ) && + tolower(item[["parent"]]$type) != "folder") { + rlang::abort( + glue::glue("The destination parent directory parameter must contain either a folder ID or a File object with type = 'folder' in the element {i}.") # nolint + ) + } + body_element$parent <- check_and_transform_id( + x = item[["parent"]], + class_name = "File" + ) + } + if (!is_missing(item[["name"]])) { + checkmate::assert_string(item[["name"]], null.ok = TRUE) + body_element$name <- item[["name"]] + } + body_elements <- append(body_elements, list(body_element)) + } + + # Build body + # nocov start + body <- list( + items = body_elements + ) + + path <- glue::glue(self$URL[["async_bulk_move"]]) + + res <- self$auth$api( + path = path, + method = "POST", + body = body + ) + + rlang::inform(glue::glue("New asynchronous job for moving files has started.")) # nolint + + return(asAsyncJob(res, auth = self$auth)) + # nocov end + }, + + # Get details of asynchronous job for copying multiple files --------------- + #' @description This call retrieves the details of an asynchronous bulk + #' copy job. + #' This information will be available for up to a month after the job has + #' been completed. + #' + #' @param job_id The ID of the copy job you are querying. + #' This ID can be found within the API response for the call for copying + #' files. + #' The function also accepts an AsyncJob object and extracts the ID. + #' + #' @importFrom rlang abort + #' @importFrom glue glue + #' + #' @return \code{\link{AsyncJob}} object. + #' + #' @examples + #' \dontrun{ + #' # Get details of an async copy job + #' a$files$async_get_copy_job(job_id = "job-id") + #' } + #' + async_get_copy_job = function(job_id) { + if (is_missing(job_id)) { + rlang::abort( + "Please provide the 'job_id' parameter." + ) + } + + job_id <- check_and_transform_id(job_id, class_name = "AsyncJob") + + # nocov start + path <- glue::glue(self$URL[["async_get_copy_job"]]) + + res <- self$auth$api( + path = path, + method = "GET" + ) + + return(asAsyncJob(res, auth = self$auth)) + # nocov end + }, + + # Get details of asynchronous job for deleting multiple files ------------- + #' @description This call retrieves the details of an asynchronous bulk + #' deletion job. This information will be available for up to a month + #' after the job has been completed. + #' + #' @param job_id The ID of the delete job you are querying. + #' This ID can be found within the API response for the call for deleting + #' files. + #' The function also accepts an AsyncJob object and extracts the ID. + #' + #' @importFrom rlang abort + #' @importFrom glue glue + #' + #' @return \code{\link{AsyncJob}} object. + #' + #' @examples + #' \dontrun{ + #' # Get details of an async delete job + #' a$files$async_get_delete_job(job_id = "job-id") + #' } + #' + async_get_delete_job = function(job_id) { + if (is_missing(job_id)) { + rlang::abort( + "Please provide the 'job_id' parameter." + ) + } + + job_id <- check_and_transform_id(job_id, class_name = "AsyncJob") + + # nocov start + path <- glue::glue(self$URL[["async_get_delete_job"]]) + + res <- self$auth$api( + path = path, + method = "GET" + ) + + return(asAsyncJob(res, auth = self$auth)) + # nocov end + }, + + # Get details of asynchronous job for moving multiple files --------------- + #' @description This call retrieves the details of an asynchronous bulk + #' move job. This information will be available for up to a month after + #' the job has been completed. + #' + #' @param job_id The ID of the move job you are querying. This ID can be + #' found within the API response for the call for moving files. + #' The function also accepts an AsyncJob object and extracts the ID. + #' + #' @importFrom rlang abort + #' @importFrom glue glue + #' + #' @return An \code{\link{AsyncJob}} object containing details of the move + #' job. + #' + #' @examples + #' \dontrun{ + #' # Get details of an async move job + #' a$files$async_get_move_job(job_id = "job-id") + #' } + #' + async_get_move_job = function(job_id) { + if (is_missing(job_id)) { + rlang::abort( + "Please provide the 'job_id' parameter." + ) + } + + job_id <- check_and_transform_id(job_id, class_name = "AsyncJob") + + # nocov start + path <- glue::glue(self$URL[["async_get_move_job"]]) + + res <- self$auth$api( + path = path, + method = "GET" + ) + + return(asAsyncJob(res, auth = self$auth)) + # nocov end + }, + + # Get details of all asynchronous jobs --------------------------------- + #' @description This call retrieves the details for all asynchronous bulk + #' jobs you have started. This information will be available for up to a + #' month after the job has been completed. + #' + #' @param limit The maximum number of collection items to return + #' for a single request. Minimum value is `1`. + #' The maximum value is `100` and the default value is `50`. + #' This is a pagination-specific attribute. + #' @param offset The zero-based starting index in the entire collection + #' of the first item to return. The default value is `0`. + #' This is a pagination-specific attribute. + #' + #' @importFrom glue glue + #' + #' @return A \code{\link{Collection}} object containing a list of + #' \code{\link{AsyncJob}} objects. + #' + #' @examples + #' \dontrun{ + #' # Get details of the first 5 async jobs + #' a$files$async_list_file_jobs(limit = 5) + #' } + #' + async_list_file_jobs = function(limit = getOption("sevenbridges2")$limit, + offset = getOption("sevenbridges2")$offset) { # nolint + # nocov start + params_list <- list( + limit = limit, + offset = offset, + path = glue::glue(self$URL[["async_list_file_jobs"]]) + ) + res <- do.call( + super$query, + params_list + ) + + res$items <- asAsyncJobList(res, auth = self$auth) + return(asCollection(res, auth = self$auth)) # nocov end } diff --git a/R/class-import.R b/R/class-import.R index 59132fe..b076761 100644 --- a/R/class-import.R +++ b/R/class-import.R @@ -1,5 +1,5 @@ # nolint start -#' @title R6 Class representing an Import +#' @title R6 Class representing an Import job #' #' @description #' R6 Class representing a resource for managing volume import jobs. @@ -27,23 +27,21 @@ Import <- R6::R6Class( #' \item `FAILED`: the import has failed. #' } state = NULL, - #' @field overwrite Whether the imported file/folder name was - #' overwritten or not, if another one with the same name had already - #' existed. + #' @field overwrite Indicates whether the imported file or folder name + #' was overwritten if another with the same name already existed. overwrite = NULL, - #' @field autorename Whether the imported file/folder name was - #' automatically renamed (by prefixing its name with an underscore and - #' number) if another one with the same name had already existed. + #' @field autorename Indicates whether the imported file or folder name + #' was automatically renamed (by prefixing its name with an underscore + #' and number) if another with the same name already existed. autorename = NULL, #' @field preserve_folder_structure Whether the imported folder #' structure was preserved or not. preserve_folder_structure = NULL, - #' @field source List containing source volume id and source location of the - #' file/folder is being imported to the platform. + #' @field source List containing source volume id and source location of + #' the file/folder is being imported to the platform. source = NULL, - #' @field destination List containing destination project id or parent - #' directory id where the file/folder is being imported, together with its - #' name. + #' @field destination List containing the source volume ID and the source + #' location of the file or folder being imported to the platform. destination = NULL, #' @field started_on Time when the import job started. started_on = NULL, diff --git a/R/class-imports-utils.R b/R/class-imports-utils.R index 3880a9a..00df95b 100644 --- a/R/class-imports-utils.R +++ b/R/class-imports-utils.R @@ -31,7 +31,8 @@ #' @param volume_items A list of \code{\link{VolumeFile}} or #' \code{\link{VolumePrefix}} objects to be imported. #' @param destination_project Destination project ID or \code{\link{Project}} -#' object. Not required, but either `destination_project` or +#' object. Not required, but either \cr +#' `destination_project` or #' `destination_parent` directory must be provided. #' @param destination_parent Folder ID or \code{\link{File}} object #' (with `type = 'FOLDER'`). Not required, but either \cr diff --git a/R/class-imports.R b/R/class-imports.R index b19d6a7..a994ed0 100644 --- a/R/class-imports.R +++ b/R/class-imports.R @@ -2,7 +2,7 @@ #' @title R6 Class representing storage imports endpoints #' #' @description -#' R6 Class representing storage imports resource endpoints. +#' R6 Class for managing storage imports resource endpoints. #' #' @importFrom R6 R6Class #' @export @@ -31,7 +31,7 @@ Imports <- R6::R6Class( }, # List import jobs -------------------------------------------------------- - #' @description This call lists import jobs initiated by particular user. + #' @description This call lists import jobs initiated by a particular user. #' Note that when you import a file from your volume on your cloud storage #' provider (Amazon Web Services or Google Cloud Storage), you are #' creating an alias on the Platform which points to the file in your @@ -194,8 +194,8 @@ Imports <- R6::R6Class( #' exact source folder structure. The default value is `TRUE` if the item #' being imported is a folder. Should not be used if you are importing a #' file. Bear in mind that if you use `preserve_folder_structure = FALSE`, - #' that the response will be the parent folder object containing imported - #' files alongside with other files if they exist. + #' the response will be the parent folder object containing imported files + #' alongside with other files if they exist. #' @param ... Other arguments that can be passed to core `api()` function #' like 'fields', etc. #' @@ -243,7 +243,7 @@ Imports <- R6::R6Class( } if (!is_missing(destination_project) && !is_missing(destination_parent)) { - rlang::abort("Either destination project or parent parameter must be proveded, not both.") # nolint + rlang::abort("Either destination project or parent parameter must be provided, not both.") # nolint } if (!is_missing(destination_project)) { destination_project <- check_and_transform_id( @@ -302,7 +302,7 @@ Imports <- R6::R6Class( }, # Delete import job ---------------------------------------------------- - #' @description Deleting import jobs is not possible. + #' @description Import jobs cannot be deleted. #' #' @importFrom rlang inform delete = function() { @@ -398,8 +398,8 @@ Imports <- R6::R6Class( #' the volume. #' \item `destination_project` - Project object or ID to import #' files/folders into. Should not be used together with - #' destination_parent. If project is used, the items will be imported - #' to the root of the project's files. + #' destination_parent. If project is used, the items will be + #' imported to the root of the project's files. #' \item `destination_parent` - File object of type 'folder' or its ID #' to import files/folders into. Should not be used together with #' destination_project. If parent is used, the import will take @@ -417,10 +417,10 @@ Imports <- R6::R6Class( #' \item `autorename` - Whether to automatically rename the item #' (by prefixing its name with an underscore and number) if another #' one with the same name already exists at the destination. - #' \item `preserve_folder_structure` - Whether to keep the exact source - #' folder structure. The default value is TRUE if the item being - #' imported is a folder. Should not be used if you are importing a - #' file. + #' \item `preserve_folder_structure` - Whether to keep the exact + #' source folder structure. The default value is TRUE if the item + #' being imported is a folder. Should not be used if you are + #' importing a file. #' } # nolint end #' Example of the list: @@ -534,7 +534,7 @@ Imports <- R6::R6Class( if (!is_missing(item[["destination_project"]]) && !is_missing(item[["destination_parent"]])) { rlang::abort( - glue::glue("Either destination project or parent parameter must be proveded in element {i}, not both.") # nolint + glue::glue("Either destination project or parent parameter must be provided in element {i}, not both.") # nolint ) } if (!is_missing(item[["destination_project"]])) { diff --git a/R/class-invoice.R b/R/class-invoice.R index fc82e9c..e37b2a2 100644 --- a/R/class-invoice.R +++ b/R/class-invoice.R @@ -7,7 +7,7 @@ #' #' @details #' This object contains information about a selected invoice, -#' including the costs for analysis and storage, and the invoice period. +#' including costs for analysis, storage, and the invoice period. #' Invoice <- R6::R6Class( "Invoice", @@ -144,7 +144,7 @@ Invoice <- R6::R6Class( }, # Reload Invoice object --------------------------------------------------- - #' @description Reload Invoice. + #' @description Refresh the Invoice object with updated information. #' #' @param ... Other arguments that can be passed to core `api()` function #' like 'fields', etc. diff --git a/R/class-invoices.R b/R/class-invoices.R index 1e655e4..56ea2ec 100644 --- a/R/class-invoices.R +++ b/R/class-invoices.R @@ -95,7 +95,7 @@ Invoices <- R6::R6Class( #' auth = auth #' ) #' - #' # Get single invoice by id + #' # Get a single invoice by id #' invoices_object$get(id = id) #' } #' diff --git a/R/class-member.R b/R/class-member.R index 282b6ee..8c586d5 100644 --- a/R/class-member.R +++ b/R/class-member.R @@ -9,7 +9,7 @@ Member <- R6::R6Class( inherit = Item, portable = FALSE, public = list( - #' @field id Member's id. + #' @field id Member's ID. id = NULL, #' @field username Member's username. username = NULL, diff --git a/R/class-permission.R b/R/class-permission.R index a62a25c..4a79631 100644 --- a/R/class-permission.R +++ b/R/class-permission.R @@ -26,7 +26,7 @@ Permission <- R6::R6Class( #' @param read User can view file names, metadata, and workflows. #' They cannot view file contents. All members of a project have read #' permissions by default. Even if you try setting read permissions to - #' `FALSE`, they will still default to `TRUE` + #' `FALSE`, they will still default to `TRUE`. #' @param copy User can view file content, copy, and download files from a #' project. Set value to `TRUE` to assign the user copy permission. #' Set to `FALSE` to remove copy permission. @@ -90,7 +90,7 @@ Permission <- R6::R6Class( string <- glue::glue("{names(x)}: {x}") names(string) <- rep("*", times = length(string)) - cli::cli_h1("Permisions") + cli::cli_h1("Permissions") cli::cli_li(string) # Close container elements diff --git a/R/class-project.R b/R/class-project.R index 277a2e7..ad0b87a 100644 --- a/R/class-project.R +++ b/R/class-project.R @@ -22,7 +22,8 @@ Project <- R6::R6Class( ), #' @field id Project identifier. It consists of project owner's username or #' if you are using Enterprise, then the Division name and project's - #' short name in form of `/` or + #' short name in form of \cr + #' `/` or \cr #' `/`. id = NULL, #' @field name Project's name. @@ -64,7 +65,7 @@ Project <- R6::R6Class( #' } #' } settings = NULL, - #' @field root_folder ID for of the project's root folder. + #' @field root_folder ID of the project's root folder. root_folder = NULL, #' @field created_by Username of the person who created the project. created_by = NULL, @@ -333,11 +334,11 @@ Project <- R6::R6Class( # nocov end # Delete project --------------------------------------------------------- - #' @description Method that allows you to delete project from a platform. - #' It can only be successfully made if you have admin status for the - #' project. \cr - #' Please be careful when using this method and note that calling it will - #' permanently delete the project from the platform. + #' @description Method that allows you to delete a project from the + #' platform. It can only be successfully made if you have admin status for + #' the project. \cr + #' Please be careful when using this method and note that calling it will + #' permanently delete the project from the platform. #' #' @importFrom rlang abort inform #' @importFrom httr content @@ -429,8 +430,8 @@ Project <- R6::R6Class( #' registering for an account on the Seven Bridges Platform. #' @param permissions List of permissions that will be associated with the #' project's member. It can contain fields: `read`, `copy`, `write`, - #' `execute` and `admin` with logical fields - `TRUE` if certain permission - #' is allowed to the user, or `FALSE` if it's not. + #' `execute` and `admin` with logical fields - `TRUE` if certain + #' permission is allowed to the user, or `FALSE` if it's not. #' Requests to add a project member must include the key permissions. #' However, if you do not include a value for some permission, it will be #' set to `FALSE` by default. The exception to this rule is the `read` @@ -531,8 +532,8 @@ Project <- R6::R6Class( #' be successfully run by a user who has admin privileges in the project. #' #' @param user The Seven Bridges Platform username of the person - #' you want to remove from the project or object of class Member containing - #' user's username. + #' you want to remove from the project or object of class Member + #' containing user's username. #' #' @importFrom rlang abort inform #' @importFrom glue glue glue_col @@ -634,8 +635,8 @@ Project <- R6::R6Class( #' Member containing user's username. #' @param permissions List of permissions that will be associated with the #' project's member. It can contain fields: `read`, `copy`, `write`, - #' `execute` and `admin` with logical fields - `TRUE` if certain permission - #' is allowed to the user, or `FALSE` if it's not. + #' `execute` and `admin` with logical fields - `TRUE` if certain + #' permission is allowed to the user, or `FALSE` if it's not. #' Requests to add a project member must include the key permissions. #' However, if you do not include a value for some permission, it will be #' set to `FALSE` by default. The exception to this rule is the `read` @@ -836,10 +837,19 @@ Project <- R6::R6Class( }, # List project's apps ---------------------------------------------------- - #' @description This call lists all apps in project. - #' - #' @param query_terms Enter one or more search terms to query Project's - #' apps. + #' @description This call lists all apps in the project. + #' + #' @param query_terms A list of search terms used to filter apps based on + #' their details. Each term is case-insensitive and can relate to the + #' app's name, label, toolkit, toolkit version, category, tagline, or + #' description. + #' You can provide a single term (e.g., `list("Compressor")`) or multiple + #' terms (e.g., `list("Expression", "Abundance")`) to search for apps + #' that match all the specified terms. If a term matches any part of the + #' app's details, the app will be included in the results. + #' Search terms can also include phrases + #' (e.g., `list("Abundance estimates input")`), which will search for + #' exact matches within app descriptions or other fields. #' @param id Use this parameter to query Project's apps based on their ID. #' @param limit The maximum number of collection items to return #' for a single request. Minimum value is `1`. @@ -942,8 +952,8 @@ Project <- R6::R6Class( #' @param parent Provide task ID or task object of the parent task to #' return all child tasks from that parent. #' A parent task is a task that specifies the criteria by which to - #' batch its inputs into a series of further sub-tasks, called child tasks. - #' See the documentation on + #' batch its inputs into a series of further sub-tasks, called child + #' tasks. See the documentation on # nolint start #' [batching tasks](https://docs.sevenbridges.com/docs/about-batch-analyses) # nolint end @@ -1032,7 +1042,7 @@ Project <- R6::R6Class( }, # List project's import jobs ---------------------------------------------- - #' @description This call lists imports initiated by particular user + #' @description This call lists imports initiated by a particular user #' into this destination project. #' #' @param volume Volume id or Volume object. List all imports @@ -1089,11 +1099,11 @@ Project <- R6::R6Class( }, # Create new task within project ------------------------------------------ - #' @description This call creates a new task. You can create either a single - #' task or a batch task by using the app's default batching, override - #' batching, or disable batching completely. A parent task is a task that - #' specifies criteria by which to batch its inputs into a series of further - #' sub-tasks, called child tasks. the documentation on + #' @description This call creates a new task. You can create either a + #' single task or a batch task by using the app's default batching, + #' override batching, or disable batching completely. A parent task is a + #' task that specifies criteria by which to batch its inputs into a series + #' of further sub-tasks, called child tasks. See the documentation on # nolint start #' [batching tasks](https://docs.sevenbridges.com/docs/about-batch-analyses) # nolint end @@ -1164,19 +1174,19 @@ Project <- R6::R6Class( #' See below for more details. #' \itemize{ #' \item `main_location` - Defines the output location for all - #' output nodes in the task. Can be a string path within the project in - #' which the task is created, for example + #' output nodes in the task. Can be a string path within the project + #' in which the task is created, for example \cr #' `/Analysis/_/` - #' or a path on an attached volume, such as - #' `volumes://volume_name//html`. + #' or a path on an attached volume, \cr + #' such as `volumes://volume_name//html`. #' Parts of the path enclosed in angle brackets <> are tokens that are #' dynamically replaced with corresponding values during task #' execution. #' \item `main_location_alias`: The string location (path) in the - #' project that will point to the actual location where the outputs are - #' stored. Used if main_location is defined as a volume path (starting - #' with volumes://), to provide an easy way of accessing output data - #' directly from project files. + #' project that will point to the actual location where the outputs + #' are stored. Used if main_location is defined as a volume path + #' (starting with volumes://), to provide an easy way of accessing + #' output data directly from project files. #' \item `nodes_override`: Enables defining of output locations #' for output nodes individually through nodes_location (see below). #' Set to `TRUE` to be able to define individual locations per output @@ -1200,9 +1210,9 @@ Project <- R6::R6Class( #' "output_location_alias" = "/rfranklin/tasks/picard" #' ) #' ``` - #' In the example above, b64html is the ID of the output node for which - #' you want to define the output location, while the parameters are - #' defined as follows: + #' In the example above, b64html is the ID of the output node for + #' which you want to define the output location, while the parameters + #' are defined as follows: #' \itemize{ #' \item `output_location` - Can be a path within the project in which #' the task is created, for example diff --git a/R/class-projects.R b/R/class-projects.R index 03da0c2..b8b5ed6 100644 --- a/R/class-projects.R +++ b/R/class-projects.R @@ -1,8 +1,8 @@ # nolint start -#' @title R6 Class representing a projects endpoints. +#' @title R6 Class representing projects endpoints. #' #' @description -#' R6 Class representing Projects resource. +#' R6 Class representing a Projects resource. #' #' @importFrom R6 R6Class #' @@ -31,8 +31,8 @@ Projects <- R6::R6Class( }, # List projects ----------------------------------------------------------- - #' @description A method to list all projects available to particular user. - #' If the username is not provided, all projects available to the + #' @description A method to list all projects available to a particular + #' user. If the username is not provided, all projects available to the #' currently authenticated user will be listed. #' Otherwise, projects will be listed for the user whose username #' is provided. @@ -45,7 +45,11 @@ Projects <- R6::R6Class( #' #' @param name Project's name. #' @param owner The username of the owner whose projects you want to query. - #' @param tags The list of project tags. + #' @param tags A list of project tags used to filter the query results. + #' Each tag should be provided as a string within the list, and tags may + #' include spaces. For example, both "my_tag_1" and "tag with spaces" are + #' valid tag values. The method will return only projects that have all + #' the specified tags. #' @param limit The maximum number of collection items to return #' for a single request. Minimum value is `1`. #' The maximum value is `100` and the default value is `50`. @@ -73,9 +77,20 @@ Projects <- R6::R6Class( limit = getOption("sevenbridges2")$limit, offset = getOption("sevenbridges2")$offset, ...) { - checkmate::assert_string(name, null.ok = TRUE) + # Check input parameters + if (!is_missing(name)) { + checkmate::assert_string(name, null.ok = TRUE) + # Transform into a list with name 'name' + name_list <- list("name" = lapply(name, c)) + name <- transform_multiple_vals(name_list) + } checkmate::assert_string(owner, null.ok = TRUE) - check_tags(tags) + if (!is_missing(tags)) { + check_tags(tags) + # Transform into a list with name 'tags' + tags_list <- list("tags" = lapply(tags, c)) + tags <- transform_multiple_vals(tags_list) + } # nocov start if (!is_missing(owner)) { @@ -99,12 +114,13 @@ Projects <- R6::R6Class( }, # Get project ----------------------------------------------------------- - #' @description This call creates Project object containing the details + #' @description This call creates a Project object containing the details #' of a specified project. #' #' @param id Project ID. It consists of project owner's username or #' if you are using Enterprise, then the Division name and project's - #' short name in form of `/` or + #' short name in form of \cr + #' `/` or \cr #' `/`. #' #' @param ... Other arguments that can be passed to core `api()` function @@ -129,13 +145,14 @@ Projects <- R6::R6Class( }, # nocov end # Delete project ---------------------------------------------------------- - #' @description Method that allows you to delete project from a platform. - #' It can only be successfully made if you have admin status for the - #' project. \cr Projects are specified by their IDs, which you can obtain by - #' using \code{Projects$query()} to list projects or by getting a + #' @description Method that allows you to delete a project from the + #' platform. It can only be successfully made if you have admin status for + #' the project. \cr + #' Projects are specified by their IDs, which you can obtain + #' by using \code{Projects$query()} to list projects or by getting a #' single project using \code{Projects$get()}. - #' Please be careful when using this method and note that calling it will - #' permanently delete the project from the platform. + #' Please be careful when using this method and note that calling it will + #' permanently delete the project from the platform. #' #' @param project \code{\link{Project}} object or project ID. #' @param ... Other arguments that can be passed to core `api()` function @@ -184,7 +201,8 @@ Projects <- R6::R6Class( # nolint start #' [spot instances](https://docs.sevenbridges.com/docs/about-spot-instances). # nolint end - #' @param use_memoization Set to `FALSE` by default. Set to `TRUE` to enable + #' @param use_memoization Set to `FALSE` by default. Set to `TRUE` to + #' enable #' [memoization](https://docs.sevenbridges.com/docs/about-memoization). #' @param use_elastic_disk Set to `TRUE` to enable #' [Elastic disk](https://docs.sevenbridges.com/page/elastic-disk). diff --git a/R/class-ratelimit.R b/R/class-ratelimit.R index 047e251..66ec8de 100644 --- a/R/class-ratelimit.R +++ b/R/class-ratelimit.R @@ -5,7 +5,7 @@ #' #' @importFrom R6 R6Class #' @details -#' This is main object for Rate Limit. +#' This is the main object for Rate Limit. Rate <- R6::R6Class( "Rate", inherit = Item, diff --git a/R/class-resource.R b/R/class-resource.R index a137213..7b56f12 100644 --- a/R/class-resource.R +++ b/R/class-resource.R @@ -38,10 +38,10 @@ Resource <- R6::R6Class( } path <- args$path - # Remove path, they are not needed for query parameters + # Remove path, it is not needed for query parameters args[["path"]] <- NULL - # Remove advance_access, they are not needed for query parameters + # Remove advance_access, it is not needed for query parameters adv_access <- extract_common_query_params(args, "advance_access") limit <- extract_common_query_params(args, "limit") offset <- extract_common_query_params(args, "offset") @@ -63,7 +63,7 @@ Resource <- R6::R6Class( }, # Generic get function ---------------------------------------------- - #' @description Generic get implementation that fetches single resource + #' @description Generic get implementation that fetches a single resource #' from the server. #' #' @param cls Resource class object. @@ -107,7 +107,7 @@ Resource <- R6::R6Class( }, # Generic delete function ------------------------------------------------ - #' @description Generic implementation that deletes the resource + #' @description Generic implementation to delete a resource #' from the server. #' #' @param cls Resource class object. @@ -118,7 +118,7 @@ Resource <- R6::R6Class( #' @importFrom glue glue delete = function(id, ...) { if (is.null(self[["URL"]][["delete"]])) { - rlang::abort("Resource can not be deleted!") + rlang::abort("Resource cannot be deleted!") } if (is_missing(id)) { rlang::abort("Please provide id parameter!") diff --git a/R/class-task.R b/R/class-task.R index 72e91b4..ec70ed7 100644 --- a/R/class-task.R +++ b/R/class-task.R @@ -49,14 +49,14 @@ Task <- R6::R6Class( created_on = NULL, #' @field start_time Task start time in form of string. start_time = NULL, - #' @field end_time Task end time in form of string . + #' @field end_time Task end time in form of string. end_time = NULL, - #' @field origin Id of the entity that created the task, e.g. - #' automation run, if task was created by an automation run. + #' @field origin ID of the entity that created the task, e.g., + #' an automation run, if task was created by an automation run. origin = NULL, - #' @field use_interruptable_instances This field can be `TRUE` or + #' @field use_interruptible_instances This field can be `TRUE` or #' `FALSE`. Set this field to `TRUE` to allow the use of spot instances. - use_interruptable_instances = NULL, + use_interruptible_instances = NULL, #' @field batch `TRUE` for batch tasks, `FALSE` for regular and child #' tasks (batch this task; if `FALSE`, will not create a batch task). batch = NULL, @@ -76,7 +76,7 @@ Task <- R6::R6Class( #' @field execution_status Task execution status list - info about current #' execution status. execution_status = NULL, - #' @field errors Validations errors list stored as a high-level errors + #' @field errors Validation errors list stored as a high-level errors #' array property in the API response. errors = NULL, #' @field warnings Validation warnings list from API response. @@ -112,8 +112,8 @@ Task <- R6::R6Class( self$start_time <- res$start_time self$end_time <- res$end_time self$origin <- res$origin - self$use_interruptable_instances <- - res$use_interruptable_instances + self$use_interruptible_instances <- + res$use_interruptible_instances self$batch <- res$batch self$batch_by <- res$batch_by self$batch_group <- res$batch_group @@ -213,8 +213,8 @@ Task <- R6::R6Class( #' is `DRAFT` can be run. #' #' @param batch Set this to `FALSE` to disable the default batching - #' for this task. Running a batch task is a recommended way to run multiple - #' tasks considering the API rate limit + #' for this task. Running a batch task is a recommended way to run + #' multiple tasks considering the API rate limit #' ([learn more](https://docs.sevenbridges.com/docs/api-rate-limit)). #' @param use_interruptible_instances This field can be `TRUE` or #' `FALSE`. Set this field to `TRUE` to allow the use of @@ -709,10 +709,10 @@ Task <- R6::R6Class( #' dynamically replaced with corresponding values during task #' execution. #' \item `main_location_alias`: The string location (path) in the - #' project that will point to the actual location where the outputs are - #' stored. Used if main_location is defined as a volume path (starting - #' with volumes://), to provide an easy way of accessing output data - #' directly from project files. + #' project that will point to the actual location where the outputs + #' are stored. Used if main_location is defined as a volume path + #' (starting with volumes://), to provide an easy way of accessing + #' output data directly from project files. #' \item `nodes_override`: Enables defining of output locations #' for output nodes individually through nodes_location (see below). #' Set to `TRUE` to be able to define individual locations per output @@ -736,9 +736,9 @@ Task <- R6::R6Class( #' "output_location_alias" = "/rfranklin/tasks/picard" #' ) #' ``` - #' In the example above, b64html is the ID of the output node for which - #' you want to define the output location, while the parameters are - #' defined as follows: + #' In the example above, b64html is the ID of the output node for + #' which you want to define the output location, while the parameters + #' are defined as follows: #' \itemize{ #' \item `output_location` - Can be a path within the project in which #' the task is created, for example diff --git a/R/class-tasks.R b/R/class-tasks.R index f9cc03c..4d3f0b4 100644 --- a/R/class-tasks.R +++ b/R/class-tasks.R @@ -39,10 +39,10 @@ Tasks <- R6::R6Class( #' @param status You can filter the returned tasks by their status. #' Set the value of status to one of the following values: `QUEUED`, #' `DRAFT`, `RUNNING`, `COMPLETED`, `ABORTED`, `FAILED`. - #' @param parent Provide task ID or Task object of the parent task to return - #' all child tasks from that parent. A parent task is a task that specifies - #' criteria by which to batch its inputs into a series of further - #' sub-tasks, called child tasks. See the documentation on + #' @param parent Provide the task ID or Task object of the parent task to + #' return all child tasks. A parent task is a task that + #' specifies criteria by which to batch its inputs into a series of + #' further sub-tasks, called child tasks. See the documentation on # nolint start #' [batching tasks](https://docs.sevenbridges.com/docs/about-batch-analyses) # nolint end @@ -64,7 +64,7 @@ Tasks <- R6::R6Class( #' ended until a specified date. #' @param order_by Order returned results by the specified field. #' Allowed values: \cr `created_time`, `start_time`, `name`, `end_time` and - #' `created_by`. \cr Sort can be done only by one column. The default + #' `created_by`. \cr Sorting can only be done by one column. The default #' value is `created_time`. #' @param order Sort results in ascending or descending order by #' specifying `asc` or `desc`, respectively. Only taken into account if @@ -185,9 +185,9 @@ Tasks <- R6::R6Class( # Get single task ------------------------------------------------------- #' @description This call returns details of the specified task. The task #' is referred to by its ID, which you can obtain by making the call to - #' list all tasks you can access. The task details include its creator, its - #' start and end time, the number of jobs completed in it, and its input - #' and output files. You can also see the status of the task. + #' list all tasks you can access. The task details include its creator, + #' its start and end time, the number of jobs completed in it, and its + #' input and output files. You can also see the status of the task. #' #' @param id The ID of the task you are querying. #' @param ... Other arguments that can be passed to core `api()` function @@ -215,10 +215,9 @@ Tasks <- R6::R6Class( }, # nocov end # Delete task ---------------------------------------------------------- - #' @description This call deletes a task from the Seven Bridges Platform. - #' Tasks are specified by their IDs, which you can obtain by using - #' \code{Tasks$query()} to list tasks or by getting a single task - #' using \code{Tasks$get()}. + #' @description Tasks are identified by their IDs, which can be obtained + #' using \code{Tasks$query()} to list tasks or \code{Tasks$get()} to + #' retrieve a single task. #' #' @param task \code{\link{Task}} object or task ID. #' @param ... Other arguments that can be passed to core `api()` function @@ -239,12 +238,12 @@ Tasks <- R6::R6Class( }, # nocov end - # Create a new draft task -------------------------------------------------- - #' @description This call creates a new task. You can create either a single - #' task or a batch task by using the app's default batching, override - #' batching, or disable batching completely. A parent task is a task that - #' specifies criteria by which to batch its inputs into a series of further - #' sub-tasks, called child tasks. the documentation on + # Create a new draft task ------------------------------------------------- + #' @description This call creates a new task. You can create either a + #' single task or a batch task by using the app's default batching, + #' override batching, or disable batching completely. A parent task is a + #' task that specifies criteria by which to batch its inputs into a series + #' of further sub-tasks, called child tasks. the documentation on # nolint start #' [batching tasks](https://docs.sevenbridges.com/docs/about-batch-analyses) # nolint end @@ -317,8 +316,8 @@ Tasks <- R6::R6Class( #' See below for more details. #' \itemize{ #' \item `main_location` - Defines the output location for all - #' output nodes in the task. Can be a string path within the project in - #' which the task is created, for example \cr + #' output nodes in the task. Can be a string path within the project + #' in which the task is created, for example \cr #' `/Analysis/_/` \cr #' or a path on an attached volume, such as \cr #' `volumes://volume_name//html`. \cr @@ -326,10 +325,10 @@ Tasks <- R6::R6Class( #' dynamically replaced with corresponding values during task #' execution. #' \item `main_location_alias`: The string location (path) in the - #' project that will point to the actual location where the outputs are - #' stored. Used if main_location is defined as a volume path (starting - #' with volumes://), to provide an easy way of accessing output data - #' directly from project files. + #' project that will point to the actual location where the outputs + #' are stored. Used if main_location is defined as a volume path + #' (starting with volumes://), to provide an easy way of accessing + #' output data directly from project files. #' \item `nodes_override`: Enables defining of output locations #' for output nodes individually through nodes_location (see below). #' Set to `TRUE` to be able to define individual locations per output @@ -353,9 +352,9 @@ Tasks <- R6::R6Class( #' "output_location_alias" = "/rfranklin/tasks/picard" #' ) #' ``` - #' In the example above, b64html is the ID of the output node for which - #' you want to define the output location, while the parameters are - #' defined as follows: + #' In the example above, b64html is the ID of the output node for + #' which you want to define the output location, while the parameters + #' are defined as follows: #' \itemize{ #' \item `output_location` - Can be a path within the project in which #' the task is created, for example @@ -487,7 +486,7 @@ Tasks <- R6::R6Class( return(asTask(res, auth = self$auth)) }, # nocov end - # Get details of multiple tasks + # Get details of multiple tasks ------------------------------------------- #' #' @description This call returns statistics for all specified tasks. #' @@ -538,7 +537,7 @@ Tasks <- R6::R6Class( } ), private = list( - # Serialize input values -------------------------------------------------- + # Serialize input values ------------------------------------------------- #' @importFrom checkmate test_r6 serialize_inputs = function(input_value) { # nocov start if (is.list(input_value)) { @@ -563,7 +562,7 @@ Tasks <- R6::R6Class( return(return_value) }, - # Convert input value to File format -------------------------------------- + # Convert input value to a File format ----------------------------------- #' @importFrom stringr str_to_title to_api_file_format = function(file) { return(list( diff --git a/R/class-team.R b/R/class-team.R new file mode 100644 index 0000000..66e8e48 --- /dev/null +++ b/R/class-team.R @@ -0,0 +1,345 @@ +#' @title R6 Class representing a Team +#' +#' @description +#' R6 Class representing a central resource for managing teams. +#' +#' @importFrom R6 R6Class +#' +#' @export +Team <- R6::R6Class( + "Team", + inherit = Item, + portable = FALSE, + public = list( + #' @field URL List of URL endpoints for this resource. + URL = list( + "members" = "teams/{self$id}/members", + "member" = "teams/{self$id}/members/{username}", + "team" = "teams/{self$id}" + ), + #' @field id The ID of the team. + id = NULL, + #' @field name Team's name. + name = NULL, + + # Initialize Team object + #' @description Create a new Team object. + #' + #' @param res Response containing the Team object information. + #' + #' @param ... Other response arguments. + initialize = function(res = NA, ...) { + # Initialize Item class + super$initialize(...) + + self$id <- res$id + self$name <- res$name + }, + + # nocov start + # Print Team object ------------------------------------------------------- + #' @description Print method for Team class. + #' + #' @importFrom purrr discard + #' @importFrom glue glue_col + #' @importFrom cli cli_h1 cli_li cli_end + #' + #' @examples + #' \dontrun{ + #' team_object <- Team$new( + #' res = x, + #' href = x$href, + #' auth = auth, + #' response = attr(x, "response") + #' ) + #' team_object$print() + #' } + print = function() { + x <- as.list(self) + + x <- purrr::discard(x, .p = is.list) + x <- purrr::discard(x, .p = is.function) + x <- purrr::discard(x, .p = is.environment) + x <- purrr::discard(x, .p = is.null) + x <- purrr::discard(x, .p = ~ .x == "") + + string <- glue::glue_col("{green {names(x)}}: {x}") + + cli::cli_h1("Team") + cli::cli_li(string) + + # Close container elements + cli::cli_end() + }, + + # Reload Team object ------------------------------------------------------ + #' @description Reload Team object information. + #' + #' @param ... Other arguments that can be passed to core `api()` function + #' like 'fields', etc. + #' + #' @importFrom rlang inform + #' + #' @examples + #' \dontrun{ + #' team_object <- Team$new( + #' res = x, + #' href = x$href, + #' auth = auth, + #' response = attr(x, "response") + #' ) + #' team_object$reload() + #' } + #' + #' @return \code{\link{Team}} object. + reload = function(...) { + super$reload( + cls = self, + ... + ) + rlang::inform("Team object is refreshed!") + }, + # nocov end + + # List team members ------------------------------------------------------- + #' @description This call retrieves a list of all team members within a + #' specified team. Each member's username will be returned. + #' + #' @param limit The maximum number of collection items to return + #' for a single request. Minimum value is `1`. + #' The maximum value is `100` and the default value is `50`. + #' This is a pagination-specific attribute. + #' @param offset The zero-based starting index in the entire collection + #' of the first item to return. The default value is `0`. + #' This is a pagination-specific attribute. + #' @param ... Other arguments that can be passed to core `api()` function + #' like 'fields', etc. + #' + #' @importFrom glue glue + #' + #' @examples + #' \dontrun{ + #' # Retrieve details of a specified team + #' my_team <- a$teams$get(id = "team-id") + #' + #' # Retrieve a list of all team members + #' my_team$list_members() + #' } + #' + #' @return A \code{\link{Collection}} of \code{\link{User}} objects. + list_members = function(limit = getOption("sevenbridges2")$limit, + offset = getOption("sevenbridges2")$offset, + ...) { + # nocov start + res <- self$auth$api( + path = glue::glue(self$URL[["members"]]), + method = "GET", + limit = limit, + offset = offset, + ... + ) + res$items <- asUserList(res, auth = self$auth) + + return(asCollection(res, auth = self$auth)) + # nocov end + }, + + # Add a team member ------------------------------------------------------- + #' @description This call adds a division member to the specified team. + #' This action requires `ADMIN` privileges. + #' + #' @param user User ID of the division member you are adding to the team + #' using the following format: `division_id/username`. Alternatively, + #' a `User` object can be provided. + #' + #' @importFrom rlang abort inform + #' @importFrom glue glue glue_col + #' + #' @examples + #' \dontrun{ + #' # Retrieve details of a specified team + #' my_team <- a$teams$get(id = "team-id") + #' + #' # Add new member to the team + #' my_team$add_member(user = "user-id") + #' } + add_member = function(user) { + if (is_missing(user)) { + rlang::abort( + "Please provide a username or a User object to add the member to the team." # nolint + ) + } + + username <- check_and_transform_id(user, + class_name = "User", + field_name = "username" + ) + + # nocov start + body <- list( + "id" = username + ) + + res <- self$auth$api( + path = glue::glue(self$URL[["members"]]), + method = "POST", + body = body + ) + + rlang::inform( + message = glue::glue_col( + "User {green {username}} has been added + to the {green {self$name}} team", + .literal = TRUE + ) + ) + # nocov end + }, + + # Remove a team member ---------------------------------------------------- + #' @description This call removes a member from a team. By removing a + #' member, you remove the user's membership to the team, but do not + #' remove their account from the division. + #' This action requires `ADMIN` privileges. + #' + #' @param user The Seven Bridges Platform username of the user to be + #' removed, specified in the format `division-name/username`, or an object + #' of class `User` that contains the username. + #' + #' @importFrom rlang abort inform + #' @importFrom glue glue glue_col + #' + #' @examples + #' \dontrun{ + #' # Retrieve details of a specified team + #' my_team <- a$teams$get(id = "team-id") + #' + #' # Remove a member from the team + #' my_team$remove_member(user = "user-id") + #' } + remove_member = function(user) { + if (is_missing(user)) { + rlang::abort( + "Please provide a username or a User object to remove the member from the team." # nolint + ) + } + + username <- check_and_transform_id(user, + class_name = "User", + field_name = "username" + ) + + # nocov start + res <- self$auth$api( + path = glue::glue(self$URL[["member"]]), + method = "DELETE" + ) + + rlang::inform( + message = glue::glue_col( + "User {green {username}} has been removed + from the {green {self$id}} team", + .literal = TRUE + ) + ) + # nocov end + }, + + # Rename a team ----------------------------------------------------------- + #' @description This call renames the specified team. This action requires + #' `ADMIN` privileges. + #' + #' @param name The new name for the team. + #' + #' @importFrom rlang abort inform + #' @importFrom checkmate assert_string + #' @importFrom glue glue glue_col + #' + #' @examples + #' \dontrun{ + #' # Retrieve details of a specified team + #' my_team <- a$teams$get(id = "team-id") + #' + #' # Rename the team + #' my_team$rename(name = "new-team-name") + #' } + rename = function(name = NULL) { + if (is_missing(name)) { + rlang::abort( + "Please provide the new name for the team." # nolint + ) + } + + checkmate::assert_string(name) + + # nocov start + body <- list( + "name" = name + ) + + res <- self$auth$api( + path = glue::glue(self$URL[["team"]]), + method = "PATCH", + body = body + ) + + # Reload object + self$initialize( + res = res, + href = res$href, + response = attr(res, "response"), + auth = self$auth + ) + + rlang::inform( + glue::glue_col("The team has been renamed.") # nolint + ) + # nocov end + }, + + # Delete a team ----------------------------------------------------------- + #' @description This call deletes a team. By deleting a team, you remove + #' the users' membership to the team, but do not remove their accounts + #' from the division. + #' This action requires `ADMIN` privileges. + #' + #' @importFrom rlang inform + #' @importFrom glue glue glue_col + #' + #' @examples + #' \dontrun{ + #' # Retrieve details of a specified team + #' my_team <- a$teams$get(id = "team-id") + #' + #' # Delete a team + #' my_team$delete() + #' } + delete = function() { + # nocov start + res <- self$auth$api( + path = glue::glue(self$URL[["team"]]), + method = "DELETE" + ) + + rlang::inform( + glue::glue_col("The team {green {self$name}} has been deleted.") # nolint + ) + # nocov end + } + ) +) + +# Helper functions for creating Team objects ---------------------------------- +asTeam <- function(x = NULL, auth = NULL) { + Team$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) +} + +asTeamList <- function(x, auth) { + obj <- lapply(x$items, asTeam, auth = auth) + obj +} diff --git a/R/class-teams.R b/R/class-teams.R new file mode 100644 index 0000000..7c7c129 --- /dev/null +++ b/R/class-teams.R @@ -0,0 +1,207 @@ +# nolint start +#' @title R6 Class representing teams endpoints +#' +#' @description +#' R6 Class representing teams resource endpoints. +#' +#' @importFrom R6 R6Class +#' +#' @export +Teams <- R6::R6Class( + "Teams", + # nolint end + inherit = Resource, + portable = FALSE, + public = list( + #' @field URL List of URL endpoints for this resource. + URL = list( + "query" = "divisions/{division_id}/teams", + "get" = "teams/{id}", + "create" = "teams", + "delete" = "teams" + ), + + #' @description Create new Teams resource object. + #' + #' @param ... Other response arguments. + initialize = function(...) { + # Initialize Resource class + super$initialize(...) + }, + + # List all teams in a division -------------------------------------------- + #' @description This call retrieves a list of all teams in a division that + #' you are a member of. Each team's ID and name will be returned. + #' + #' @param division The string ID of the division or Division object + #' you are querying. + #' @param list_all Boolean. Set this field to `TRUE` if you want to list + #' all teams within the division (regardless of whether you are a member + #' of a team or not). Default value is `FALSE`. + #' @param ... Other arguments that can be passed to core `api()` function + #' like 'fields', etc. + #' + #' @importFrom rlang abort + #' @importFrom checkmate assert_logical + #' @importFrom glue glue + #' + #' @examples + #' \dontrun{ + #' # Retrieve a list of all teams within the division regardless of + #' # whether you are a member of a team or not + #' a$teams$query(division = "division-id", list_all = TRUE) + #' } + #' + #' @return A \code{\link{Collection}} of \code{\link{Team}} objects. + query = function(division, list_all = FALSE, ...) { + if (is_missing(division)) { + rlang::abort("Please provide the division ID or Division object you're querying.") # nolint + } + division_id <- check_and_transform_id(division, + class_name = "Division", + field_name = "id" + ) + + checkmate::assert_logical(list_all) + + # nocov start + list_all <- ifelse(isTRUE(list_all), "true", "false") + + params_list <- list( + path = glue::glue(self$URL[["query"]]), + "_all" = list_all, + ... + ) + + res <- do.call( + super$query, + params_list + ) + + res$items <- asTeamList(res, auth = self$auth) + + return(asCollection(res, auth = self$auth)) + # nocov end + }, + + # Get details of a team ----------------------------------------------- + #' @description This call returns the details of a specified team. + #' You can only get details of a team you are a member of. + #' + #' @param id The ID of the team you are querying. The function + #' also accepts a Team object and extracts the ID. + #' @param ... Other arguments that can be passed to core `api()` function + #' like 'fields', etc. + #' + #' @importFrom rlang abort + #' + #' @return \code{\link{Team}} object. + #' + #' @examples + #' \dontrun{ + #' # Retrieve details of a specified team + #' a$teams$get(id = "team-id") + #' } + get = function(id, ...) { + if (is_missing(id)) { + rlang::abort( + "Please provide the 'id' parameter." + ) + } + + id <- check_and_transform_id(id, + class_name = "Team" + ) + + # nocov start + res <- super$get( + cls = self, + id = id, + ... + ) + + return(asTeam(res, auth = self$auth)) + # nocov end + }, + + # Create a team -------------------------------------------- + #' @description This call creates a new team within a specified division. + #' + #' @param division The string ID of the division or Division object + #' where you want to create a team. + #' @param name Enter the name for the new team. + #' + #' @importFrom rlang abort + #' @importFrom checkmate assert_string + #' + #' @examples + #' \dontrun{ + #' # Create new team + #' a$teams$create(division = "division-id", name = "my-new-team") + #' } + #' + #' @return A \code{\link{Team}} object. + create = function(division, name) { + if (is_missing(division) || is_missing(name)) { + rlang::abort("Division or new team name is missing. Please provide both parameters.") # nolint + } + division_id <- check_and_transform_id(division, + class_name = "Division", + field_name = "id" + ) + checkmate::assert_string(name, null.ok = FALSE) + + # nocov start + body <- list( + division = division_id, + name = name + ) + + res <- self$auth$api( + path = self$URL[["create"]], + method = "POST", + body = body + ) + + return(asTeam(res, auth = self$auth)) + }, # nocov end + + # Delete a team ----------------------------------------------- + #' @description This call deletes a team. By deleting a team, you remove + #' the users' membership to the team, but do not remove their accounts + #' from the division. + #' + #' @param team The team ID or Team object that you want to delete. + #' @param ... Other arguments that can be passed to core `api()` function. + #' + #' @importFrom rlang abort inform + #' @importFrom glue glue_col + #' + #' @examples + #' \dontrun{ + #' # Delete a team + #' a$teams$delete(team = "team-id") + #' } + delete = function(team, ...) { + if (is_missing(team)) { + rlang::abort( + "Please provide the team ID as string or as Team object." + ) + } + + id <- check_and_transform_id(team, + class_name = "Team" + ) + + # nocov start + res <- super$delete( + id = id, + ... + ) + + rlang::inform( + glue::glue_col("The team {green {id} } has been deleted successfully.") + ) # nocov end + } + ) +) diff --git a/R/class-upload.R b/R/class-upload.R index c10b95e..0062455 100644 --- a/R/class-upload.R +++ b/R/class-upload.R @@ -20,7 +20,7 @@ Upload <- R6::R6Class( ), #' @field upload_id Upload ID received after upload initialization. upload_id = NULL, - #' @field path Relative or absolute path to the file on the local disc. + #' @field path Relative or absolute path to the file on the local disk. path = NULL, #' @field project Project's identifier (character). project = NULL, @@ -98,7 +98,7 @@ Upload <- R6::R6Class( #' auth = auth #' ) #' - #' # Print upload object information + #' # Print the upload object information #' upload_object$print(name = name) #' } #' @@ -119,7 +119,7 @@ Upload <- R6::R6Class( }, # nocov end # Initialize multipart file upload --------------------------------------- - #' @description Initialize new multipart file upload. + #' @description Initialize a new multipart file upload. #' #' @importFrom glue glue glue_col #' @importFrom rlang abort @@ -301,7 +301,7 @@ Upload <- R6::R6Class( ) rlang::inform( paste0( - "Estimated uploading speed: ", + "Estimated upload speed: ", ceiling(self$file_size / 1024 / 1024 / as.numeric(.diff)), " Mb/", attr(.diff, "unit") ) @@ -513,8 +513,8 @@ Part <- R6::R6Class( # Get upload part info ---------------------------------------------------- #' @description Get upload part info. #' - #' @param upload_id Upload object or ID of the upload process that part. - #' belongs to. + #' @param upload_id Upload object or ID of the upload process to which the + #' part belongs. #' #' @importFrom glue glue #' diff --git a/R/class-user.R b/R/class-user.R index e8cb87f..4d8789c 100644 --- a/R/class-user.R +++ b/R/class-user.R @@ -4,7 +4,7 @@ #' User object containing user information. #' #' @importFrom R6 R6Class -#' @details This is main object for Users. +#' @details This is the main object for Users. User <- R6::R6Class( "User", inherit = Item, @@ -31,9 +31,9 @@ User <- R6::R6Class( address = NULL, #' @field city User's city of residence. city = NULL, - #' @field state User's state of residence. + #' @field state User's state of residence. state = NULL, - #' @field country User's country of residence. + #' @field country User's country of residence. country = NULL, #' @field zip_code Zip code for the user's residence. zip_code = NULL, @@ -143,3 +143,8 @@ asUser <- function(x = NULL, auth = NULL) { response = attr(x, "response") ) } + +asUserList <- function(x, auth) { + obj <- lapply(x$items, asUser, auth = auth) + obj +} diff --git a/R/class-volume.R b/R/class-volume.R index 5a9da42..cbf111f 100644 --- a/R/class-volume.R +++ b/R/class-volume.R @@ -22,8 +22,8 @@ Volume <- R6::R6Class( "member_username" = "storage/volumes/{self$id}/members/{username}", "member_permissions" = "storage/volumes/{self$id}/members/{username}/permissions" # nolint ), - #' @field id Volume ID, constructed from `{division}/{volume_name}` - #' or `{volume_owner}/{volume_name}`. + #' @field id Volume ID, constructed from `{division}/{volume_name}` or \cr + #' `{volume_owner}/{volume_name}`. id = NULL, #' @field name The name of the volume. It must be unique from all #' other volumes for this user. Required if `from_path` parameter @@ -120,6 +120,7 @@ Volume <- R6::R6Class( # Reload Volume object ---------------------------------------------------- #' @description Reload Volume object information. + #' #' @param ... Other arguments that can be passed to core `api()` function #' like 'fields', etc. #' @@ -218,9 +219,9 @@ Volume <- R6::R6Class( # Deactivate volume ------------------------------------------------------- #' @description Deactivate volume. #' Once deactivated, you cannot import from, export to, or browse within a - #' volume. As such, the content of the files imported from this volume will - #' no longer be accessible on the Platform. However, you can update the - #' volume and manage members. \cr + #' volume. As such, the content of the files imported from this volume + #' will no longer be accessible on the Platform. However, you can update + #' the volume and manage members. \cr #' Note that you cannot deactivate the volume if you have running imports #' or exports unless you force the operation using the query parameter #' force=TRUE. @@ -275,6 +276,7 @@ Volume <- R6::R6Class( #' @description Reactivate volume. #' This function reactivates the previously deactivated volume by updating #' the `active` field of the volume to `TRUE`. + #' #' @param ... Other query parameters or arguments that can be passed to #' core `api()` function like 'force'. #' Use it within query parameter, like `query = list(force = TRUE)`. @@ -375,6 +377,7 @@ Volume <- R6::R6Class( # List volume contents ---------------------------------------------------- #' @description List volume contents. #' This call lists the contents of a specific volume. + #' #' @param prefix This is parent parameter in volume context. If specified, #' the content of the parent directory on the current volume is listed. #' @param limit The maximum number of collection items to return @@ -539,7 +542,8 @@ Volume <- R6::R6Class( #' volume_object$list_members() #' } #' - #' @return \code{\link{Collection}} containing \code{\link{Member}} objects. + #' @return \code{\link{Collection}} containing \code{\link{Member}} + #' objects. list_members = function(limit = getOption("sevenbridges2")$limit, offset = getOption("sevenbridges2")$offset, ...) { @@ -580,8 +584,6 @@ Volume <- R6::R6Class( #' permissions = list(read = TRUE, copy = TRUE, write = FALSE, #' admin = FALSE) #' ``` - #' @importFrom checkmate assert_list assert_subset - #' @importFrom glue glue #' #' @examples #' \dontrun{ @@ -612,39 +614,142 @@ Volume <- R6::R6Class( class_name = "Member", field_name = "username" ) - checkmate::assert_list(permissions, - null.ok = FALSE, len = 4, - types = "logical" + # nocov start + res <- self$private$add_member_general(username, + permissions, + type = "USER" ) - checkmate::assert_subset(names(permissions), - empty.ok = FALSE, - choices = c("read", "copy", "write", "admin") + + return(asMember(res, auth = self$auth)) + # nocov end + }, + + # Add team to a volume (Enterprise users) -------------------------------- + #' @description Add a specific team as a member to a volume. + #' Only Enterprise users that are part of some division can add teams + #' to a volume created within that division. + #' + #' @param team The Seven Bridges Platform ID of a team + #' you want to add to the volume or object of class Team containing + #' team's ID. Team must be created within a division where the volume is + #' created too. + #' @param permissions List of permissions granted to the team being added. + #' Permissions include listing the contents of a volume, importing files + #' from the volume to the Platform, exporting files from the Platform to + #' the volume, and admin privileges. \cr + #' It can contain fields: 'read', 'copy', 'write' and 'admin' with + #' logical fields - TRUE if certain permission is allowed to the team, or + #' FALSE if it's not. + #' Example: + #' ```{r} + #' permissions = list(read = TRUE, copy = TRUE, write = FALSE, + #' admin = FALSE) + #' ``` + #' + #' @examples + #' \dontrun{ + #' # x is API response when volume is requested + #' volume_object <- Volume$new( + #' res = x, + #' href = x$href, + #' auth = auth, + #' response = attr(x, "response") + #' ) + #' + #' # Add volume member + #' volume_object$add_member_team( + #' team = , + #' permissions = list(read = TRUE, copy = FALSE) + #' ) + #' } + #' + #' @return \code{\link{Member}} object. + add_member_team = function(team, + permissions = list( + read = TRUE, + copy = FALSE, + write = FALSE, + admin = FALSE + )) { + team <- check_and_transform_id(team, + class_name = "Team", + field_name = "id" ) # nocov start - path <- glue::glue(self$URL[["members"]]) + res <- self$private$add_member_general(team, permissions, type = "TEAM") - body <- list( - username = username, - permissions = permissions + return(asMember(res, auth = self$auth)) + # nocov end + }, + # Add division to a volume (Enterprise users) ----------------------- + #' @description Add a specific division as a member to a volume. + #' Only Enterprise users (with Enterprise accounts) can add divisions to a + #' volume that is created with that Enterprise account (not within other + #' divisions). + #' + #' @param division The Seven Bridges Platform ID of a division + #' you want to add to the volume or object of class Division containing + #' division's ID. + #' @param permissions List of permissions granted to the division being + #' added. Permissions include listing the contents of a volume, importing + #' files from the volume to the Platform, exporting files from the + #' Platform to the volume, and admin privileges. \cr + #' It can contain fields: 'read', 'copy', 'write' and 'admin' with + #' logical fields - TRUE if certain permission is allowed to the division, + #' or FALSE if it's not. + #' Example: + #' ```{r} + #' permissions = list(read = TRUE, copy = TRUE, write = FALSE, + #' admin = FALSE) + #' ``` + #' + #' @examples + #' \dontrun{ + #' # x is API response when volume is requested + #' volume_object <- Volume$new( + #' res = x, + #' href = x$href, + #' auth = auth, + #' response = attr(x, "response") + #' ) + #' + #' # Add volume member + #' volume_object$add_member_division( + #' division = , + #' permissions = list(read = TRUE, copy = FALSE) + #' ) + #' } + #' + #' @return \code{\link{Member}} object. + add_member_division = function(division, + permissions = list( + read = TRUE, + copy = FALSE, + write = FALSE, + admin = FALSE + )) { + division <- check_and_transform_id(division, + class_name = "Division", + field_name = "id" ) - res <- self$auth$api( - path = path, - method = "POST", - body = body, - advance_access = TRUE + # nocov start + res <- self$private$add_member_general(division, + permissions, + type = "DIVISION" ) return(asMember(res, auth = self$auth)) # nocov end }, - # Remove volume members --------------------------------------------------- #' @description Remove member from a volume. #' This function removes members from the specified volume. #' - #' @param user The Seven Bridges Platform username of the person - #' you want to remove from the volume or object of class Member containing - #' user's username. + #' @param member The Seven Bridges Platform username of the person + #' you want to remove from the volume, or team ID or division ID + #' (for Enterprise users only) or object of class Member containing + #' member's ID. + #' #' @importFrom glue glue glue_col #' #' @examples @@ -658,13 +763,13 @@ Volume <- R6::R6Class( #' ) #' #' # Remove volume member - #' volume_object$remove_member(user = user) + #' volume_object$remove_member(member = member) #' } #' - remove_member = function(user) { - username <- check_and_transform_id(user, + remove_member = function(member) { + username <- check_and_transform_id(member, class_name = "Member", - field_name = "username" + field_name = "id" ) # nocov start path <- glue::glue(self$URL[["member_username"]]) @@ -683,9 +788,10 @@ Volume <- R6::R6Class( #' @description Get member's details. #' This function returns member's information. #' - #' @param user The Seven Bridges Platform username of the person - #' you want to get information about or object of class Member containing - #' user's username. + #' @param member The Seven Bridges Platform username of the person + #' you want to get information about, or team ID or division ID + #' (for Enterprise users only) or object of class Member containing + #' member's ID. #' @param ... Other arguments that can be passed to core `api()` function #' like 'fields', etc. #' @@ -702,14 +808,14 @@ Volume <- R6::R6Class( #' ) #' #' # Get volume member - #' volume_object$get_member(user = user) + #' volume_object$get_member(member = member) #' } #' #' @return \code{\link{Member}} object. - get_member = function(user, ...) { - username <- check_and_transform_id(user, + get_member = function(member, ...) { + username <- check_and_transform_id(member, class_name = "Member", - field_name = "username" + field_name = "id" ) # nocov start path <- glue::glue(self$URL[["member_username"]]) @@ -728,11 +834,13 @@ Volume <- R6::R6Class( # Modify volume member's permissions -------------------------------------- #' @description Modify volume member's permissions. #' This function modifies the permissions for a member of a specific - #' volume. Note that this does not overwrite all previously set permissions - #' for the member. - #' @param user The Seven Bridges Platform username of the person - #' you want to modify permissions for or object of class Member containing - #' user's username. + #' volume. Note that this does not overwrite all previously set + #' permissions for the member. + #' + #' @param member The Seven Bridges Platform username of the person + #' you want to modify permissions for or team ID or division ID + #' (for Enterprise users only) or object of class Member containing + #' member's ID. #' @param permissions List of specific (or all) permissions you want to #' update for the member of the volume. #' Permissions include listing the contents of a volume, importing files @@ -762,22 +870,22 @@ Volume <- R6::R6Class( #' #' # Modify volume member permissions #' volume_object$modify_member_permissions( - #' user = user, + #' member = member, #' permission = list(read = TRUE, copy = TRUE) #' ) #' } #' #' @return \code{\link{Permission}} object. - modify_member_permissions = function(user, + modify_member_permissions = function(member, permissions = list( read = TRUE, copy = FALSE, write = FALSE, admin = FALSE )) { - username <- check_and_transform_id(user, + username <- check_and_transform_id(member, class_name = "Member", - field_name = "username" + field_name = "id" ) checkmate::assert_list(permissions, null.ok = FALSE, max.len = 4, @@ -915,6 +1023,55 @@ Volume <- R6::R6Class( ... ) } # nocov end + ), + private = list( + # Private general method to add members to a volume ---------------------- + # This is a utility function used in public methods add_member, + # add_member_team and add_member_division that allow users of different + # roles (regular and Enterprise) to add members to the specified volume. + # Users can add regular users, teams or divisions which can be specified + # with 'type' parameter (allowed values are USER, TEAM or DIVISION). + #' @importFrom checkmate assert_string assert_list assert_subset + #' @importFrom glue glue + add_member_general = function(member, + permissions = list( + read = TRUE, + copy = FALSE, + write = FALSE, + admin = FALSE + ), + type) { + checkmate::assert_string(member, null.ok = FALSE) + checkmate::assert_list(permissions, + null.ok = FALSE, len = 4, + types = "logical" + ) + checkmate::assert_subset(names(permissions), + empty.ok = FALSE, + choices = c("read", "copy", "write", "admin") + ) + checkmate::assert_subset(type, + empty.ok = FALSE, + choices = c("USER", "TEAM", "DIVISION") + ) + # nocov start + path <- glue::glue(self$URL[["members"]]) + + body <- list( + username = member, + permissions = permissions, + type = type + ) + + res <- self$auth$api( + path = path, + method = "POST", + body = body, + advance_access = TRUE + ) + + return(res) + } # nocov end ) ) diff --git a/R/class-volumecontent-collection.R b/R/class-volumecontent-collection.R index e4cfd54..e2046d2 100644 --- a/R/class-volumecontent-collection.R +++ b/R/class-volumecontent-collection.R @@ -111,7 +111,7 @@ VolumeContentCollection <- R6::R6Class( # Get next page of results ------------------------------------------------ #' @description Return next page of results. #' - #' @param ... Other arguments or query parameters that can be passed to + #' @param ... Other arguments or query parameters that can be passed to the #' core `api()` function like 'advance_access', 'fields' etc. #' #' @importFrom rlang abort @@ -152,7 +152,7 @@ VolumeContentCollection <- R6::R6Class( }, # nocov end # Get previous page of results -------------------------------------------- - #' @description Return previous page of results. + #' @description Return the previous page of results. #' #' @importFrom rlang abort #' @@ -178,7 +178,7 @@ VolumeContentCollection <- R6::R6Class( # Get all results --------------------------------------------------------- #' @description Fetches all available items. #' - #' @param ... Other arguments or query parameters that can be passed to + #' @param ... Other arguments or query parameters that can be passed to the #' core `api()` function like 'advance_access', 'fields' etc. #' #' @importFrom rlang abort diff --git a/R/utils-validations.R b/R/utils-validations.R index 1231260..832c36f 100644 --- a/R/utils-validations.R +++ b/R/utils-validations.R @@ -46,7 +46,7 @@ status_check <- function(req, as = "parsed", ...) { print(content(req, as = as, ...)) rlang::abort(paste( - "Error of unknown type occured: ", + "Error of unknown type occurred: ", httr::status_code(req) )) @@ -56,7 +56,7 @@ status_check <- function(req, as = "parsed", ...) { # Check if input value is missing -------------------------------------------- #' @description This function checks whether the input #' value is a vector of minimum length 1, with no empty -#' value and no all missing values. +#' value and not all missing values. #' If the input value is not a vector, it checks only if #' the value is set at all (original meaning of 'missing' function) #' in order to be able to use it with other object types. @@ -255,7 +255,7 @@ check_folder_name <- function(name) { rlang::abort("The folder name cannot start with \"__\"") } if (grepl("\\s", name)) { - rlang::abort("The folder name cannot contain spaces in the name.") + rlang::abort("The folder name cannot contain spaces.") } } diff --git a/cran-comments.md b/cran-comments.md index 139d29f..32e2845 100644 --- a/cran-comments.md +++ b/cran-comments.md @@ -1,6 +1,6 @@ ## Comments -#### 2024-07-01 +### 2024-07-01 This is a new release (0.2.0). @@ -13,18 +13,120 @@ It introduces support for bulk actions in the API client library: These changes aim to enhance functionality and maintain compatibility with current R environments. -## Test environments +#### Test environments * Local machine, macOS, R 4.4.0 * devtools:: * check_win_devel() -## R CMD check results +#### R CMD check results 0 errors ✔ | 0 warnings ✔ | 1 note ✖ -* checking installed package size ... NOTE +``` +checking installed package size ... NOTE installed size is 7.8Mb sub-directories of 1Mb or more: R 2.0Mb doc 5.2Mb +``` + +--- + +### 2025-02-24 + +This release (0.3.0) introduces support for asynchronous bulk actions in the API client library: + +* Added new methods for async bulk actions, enabling non-blocking operations on multiple items. +* Introduced `async_bulk_copy()`, `async_bulk_delete()`, and `async_bulk_move()` for bulk file operations. +* Added methods to retrieve details of asynchronous jobs: `async_get_copy_job()`, `async_get_delete_job()`, `async_get_move_job()`, and `async_list_file_jobs()`. +* Updated the `quickstart.Rmd` vignette: + - Replaced the outdated example app for `Auth$apps$copy()`. + - Updated example input files. + - Fixed typos and improved readability. + +#### Test environments + +* Local machine, macOS, R 4.4.0 +* devtools:: + * check_win_devel() + +#### R CMD check results + +0 errors ✔ | 0 warnings ✔ | 1 note ✖ + +``` +checking installed package size ... NOTE + installed size is 7.8Mb + sub-directories of 1Mb or more: + R 2.0Mb + doc 5.2Mb +``` + +There is one more NOTE, but only for `devtools::check_win_devel()`: + +``` +Found the following (possibly) invalid URLs: + URL: https://portal.azure.com/ + From: man/Volumes.Rd + Status: 403 + Message: Forbidden +``` + +- This is a valid URL which passes `urlchecker::url_check()`, but it requires +login access. +- The `Volumes` class and its methods have not been modified in this release. + +--- + +### 2025-03-25 + +This release (0.4.0) introduces support for Enterprise API actions in the API +client library: + +* Added new methods for managing organizational structures, including divisions +and teams, with support for listing, creating, modifying, and removing these +entities. + +* Introduced support for managing volume access with enterprise members by +adding methods for assigning users, teams, and divisions to volumes. + +* Internally refactored volume access logic by introducing a shared method used +across volume member-related operations. + +* Added a new vignette `Enterprise_actions.Rmd` and updated +`Files_upload_and_Volumes.Rmd` to document the new functionality. + +* Performed a package-wide review to fix typos and improve clarity across R +scripts, tests, and vignettes. + +#### Test environments + +* Local machine, macOS, R 4.4.0 +* devtools:: + * check_win_devel() + +#### R CMD check results + +0 errors ✔ | 0 warnings ✔ | 1 note ✖ + +``` +checking installed package size ... NOTE + installed size is 9.1Mb + sub-directories of 1Mb or more: + R 2.0Mb + doc 6.4Mb +``` + +There is one more NOTE, but only for `devtools::check_win_devel()`: + +``` +Found the following (possibly) invalid URLs: + URL: https://portal.azure.com/ + From: man/Volumes.Rd + Status: 403 + Message: Forbidden +``` + +- This is a valid URL which passes `urlchecker::url_check()`, but it is not +accessible without authentication. diff --git a/docker/Dockerfile.CI b/docker/Dockerfile.CI new file mode 100644 index 0000000..1470b51 --- /dev/null +++ b/docker/Dockerfile.CI @@ -0,0 +1,21 @@ +FROM rocker/r-ver:4.4.0 + +# Install system dependencies +RUN apt-get update && apt-get install -y \ + git libssl-dev libcurl4-openssl-dev \ + libfreetype6-dev libfribidi-dev libharfbuzz-dev libxml2-dev \ + libfontconfig1-dev libgit2-dev pandoc libicu-dev libz-dev \ + libjpeg-dev libpng-dev libtiff-dev make zlib1g-dev \ + nodejs npm \ + && rm -rf /var/lib/apt/lists/* + + +COPY renv.lock /renv.lock + +RUN Rscript -e 'install.packages(c("remotes", "devtools", "covr"), repos = "http://cran.r-project.org")' + +RUN Rscript -e 'if (!requireNamespace("renv", quietly = TRUE)) remotes::install_version("renv", version = "1.0.7")' + +RUN Rscript -e 'renv::restore(lockfile = "renv.lock")' + +COPY docker/Dockerfile.CI /opt/Dockerfile diff --git a/inst/WORDLIST b/inst/WORDLIST index e196b27..19ef1e1 100644 --- a/inst/WORDLIST +++ b/inst/WORDLIST @@ -13,6 +13,8 @@ asApp asBillingList asFileList asProjectList +async +AsyncJob attr aut auth @@ -46,6 +48,7 @@ copyOf coverageReportPaths covr cph +cran cre createdBy createdOn @@ -56,8 +59,10 @@ cwlVersion DejaVu DESCRIPTON DescTools +dev devtools df +Dockerfile dockerPull dropdown DRS @@ -124,11 +129,25 @@ knitr LazyData len li +libcurl +libfontconfig +libfreetype +libfribidi +libgit +libharfbuzz +libicu +libjpeg +libpng +libssl +libtiff +libxml +libz licensable Licensor lifecycle Lifecycle linearGradient +lockfile lovegood luna mageddon @@ -147,15 +166,19 @@ nav navbar Neue nocov +nodejs nolint Noto +npm Obucina obucina onwards +openssl OSS outputBinding ovewrite pageable +pandoc param pkgdown pre @@ -164,20 +187,27 @@ projectName purrr px Quickstart +quickstart readr rect +renv +repos reproducibility req +requireNamespace resubmission Resubmission +rf rfranklin rlang rlang's rmarkdown +Rmd RO Roboto Roxygen RoxygenNote +Rscript RW rx sbg @@ -189,6 +219,7 @@ serviceaccount setenv sevenbridges SevenBridges +sgg SHA sjdbGTFfile sonarqube @@ -198,6 +229,7 @@ str stringi stringr subfields +subfolder sublicense subprocess svg @@ -212,12 +244,14 @@ trifunovic Trifunovic UI unmount +unmounting uploader urlencoded vayu VCFtools Velsera velsera +ver Verdana VignetteBuilder vladimir @@ -232,3 +266,4 @@ xlink xmlns yaml yyyy +zlib diff --git a/man/App.Rd b/man/App.Rd index 8c45a85..5924ac2 100644 --- a/man/App.Rd +++ b/man/App.Rd @@ -269,8 +269,7 @@ remember that the project ID should be specified in \code{rfranklin/my-project}, or as \verb{/} depending on the account \cr type.} -\item{\code{name}}{The new name the app will have in the target project. -Optional.} +\item{\code{name}}{The new name for the app in the target project (optional).} \item{\code{strategy}}{The method for copying the app. Supported strategies: \itemize{ @@ -284,8 +283,8 @@ app as the copied app. }} \item{\code{use_revision}}{Parameter specifying which app's revision should be -copied. If set to \code{FALSE} (default), the latest revision of the app will -be copied.} +copied. If set to \code{FALSE} (default), the latest revision of the app +will be copied.} \item{\code{...}}{Other arguments that can be passed to core \code{api()} function like 'fields', etc.} @@ -383,10 +382,10 @@ Create a new app revision. \describe{ \item{\code{raw}}{A list containing a raw CWL for the app revision you are about to create. To generate such a list, you might want to load some -existing JSON / YAML file. In case that your CWL file is in JSON format, -please use the \code{fromJSON} function from the \code{jsonlite} package to -minimize potential problems with parsing the JSON file. If you want to -load a CWL file in YAML format, it is highly recommended to use the +existing JSON / YAML file. In case that your CWL file is in JSON +format, please use the \code{fromJSON} function from the \code{jsonlite} package +to minimize potential problems with parsing the JSON file. If you want +to load a CWL file in YAML format, it is highly recommended to use the \code{read_yaml} function from the \code{yaml} package. Keep in mind that this parameter should not be used together with the \code{file_path} parameter.} @@ -485,9 +484,8 @@ has been copied. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-App-input_matrix}{}}} \subsection{Method \code{input_matrix()}}{ -Get inputs matrix for the app - what are expected inputs -required or not, with their details about the expected types, -descriptions etc. +Get an input matrix for the app, listing expected inputs +(required or optional) along with their types, descriptions, etc. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{App$input_matrix()}\if{html}{\out{
}} } @@ -500,9 +498,8 @@ Data frame. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-App-output_matrix}{}}} \subsection{Method \code{output_matrix()}}{ -Get outputs matrix for the app - what are the expected -outputs of the task running this app, with their details about the -expected types, descriptions etc. +Get an output matrix for the app, listing expected outputs +of tasks that run this app, along with their types, descriptions, etc. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{App$output_matrix()}\if{html}{\out{
}} } @@ -515,11 +512,11 @@ Data frame. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-App-create_task}{}}} \subsection{Method \code{create_task()}}{ -This call creates a new task. You can create either a single -task or a batch task by using the app's default batching, override -batching, or disable batching completely. A parent task is a task that -specifies criteria by which to batch its inputs into a series of further -sub-tasks, called child tasks. The documentation on +This call creates a new task. You can create either a +single task or a batch task by using the app's default batching, +override batching, or disable batching completely. A parent task is a +task that specifies criteria by which to batch its inputs into a series +of further sub-tasks, called child tasks. The documentation on \href{https://docs.sevenbridges.com/docs/about-batch-analyses}{batching tasks} for more details on batching criteria. \subsection{Usage}{ @@ -530,7 +527,7 @@ for more details on batching criteria. description = NULL, execution_settings = NULL, inputs = NULL, - output_location = output_location, + output_location = NULL, batch = NULL, batch_input = NULL, batch_by = NULL, @@ -611,8 +608,8 @@ output node locations within nodes_location. See below for more details. \itemize{ \item \code{main_location} - Defines the output location for all -output nodes in the task. Can be a string path within the project in -which the task is created, for example \cr +output nodes in the task. Can be a string path within the project +in which the task is created, for example \cr \verb{/Analysis/_/} or a path on an attached volume, \cr such as \verb{volumes://volume_name//html}. @@ -620,10 +617,10 @@ Parts of the path enclosed in angle brackets <> are tokens that are dynamically replaced with corresponding values during task execution. \item \code{main_location_alias}: The string location (path) in the -project that will point to the actual location where the outputs are -stored. Used if main_location is defined as a volume path (starting -with volumes://), to provide an easy way of accessing output data -directly from project files. +project that will point to the actual location where the outputs +are stored. Used if main_location is defined as a volume path +(starting with volumes://), to provide an easy way of accessing +output data directly from project files. \item \code{nodes_override}: Enables defining of output locations for output nodes individually through nodes_location (see below). Set to \code{TRUE} to be able to define individual locations per output @@ -648,9 +645,9 @@ Example: ) }\if{html}{\out{}} -\if{html}{\out{
}}\preformatted{ In the example above, b64html is the ID of the output node for which - you want to define the output location, while the parameters are - defined as follows: +\if{html}{\out{
}}\preformatted{ In the example above, b64html is the ID of the output node for + which you want to define the output location, while the parameters + are defined as follows: }\if{html}{\out{
}} \itemize{ diff --git a/man/Apps.Rd b/man/Apps.Rd index ef6af47..573cebb 100644 --- a/man/Apps.Rd +++ b/man/Apps.Rd @@ -2,9 +2,9 @@ % Please edit documentation in R/class-apps.R \name{Apps} \alias{Apps} -\title{R6 Class representing apps endpoint} +\title{R6 Class representing the apps endpoint} \description{ -R6 Class representing apps resource endpoint. +R6 Class representing the apps resource endpoint. } \examples{ @@ -100,7 +100,7 @@ R6 Class representing apps resource endpoint. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Apps-new}{}}} \subsection{Method \code{new()}}{ -Create new Apps resource object. +Create a new Apps resource object. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Apps$new(...)}\if{html}{\out{
}} } @@ -142,9 +142,17 @@ to restrict the results to apps from that project only.} \item{\code{visibility}}{Set this to \code{public} to see all public apps on the Seven Bridges Platform.} -\item{\code{query_terms}}{Enter one or more search terms to query apps. -Read more about how to use the query_terms parameter in our -\href{https://docs.sevenbridges.com/reference/list-all-apps-available-to-you#query-apps}{API documentation}.} +\item{\code{query_terms}}{A list of search terms used to filter apps based on +their details. Each term is case-insensitive and can relate to the +app's name, label, toolkit, toolkit version, category, tagline, or +description. +You can provide a single term (e.g., \code{list("Compressor")}) or multiple +terms (e.g., \code{list("Expression", "Abundance")}) to search for apps +that match all the specified terms. If a term matches any part of the +app's details, the app will be included in the results. +Search terms can also include phrases +(e.g., \code{list("Abundance estimates input")}), which will search for +exact matches within app descriptions or other fields.} \item{\code{id}}{Use this parameter to query apps based on their ID.} @@ -158,10 +166,9 @@ of the first item to return. The default value is \code{0}. This is a pagination-specific attribute.} \item{\code{fields}}{Selector specifying a subset of fields to include in the -response. For querying apps it is set to return all fields except 'raw' -which stores CWL in form of a list. Please be careful when setting to -return all fields, since the execution of this API request could be -time-consuming.} +response. For querying apps, it is set to return all fields except +'raw' which stores CWL as a list. Be cautious when requesting all +fields, as this API request may take a long time to execute.} \item{\code{...}}{Other arguments that can be passed to core \code{api()} function.} } @@ -192,11 +199,10 @@ time-consuming.} \if{latex}{\out{\hypertarget{method-Apps-get}{}}} \subsection{Method \code{get()}}{ This call returns information about the specified app. -The app should be one in a project that you can access; -this could be an app that has been uploaded to the Seven Bridges -Platform by a project member, or a publicly available app that has -been copied to the project. \cr -More about this operation you can find in our +The app must be in a project you can access. It could be an app +uploaded to the Seven Bridges Platform by a project member or a public +app copied into the project. \cr +You can find more details about this operation in our \href{https://docs.sevenbridges.com/reference/get-details-of-an-app}{API documentation}. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Apps$get(id, revision = NULL, ...)}\if{html}{\out{
}} @@ -240,10 +246,10 @@ like 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Apps-copy}{}}} \subsection{Method \code{copy()}}{ -This call copies the specified app to the specified project. -The app should be one in a project that you can access; this could be an -app that has been uploaded to the Seven Bridges Platform by a project -member, or a publicly available app that has been copied to the project. +This call copies the specified app to the specified +project. The app must be in a project you can access. It could be an +app uploaded to the Seven Bridges Platform by a project member or a +public app copied into the project. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Apps$copy( app, @@ -272,7 +278,8 @@ If its name will not change, omit this key.} \itemize{ \item \code{clone} : copy all revisions; get updates from the same app as the copied app (default); -\item \code{direct}: copy latest revision; get updates from the copied app; +\item \code{direct}: copy latest revision; get updates from the copied +app; \item \code{clone_direct}: copy all revisions; get updates from the copied app; \item \code{transient}: copy latest revision; get updates from the same @@ -326,8 +333,9 @@ This call allows you to add an app using raw CWL. \describe{ \item{\code{raw}}{The body of the request should be a CWL app description saved as a \code{JSON} or \code{YAML} file. For a template of this description, try -making the call to get raw CWL for an app about an app already in one of -your projects. Shouldn't be used together with \code{from_path} parameter.} +making the call to get raw CWL for an app about an app already in one +of your projects. Shouldn't be used together with \code{from_path} +parameter.} \item{\code{from_path}}{File containing CWL app description. Shouldn't be used together with raw parameter.} diff --git a/man/AsyncJob.Rd b/man/AsyncJob.Rd new file mode 100644 index 0000000..91d9629 --- /dev/null +++ b/man/AsyncJob.Rd @@ -0,0 +1,183 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class-AsyncJob.R +\name{AsyncJob} +\alias{AsyncJob} +\title{R6 Class representing an AsyncJob} +\description{ +R6 Class representing a resource for managing asynchronous jobs. +} +\examples{ + +## ------------------------------------------------ +## Method `AsyncJob$print` +## ------------------------------------------------ + +\dontrun{ + # x is API response when app is requested + asyncjob_object <- AsyncJob$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + asyncjob_object$print() +} + +## ------------------------------------------------ +## Method `AsyncJob$reload` +## ------------------------------------------------ + +\dontrun{ + # x is API response when AsyncJob is requested + asyncjob_object <- AsyncJob$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + asyncjob_object$reload() +} +} +\section{Super class}{ +\code{\link[sevenbridges2:Item]{sevenbridges2::Item}} -> \code{AsyncJob} +} +\section{Public fields}{ +\if{html}{\out{
}} +\describe{ +\item{\code{id}}{Asynchronous job ID.} + +\item{\code{type}}{The type of job. Can be one of: COPY, DELETE, MOVE.} + +\item{\code{state}}{The following states are available: SUBMITTED, RESOLVING, +RUNNING and FINISHED.} + +\item{\code{result}}{The result of the job.} + +\item{\code{total_files}}{The total number of files that were processed for +the job.} + +\item{\code{completed_files}}{The number of files that were successfully +completed.} + +\item{\code{failed_files}}{The number of files that failed.} + +\item{\code{started_on}}{The time and date the job started.} + +\item{\code{finished_on}}{The time and date the job finished.} +} +\if{html}{\out{
}} +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-AsyncJob-new}{\code{AsyncJob$new()}} +\item \href{#method-AsyncJob-print}{\code{AsyncJob$print()}} +\item \href{#method-AsyncJob-reload}{\code{AsyncJob$reload()}} +\item \href{#method-AsyncJob-clone}{\code{AsyncJob$clone()}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-AsyncJob-new}{}}} +\subsection{Method \code{new()}}{ +Create a new AsyncJob object. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{AsyncJob$new(res = NA, ...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{res}}{Response containing AsyncJob object information.} + +\item{\code{...}}{Other response arguments.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A new \code{AsyncJob} object. +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-AsyncJob-print}{}}} +\subsection{Method \code{print()}}{ +Print method for AsyncJob class. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{AsyncJob$print()}\if{html}{\out{
}} +} + +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # x is API response when app is requested + asyncjob_object <- AsyncJob$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + asyncjob_object$print() +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-AsyncJob-reload}{}}} +\subsection{Method \code{reload()}}{ +Reloads AsyncJob object information. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{AsyncJob$reload(...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{...}}{Other arguments that can be passed to core \code{api()} function +like 'fields', etc.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{\link{AsyncJob}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # x is API response when AsyncJob is requested + asyncjob_object <- AsyncJob$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + asyncjob_object$reload() +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-AsyncJob-clone}{}}} +\subsection{Method \code{clone()}}{ +The objects of this class are cloneable with this method. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{AsyncJob$clone(deep = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{deep}}{Whether to make a deep clone.} +} +\if{html}{\out{
}} +} +} +} diff --git a/man/Auth.Rd b/man/Auth.Rd index 388eda4..5adfce1 100644 --- a/man/Auth.Rd +++ b/man/Auth.Rd @@ -4,7 +4,7 @@ \alias{Auth} \title{R6 Class Representing Authentication Object} \description{ -Authentication object with methods to access API endpoints. +Authentication object with methods for accessing API endpoints. Every object could be requested from this Auth object and any action could start from this object using cascading style. Please check \code{vignette("Authentication_and_Billing", package = "sevenbridges2")} @@ -187,7 +187,8 @@ the auth token.} \item{\code{profile_name}}{Profile name in the user configuration file.} -\item{\code{fs}}{FS (FileSystem) object, for mount and unmount file system.} +\item{\code{fs}}{FS (FileSystem) object, for mounting and unmounting the file +system.} \item{\code{authorization}}{Is the \code{token} an API authentication token (\code{FALSE}) or an access token from the @@ -204,7 +205,7 @@ platform.} \item{\code{volumes}}{Volumes object, for accessing volumes resources on the platform.} -\item{\code{tasks}}{Tasks object, for accessing volumes resources on the +\item{\code{tasks}}{Tasks object, for accessing tasks resources on the platform.} \item{\code{imports}}{Storage imports object, for accessing volume imports @@ -216,8 +217,14 @@ resources on the platform.} \item{\code{invoices}}{Invoices object, for accessing invoice resources on the platform.} -\item{\code{billing_groups}}{Billing_groups object, for accessing billing groups -resources on the platform.} +\item{\code{billing_groups}}{Billing_groups object, for accessing billing +groups resources on the platform.} + +\item{\code{divisions}}{Divisions object, for accessing divisions resources on +the platform.} + +\item{\code{teams}}{Teams object, for accessing teams resources on +the platform.} } \if{html}{\out{
}} } @@ -270,7 +277,7 @@ directly, Default is \code{"direct"}.} \item{\code{platform}}{The platform to use. -If \code{platform} and \code{url} are both not specified, +If neither \code{platform} nor \code{url} is specified the default is \code{"aws-us"} (Seven Bridges Platform - US). Other possible values include: \itemize{ @@ -283,7 +290,7 @@ Other possible values include: \item{\code{url}}{Base URL for API. Please only use this when you want to specify a platform that is not in the \code{platform} list -above, and also leaving \code{platform} unspecified.} +above, while leaving \code{platform} unspecified.} \item{\code{token}}{API authentication token or \code{access_token} for Seven Bridges single sign-on. Authentication token uniquely identifies @@ -393,8 +400,8 @@ pass arguments to core \code{api()} function. \code{query} parameters or full \code{url} to some resource.} \item{\code{limit}}{The maximum number of collection items to return for a -single request. Minimum value is \code{1}. The maximum value is \code{100} and the -default value is \code{50}. +single request. Minimum value is \code{1}. The maximum value is \code{100} and +the default value is \code{50}. This is a pagination-specific attribute.} \item{\code{offset}}{The zero-based starting index in the entire collection of @@ -476,9 +483,9 @@ authenticated user will be returned.} \if{latex}{\out{\hypertarget{method-Auth-rate_limit}{}}} \subsection{Method \code{rate_limit()}}{ Get information about current rate limit. \cr \cr -This call returns information about your current rate limit. This is the -number of API calls you can make in one hour. This call also returns -information about your current instance limit. +This call returns information about your current rate limit. This is +the number of API calls you can make in one hour. This call also +returns information about your current instance limit. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Auth$rate_limit()}\if{html}{\out{
}} } @@ -538,8 +545,8 @@ specified Platform folder, within the project to which the folder belongs. If project is used, the call will upload the file to the root of the project's files.} -\item{\code{filename}}{Optional new file name. By default the uploaded file will -have the same name as the original file provided with the \code{path} +\item{\code{filename}}{Optional new file name. By default the uploaded file +will have the same name as the original file provided with the \code{path} parameter. If its name will not change, omit this key.} \item{\code{overwrite}}{In case there is already a file with the same name in @@ -549,9 +556,9 @@ If overwrite is set to \code{TRUE} and a file already exists under the name specified in the request, the existing file will be deleted and a new one created in its place.} -\item{\code{part_size}}{The preferred size for upload parts in bytes. If omitted -or set to a value that is incompatible with the cloud storage provider, -a default value will be used.} +\item{\code{part_size}}{The preferred size for upload parts in bytes. If +omitted or set to a value that is incompatible with the cloud storage +provider, a default value will be used.} \item{\code{init}}{If \code{TRUE}, the method will initialize and return the Upload object and stop. If \code{FALSE}, the method will return the Upload object @@ -649,8 +656,9 @@ to abort.} \if{latex}{\out{\hypertarget{method-Auth-send_feedback}{}}} \subsection{Method \code{send_feedback()}}{ Send feedback to Seven Bridges. \cr \cr -Send feedback on ideas, thoughts, and problems via the sevenbridges2 API -package with three available types: \code{idea}, \code{thought}, and \code{problem}. +Send feedback on ideas, thoughts, and problems via the sevenbridges2 +API package with three available types: \code{idea}, \code{thought}, and +\code{problem}. You can send one feedback item per minute. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Auth$send_feedback( diff --git a/man/Billing.Rd b/man/Billing.Rd index 1e9da13..a42b05c 100644 --- a/man/Billing.Rd +++ b/man/Billing.Rd @@ -7,7 +7,7 @@ R6 Class representing a central resource for managing billing groups. } \details{ -This is main object for Billing +This is the main object for Billing } \examples{ @@ -115,7 +115,7 @@ This is main object for Billing \item{\code{name}}{Billing group name.} -\item{\code{type}}{Billing group type} +\item{\code{type}}{Billing group type.} \item{\code{pending}}{Billing group approval status.} @@ -160,7 +160,7 @@ Create a new Billing object. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Billing-print}{}}} \subsection{Method \code{print()}}{ -Print billing group information as a bullet list. +Prints billing group information as a bullet list. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Billing$print()}\if{html}{\out{
}} } @@ -231,7 +231,8 @@ like 'limit', 'offset', 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Billing-analysis_breakdown}{}}} \subsection{Method \code{analysis_breakdown()}}{ -Method for getting a analysis breakdown for a billing group. +Method for getting an analysis breakdown for a billing +group. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Billing$analysis_breakdown( date_from = NULL, diff --git a/man/Billing_groups.Rd b/man/Billing_groups.Rd index 6a60cfd..c0f6965 100644 --- a/man/Billing_groups.Rd +++ b/man/Billing_groups.Rd @@ -134,7 +134,7 @@ like query parameters, 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Billing_groups-get}{}}} \subsection{Method \code{get()}}{ -Retrieve a single billing group, specified by its id. +Retrieve a single billing group, specified by its ID. To find the \code{billing_group}, use the call \code{Billing_groups$query()} to list all your billing groups. The information returned includes the billing group owner, the total balance, and the status of diff --git a/man/Collection.Rd b/man/Collection.Rd index 0e834cc..d237506 100644 --- a/man/Collection.Rd +++ b/man/Collection.Rd @@ -5,7 +5,7 @@ \title{R6 Class representing a Collection of objects} \description{ R6 Class representing a resource for managing collections. -Wrapper for Seven Bridges pageable resources. +A wrapper for Seven Bridges pageable resources. Among the actual collection items it contains information regarding the total number of entries available on the server and resource API request URL (href). @@ -199,7 +199,7 @@ Print method for Collection class. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Collection-next_page}{}}} \subsection{Method \code{next_page()}}{ -Return next page of results. +Returns the next page of results. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Collection$next_page(...)}\if{html}{\out{
}} } @@ -239,7 +239,7 @@ like 'advanced_access', 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Collection-prev_page}{}}} \subsection{Method \code{prev_page()}}{ -Return previous page of results. +Returns the previous page of results. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Collection$prev_page(...)}\if{html}{\out{
}} } diff --git a/man/Division.Rd b/man/Division.Rd new file mode 100644 index 0000000..3e51bce --- /dev/null +++ b/man/Division.Rd @@ -0,0 +1,365 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class-division.R +\name{Division} +\alias{Division} +\title{R6 Class representing a Division} +\description{ +R6 Class representing a central resource for managing divisions. +} +\examples{ + +## ------------------------------------------------ +## Method `Division$print` +## ------------------------------------------------ + +\dontrun{ + division_object <- Division$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + division_object$print() +} + +## ------------------------------------------------ +## Method `Division$reload` +## ------------------------------------------------ + +\dontrun{ + division_object <- Division$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + division_object$reload() +} + + +## ------------------------------------------------ +## Method `Division$list_teams` +## ------------------------------------------------ + +\dontrun{ + # Get details of a specific division + division_obj <- a$divisions$get(id = "division-id") + + # Retrieve a list of division teams you are a member of + division_obj$list_teams() + + # Retrieve a list of all teams within the division regardless of + # whether you are a member of a team or not + division_obj$list_teams(list_all = TRUE) +} + + +## ------------------------------------------------ +## Method `Division$list_members` +## ------------------------------------------------ + +\dontrun{ + # Get details of a specific division + division_obj <- a$divisions$get(id = "division-id") + + # Retrieve a list of all division members + division_obj$list_members() + + # Or filter members by role. The following roles are supported: + # "MEMBER", "ADMIN", and "EXTERNAL_COLLABORATOR" + division_obj$list_members(role = "ADMIN") +} + + +## ------------------------------------------------ +## Method `Division$remove_member` +## ------------------------------------------------ + +\dontrun{ + # Retrieve details of a specific division + division_obj <- a$divisions$get(id = "division-id") + + # Remove a member using their username + division_obj$remove_member(user = "division-name/username") + + # Remove a member using a User object + members <- division_obj$list_members(role = "MEMBER") + member_to_remove <- members$items[[1]] + division_obj$remove_member(user = member_to_remove) +} +} +\section{Super class}{ +\code{\link[sevenbridges2:Item]{sevenbridges2::Item}} -> \code{Division} +} +\section{Public fields}{ +\if{html}{\out{
}} +\describe{ +\item{\code{URL}}{List of URL endpoints for this resource.} + +\item{\code{id}}{The ID of the division.} + +\item{\code{name}}{Division's name.} +} +\if{html}{\out{
}} +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-Division-new}{\code{Division$new()}} +\item \href{#method-Division-print}{\code{Division$print()}} +\item \href{#method-Division-reload}{\code{Division$reload()}} +\item \href{#method-Division-list_teams}{\code{Division$list_teams()}} +\item \href{#method-Division-list_members}{\code{Division$list_members()}} +\item \href{#method-Division-remove_member}{\code{Division$remove_member()}} +\item \href{#method-Division-clone}{\code{Division$clone()}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Division-new}{}}} +\subsection{Method \code{new()}}{ +Create a new Division object. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Division$new(res = NA, ...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{res}}{Response containing the Division object information.} + +\item{\code{...}}{Other response arguments.} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Division-print}{}}} +\subsection{Method \code{print()}}{ +Print method for Division class. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Division$print()}\if{html}{\out{
}} +} + +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + division_object <- Division$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + division_object$print() +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Division-reload}{}}} +\subsection{Method \code{reload()}}{ +Reload Division object information. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Division$reload(...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{...}}{Other arguments that can be passed to core \code{api()} function +like 'fields', etc. + +@importFrom rlang inform} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{\link{Division}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + division_object <- Division$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + division_object$reload() +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Division-list_teams}{}}} +\subsection{Method \code{list_teams()}}{ +This call retrieves a list of all teams in a division that +you are a member of. Each team's ID and name will be returned. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Division$list_teams(list_all = FALSE, ...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{list_all}}{Boolean. Set this field to \code{TRUE} if you want to list +all teams within the division (regardless of whether you are a member +of a team or not). Default value is \code{FALSE}.} + +\item{\code{...}}{Other arguments that can be passed to core \code{api()} function +like 'fields', etc.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \code{\link{Collection}} of \code{\link{Team}} objects. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Get details of a specific division + division_obj <- a$divisions$get(id = "division-id") + + # Retrieve a list of division teams you are a member of + division_obj$list_teams() + + # Retrieve a list of all teams within the division regardless of + # whether you are a member of a team or not + division_obj$list_teams(list_all = TRUE) +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Division-list_members}{}}} +\subsection{Method \code{list_members()}}{ +This call retrieves a list of all members of a division. In +addition, you can list members with a specific role, e.g. all +administrators within a division. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Division$list_members( + role = NULL, + limit = getOption("sevenbridges2")$limit, + offset = getOption("sevenbridges2")$offset, + ... +)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{role}}{Filter members by role. Supported roles are \code{ADMIN}, +\code{MEMBER}, and \code{EXTERNAL_COLLABORATOR}. If \code{NULL} (default), members of +all roles will be retrieved.} + +\item{\code{limit}}{The maximum number of collection items to return +for a single request. Minimum value is \code{1}. +The maximum value is \code{100} and the default value is \code{50}. +This is a pagination-specific attribute.} + +\item{\code{offset}}{The zero-based starting index in the entire collection +of the first item to return. The default value is \code{0}. +This is a pagination-specific attribute.} + +\item{\code{...}}{Other arguments that can be passed to core \code{api()} function +like other query parameters or 'fields', etc.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \code{\link{Collection}} of \code{\link{User}} objects. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Get details of a specific division + division_obj <- a$divisions$get(id = "division-id") + + # Retrieve a list of all division members + division_obj$list_members() + + # Or filter members by role. The following roles are supported: + # "MEMBER", "ADMIN", and "EXTERNAL_COLLABORATOR" + division_obj$list_members(role = "ADMIN") +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Division-remove_member}{}}} +\subsection{Method \code{remove_member()}}{ +Removes a specified user from a division. This action +revokes the user's membership in the division but does not delete their +Platform account. Note that only users with the \code{ADMIN} role in the +division can perform this action. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Division$remove_member(user)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{user}}{The Seven Bridges Platform username of the user to be +removed, specified in the format \code{division-name/username}, or an object +of class \code{User} that contains the username.} +} +\if{html}{\out{
}} +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Retrieve details of a specific division + division_obj <- a$divisions$get(id = "division-id") + + # Remove a member using their username + division_obj$remove_member(user = "division-name/username") + + # Remove a member using a User object + members <- division_obj$list_members(role = "MEMBER") + member_to_remove <- members$items[[1]] + division_obj$remove_member(user = member_to_remove) +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Division-clone}{}}} +\subsection{Method \code{clone()}}{ +The objects of this class are cloneable with this method. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Division$clone(deep = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{deep}}{Whether to make a deep clone.} +} +\if{html}{\out{
}} +} +} +} diff --git a/man/Divisions.Rd b/man/Divisions.Rd new file mode 100644 index 0000000..6c3eb79 --- /dev/null +++ b/man/Divisions.Rd @@ -0,0 +1,150 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class-divisions.R +\name{Divisions} +\alias{Divisions} +\title{R6 Class representing divisions endpoints.} +\description{ +R6 Class representing Divisions resource. +} +\examples{ + +## ------------------------------------------------ +## Method `Divisions$query` +## ------------------------------------------------ + +\dontrun{ + # Retrieve a list of all divisions you are a member of + a$Divisions$query() +} + +## ------------------------------------------------ +## Method `Divisions$get` +## ------------------------------------------------ + +\dontrun{ + # Retrieve details of a specified division + a$Divisions$get(id = "division-id") +} +} +\section{Super class}{ +\code{\link[sevenbridges2:Resource]{sevenbridges2::Resource}} -> \code{Divisions} +} +\section{Public fields}{ +\if{html}{\out{
}} +\describe{ +\item{\code{URL}}{List of URL endpoints for this resource.} +} +\if{html}{\out{
}} +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-Divisions-new}{\code{Divisions$new()}} +\item \href{#method-Divisions-query}{\code{Divisions$query()}} +\item \href{#method-Divisions-get}{\code{Divisions$get()}} +\item \href{#method-Divisions-clone}{\code{Divisions$clone()}} +} +} +\if{html}{\out{ +
Inherited methods + +
+}} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Divisions-new}{}}} +\subsection{Method \code{new()}}{ +Create new Divisions resource object. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Divisions$new(...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{...}}{Other response arguments.} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Divisions-query}{}}} +\subsection{Method \code{query()}}{ +This call retrieves a list of all divisions you are a +member of. Each division's ID, name and URL on platform will be +returned. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Divisions$query()}\if{html}{\out{
}} +} + +\subsection{Returns}{ +A \code{\link{Collection}} of \code{\link{Division}} objects. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Retrieve a list of all divisions you are a member of + a$Divisions$query() +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Divisions-get}{}}} +\subsection{Method \code{get()}}{ +This call returns the details of a specified division. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Divisions$get(id, ...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{id}}{The ID of the division you are querying. The function +also accepts a Division object and extracts the ID.} + +\item{\code{...}}{Other arguments that can be passed to core \code{api()} function +like 'fields', etc.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{\link{Division}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Retrieve details of a specified division + a$Divisions$get(id = "division-id") +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Divisions-clone}{}}} +\subsection{Method \code{clone()}}{ +The objects of this class are cloneable with this method. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Divisions$clone(deep = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{deep}}{Whether to make a deep clone.} +} +\if{html}{\out{
}} +} +} +} diff --git a/man/Export.Rd b/man/Export.Rd index 6d93f2c..aa8969b 100644 --- a/man/Export.Rd +++ b/man/Export.Rd @@ -62,15 +62,15 @@ export_object <- Export$new( \item \code{FAILED}: the export has failed. }} -\item{\code{source}}{List containing source file id that is being exported to -the volume.} +\item{\code{source}}{List containing the source file ID that is being exported +to the volume.} -\item{\code{destination}}{List containing destination volume id and location -(file name) on the volume where the file is being exported.} +\item{\code{destination}}{List containing the destination volume ID and +location (file name) on the volume where the file is being exported.} -\item{\code{overwrite}}{Whether the exported file name was -overwritten or not, if another one with the same name had already -existed on the volume.} +\item{\code{overwrite}}{Indicates whether the exported file name was +overwritten if another file with the same name already existed on the +volume.} \item{\code{started_on}}{Time when the export job started.} @@ -147,7 +147,7 @@ export_object <- Export$new( \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Export-reload}{}}} \subsection{Method \code{reload()}}{ -Reload Export object information. +Refresh the Export object with updated information. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Export$reload(...)}\if{html}{\out{
}} } diff --git a/man/Exports.Rd b/man/Exports.Rd index 5a6b4b4..b0b8260 100644 --- a/man/Exports.Rd +++ b/man/Exports.Rd @@ -149,7 +149,7 @@ Create a new Exports object. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Exports-query}{}}} \subsection{Method \code{query()}}{ -This call lists export jobs initiated by particular user. +This call lists export jobs initiated by a particular user. Note that when you export a file from a project on the Platform into a volume, you write to your cloud storage bucket. \subsection{Usage}{ @@ -258,9 +258,10 @@ like 'fields', etc.} \if{latex}{\out{\hypertarget{method-Exports-submit_export}{}}} \subsection{Method \code{submit_export()}}{ This call lets you queue a job to export a file from a -project on the Platform into a volume. The file selected for export must -not be a public file or an alias. Aliases are objects stored in your -cloud storage bucket which have been made available on the Platform. +project on the Platform into a volume. The file selected for export +must not be a public file or an alias. Aliases are objects stored in +your cloud storage bucket which have been made available on the +Platform. The volume you are exporting to must be configured for read-write access. To do this, set the \code{access_mode} parameter to \code{RW} when creating or modifying a volume. \cr @@ -311,8 +312,8 @@ been configured with a prefix parameter, the value of prefix will be prepended to location before attempting to create the file on the volume. -If you would like to export the file into some folder on the volume, -please add folder name as prefix before file name in form +If you would like to export the file into a folder on the volume, +please add the folder name as a prefix before the file name in the form \verb{/}.} \item{\code{overwrite}}{Set to \code{TRUE} if you want to overwrite the item @@ -327,7 +328,7 @@ source file will remain on the Platform.} exporting to this bucket. Supported values: \code{AES256} (SSE-S3 encryption), \code{aws:kms}, \code{null} (no server-side encryption). Default: \code{AES256}. -\item \code{sse_aws_kms_key_id}: Applies to type: \code{s3}. +\item \code{sse_aws_kms_key_Id}: Applies to type: \code{s3}. If AWS KMS encryption is used, this should be set to the required KMS key. If not set and \code{aws:kms} is set as \code{sse_algorithm}, default KMS key is used. @@ -370,7 +371,7 @@ like 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Exports-delete}{}}} \subsection{Method \code{delete()}}{ -Deleting export jobs is not possible. +Export jobs cannot be deleted. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Exports$delete()}\if{html}{\out{
}} } @@ -476,7 +477,7 @@ like: exporting to this bucket. Supported values: \code{AES256} (SSE-S3 encryption), \code{aws:kms}, \code{null} (no server-side encryption). Default: \code{AES256}. -\item \code{sse_aws_kms_key_id}: Applies to type: \code{s3}. +\item \code{sse_aws_kms_key_Id}: Applies to type: \code{s3}. If AWS KMS encryption is used, this should be set to the required KMS key. If not set and \code{aws:kms} is set as \code{sse_algorithm}, default KMS key is used. diff --git a/man/File.Rd b/man/File.Rd index dd64dfa..7d5b12e 100644 --- a/man/File.Rd +++ b/man/File.Rd @@ -289,7 +289,7 @@ file_object <- File$new( \item{\code{tags}}{List of tags associated with the file.} -\item{\code{metadata}}{List for metadata associated with the file.} +\item{\code{metadata}}{List of metadata associated with the file.} \item{\code{url}}{File download URL.} @@ -297,7 +297,8 @@ file_object <- File$new( \item{\code{type}}{This can be of type \code{file} or \code{folder}.} -\item{\code{secondary_files}}{Secondary files linked to the file if exist.} +\item{\code{secondary_files}}{Secondary files linked to the file, if they +exist.} } \if{html}{\out{
}} } @@ -464,9 +465,8 @@ file_object <- File$new( \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-File-update}{}}} \subsection{Method \code{update()}}{ -Updates the name, the full set metadata, and tags +Updates the name, the full set of metadata, and tags for a specified file. -. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{File$update(name = NULL, metadata = NULL, tags = NULL, ...)}\if{html}{\out{
}} } @@ -477,8 +477,8 @@ for a specified file. \item{\code{name}}{The new name of the file.} \item{\code{metadata}}{The metadata fields and their values that you want to -update. This is a named list of key-value pairs. The keys and values are -strings.} +update. This is a named list of key-value pairs. The keys and values +are strings.} \item{\code{tags}}{The tags you want to update, represented as unnamed list of values to add as tags.} @@ -708,8 +708,8 @@ More details about how to modify metadata, you can find in the \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{metadata_fields}}{Enter a list of key-value pairs of metadata fields -and metadata values.} +\item{\code{metadata_fields}}{Enter a list of key-value pairs of metadata +fields and metadata values.} \item{\code{overwrite}}{Set to \code{TRUE} if you want to overwrite existing tags. Default: \code{FALSE}.} @@ -873,7 +873,7 @@ file_object <- File$new( \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-File-download}{}}} \subsection{Method \code{download()}}{ -Download method for File objects. It allows download a +Download method for File objects. It allows downloading a platform file to your local computer. To specify the destination for your download, you should provide the path to the destination directory as \code{directory_path} parameter. @@ -930,9 +930,10 @@ file_object <- File$new( \if{latex}{\out{\hypertarget{method-File-submit_export}{}}} \subsection{Method \code{submit_export()}}{ This call lets you queue a job to export this file from a -project on the Platform into a volume. The file selected for export must -not be a public file or an alias. Aliases are objects stored in your -cloud storage bucket which have been made available on the Platform. +project on the Platform into a volume. The file selected for export +must not be a public file or an alias. Aliases are objects stored in +your cloud storage bucket which have been made available on the +Platform. The volume you are exporting to must be configured for read-write access. To do this, set the \code{access_mode} parameter to \code{RW} when creating or modifying a volume. \cr @@ -983,7 +984,7 @@ If you would like to export the file into some folder on the volume, please add folder name as prefix before file name in form \verb{/}.} -\item{\code{overwrite}}{Set to \code{TRUE} of you want to overwrite the item that +\item{\code{overwrite}}{Set to \code{TRUE} if you want to overwrite the item that already exists at the destination. Default: \code{FALSE}.} \item{\code{copy_only}}{If \code{TRUE}, file will be copied to a volume but @@ -995,7 +996,7 @@ source file will remain on the Platform.} exporting to this bucket. Supported values: \code{AES256} (SSE-S3 encryption), \code{aws:kms}, \code{null} (no server-side encryption). Default: \code{AES256}. -\item \code{sse_aws_kms_key_id}: Applies to type: \code{s3}. +\item \code{sse_aws_kms_key_Id}: Applies to type: \code{s3}. If AWS KMS encryption is used, this should be set to the required KMS key. If not set and \code{aws:kms} is set as \code{sse_algorithm}, default KMS key is used. diff --git a/man/Files.Rd b/man/Files.Rd index ba0a039..97bfd0e 100644 --- a/man/Files.Rd +++ b/man/Files.Rd @@ -74,7 +74,6 @@ R6 Class representing Files resource. } - ## ------------------------------------------------ ## Method `Files$bulk_delete` ## ------------------------------------------------ @@ -90,7 +89,6 @@ R6 Class representing Files resource. } - ## ------------------------------------------------ ## Method `Files$bulk_get` ## ------------------------------------------------ @@ -103,7 +101,6 @@ R6 Class representing Files resource. } - ## ------------------------------------------------ ## Method `Files$bulk_update` ## ------------------------------------------------ @@ -116,7 +113,6 @@ R6 Class representing Files resource. } - ## ------------------------------------------------ ## Method `Files$bulk_edit` ## ------------------------------------------------ @@ -128,6 +124,112 @@ R6 Class representing Files resource. ) } + +## ------------------------------------------------ +## Method `Files$async_bulk_copy` +## ------------------------------------------------ + +\dontrun{ + # Copy multiple files + a$files$async_bulk_copy( + items = list( + list( + file = '', + parent = '' + ), + list( + file = '', + project = '', + name = 'copied_file.txt' + ), + list( + file = '', + parent = '', + name = 'copied_file2.txt' + ) + ) + ) +} + + +## ------------------------------------------------ +## Method `Files$async_bulk_delete` +## ------------------------------------------------ + +\dontrun{ + # Delete multiple files + a$files$async_bulk_delete( + items = list(file_obj1, file_obj2, "", "") + ) +} + + +## ------------------------------------------------ +## Method `Files$async_bulk_move` +## ------------------------------------------------ + +\dontrun{ + # Move multiple files + a$files$async_bulk_move( + items = list( + list( + file = '', + parent = '' + ), + list( + file = '', + project = '', + name = 'moved_file.txt' + ), + list( + file = '', + parent = '', + name = 'moved_file2.txt' + ) + ) + ) +} + + +## ------------------------------------------------ +## Method `Files$async_get_copy_job` +## ------------------------------------------------ + +\dontrun{ + # Get details of an async copy job + a$files$async_get_copy_job(job_id = "job-id") +} + + +## ------------------------------------------------ +## Method `Files$async_get_delete_job` +## ------------------------------------------------ + +\dontrun{ + # Get details of an async delete job + a$files$async_get_delete_job(job_id = "job-id") +} + + +## ------------------------------------------------ +## Method `Files$async_get_move_job` +## ------------------------------------------------ + +\dontrun{ + # Get details of an async move job + a$files$async_get_move_job(job_id = "job-id") +} + + +## ------------------------------------------------ +## Method `Files$async_list_file_jobs` +## ------------------------------------------------ + +\dontrun{ + # Get details of the first 5 async jobs + a$files$async_list_file_jobs(limit = 5) +} + } \section{Super class}{ \code{\link[sevenbridges2:Resource]{sevenbridges2::Resource}} -> \code{Files} @@ -152,6 +254,13 @@ R6 Class representing Files resource. \item \href{#method-Files-bulk_get}{\code{Files$bulk_get()}} \item \href{#method-Files-bulk_update}{\code{Files$bulk_update()}} \item \href{#method-Files-bulk_edit}{\code{Files$bulk_edit()}} +\item \href{#method-Files-async_bulk_copy}{\code{Files$async_bulk_copy()}} +\item \href{#method-Files-async_bulk_delete}{\code{Files$async_bulk_delete()}} +\item \href{#method-Files-async_bulk_move}{\code{Files$async_bulk_move()}} +\item \href{#method-Files-async_get_copy_job}{\code{Files$async_get_copy_job()}} +\item \href{#method-Files-async_get_delete_job}{\code{Files$async_get_delete_job()}} +\item \href{#method-Files-async_get_move_job}{\code{Files$async_get_move_job()}} +\item \href{#method-Files-async_list_file_jobs}{\code{Files$async_list_file_jobs()}} \item \href{#method-Files-clone}{\code{Files$clone()}} } } @@ -187,7 +296,7 @@ specified project or directory within a project, but not the contents of the subdirectories. \cr To list the contents of a subdirectory, make a new call and specify the subdirectory ID as the \code{parent} parameter. \cr -More information you can find in our +For more details, see our \href{https://docs.sevenbridges.com/reference/list-files-primary-method}{API documentation}. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Files$query( @@ -232,9 +341,11 @@ multiple instances of the same metadata field.} \item{\code{origin}}{Task object. List only files produced by task.} -\item{\code{tag}}{List files containing this tag. Note that the tag must be an -exact complete string for the results to match. Multiple tags can be -represented by vector of values.} +\item{\code{tag}}{Filters the files based on the specified tag(s). Each tag +must be an exact, complete match, for the results to match. Tags may +include spaces. Multiple tags should be provided as a vector of +strings. The method will return files that have any of the specified +tags.} \item{\code{limit}}{The maximum number of collection items to return for a single request. Minimum value is \code{1}. @@ -353,7 +464,7 @@ Copy file/files to the specified project. This call allows you to copy files between projects. Unlike the call to copy a file between projects, this call lets you batch the copy operation and copy a list of files at a time. \cr -More information you may find +More information can be found here \href{https://docs.sevenbridges.com/reference/copy-files-between-projects}{here}. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Files$copy(files, destination_project)}\if{html}{\out{
}} @@ -426,7 +537,6 @@ object which must be of type \code{FOLDER}.} ) } - } \if{html}{\out{
}} @@ -468,7 +578,6 @@ the console. a$files$bulk_delete(files = list(File_Object_1, File_Object_2)) } - } \if{html}{\out{
}} @@ -506,7 +615,6 @@ can retrieve the details for per call is 100. ) } - } \if{html}{\out{
}} @@ -561,7 +669,6 @@ The maximum number of files you can update the details for per call is ) } - } \if{html}{\out{
}} @@ -621,6 +728,409 @@ The maximum number of files you can update the details for per call is } +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Files-async_bulk_copy}{}}} +\subsection{Method \code{async_bulk_copy()}}{ +This call lets you perform a bulk copy of files and +folders. Any underlying folder structure will be preserved. +You can copy: +\itemize{ +\item to a folder within the same project, +\item to another project, +\item to a folder in another project. +} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Files$async_bulk_copy(items)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{items}}{Nested list of elements containing information about each +file/folder to be copied. For each element, you must provide: + +\itemize{ +\item \code{file} - The ID of the file or folder you are copying. +Copying the project root folder is not allowed. +Use the API call for listing all files to obtain the ID. +\item \code{parent} - The ID of the folder you are copying files to. +It should not be used together with \code{project}. If \code{project} is +used, the items will be imported to the root of the project +files. If \code{parent} is used, the import will take place into the +specified folder, within the project to which the folder belongs. +\item \code{project} - The project you are copying the file to. +It should not be used together with \code{parent}. If \code{parent} is +used, the import will take place into the specified folder, +within the project to which the folder belongs. If \code{project} is +used, the items will be imported to the root of the project +files. +\item \code{name} - Enter the new name for the file if you want to +rename it in the destination folder. +} +Example of the list: + +\if{html}{\out{
}}\preformatted{items <- list( + list( + file = '', + parent = '' + ), + list( + file = '', + project = '', + name = 'copied_file.txt' + ), + list( + file = '', + parent = '', + name = 'copied_file2.txt' + ) + ) +}\if{html}{\out{
}} + +Read more on how to \href{https://docs.sevenbridges.com/reference/copy-multiple-files}{perform async copy action on multiple files}.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{\link{AsyncJob}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Copy multiple files + a$files$async_bulk_copy( + items = list( + list( + file = '', + parent = '' + ), + list( + file = '', + project = '', + name = 'copied_file.txt' + ), + list( + file = '', + parent = '', + name = 'copied_file2.txt' + ) + ) + ) +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Files-async_bulk_delete}{}}} +\subsection{Method \code{async_bulk_delete()}}{ +This call lets you perform an asynchronous bulk +deletion of files or folders. Deleting folders which aren't empty is +allowed. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Files$async_bulk_delete(items)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{items}}{List of File objects (both \code{file} or \code{folder} type) or list +of IDs of files/folders you want to delete. +Read more on how to \href{https://docs.sevenbridges.com/reference/delete-multiple-files-and-folders}{perform async delete action on multiple files}.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{\link{AsyncJob}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Delete multiple files + a$files$async_bulk_delete( + items = list(file_obj1, file_obj2, "", "") + ) +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Files-async_bulk_move}{}}} +\subsection{Method \code{async_bulk_move()}}{ +This call lets you perform a bulk move operation of files +and folders. +You can move: +\itemize{ +\item to a root project folder, +\item to a subfolder within the same project or a different +project. +} +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Files$async_bulk_move(items)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{items}}{Nested list of elements containing information about each +file/folder to be moved. For each element, you must provide: + +\itemize{ +\item \code{file} - The ID of the file or folder you are moving. Use the +API call for listing all files or folders to obtain the ID. +\item \code{parent} - The ID of the folder you are moving the files to, +which should not be used along with \code{project}. If \code{project} is +used, the items will be imported to the root of the project files. +If \code{parent} is used, the import will take place into the +specified folder, within the project to which the folder belongs. +\item \code{project} - The project you are moving the files to. It +should not be used together with \code{parent}. If \code{parent} is used, +the import will take place into the specified folder, within the +project to which the folder belongs. If \code{project} is used, the +items will be imported to the root of the project files. +\item \code{name} - Enter the new name for the file or folder if you +want to rename at the destination. +} +Example of the list: + +\if{html}{\out{
}}\preformatted{items <- list( + list( + file = '', + parent = '' + ), + list( + file = '', + project = '', + name = 'moved_file.txt' + ), + list( + file = '', + parent = '', + name = 'moved_file2.txt' + ) + ) +}\if{html}{\out{
}} + +Read more on how to \href{https://docs.sevenbridges.com/reference/move-multiple-files-or-folders}{perform async move action on multiple files}.} +} +\if{html}{\out{
}} +} +\subsection{Details}{ +Rules for moving files and folders: +\itemize{ +\item The file ID is preserved after the move. +\item The folder ID is changed after the move. +\item The destination must be an existing folder. +\item If the target folder contains a folder with the same +name, the contents of both folders will be merged. +\item If a file with the same name already exists, the source +file will be automatically renamed (by adding a numeric +prefix). +\item You need to have WRITE permissions for both source +and destination folders. +} +} + +\subsection{Returns}{ +\code{\link{AsyncJob}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Move multiple files + a$files$async_bulk_move( + items = list( + list( + file = '', + parent = '' + ), + list( + file = '', + project = '', + name = 'moved_file.txt' + ), + list( + file = '', + parent = '', + name = 'moved_file2.txt' + ) + ) + ) +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Files-async_get_copy_job}{}}} +\subsection{Method \code{async_get_copy_job()}}{ +This call retrieves the details of an asynchronous bulk +copy job. +This information will be available for up to a month after the job has +been completed. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Files$async_get_copy_job(job_id)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{job_id}}{The ID of the copy job you are querying. +This ID can be found within the API response for the call for copying +files. +The function also accepts an AsyncJob object and extracts the ID.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{\link{AsyncJob}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Get details of an async copy job + a$files$async_get_copy_job(job_id = "job-id") +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Files-async_get_delete_job}{}}} +\subsection{Method \code{async_get_delete_job()}}{ +This call retrieves the details of an asynchronous bulk +deletion job. This information will be available for up to a month +after the job has been completed. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Files$async_get_delete_job(job_id)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{job_id}}{The ID of the delete job you are querying. +This ID can be found within the API response for the call for deleting +files. +The function also accepts an AsyncJob object and extracts the ID.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{\link{AsyncJob}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Get details of an async delete job + a$files$async_get_delete_job(job_id = "job-id") +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Files-async_get_move_job}{}}} +\subsection{Method \code{async_get_move_job()}}{ +This call retrieves the details of an asynchronous bulk +move job. This information will be available for up to a month after +the job has been completed. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Files$async_get_move_job(job_id)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{job_id}}{The ID of the move job you are querying. This ID can be +found within the API response for the call for moving files. +The function also accepts an AsyncJob object and extracts the ID.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +An \code{\link{AsyncJob}} object containing details of the move +job. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Get details of an async move job + a$files$async_get_move_job(job_id = "job-id") +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Files-async_list_file_jobs}{}}} +\subsection{Method \code{async_list_file_jobs()}}{ +This call retrieves the details for all asynchronous bulk +jobs you have started. This information will be available for up to a +month after the job has been completed. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Files$async_list_file_jobs( + limit = getOption("sevenbridges2")$limit, + offset = getOption("sevenbridges2")$offset +)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{limit}}{The maximum number of collection items to return +for a single request. Minimum value is \code{1}. +The maximum value is \code{100} and the default value is \code{50}. +This is a pagination-specific attribute.} + +\item{\code{offset}}{The zero-based starting index in the entire collection +of the first item to return. The default value is \code{0}. +This is a pagination-specific attribute.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \code{\link{Collection}} object containing a list of +\code{\link{AsyncJob}} objects. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Get details of the first 5 async jobs + a$files$async_list_file_jobs(limit = 5) +} + +} +\if{html}{\out{
}} + +} + } \if{html}{\out{
}} \if{html}{\out{}} diff --git a/man/Import.Rd b/man/Import.Rd index abac06c..38661a8 100644 --- a/man/Import.Rd +++ b/man/Import.Rd @@ -2,7 +2,7 @@ % Please edit documentation in R/class-import.R \name{Import} \alias{Import} -\title{R6 Class representing an Import} +\title{R6 Class representing an Import job} \description{ R6 Class representing a resource for managing volume import jobs. } @@ -62,23 +62,21 @@ R6 Class representing a resource for managing volume import jobs. \item \code{FAILED}: the import has failed. }} -\item{\code{overwrite}}{Whether the imported file/folder name was -overwritten or not, if another one with the same name had already -existed.} +\item{\code{overwrite}}{Indicates whether the imported file or folder name +was overwritten if another with the same name already existed.} -\item{\code{autorename}}{Whether the imported file/folder name was -automatically renamed (by prefixing its name with an underscore and -number) if another one with the same name had already existed.} +\item{\code{autorename}}{Indicates whether the imported file or folder name +was automatically renamed (by prefixing its name with an underscore +and number) if another with the same name already existed.} \item{\code{preserve_folder_structure}}{Whether the imported folder structure was preserved or not.} -\item{\code{source}}{List containing source volume id and source location of the -file/folder is being imported to the platform.} +\item{\code{source}}{List containing source volume id and source location of +the file/folder is being imported to the platform.} -\item{\code{destination}}{List containing destination project id or parent -directory id where the file/folder is being imported, together with its -name.} +\item{\code{destination}}{List containing the source volume ID and the source +location of the file or folder being imported to the platform.} \item{\code{started_on}}{Time when the import job started.} diff --git a/man/Imports.Rd b/man/Imports.Rd index 32fd77c..9b3dbf9 100644 --- a/man/Imports.Rd +++ b/man/Imports.Rd @@ -4,7 +4,7 @@ \alias{Imports} \title{R6 Class representing storage imports endpoints} \description{ -R6 Class representing storage imports resource endpoints. +R6 Class for managing storage imports resource endpoints. } \examples{ @@ -143,7 +143,7 @@ Create a new Imports object. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Imports-query}{}}} \subsection{Method \code{query()}}{ -This call lists import jobs initiated by particular user. +This call lists import jobs initiated by a particular user. Note that when you import a file from your volume on your cloud storage provider (Amazon Web Services or Google Cloud Storage), you are creating an alias on the Platform which points to the file in your @@ -332,8 +332,8 @@ be renamed, not the whole folder.} exact source folder structure. The default value is \code{TRUE} if the item being imported is a folder. Should not be used if you are importing a file. Bear in mind that if you use \code{preserve_folder_structure = FALSE}, -that the response will be the parent folder object containing imported -files alongside with other files if they exist.} +the response will be the parent folder object containing imported files +alongside with other files if they exist.} \item{\code{...}}{Other arguments that can be passed to core \code{api()} function like 'fields', etc.} @@ -368,7 +368,7 @@ like 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Imports-delete}{}}} \subsection{Method \code{delete()}}{ -Deleting import jobs is not possible. +Import jobs cannot be deleted. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Imports$delete()}\if{html}{\out{
}} } @@ -457,8 +457,8 @@ prepended to the location before attempting to locate the item on the volume. \item \code{destination_project} - Project object or ID to import files/folders into. Should not be used together with -destination_parent. If project is used, the items will be imported -to the root of the project's files. +destination_parent. If project is used, the items will be +imported to the root of the project's files. \item \code{destination_parent} - File object of type 'folder' or its ID to import files/folders into. Should not be used together with destination_project. If parent is used, the import will take @@ -476,10 +476,10 @@ slashes ('/'). \item \code{autorename} - Whether to automatically rename the item (by prefixing its name with an underscore and number) if another one with the same name already exists at the destination. -\item \code{preserve_folder_structure} - Whether to keep the exact source -folder structure. The default value is TRUE if the item being -imported is a folder. Should not be used if you are importing a -file. +\item \code{preserve_folder_structure} - Whether to keep the exact +source folder structure. The default value is TRUE if the item +being imported is a folder. Should not be used if you are +importing a file. } Example of the list: diff --git a/man/Invoice.Rd b/man/Invoice.Rd index 59aba61..7a7250c 100644 --- a/man/Invoice.Rd +++ b/man/Invoice.Rd @@ -8,7 +8,7 @@ R6 Class representing invoice information. } \details{ This object contains information about a selected invoice, -including the costs for analysis and storage, and the invoice period. +including costs for analysis, storage, and the invoice period. } \examples{ @@ -134,7 +134,7 @@ Print invoice information as a bullet list. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Invoice-reload}{}}} \subsection{Method \code{reload()}}{ -Reload Invoice. +Refresh the Invoice object with updated information. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Invoice$reload(...)}\if{html}{\out{
}} } diff --git a/man/Invoices.Rd b/man/Invoices.Rd index 5032f6b..54098ff 100644 --- a/man/Invoices.Rd +++ b/man/Invoices.Rd @@ -31,7 +31,7 @@ R6 Class representing invoice resource endpoints auth = auth ) - # Get single invoice by id + # Get a single invoice by id invoices_object$get(id = id) } @@ -168,7 +168,7 @@ like 'fields', etc.} auth = auth ) - # Get single invoice by id + # Get a single invoice by id invoices_object$get(id = id) } diff --git a/man/Member.Rd b/man/Member.Rd index 4f00806..4606557 100644 --- a/man/Member.Rd +++ b/man/Member.Rd @@ -50,7 +50,7 @@ R6 Class representing a resource for managing project members. \section{Public fields}{ \if{html}{\out{
}} \describe{ -\item{\code{id}}{Member's id.} +\item{\code{id}}{Member's ID.} \item{\code{username}}{Member's username.} diff --git a/man/Part.Rd b/man/Part.Rd index 2218d76..15ceeb3 100644 --- a/man/Part.Rd +++ b/man/Part.Rd @@ -182,8 +182,8 @@ Get upload part info. \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{upload_id}}{Upload object or ID of the upload process that part. -belongs to.} +\item{\code{upload_id}}{Upload object or ID of the upload process to which the +part belongs.} } \if{html}{\out{
}} } diff --git a/man/Permission.Rd b/man/Permission.Rd index 03756d3..6e1036e 100644 --- a/man/Permission.Rd +++ b/man/Permission.Rd @@ -100,7 +100,7 @@ Create a new Permission object. \item{\code{read}}{User can view file names, metadata, and workflows. They cannot view file contents. All members of a project have read permissions by default. Even if you try setting read permissions to -\code{FALSE}, they will still default to \code{TRUE}} +\code{FALSE}, they will still default to \code{TRUE}.} \item{\code{copy}}{User can view file content, copy, and download files from a project. Set value to \code{TRUE} to assign the user copy permission. diff --git a/man/Project.Rd b/man/Project.Rd index a5882d1..2c3c490 100644 --- a/man/Project.Rd +++ b/man/Project.Rd @@ -348,7 +348,8 @@ R6 Class representing a central resource for managing projects. \item{\code{id}}{Project identifier. It consists of project owner's username or if you are using Enterprise, then the Division name and project's -short name in form of \verb{/} or +short name in form of \cr +\verb{/} or \cr \verb{/}.} \item{\code{name}}{Project's name.} @@ -388,7 +389,7 @@ and the default value is \code{24}. } }} -\item{\code{root_folder}}{ID for of the project's root folder.} +\item{\code{root_folder}}{ID of the project's root folder.} \item{\code{created_by}}{Username of the person who created the project.} @@ -617,9 +618,9 @@ like 'limit', 'offset', 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Project-delete}{}}} \subsection{Method \code{delete()}}{ -Method that allows you to delete project from a platform. -It can only be successfully made if you have admin status for the -project. \cr +Method that allows you to delete a project from the +platform. It can only be successfully made if you have admin status for +the project. \cr Please be careful when using this method and note that calling it will permanently delete the project from the platform. \subsection{Usage}{ @@ -730,8 +731,8 @@ registering for an account on the Seven Bridges Platform.} \item{\code{permissions}}{List of permissions that will be associated with the project's member. It can contain fields: \code{read}, \code{copy}, \code{write}, -\code{execute} and \code{admin} with logical fields - \code{TRUE} if certain permission -is allowed to the user, or \code{FALSE} if it's not. +\code{execute} and \code{admin} with logical fields - \code{TRUE} if certain +permission is allowed to the user, or \code{FALSE} if it's not. Requests to add a project member must include the key permissions. However, if you do not include a value for some permission, it will be set to \code{FALSE} by default. The exception to this rule is the \code{read} @@ -793,8 +794,8 @@ be successfully run by a user who has admin privileges in the project. \if{html}{\out{
}} \describe{ \item{\code{user}}{The Seven Bridges Platform username of the person -you want to remove from the project or object of class Member containing -user's username.} +you want to remove from the project or object of class Member +containing user's username.} } \if{html}{\out{
}} } @@ -889,8 +890,8 @@ Member containing user's username.} \item{\code{permissions}}{List of permissions that will be associated with the project's member. It can contain fields: \code{read}, \code{copy}, \code{write}, -\code{execute} and \code{admin} with logical fields - \code{TRUE} if certain permission -is allowed to the user, or \code{FALSE} if it's not. +\code{execute} and \code{admin} with logical fields - \code{TRUE} if certain +permission is allowed to the user, or \code{FALSE} if it's not. Requests to add a project member must include the key permissions. However, if you do not include a value for some permission, it will be set to \code{FALSE} by default. The exception to this rule is the \code{read} @@ -1066,7 +1067,7 @@ Get project's root folder object \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Project-list_apps}{}}} \subsection{Method \code{list_apps()}}{ -This call lists all apps in project. +This call lists all apps in the project. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Project$list_apps( query_terms = NULL, @@ -1080,8 +1081,17 @@ This call lists all apps in project. \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{query_terms}}{Enter one or more search terms to query Project's -apps.} +\item{\code{query_terms}}{A list of search terms used to filter apps based on +their details. Each term is case-insensitive and can relate to the +app's name, label, toolkit, toolkit version, category, tagline, or +description. +You can provide a single term (e.g., \code{list("Compressor")}) or multiple +terms (e.g., \code{list("Expression", "Abundance")}) to search for apps +that match all the specified terms. If a term matches any part of the +app's details, the app will be included in the results. +Search terms can also include phrases +(e.g., \code{list("Abundance estimates input")}), which will search for +exact matches within app descriptions or other fields.} \item{\code{id}}{Use this parameter to query Project's apps based on their ID.} @@ -1223,8 +1233,8 @@ Set the value of status to one of the following values: \item{\code{parent}}{Provide task ID or task object of the parent task to return all child tasks from that parent. A parent task is a task that specifies the criteria by which to -batch its inputs into a series of further sub-tasks, called child tasks. -See the documentation on +batch its inputs into a series of further sub-tasks, called child +tasks. See the documentation on \href{https://docs.sevenbridges.com/docs/about-batch-analyses}{batching tasks} for more details on how to run tasks in batches.} @@ -1301,7 +1311,7 @@ like 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Project-list_imports}{}}} \subsection{Method \code{list_imports()}}{ -This call lists imports initiated by particular user +This call lists imports initiated by a particular user into this destination project. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Project$list_imports( @@ -1373,11 +1383,11 @@ like 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Project-create_task}{}}} \subsection{Method \code{create_task()}}{ -This call creates a new task. You can create either a single -task or a batch task by using the app's default batching, override -batching, or disable batching completely. A parent task is a task that -specifies criteria by which to batch its inputs into a series of further -sub-tasks, called child tasks. the documentation on +This call creates a new task. You can create either a +single task or a batch task by using the app's default batching, +override batching, or disable batching completely. A parent task is a +task that specifies criteria by which to batch its inputs into a series +of further sub-tasks, called child tasks. See the documentation on \href{https://docs.sevenbridges.com/docs/about-batch-analyses}{batching tasks} for more details on batching criteria. \subsection{Usage}{ @@ -1470,19 +1480,19 @@ output node locations within nodes_location. See below for more details. \itemize{ \item \code{main_location} - Defines the output location for all -output nodes in the task. Can be a string path within the project in -which the task is created, for example +output nodes in the task. Can be a string path within the project +in which the task is created, for example \cr \verb{/Analysis/_/} -or a path on an attached volume, such as -\verb{volumes://volume_name//html}. +or a path on an attached volume, \cr +such as \verb{volumes://volume_name//html}. Parts of the path enclosed in angle brackets <> are tokens that are dynamically replaced with corresponding values during task execution. \item \code{main_location_alias}: The string location (path) in the -project that will point to the actual location where the outputs are -stored. Used if main_location is defined as a volume path (starting -with volumes://), to provide an easy way of accessing output data -directly from project files. +project that will point to the actual location where the outputs +are stored. Used if main_location is defined as a volume path +(starting with volumes://), to provide an easy way of accessing +output data directly from project files. \item \code{nodes_override}: Enables defining of output locations for output nodes individually through nodes_location (see below). Set to \code{TRUE} to be able to define individual locations per output @@ -1507,9 +1517,9 @@ Example: ) }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{ In the example above, b64html is the ID of the output node for which - you want to define the output location, while the parameters are - defined as follows: +\if{html}{\out{
}}\preformatted{ In the example above, b64html is the ID of the output node for + which you want to define the output location, while the parameters + are defined as follows: }\if{html}{\out{
}} \itemize{ diff --git a/man/Projects.Rd b/man/Projects.Rd index bc4b4a2..3e9c1c7 100644 --- a/man/Projects.Rd +++ b/man/Projects.Rd @@ -2,9 +2,9 @@ % Please edit documentation in R/class-projects.R \name{Projects} \alias{Projects} -\title{R6 Class representing a projects endpoints.} +\title{R6 Class representing projects endpoints.} \description{ -R6 Class representing Projects resource. +R6 Class representing a Projects resource. } \examples{ @@ -102,8 +102,8 @@ Create new Projects resource object. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Projects-query}{}}} \subsection{Method \code{query()}}{ -A method to list all projects available to particular user. -If the username is not provided, all projects available to the +A method to list all projects available to a particular +user. If the username is not provided, all projects available to the currently authenticated user will be listed. Otherwise, projects will be listed for the user whose username is provided. @@ -129,7 +129,11 @@ More details on how to query projects, you can find in our \item{\code{owner}}{The username of the owner whose projects you want to query.} -\item{\code{tags}}{The list of project tags.} +\item{\code{tags}}{A list of project tags used to filter the query results. +Each tag should be provided as a string within the list, and tags may +include spaces. For example, both "my_tag_1" and "tag with spaces" are +valid tag values. The method will return only projects that have all +the specified tags.} \item{\code{limit}}{The maximum number of collection items to return for a single request. Minimum value is \code{1}. @@ -167,7 +171,7 @@ like other query parameters or 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Projects-get}{}}} \subsection{Method \code{get()}}{ -This call creates Project object containing the details +This call creates a Project object containing the details of a specified project. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Projects$get(id, ...)}\if{html}{\out{
}} @@ -178,7 +182,8 @@ of a specified project. \describe{ \item{\code{id}}{Project ID. It consists of project owner's username or if you are using Enterprise, then the Division name and project's -short name in form of \verb{/} or +short name in form of \cr +\verb{/} or \cr \verb{/}.} \item{\code{...}}{Other arguments that can be passed to core \code{api()} function @@ -208,10 +213,11 @@ like 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Projects-delete}{}}} \subsection{Method \code{delete()}}{ -Method that allows you to delete project from a platform. -It can only be successfully made if you have admin status for the -project. \cr Projects are specified by their IDs, which you can obtain by -using \code{Projects$query()} to list projects or by getting a +Method that allows you to delete a project from the +platform. It can only be successfully made if you have admin status for +the project. \cr +Projects are specified by their IDs, which you can obtain +by using \code{Projects$query()} to list projects or by getting a single project using \code{Projects$get()}. Please be careful when using this method and note that calling it will permanently delete the project from the platform. @@ -292,7 +298,8 @@ define the project as open i.e. one which will contain open data.} \item{\code{use_interruptible_instances}}{Defines the use of \href{https://docs.sevenbridges.com/docs/about-spot-instances}{spot instances}.} -\item{\code{use_memoization}}{Set to \code{FALSE} by default. Set to \code{TRUE} to enable +\item{\code{use_memoization}}{Set to \code{FALSE} by default. Set to \code{TRUE} to +enable \href{https://docs.sevenbridges.com/docs/about-memoization}{memoization}.} \item{\code{use_elastic_disk}}{Set to \code{TRUE} to enable diff --git a/man/Rate.Rd b/man/Rate.Rd index 7ddeca0..cfe99af 100644 --- a/man/Rate.Rd +++ b/man/Rate.Rd @@ -7,7 +7,7 @@ Rate object containing information about user's rate limit. } \details{ -This is main object for Rate Limit. +This is the main object for Rate Limit. } \section{Super class}{ \code{\link[sevenbridges2:Item]{sevenbridges2::Item}} -> \code{Rate} diff --git a/man/Resource.Rd b/man/Resource.Rd index 178574e..394da2a 100644 --- a/man/Resource.Rd +++ b/man/Resource.Rd @@ -67,7 +67,7 @@ Generic query implementation that is used by the resources. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Resource-get}{}}} \subsection{Method \code{get()}}{ -Generic get implementation that fetches single resource +Generic get implementation that fetches a single resource from the server. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Resource$get(cls, id, ...)}\if{html}{\out{
}} @@ -90,7 +90,7 @@ like 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Resource-delete}{}}} \subsection{Method \code{delete()}}{ -Generic implementation that deletes the resource +Generic implementation to delete a resource from the server. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Resource$delete(id, ...)}\if{html}{\out{
}} diff --git a/man/Task.Rd b/man/Task.Rd index 5006234..81c92b8 100644 --- a/man/Task.Rd +++ b/man/Task.Rd @@ -229,12 +229,12 @@ the task is located in.} \item{\code{start_time}}{Task start time in form of string.} -\item{\code{end_time}}{Task end time in form of string .} +\item{\code{end_time}}{Task end time in form of string.} -\item{\code{origin}}{Id of the entity that created the task, e.g. -automation run, if task was created by an automation run.} +\item{\code{origin}}{ID of the entity that created the task, e.g., +an automation run, if task was created by an automation run.} -\item{\code{use_interruptable_instances}}{This field can be \code{TRUE} or +\item{\code{use_interruptible_instances}}{This field can be \code{TRUE} or \code{FALSE}. Set this field to \code{TRUE} to allow the use of spot instances.} \item{\code{batch}}{\code{TRUE} for batch tasks, \code{FALSE} for regular and child @@ -256,7 +256,7 @@ which is the parent of this task).} \item{\code{execution_status}}{Task execution status list - info about current execution status.} -\item{\code{errors}}{Validations errors list stored as a high-level errors +\item{\code{errors}}{Validation errors list stored as a high-level errors array property in the API response.} \item{\code{warnings}}{Validation warnings list from API response.} @@ -398,8 +398,8 @@ is \code{DRAFT} can be run. \if{html}{\out{
}} \describe{ \item{\code{batch}}{Set this to \code{FALSE} to disable the default batching -for this task. Running a batch task is a recommended way to run multiple -tasks considering the API rate limit +for this task. Running a batch task is a recommended way to run +multiple tasks considering the API rate limit (\href{https://docs.sevenbridges.com/docs/api-rate-limit}{learn more}).} \item{\code{use_interruptible_instances}}{This field can be \code{TRUE} or @@ -890,10 +890,10 @@ Parts of the path enclosed in angle brackets <> are tokens that are dynamically replaced with corresponding values during task execution. \item \code{main_location_alias}: The string location (path) in the -project that will point to the actual location where the outputs are -stored. Used if main_location is defined as a volume path (starting -with volumes://), to provide an easy way of accessing output data -directly from project files. +project that will point to the actual location where the outputs +are stored. Used if main_location is defined as a volume path +(starting with volumes://), to provide an easy way of accessing +output data directly from project files. \item \code{nodes_override}: Enables defining of output locations for output nodes individually through nodes_location (see below). Set to \code{TRUE} to be able to define individual locations per output @@ -918,9 +918,9 @@ Example: ) }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{ In the example above, b64html is the ID of the output node for which - you want to define the output location, while the parameters are - defined as follows: +\if{html}{\out{
}}\preformatted{ In the example above, b64html is the ID of the output node for + which you want to define the output location, while the parameters + are defined as follows: }\if{html}{\out{
}} \itemize{ diff --git a/man/Tasks.Rd b/man/Tasks.Rd index 95585d9..299e4ff 100644 --- a/man/Tasks.Rd +++ b/man/Tasks.Rd @@ -93,10 +93,10 @@ Read more about how to use query parameters properly Set the value of status to one of the following values: \code{QUEUED}, \code{DRAFT}, \code{RUNNING}, \code{COMPLETED}, \code{ABORTED}, \code{FAILED}.} -\item{\code{parent}}{Provide task ID or Task object of the parent task to return -all child tasks from that parent. A parent task is a task that specifies -criteria by which to batch its inputs into a series of further -sub-tasks, called child tasks. See the documentation on +\item{\code{parent}}{Provide the task ID or Task object of the parent task to +return all child tasks. A parent task is a task that +specifies criteria by which to batch its inputs into a series of +further sub-tasks, called child tasks. See the documentation on \href{https://docs.sevenbridges.com/docs/about-batch-analyses}{batching tasks} for more details on how to run tasks in batches.} @@ -124,7 +124,7 @@ ended until a specified date.} \item{\code{order_by}}{Order returned results by the specified field. Allowed values: \cr \code{created_time}, \code{start_time}, \code{name}, \code{end_time} and -\code{created_by}. \cr Sort can be done only by one column. The default +\code{created_by}. \cr Sorting can only be done by one column. The default value is \code{created_time}.} \item{\code{order}}{Sort results in ascending or descending order by @@ -158,9 +158,9 @@ like 'fields', etc.} \subsection{Method \code{get()}}{ This call returns details of the specified task. The task is referred to by its ID, which you can obtain by making the call to -list all tasks you can access. The task details include its creator, its -start and end time, the number of jobs completed in it, and its input -and output files. You can also see the status of the task. +list all tasks you can access. The task details include its creator, +its start and end time, the number of jobs completed in it, and its +input and output files. You can also see the status of the task. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Tasks$get(id, ...)}\if{html}{\out{
}} } @@ -183,10 +183,9 @@ like 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Tasks-delete}{}}} \subsection{Method \code{delete()}}{ -This call deletes a task from the Seven Bridges Platform. -Tasks are specified by their IDs, which you can obtain by using -\code{Tasks$query()} to list tasks or by getting a single task -using \code{Tasks$get()}. +Tasks are identified by their IDs, which can be obtained +using \code{Tasks$query()} to list tasks or \code{Tasks$get()} to +retrieve a single task. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Tasks$delete(task, ...)}\if{html}{\out{
}} } @@ -206,11 +205,11 @@ as 'fields', etc.} \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Tasks-create}{}}} \subsection{Method \code{create()}}{ -This call creates a new task. You can create either a single -task or a batch task by using the app's default batching, override -batching, or disable batching completely. A parent task is a task that -specifies criteria by which to batch its inputs into a series of further -sub-tasks, called child tasks. the documentation on +This call creates a new task. You can create either a +single task or a batch task by using the app's default batching, +override batching, or disable batching completely. A parent task is a +task that specifies criteria by which to batch its inputs into a series +of further sub-tasks, called child tasks. the documentation on \href{https://docs.sevenbridges.com/docs/about-batch-analyses}{batching tasks} for more details on batching criteria. \subsection{Usage}{ @@ -307,8 +306,8 @@ output node locations within nodes_location. See below for more details. \itemize{ \item \code{main_location} - Defines the output location for all -output nodes in the task. Can be a string path within the project in -which the task is created, for example \cr +output nodes in the task. Can be a string path within the project +in which the task is created, for example \cr \verb{/Analysis/_/} \cr or a path on an attached volume, such as \cr \verb{volumes://volume_name//html}. \cr @@ -316,10 +315,10 @@ Parts of the path enclosed in angle brackets <> are tokens that are dynamically replaced with corresponding values during task execution. \item \code{main_location_alias}: The string location (path) in the -project that will point to the actual location where the outputs are -stored. Used if main_location is defined as a volume path (starting -with volumes://), to provide an easy way of accessing output data -directly from project files. +project that will point to the actual location where the outputs +are stored. Used if main_location is defined as a volume path +(starting with volumes://), to provide an easy way of accessing +output data directly from project files. \item \code{nodes_override}: Enables defining of output locations for output nodes individually through nodes_location (see below). Set to \code{TRUE} to be able to define individual locations per output @@ -344,9 +343,9 @@ Example: ) }\if{html}{\out{
}} -\if{html}{\out{
}}\preformatted{ In the example above, b64html is the ID of the output node for which - you want to define the output location, while the parameters are - defined as follows: +\if{html}{\out{
}}\preformatted{ In the example above, b64html is the ID of the output node for + which you want to define the output location, while the parameters + are defined as follows: }\if{html}{\out{
}} \itemize{ diff --git a/man/Team.Rd b/man/Team.Rd new file mode 100644 index 0000000..17ac42f --- /dev/null +++ b/man/Team.Rd @@ -0,0 +1,408 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class-team.R +\name{Team} +\alias{Team} +\title{R6 Class representing a Team} +\description{ +R6 Class representing a central resource for managing teams. +} +\examples{ + +## ------------------------------------------------ +## Method `Team$print` +## ------------------------------------------------ + +\dontrun{ + team_object <- Team$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + team_object$print() +} + +## ------------------------------------------------ +## Method `Team$reload` +## ------------------------------------------------ + +\dontrun{ + team_object <- Team$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + team_object$reload() +} + + +## ------------------------------------------------ +## Method `Team$list_members` +## ------------------------------------------------ + +\dontrun{ + # Retrieve details of a specified team + my_team <- a$teams$get(id = "team-id") + + # Retrieve a list of all team members + my_team$list_members() +} + + +## ------------------------------------------------ +## Method `Team$add_member` +## ------------------------------------------------ + +\dontrun{ + # Retrieve details of a specified team + my_team <- a$teams$get(id = "team-id") + + # Add new member to the team + my_team$add_member(user = "user-id") +} + +## ------------------------------------------------ +## Method `Team$remove_member` +## ------------------------------------------------ + +\dontrun{ + # Retrieve details of a specified team + my_team <- a$teams$get(id = "team-id") + + # Remove a member from the team + my_team$remove_member(user = "user-id") +} + +## ------------------------------------------------ +## Method `Team$rename` +## ------------------------------------------------ + +\dontrun{ + # Retrieve details of a specified team + my_team <- a$teams$get(id = "team-id") + + # Rename the team + my_team$rename(name = "new-team-name") +} + +## ------------------------------------------------ +## Method `Team$delete` +## ------------------------------------------------ + +\dontrun{ + # Retrieve details of a specified team + my_team <- a$teams$get(id = "team-id") + + # Delete a team + my_team$delete() +} +} +\section{Super class}{ +\code{\link[sevenbridges2:Item]{sevenbridges2::Item}} -> \code{Team} +} +\section{Public fields}{ +\if{html}{\out{
}} +\describe{ +\item{\code{URL}}{List of URL endpoints for this resource.} + +\item{\code{id}}{The ID of the team.} + +\item{\code{name}}{Team's name.} +} +\if{html}{\out{
}} +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-Team-new}{\code{Team$new()}} +\item \href{#method-Team-print}{\code{Team$print()}} +\item \href{#method-Team-reload}{\code{Team$reload()}} +\item \href{#method-Team-list_members}{\code{Team$list_members()}} +\item \href{#method-Team-add_member}{\code{Team$add_member()}} +\item \href{#method-Team-remove_member}{\code{Team$remove_member()}} +\item \href{#method-Team-rename}{\code{Team$rename()}} +\item \href{#method-Team-delete}{\code{Team$delete()}} +\item \href{#method-Team-clone}{\code{Team$clone()}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Team-new}{}}} +\subsection{Method \code{new()}}{ +Create a new Team object. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Team$new(res = NA, ...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{res}}{Response containing the Team object information.} + +\item{\code{...}}{Other response arguments.} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Team-print}{}}} +\subsection{Method \code{print()}}{ +Print method for Team class. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Team$print()}\if{html}{\out{
}} +} + +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + team_object <- Team$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + team_object$print() +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Team-reload}{}}} +\subsection{Method \code{reload()}}{ +Reload Team object information. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Team$reload(...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{...}}{Other arguments that can be passed to core \code{api()} function +like 'fields', etc.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{\link{Team}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + team_object <- Team$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + team_object$reload() +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Team-list_members}{}}} +\subsection{Method \code{list_members()}}{ +This call retrieves a list of all team members within a +specified team. Each member's username will be returned. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Team$list_members( + limit = getOption("sevenbridges2")$limit, + offset = getOption("sevenbridges2")$offset, + ... +)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{limit}}{The maximum number of collection items to return +for a single request. Minimum value is \code{1}. +The maximum value is \code{100} and the default value is \code{50}. +This is a pagination-specific attribute.} + +\item{\code{offset}}{The zero-based starting index in the entire collection +of the first item to return. The default value is \code{0}. +This is a pagination-specific attribute.} + +\item{\code{...}}{Other arguments that can be passed to core \code{api()} function +like 'fields', etc.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \code{\link{Collection}} of \code{\link{User}} objects. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Retrieve details of a specified team + my_team <- a$teams$get(id = "team-id") + + # Retrieve a list of all team members + my_team$list_members() +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Team-add_member}{}}} +\subsection{Method \code{add_member()}}{ +This call adds a division member to the specified team. +This action requires \code{ADMIN} privileges. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Team$add_member(user)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{user}}{User ID of the division member you are adding to the team +using the following format: \code{division_id/username}. Alternatively, +a \code{User} object can be provided.} +} +\if{html}{\out{
}} +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Retrieve details of a specified team + my_team <- a$teams$get(id = "team-id") + + # Add new member to the team + my_team$add_member(user = "user-id") +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Team-remove_member}{}}} +\subsection{Method \code{remove_member()}}{ +This call removes a member from a team. By removing a +member, you remove the user's membership to the team, but do not +remove their account from the division. +This action requires \code{ADMIN} privileges. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Team$remove_member(user)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{user}}{The Seven Bridges Platform username of the user to be +removed, specified in the format \code{division-name/username}, or an object +of class \code{User} that contains the username.} +} +\if{html}{\out{
}} +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Retrieve details of a specified team + my_team <- a$teams$get(id = "team-id") + + # Remove a member from the team + my_team$remove_member(user = "user-id") +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Team-rename}{}}} +\subsection{Method \code{rename()}}{ +This call renames the specified team. This action requires +\code{ADMIN} privileges. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Team$rename(name = NULL)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{name}}{The new name for the team.} +} +\if{html}{\out{
}} +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Retrieve details of a specified team + my_team <- a$teams$get(id = "team-id") + + # Rename the team + my_team$rename(name = "new-team-name") +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Team-delete}{}}} +\subsection{Method \code{delete()}}{ +This call deletes a team. By deleting a team, you remove +the users' membership to the team, but do not remove their accounts +from the division. +This action requires \code{ADMIN} privileges. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Team$delete()}\if{html}{\out{
}} +} + +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Retrieve details of a specified team + my_team <- a$teams$get(id = "team-id") + + # Delete a team + my_team$delete() +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Team-clone}{}}} +\subsection{Method \code{clone()}}{ +The objects of this class are cloneable with this method. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Team$clone(deep = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{deep}}{Whether to make a deep clone.} +} +\if{html}{\out{
}} +} +} +} diff --git a/man/Teams.Rd b/man/Teams.Rd new file mode 100644 index 0000000..f7307f2 --- /dev/null +++ b/man/Teams.Rd @@ -0,0 +1,250 @@ +% Generated by roxygen2: do not edit by hand +% Please edit documentation in R/class-teams.R +\name{Teams} +\alias{Teams} +\title{R6 Class representing teams endpoints} +\description{ +R6 Class representing teams resource endpoints. +} +\examples{ + +## ------------------------------------------------ +## Method `Teams$query` +## ------------------------------------------------ + +\dontrun{ + # Retrieve a list of all teams within the division regardless of + # whether you are a member of a team or not + a$teams$query(division = "division-id", list_all = TRUE) +} + + +## ------------------------------------------------ +## Method `Teams$get` +## ------------------------------------------------ + +\dontrun{ + # Retrieve details of a specified team + a$teams$get(id = "team-id") +} + +## ------------------------------------------------ +## Method `Teams$create` +## ------------------------------------------------ + +\dontrun{ + # Create new team + a$teams$create(division = "division-id", name = "my-new-team") +} + + +## ------------------------------------------------ +## Method `Teams$delete` +## ------------------------------------------------ + +\dontrun{ + # Delete a team + a$teams$delete(team = "team-id") +} +} +\section{Super class}{ +\code{\link[sevenbridges2:Resource]{sevenbridges2::Resource}} -> \code{Teams} +} +\section{Public fields}{ +\if{html}{\out{
}} +\describe{ +\item{\code{URL}}{List of URL endpoints for this resource.} +} +\if{html}{\out{
}} +} +\section{Methods}{ +\subsection{Public methods}{ +\itemize{ +\item \href{#method-Teams-new}{\code{Teams$new()}} +\item \href{#method-Teams-query}{\code{Teams$query()}} +\item \href{#method-Teams-get}{\code{Teams$get()}} +\item \href{#method-Teams-create}{\code{Teams$create()}} +\item \href{#method-Teams-delete}{\code{Teams$delete()}} +\item \href{#method-Teams-clone}{\code{Teams$clone()}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Teams-new}{}}} +\subsection{Method \code{new()}}{ +Create new Teams resource object. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Teams$new(...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{...}}{Other response arguments.} +} +\if{html}{\out{
}} +} +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Teams-query}{}}} +\subsection{Method \code{query()}}{ +This call retrieves a list of all teams in a division that +you are a member of. Each team's ID and name will be returned. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Teams$query(division, list_all = FALSE, ...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{division}}{The string ID of the division or Division object +you are querying.} + +\item{\code{list_all}}{Boolean. Set this field to \code{TRUE} if you want to list +all teams within the division (regardless of whether you are a member +of a team or not). Default value is \code{FALSE}.} + +\item{\code{...}}{Other arguments that can be passed to core \code{api()} function +like 'fields', etc.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \code{\link{Collection}} of \code{\link{Team}} objects. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Retrieve a list of all teams within the division regardless of + # whether you are a member of a team or not + a$teams$query(division = "division-id", list_all = TRUE) +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Teams-get}{}}} +\subsection{Method \code{get()}}{ +This call returns the details of a specified team. +You can only get details of a team you are a member of. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Teams$get(id, ...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{id}}{The ID of the team you are querying. The function +also accepts a Team object and extracts the ID.} + +\item{\code{...}}{Other arguments that can be passed to core \code{api()} function +like 'fields', etc.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{\link{Team}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Retrieve details of a specified team + a$teams$get(id = "team-id") +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Teams-create}{}}} +\subsection{Method \code{create()}}{ +This call creates a new team within a specified division. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Teams$create(division, name)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{division}}{The string ID of the division or Division object +where you want to create a team.} + +\item{\code{name}}{Enter the name for the new team.} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +A \code{\link{Team}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Create new team + a$teams$create(division = "division-id", name = "my-new-team") +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Teams-delete}{}}} +\subsection{Method \code{delete()}}{ +This call deletes a team. By deleting a team, you remove +the users' membership to the team, but do not remove their accounts +from the division. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Teams$delete(team, ...)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{team}}{The team ID or Team object that you want to delete.} + +\item{\code{...}}{Other arguments that can be passed to core \code{api()} function.} +} +\if{html}{\out{
}} +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ + # Delete a team + a$teams$delete(team = "team-id") +} +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Teams-clone}{}}} +\subsection{Method \code{clone()}}{ +The objects of this class are cloneable with this method. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Teams$clone(deep = FALSE)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{deep}}{Whether to make a deep clone.} +} +\if{html}{\out{
}} +} +} +} diff --git a/man/Upload.Rd b/man/Upload.Rd index 23bb8a3..3fe85e7 100644 --- a/man/Upload.Rd +++ b/man/Upload.Rd @@ -19,7 +19,7 @@ R6 Class representing a resource for managing files' uploads. auth = auth ) - # Print upload object information + # Print the upload object information upload_object$print(name = name) } @@ -95,7 +95,7 @@ R6 Class representing a resource for managing files' uploads. \item{\code{upload_id}}{Upload ID received after upload initialization.} -\item{\code{path}}{Relative or absolute path to the file on the local disc.} +\item{\code{path}}{Relative or absolute path to the file on the local disk.} \item{\code{project}}{Project's identifier (character).} @@ -194,7 +194,7 @@ Print method for Upload class. auth = auth ) - # Print upload object information + # Print the upload object information upload_object$print(name = name) } @@ -208,7 +208,7 @@ Print method for Upload class. \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-Upload-init}{}}} \subsection{Method \code{init()}}{ -Initialize new multipart file upload. +Initialize a new multipart file upload. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Upload$init()}\if{html}{\out{
}} } diff --git a/man/User.Rd b/man/User.Rd index 24a69e8..8647669 100644 --- a/man/User.Rd +++ b/man/User.Rd @@ -7,7 +7,7 @@ User object containing user information. } \details{ -This is main object for Users. +This is the main object for Users. } \section{Super class}{ \code{\link[sevenbridges2:Item]{sevenbridges2::Item}} -> \code{User} diff --git a/man/Volume.Rd b/man/Volume.Rd index 6fb8509..34187a3 100644 --- a/man/Volume.Rd +++ b/man/Volume.Rd @@ -194,6 +194,48 @@ volume_object <- Volume$new( } +## ------------------------------------------------ +## Method `Volume$add_member_team` +## ------------------------------------------------ + +\dontrun{ +# x is API response when volume is requested +volume_object <- Volume$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + + # Add volume member + volume_object$add_member_team( + team = , + permissions = list(read = TRUE, copy = FALSE) + ) +} + + +## ------------------------------------------------ +## Method `Volume$add_member_division` +## ------------------------------------------------ + +\dontrun{ +# x is API response when volume is requested +volume_object <- Volume$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + + # Add volume member + volume_object$add_member_division( + division = , + permissions = list(read = TRUE, copy = FALSE) + ) +} + + ## ------------------------------------------------ ## Method `Volume$remove_member` ## ------------------------------------------------ @@ -208,7 +250,7 @@ volume_object <- Volume$new( ) # Remove volume member - volume_object$remove_member(user = user) + volume_object$remove_member(member = member) } @@ -226,7 +268,7 @@ volume_object <- Volume$new( ) # Get volume member - volume_object$get_member(user = user) + volume_object$get_member(member = member) } @@ -245,7 +287,7 @@ volume_object <- Volume$new( # Modify volume member permissions volume_object$modify_member_permissions( - user = user, + member = member, permission = list(read = TRUE, copy = TRUE) ) } @@ -298,8 +340,8 @@ volume_object <- Volume$new( \describe{ \item{\code{URL}}{List of URL endpoints for this resource.} -\item{\code{id}}{Volume ID, constructed from \code{{division}/{volume_name}} -or \code{{volume_owner}/{volume_name}}.} +\item{\code{id}}{Volume ID, constructed from \code{{division}/{volume_name}} or \cr +\code{{volume_owner}/{volume_name}}.} \item{\code{name}}{The name of the volume. It must be unique from all other volumes for this user. Required if \code{from_path} parameter @@ -340,6 +382,8 @@ set to \code{FALSE}.} \item \href{#method-Volume-get_file}{\code{Volume$get_file()}} \item \href{#method-Volume-list_members}{\code{Volume$list_members()}} \item \href{#method-Volume-add_member}{\code{Volume$add_member()}} +\item \href{#method-Volume-add_member_team}{\code{Volume$add_member_team()}} +\item \href{#method-Volume-add_member_division}{\code{Volume$add_member_division()}} \item \href{#method-Volume-remove_member}{\code{Volume$remove_member()}} \item \href{#method-Volume-get_member}{\code{Volume$get_member()}} \item \href{#method-Volume-modify_member_permissions}{\code{Volume$modify_member_permissions()}} @@ -495,9 +539,9 @@ volume_object <- Volume$new( \subsection{Method \code{deactivate()}}{ Deactivate volume. Once deactivated, you cannot import from, export to, or browse within a -volume. As such, the content of the files imported from this volume will -no longer be accessible on the Platform. However, you can update the -volume and manage members. \cr +volume. As such, the content of the files imported from this volume +will no longer be accessible on the Platform. However, you can update +the volume and manage members. \cr Note that you cannot deactivate the volume if you have running imports or exports unless you force the operation using the query parameter force=TRUE. @@ -766,7 +810,8 @@ like 'fields', etc.} \if{html}{\out{
}} } \subsection{Returns}{ -\code{\link{Collection}} containing \code{\link{Member}} objects. +\code{\link{Collection}} containing \code{\link{Member}} +objects. } \subsection{Examples}{ \if{html}{\out{
}} @@ -850,6 +895,134 @@ volume_object <- Volume$new( } +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Volume-add_member_team}{}}} +\subsection{Method \code{add_member_team()}}{ +Add a specific team as a member to a volume. +Only Enterprise users that are part of some division can add teams +to a volume created within that division. +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Volume$add_member_team( + team, + permissions = list(read = TRUE, copy = FALSE, write = FALSE, admin = FALSE) +)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{team}}{The Seven Bridges Platform ID of a team +you want to add to the volume or object of class Team containing +team's ID. Team must be created within a division where the volume is +created too.} + +\item{\code{permissions}}{List of permissions granted to the team being added. +Permissions include listing the contents of a volume, importing files +from the volume to the Platform, exporting files from the Platform to +the volume, and admin privileges. \cr +It can contain fields: 'read', 'copy', 'write' and 'admin' with +logical fields - TRUE if certain permission is allowed to the team, or +FALSE if it's not. +Example: + +\if{html}{\out{
}}\preformatted{ permissions = list(read = TRUE, copy = TRUE, write = FALSE, + admin = FALSE) +}\if{html}{\out{
}}} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{\link{Member}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ +# x is API response when volume is requested +volume_object <- Volume$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + + # Add volume member + volume_object$add_member_team( + team = , + permissions = list(read = TRUE, copy = FALSE) + ) +} + +} +\if{html}{\out{
}} + +} + +} +\if{html}{\out{
}} +\if{html}{\out{}} +\if{latex}{\out{\hypertarget{method-Volume-add_member_division}{}}} +\subsection{Method \code{add_member_division()}}{ +Add a specific division as a member to a volume. +Only Enterprise users (with Enterprise accounts) can add divisions to a +volume that is created with that Enterprise account (not within other +divisions). +\subsection{Usage}{ +\if{html}{\out{
}}\preformatted{Volume$add_member_division( + division, + permissions = list(read = TRUE, copy = FALSE, write = FALSE, admin = FALSE) +)}\if{html}{\out{
}} +} + +\subsection{Arguments}{ +\if{html}{\out{
}} +\describe{ +\item{\code{division}}{The Seven Bridges Platform ID of a division +you want to add to the volume or object of class Division containing +division's ID.} + +\item{\code{permissions}}{List of permissions granted to the division being +added. Permissions include listing the contents of a volume, importing +files from the volume to the Platform, exporting files from the +Platform to the volume, and admin privileges. \cr +It can contain fields: 'read', 'copy', 'write' and 'admin' with +logical fields - TRUE if certain permission is allowed to the division, +or FALSE if it's not. +Example: + +\if{html}{\out{
}}\preformatted{ permissions = list(read = TRUE, copy = TRUE, write = FALSE, + admin = FALSE) +}\if{html}{\out{
}}} +} +\if{html}{\out{
}} +} +\subsection{Returns}{ +\code{\link{Member}} object. +} +\subsection{Examples}{ +\if{html}{\out{
}} +\preformatted{\dontrun{ +# x is API response when volume is requested +volume_object <- Volume$new( + res = x, + href = x$href, + auth = auth, + response = attr(x, "response") + ) + + # Add volume member + volume_object$add_member_division( + division = , + permissions = list(read = TRUE, copy = FALSE) + ) +} + +} +\if{html}{\out{
}} + +} + } \if{html}{\out{
}} \if{html}{\out{}} @@ -858,15 +1031,16 @@ volume_object <- Volume$new( Remove member from a volume. This function removes members from the specified volume. \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{Volume$remove_member(user)}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{Volume$remove_member(member)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{user}}{The Seven Bridges Platform username of the person -you want to remove from the volume or object of class Member containing -user's username.} +\item{\code{member}}{The Seven Bridges Platform username of the person +you want to remove from the volume, or team ID or division ID +(for Enterprise users only) or object of class Member containing +member's ID.} } \if{html}{\out{
}} } @@ -882,7 +1056,7 @@ volume_object <- Volume$new( ) # Remove volume member - volume_object$remove_member(user = user) + volume_object$remove_member(member = member) } } @@ -898,15 +1072,16 @@ volume_object <- Volume$new( Get member's details. This function returns member's information. \subsection{Usage}{ -\if{html}{\out{
}}\preformatted{Volume$get_member(user, ...)}\if{html}{\out{
}} +\if{html}{\out{
}}\preformatted{Volume$get_member(member, ...)}\if{html}{\out{
}} } \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{user}}{The Seven Bridges Platform username of the person -you want to get information about or object of class Member containing -user's username.} +\item{\code{member}}{The Seven Bridges Platform username of the person +you want to get information about, or team ID or division ID +(for Enterprise users only) or object of class Member containing +member's ID.} \item{\code{...}}{Other arguments that can be passed to core \code{api()} function like 'fields', etc.} @@ -928,7 +1103,7 @@ volume_object <- Volume$new( ) # Get volume member - volume_object$get_member(user = user) + volume_object$get_member(member = member) } } @@ -943,11 +1118,11 @@ volume_object <- Volume$new( \subsection{Method \code{modify_member_permissions()}}{ Modify volume member's permissions. This function modifies the permissions for a member of a specific -volume. Note that this does not overwrite all previously set permissions -for the member. +volume. Note that this does not overwrite all previously set +permissions for the member. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{Volume$modify_member_permissions( - user, + member, permissions = list(read = TRUE, copy = FALSE, write = FALSE, admin = FALSE) )}\if{html}{\out{
}} } @@ -955,9 +1130,10 @@ for the member. \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{user}}{The Seven Bridges Platform username of the person -you want to modify permissions for or object of class Member containing -user's username.} +\item{\code{member}}{The Seven Bridges Platform username of the person +you want to modify permissions for or team ID or division ID +(for Enterprise users only) or object of class Member containing +member's ID.} \item{\code{permissions}}{List of specific (or all) permissions you want to update for the member of the volume. @@ -991,7 +1167,7 @@ volume_object <- Volume$new( # Modify volume member permissions volume_object$modify_member_permissions( - user = user, + member = member, permission = list(read = TRUE, copy = TRUE) ) } diff --git a/man/VolumeContentCollection.Rd b/man/VolumeContentCollection.Rd index b32f1a5..bf25c92 100644 --- a/man/VolumeContentCollection.Rd +++ b/man/VolumeContentCollection.Rd @@ -174,7 +174,7 @@ Return next page of results. \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{...}}{Other arguments or query parameters that can be passed to +\item{\code{...}}{Other arguments or query parameters that can be passed to the core \code{api()} function like 'advance_access', 'fields' etc.} } \if{html}{\out{
}} @@ -205,7 +205,7 @@ vol_con_col_object <- VolumeContentCollection$new( \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-VolumeContentCollection-prev_page}{}}} \subsection{Method \code{prev_page()}}{ -Return previous page of results. +Return the previous page of results. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{VolumeContentCollection$prev_page()}\if{html}{\out{
}} } @@ -244,7 +244,7 @@ Fetches all available items. \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{...}}{Other arguments or query parameters that can be passed to +\item{\code{...}}{Other arguments or query parameters that can be passed to the core \code{api()} function like 'advance_access', 'fields' etc.} } \if{html}{\out{
}} diff --git a/man/VolumeFile.Rd b/man/VolumeFile.Rd index 74359ee..30d09a9 100644 --- a/man/VolumeFile.Rd +++ b/man/VolumeFile.Rd @@ -77,7 +77,7 @@ volume_file_object <- VolumeFile$new( \item{\code{volume}}{Volume id.} -\item{\code{metadata}}{File's metadata if exists.} +\item{\code{metadata}}{File metadata, if it exists.} } \if{html}{\out{
}} } @@ -158,7 +158,7 @@ like 'fields', etc.} \if{html}{\out{
}} } \subsection{Returns}{ -\code{\link{VolumeFile}} object. +A \code{\link{VolumeFile}} object. } \subsection{Examples}{ \if{html}{\out{
}} @@ -185,8 +185,8 @@ volume_file_object <- VolumeFile$new( \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-VolumeFile-import}{}}} \subsection{Method \code{import()}}{ -This call lets you queue a job to import this file or folder -from a volume into a project on the Platform. \cr +This call lets you queue a job to import this file or +folder from a volume into a project on the Platform. \cr Essentially, you are importing an item from your cloud storage provider (Amazon Web Services, Google Cloud Storage, Azure or Ali Cloud) via the volume onto the Platform. \cr diff --git a/man/VolumePrefix.Rd b/man/VolumePrefix.Rd index dcc4b95..6d2c5c9 100644 --- a/man/VolumePrefix.Rd +++ b/man/VolumePrefix.Rd @@ -21,7 +21,7 @@ volume_prefix_object <- VolumePrefix$new( response = attr(x, "response") ) - # Print volume prefix object + # Print the Volume Prefix object volume_prefix_object$print() } @@ -117,7 +117,7 @@ Create a new VolumePrefix object. \subsection{Arguments}{ \if{html}{\out{
}} \describe{ -\item{\code{res}}{Response containing VolumePrefix object info.} +\item{\code{res}}{Response containing VolumePrefix object information.} \item{\code{...}}{Other response arguments.} } @@ -144,7 +144,7 @@ volume_prefix_object <- VolumePrefix$new( response = attr(x, "response") ) - # Print volume prefix object + # Print the Volume Prefix object volume_prefix_object$print() } @@ -158,7 +158,7 @@ volume_prefix_object <- VolumePrefix$new( \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-VolumePrefix-reload}{}}} \subsection{Method \code{reload()}}{ -Reload VolumePrefix object information. +Reload the VolumePrefix object information. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{VolumePrefix$reload()}\if{html}{\out{
}} } @@ -188,7 +188,7 @@ volume_prefix_object <- VolumePrefix$new( \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-VolumePrefix-list_contents}{}}} \subsection{Method \code{list_contents()}}{ -List volume folder contents. +List the contents of a volume folder. This call lists the contents of a specific volume folder. \subsection{Usage}{ \if{html}{\out{
}}\preformatted{VolumePrefix$list_contents( @@ -246,8 +246,8 @@ volume_prefix_object <- VolumePrefix$new( \if{html}{\out{}} \if{latex}{\out{\hypertarget{method-VolumePrefix-import}{}}} \subsection{Method \code{import()}}{ -This call lets you queue a job to import this file or folder -from a volume into a project on the Platform. \cr +This call lets you queue a job to import this file or +folder from a volume into a project on the Platform. \cr Essentially, you are importing an item from your cloud storage provider (Amazon Web Services, Google Cloud Storage, Azure or Ali Cloud) via the volume onto the Platform. \cr @@ -287,8 +287,9 @@ the complete location (including the prefix) on the volume. \cr Segments are considered to be separated with forward slashes /. Allowed characters in file names are all alphanumeric and special -characters except forward slash /, while folder names can contain -alphanumeric and special characters _, - and ..} +characters except forward slash (/), while folder names can contain +alphanumeric and special characters underscores (_), hyphens (-), and +dots (.).} \item{\code{overwrite}}{Set to \code{TRUE} if you want to overwrite the item if another one with the same name already exists at the destination. diff --git a/man/prepare_items_for_bulk_export.Rd b/man/prepare_items_for_bulk_export.Rd index 1b3bf37..d1f4971 100644 --- a/man/prepare_items_for_bulk_export.Rd +++ b/man/prepare_items_for_bulk_export.Rd @@ -46,7 +46,7 @@ Keep in mind that the same overwrite option will be applied to all items exporting to this bucket. Supported values: \code{AES256} (SSE-S3 encryption), \code{aws:kms}, \code{null} (no server-side encryption). Default: \code{AES256}. -\item \code{sse_aws_kms_key_id}: Applies to type: \code{s3}. +\item \code{sse_aws_kms_key_Id}: Applies to type: \code{s3}. If AWS KMS encryption is used, this should be set to the required KMS key. If not set and \code{aws:kms} is set as \code{sse_algorithm}, default KMS key is used. @@ -60,7 +60,7 @@ Keep in mind that the same properties will be applied to all items (files) in the resulting list.} } \value{ -List of body params items for for staring an export job. +List of body params items for starting an export job. } \description{ Utility function to prepare the \code{items} parameter, a list of @@ -82,15 +82,15 @@ item: However, keep in mind that there are certain constraints: \itemize{ \item The same \code{destination_volume} applies to all items in the -. resulting list. +resulting list. \item The same applies to \code{overwrite} and \code{properties} parameters. \item By default, the \code{destination_location} field is populated with the source file name. Upon retrieval of the list of items for bulk -export, you can manually update the \code{destination_location} field -for each element of the list as needed. Additionally, you have the -flexibility to manually modify any other fields in the list if -required. +export, you can manually update the \cr +\code{destination_location} field for each element of the list as needed. +Additionally, you have the flexibility to manually modify any other +fields in the list if required. } } \examples{ diff --git a/man/prepare_items_for_bulk_import.Rd b/man/prepare_items_for_bulk_import.Rd index 817d96c..3820d8f 100644 --- a/man/prepare_items_for_bulk_import.Rd +++ b/man/prepare_items_for_bulk_import.Rd @@ -17,7 +17,8 @@ prepare_items_for_bulk_import( \code{\link{VolumePrefix}} objects to be imported.} \item{destination_project}{Destination project ID or \code{\link{Project}} -object. Not required, but either \code{destination_project} or +object. Not required, but either \cr +\code{destination_project} or \code{destination_parent} directory must be provided.} \item{destination_parent}{Folder ID or \code{\link{File}} object diff --git a/renv.lock b/renv.lock index cec6e65..30602f7 100644 --- a/renv.lock +++ b/renv.lock @@ -11,14 +11,14 @@ "Packages": { "BH": { "Package": "BH", - "Version": "1.84.0-0", + "Version": "1.87.0-1", "Source": "Repository", "Repository": "CRAN", - "Hash": "a8235afbcd6316e6e91433ea47661013" + "Hash": "468d9a03ba57f22ebde50060fd13ba9f" }, "DescTools": { "Package": "DescTools", - "Version": "0.99.54", + "Version": "0.99.59", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -34,6 +34,7 @@ "gld", "grDevices", "graphics", + "haven", "httr", "methods", "mvtnorm", @@ -43,13 +44,13 @@ "utils", "withr" ], - "Hash": "cdd76cdd712d77020083cf669af8b3f3" + "Hash": "60aea3ab405a250f027f9fe8e2a2baca" }, "Exact": { "Package": "Exact", - "Version": "3.2", + "Version": "3.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "graphics", @@ -57,22 +58,22 @@ "stats", "utils" ], - "Hash": "1a43175d291899a4b2965b5d8db260e0" + "Hash": "72eeb792b6ae3bef92624916c328bcff" }, "KernSmooth": { "Package": "KernSmooth", - "Version": "2.23-22", + "Version": "2.23-26", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "stats" ], - "Hash": "2fecebc3047322fa5930f74fae5de70f" + "Hash": "2fb39782c07b5ad422b0448ae83f64c4" }, "MASS": { "Package": "MASS", - "Version": "7.3-60.2", + "Version": "7.3-65", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -83,11 +84,11 @@ "stats", "utils" ], - "Hash": "2f342c46163b0b54d7b64d1f798e2c78" + "Hash": "a41d0fc833ea756a1136b60a437efe26" }, "Matrix": { "Package": "Matrix", - "Version": "1.7-0", + "Version": "1.7-3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -100,7 +101,7 @@ "stats", "utils" ], - "Hash": "1920b2f11133b12350024297d8a4ff4a" + "Hash": "fb578c2b5d796882c60e9f770352f7c4" }, "R.cache": { "Package": "R.cache", @@ -130,7 +131,7 @@ }, "R.oo": { "Package": "R.oo", - "Version": "1.26.0", + "Version": "1.27.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -139,11 +140,11 @@ "methods", "utils" ], - "Hash": "4fed809e53ddb5407b3da3d0f572e591" + "Hash": "6ac79ff194202248cf946fe3a5d6d498" }, "R.utils": { "Package": "R.utils", - "Version": "2.12.3", + "Version": "2.13.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -154,38 +155,38 @@ "tools", "utils" ], - "Hash": "3dc2829b790254bfba21e60965787651" + "Hash": "d32373d88da809f8974d5307481862b0" }, "R6": { "Package": "R6", - "Version": "2.5.1", + "Version": "2.6.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "470851b6d5d0ac559e9d01bb352b4021" + "Hash": "d4335fe7207f1c01ab8c41762f5840d4" }, "Rcpp": { "Package": "Rcpp", - "Version": "1.0.12", + "Version": "1.0.14", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "methods", "utils" ], - "Hash": "5ea2700d21e038ace58269ecdbeb9ec0" + "Hash": "e7bdd9ee90e96921ca8a0f1972d66682" }, "askpass": { "Package": "askpass", - "Version": "1.2.0", + "Version": "1.2.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "sys" ], - "Hash": "cad6cf7f1d5f6e906700b9d3e718c796" + "Hash": "c39f4155b3ceb1a9a2799d700fbd4b6a" }, "backports": { "Package": "backports", @@ -209,27 +210,28 @@ }, "bit": { "Package": "bit", - "Version": "4.0.5", + "Version": "4.6.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "d242abec29412ce988848d0294b208fd" + "Hash": "ebe86ffd194564abdc895d87742d5a29" }, "bit64": { "Package": "bit64", - "Version": "4.0.5", + "Version": "4.6.0-1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "bit", + "graphics", "methods", "stats", "utils" ], - "Hash": "9fe98599ca456d6552421db0d6772d8f" + "Hash": "4f572fbc586294afff277db583b9060f" }, "boot": { "Package": "boot", @@ -262,7 +264,7 @@ }, "bslib": { "Package": "bslib", - "Version": "0.7.0", + "Version": "0.9.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -280,7 +282,7 @@ "rlang", "sass" ], - "Hash": "8644cc53f43828f19133548195d7e59e" + "Hash": "70a6489cc254171fb9b4a7f130f44dca" }, "cachem": { "Package": "cachem", @@ -320,19 +322,19 @@ }, "checkmate": { "Package": "checkmate", - "Version": "2.3.1", + "Version": "2.3.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "backports", "utils" ], - "Hash": "c01cab1cb0f9125211a6fc99d540e315" + "Hash": "0e14e01ce07e7c88fd25de6d4260d26b" }, "class": { "Package": "class", - "Version": "7.3-22", + "Version": "7.3-23", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -341,18 +343,18 @@ "stats", "utils" ], - "Hash": "f91f6b29f38b8c280f2b9477787d4bb2" + "Hash": "d0cb9cc838c3b43560bd958fc4317fdc" }, "cli": { "Package": "cli", - "Version": "3.6.2", + "Version": "3.6.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "1216ac65ac55ec0058a6f75d7ca0fd52" + "Hash": "491c34d3d9dd0d2fe13d9f278bb90795" }, "clipr": { "Package": "clipr", @@ -366,7 +368,7 @@ }, "cluster": { "Package": "cluster", - "Version": "2.1.6", + "Version": "2.1.8.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -376,7 +378,7 @@ "stats", "utils" ], - "Hash": "0aaa05204035dc43ea0004b9c76611dd" + "Hash": "e16d49a008e1a22ee863fb9a51de9bde" }, "codetools": { "Package": "codetools", @@ -390,10 +392,10 @@ }, "commonmark": { "Package": "commonmark", - "Version": "1.9.1", + "Version": "1.9.5", "Source": "Repository", "Repository": "CRAN", - "Hash": "5d8225445acb167abf7797de48b2ee3c" + "Hash": "4ac08754c8ed35996b7c343fbb22885a" }, "config": { "Package": "config", @@ -427,17 +429,17 @@ }, "cpp11": { "Package": "cpp11", - "Version": "0.4.7", + "Version": "0.5.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "5a295d7d963cc5035284dcdbaf334f4e" + "Hash": "2720e3fd3dad08f34b19b56b3d6f073d" }, "crayon": { "Package": "crayon", - "Version": "1.5.2", + "Version": "1.5.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -445,13 +447,13 @@ "methods", "utils" ], - "Hash": "e8a1e41acf02548751f45c718d55aa6a" + "Hash": "859d96e65ef198fd43e82b9628d593ef" }, "credentials": { "Package": "credentials", - "Version": "2.0.1", + "Version": "2.0.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "askpass", "curl", @@ -459,17 +461,17 @@ "openssl", "sys" ], - "Hash": "c7844b32098dcbd1c59cbd8dddb4ecc6" + "Hash": "09fd631e607a236f8cc7f9604db32cb8" }, "curl": { "Package": "curl", - "Version": "5.2.1", + "Version": "6.2.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R" ], - "Hash": "411ca2c03b1ce5f548345d2fc2685f7a" + "Hash": "d65efa2a203bb99faa78690eee928f30" }, "cyclocomp": { "Package": "cyclocomp", @@ -487,14 +489,14 @@ }, "data.table": { "Package": "data.table", - "Version": "1.15.4", + "Version": "1.17.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "8ee9ac56ef633d0c7cab8b2ca87d683e" + "Hash": "d06cd1a942bb17b607df7d57048d6840" }, "desc": { "Package": "desc", @@ -560,14 +562,14 @@ }, "digest": { "Package": "digest", - "Version": "0.6.35", + "Version": "0.6.37", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "utils" ], - "Hash": "698ece7ba5a4fa4559e3d537e7ec3d31" + "Hash": "33698c4b3127fc9f506654607fb73676" }, "docopt": { "Package": "docopt", @@ -581,7 +583,7 @@ }, "downlit": { "Package": "downlit", - "Version": "0.4.3", + "Version": "0.4.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -597,13 +599,13 @@ "withr", "yaml" ], - "Hash": "14fa1f248b60ed67e1f5418391a17b14" + "Hash": "45a6a596bf0108ee1ff16a040a2df897" }, "e1071": { "Package": "e1071", - "Version": "1.7-14", + "Version": "1.7-16", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "class", "grDevices", @@ -613,7 +615,7 @@ "stats", "utils" ], - "Hash": "4ef372b716824753719a8a38b258442d" + "Hash": "27a09ca40266a1066d62ef5402dd51d6" }, "ellipsis": { "Package": "ellipsis", @@ -628,25 +630,24 @@ }, "evaluate": { "Package": "evaluate", - "Version": "0.23", + "Version": "1.0.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ - "R", - "methods" + "R" ], - "Hash": "daf4a1246be12c1fa8c7705a0935c1a0" + "Hash": "e9651417729bbe7472e32b5027370e79" }, "expm": { "Package": "expm", - "Version": "0.999-9", + "Version": "1.0-0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "Matrix", "methods" ], - "Hash": "a9cfdee9645dd6b09ba8d4b9a9befa77" + "Hash": "a44b2810f36c1cda5d52eee6ec96cafa" }, "fansi": { "Package": "fansi", @@ -669,7 +670,7 @@ }, "fontawesome": { "Package": "fontawesome", - "Version": "0.5.2", + "Version": "0.5.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -677,7 +678,23 @@ "htmltools", "rlang" ], - "Hash": "c2efdd5f0bcd1ea861c2d4e2a883a67d" + "Hash": "bd1297f9b5b1fc1372d19e2c4cd82215" + }, + "forcats": { + "Package": "forcats", + "Version": "1.0.0", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "glue", + "lifecycle", + "magrittr", + "rlang", + "tibble" + ], + "Hash": "1a0a9a3d5083d0d573c4214576f1e690" }, "foreach": { "Package": "foreach", @@ -694,7 +711,7 @@ }, "foreign": { "Package": "foreign", - "Version": "0.8-86", + "Version": "0.8-88", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -703,22 +720,22 @@ "stats", "utils" ], - "Hash": "550170303dbb19d07b2bcc288068e7dc" + "Hash": "ffaf42daf543339d0961120cb1de57b8" }, "fs": { "Package": "fs", - "Version": "1.6.4", + "Version": "1.6.5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "15aeb8c27f5ea5161f9f6a641fafd93a" + "Hash": "7f48af39fa27711ea5fbd183b399920d" }, "gert": { "Package": "gert", - "Version": "2.0.1", + "Version": "2.1.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -729,7 +746,7 @@ "sys", "zip" ], - "Hash": "f70d3fe2d9e7654213a946963d1591eb" + "Hash": "ae855ad6d7be20dd7b05d43d25700398" }, "gh": { "Package": "gh", @@ -761,7 +778,7 @@ }, "gld": { "Package": "gld", - "Version": "2.6.6", + "Version": "2.6.7", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -770,18 +787,39 @@ "lmom", "stats" ], - "Hash": "71173258033324618dc8a09b3e27269e" + "Hash": "c0fb9f61bfa549d9606801b1ee56a643" }, "glue": { "Package": "glue", - "Version": "1.7.0", + "Version": "1.8.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "methods" ], - "Hash": "e0b3a53876554bd45879e596cdb10a52" + "Hash": "5899f1eaa825580172bb56c08266f37c" + }, + "haven": { + "Package": "haven", + "Version": "2.5.4", + "Source": "Repository", + "Repository": "CRAN", + "Requirements": [ + "R", + "cli", + "cpp11", + "forcats", + "hms", + "lifecycle", + "methods", + "readr", + "rlang", + "tibble", + "tidyselect", + "vctrs" + ], + "Hash": "9171f898db9d9c4c1b2c745adc2c1ef1" }, "here": { "Package": "here", @@ -881,7 +919,7 @@ }, "httr2": { "Package": "httr2", - "Version": "1.0.1", + "Version": "1.1.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -898,7 +936,7 @@ "vctrs", "withr" ], - "Hash": "03d741c92fda96d98c3a3f22494e3b4a" + "Hash": "637dfd6294964bd23b07e5eb9b3cab11" }, "ini": { "Package": "ini", @@ -930,17 +968,17 @@ }, "jsonlite": { "Package": "jsonlite", - "Version": "1.8.8", + "Version": "1.9.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "methods" ], - "Hash": "e1b9c55281c5adc4dd113652d9e26768" + "Hash": "c72fbb0e7ee73ea7497ffeebe44f0d91" }, "knitr": { "Package": "knitr", - "Version": "1.46", + "Version": "1.50", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -952,18 +990,18 @@ "xfun", "yaml" ], - "Hash": "6e008ab1d696a5283c79765fa7b56b47" + "Hash": "5a07d8ec459d7b80bd4acca5f4a6e062" }, "later": { "Package": "later", - "Version": "1.3.2", + "Version": "1.4.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "Rcpp", "rlang" ], - "Hash": "a3e051d405326b8b0012377434c62b37" + "Hash": "501744395cac0bab0fbcfab9375ae92c" }, "lattice": { "Package": "lattice", @@ -1005,14 +1043,14 @@ }, "lintr": { "Package": "lintr", - "Version": "3.1.2", + "Version": "3.2.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "backports", + "cli", "codetools", - "cyclocomp", "digest", "glue", "knitr", @@ -1022,19 +1060,19 @@ "xml2", "xmlparsedata" ], - "Hash": "08cff46381a242d44c0d8dd0aabd9f71" + "Hash": "45b44c7f1040cce8f34ec0a9c92d47f3" }, "lmom": { "Package": "lmom", - "Version": "3.0", + "Version": "3.2", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "graphics", "stats" ], - "Hash": "a69348cee0766082223f1c7e2a545505" + "Hash": "a75d2dd42af9b4cb291815889cdcff77" }, "magrittr": { "Package": "magrittr", @@ -1076,13 +1114,13 @@ }, "mime": { "Package": "mime", - "Version": "0.12", + "Version": "0.13", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "tools" ], - "Hash": "18e9c28c1d3ca1560ce30658b22ce104" + "Hash": "0ec19f34c72fab674d8f2b4b1c6410e1" }, "miniUI": { "Package": "miniUI", @@ -1098,18 +1136,18 @@ }, "mvtnorm": { "Package": "mvtnorm", - "Version": "1.2-5", + "Version": "1.3-3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "stats" ], - "Hash": "4d1891e59ac7a12b4e7e8a69349125f1" + "Hash": "c7241e6be9d6df551a2e539a50f5c875" }, "nlme": { "Package": "nlme", - "Version": "3.1-164", + "Version": "3.1-167", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1119,11 +1157,11 @@ "stats", "utils" ], - "Hash": "a623a2239e642806158bc4dc3f51565d" + "Hash": "abd9318b4073223646c0f9d3ed641904" }, "nnet": { "Package": "nnet", - "Version": "7.3-19", + "Version": "7.3-20", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1131,26 +1169,25 @@ "stats", "utils" ], - "Hash": "2c797b46eea7fb58ede195bc0b1f1138" + "Hash": "c955edf99ff24a32e96bd0a22645af60" }, "openssl": { "Package": "openssl", - "Version": "2.2.0", + "Version": "2.3.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "askpass" ], - "Hash": "2bcca3848e4734eb3b16103bc9aa4b8e" + "Hash": "bc54d87ebf858b28de18df4bca6528d3" }, "pillar": { "Package": "pillar", - "Version": "1.9.0", + "Version": "1.10.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "cli", - "fansi", "glue", "lifecycle", "rlang", @@ -1158,11 +1195,11 @@ "utils", "vctrs" ], - "Hash": "15da5a8412f317beeee6175fbc76f4bb" + "Hash": "8b16b6097daef84cd3c40a6a7c5c9d86" }, "pkgbuild": { "Package": "pkgbuild", - "Version": "1.4.4", + "Version": "1.4.6", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1173,7 +1210,7 @@ "desc", "processx" ], - "Hash": "a29e8e134a460a01e0ca67a4763c595b" + "Hash": "2914aa6216361f59e40d5c84667ac155" }, "pkgconfig": { "Package": "pkgconfig", @@ -1187,9 +1224,9 @@ }, "pkgdown": { "Package": "pkgdown", - "Version": "2.0.9", + "Version": "2.1.1", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "bslib", @@ -1198,11 +1235,11 @@ "desc", "digest", "downlit", + "fontawesome", "fs", - "httr", + "httr2", "jsonlite", - "magrittr", - "memoise", + "openssl", "purrr", "ragg", "rlang", @@ -1213,28 +1250,29 @@ "xml2", "yaml" ], - "Hash": "8bf1151ed1a48328d71b937e651117a6" + "Hash": "df2912d5873422b55a13002510f02c9f" }, "pkgload": { "Package": "pkgload", - "Version": "1.3.4", + "Version": "1.4.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "cli", - "crayon", "desc", "fs", "glue", + "lifecycle", "methods", "pkgbuild", + "processx", "rlang", "rprojroot", "utils", "withr" ], - "Hash": "876c618df5ae610be84356d5d7a5d124" + "Hash": "2ec30ffbeec83da57655b850cf2d3e0e" }, "praise": { "Package": "praise", @@ -1274,7 +1312,7 @@ }, "processx": { "Package": "processx", - "Version": "3.8.4", + "Version": "3.8.6", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1283,22 +1321,20 @@ "ps", "utils" ], - "Hash": "0c90a7d71988856bad2a2a45dd871bb9" + "Hash": "720161b280b0a35f4d1490ead2fe81d0" }, "profvis": { "Package": "profvis", - "Version": "0.3.8", + "Version": "0.4.0", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "R", "htmlwidgets", - "purrr", "rlang", - "stringr", "vctrs" ], - "Hash": "aa5a3864397ce6ae03458f98618395a1" + "Hash": "bffa126bf92987e677c12cfb5651fc1d" }, "progress": { "Package": "progress", @@ -1316,7 +1352,7 @@ }, "promises": { "Package": "promises", - "Version": "1.3.0", + "Version": "1.3.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1328,7 +1364,7 @@ "rlang", "stats" ], - "Hash": "434cd5388a3979e74be5c219bcd6e77d" + "Hash": "c84fd4f75ea1f5434735e08b7f50fbca" }, "proxy": { "Package": "proxy", @@ -1344,18 +1380,18 @@ }, "ps": { "Package": "ps", - "Version": "1.7.6", + "Version": "1.9.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "dd2b9319ee0656c8acf45c7f40c59de7" + "Hash": "8609dabea57eccf858a5923e4a9e77d4" }, "purrr": { "Package": "purrr", - "Version": "1.0.2", + "Version": "1.0.4", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1366,18 +1402,18 @@ "rlang", "vctrs" ], - "Hash": "1cba04a4e9414bdefc9dcaa99649a8dc" + "Hash": "cc8b5d43f90551fa6df0a6be5d640a4f" }, "ragg": { "Package": "ragg", - "Version": "1.3.2", + "Version": "1.3.3", "Source": "Repository", - "Repository": "CRAN", + "Repository": "RSPM", "Requirements": [ "systemfonts", "textshaping" ], - "Hash": "e3087db406e079a8a2fd87f413918ed3" + "Hash": "0595fe5e47357111f29ad19101c7d271" }, "rappdirs": { "Package": "rappdirs", @@ -1436,7 +1472,7 @@ }, "readxl": { "Package": "readxl", - "Version": "1.4.3", + "Version": "1.4.5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1447,7 +1483,7 @@ "tibble", "utils" ], - "Hash": "8cf9c239b96df1bbb133b74aef77ad0a" + "Hash": "18948de59f05d38a44d3e5065a76b4b6" }, "rematch": { "Package": "rematch", @@ -1502,18 +1538,18 @@ }, "rlang": { "Package": "rlang", - "Version": "1.1.3", + "Version": "1.1.5", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "utils" ], - "Hash": "42548638fae05fd9a9b5f3f437fbbbe2" + "Hash": "724dcc1490cd7071ee75ca2994a5446e" }, "rmarkdown": { "Package": "rmarkdown", - "Version": "2.27", + "Version": "2.29", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1532,7 +1568,7 @@ "xfun", "yaml" ], - "Hash": "27f9502e1cdbfa195f94e03b0f517484" + "Hash": "df99277f63d01c34e95e3d2f06a79736" }, "rootSolve": { "Package": "rootSolve", @@ -1549,7 +1585,7 @@ }, "roxygen2": { "Package": "roxygen2", - "Version": "7.3.1", + "Version": "7.3.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1571,11 +1607,11 @@ "withr", "xml2" ], - "Hash": "c25fe7b2d8cba73d1b63c947bf7afdb9" + "Hash": "6ee25f9054a70f44d615300ed531ba8d" }, "rpart": { "Package": "rpart", - "Version": "4.1.23", + "Version": "4.1.24", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1584,7 +1620,7 @@ "graphics", "stats" ], - "Hash": "b3d390424f41d04174cccf84d49676c2" + "Hash": "ad31b457482eda7a12e51c5d8e7b0be4" }, "rprojroot": { "Package": "rprojroot", @@ -1598,10 +1634,10 @@ }, "rstudioapi": { "Package": "rstudioapi", - "Version": "0.16.0", + "Version": "0.17.1", "Source": "Repository", "Repository": "CRAN", - "Hash": "96710351d642b70e8f02ddeb237c46a7" + "Hash": "5f90cd73946d706cfe26024294236113" }, "rversions": { "Package": "rversions", @@ -1631,7 +1667,7 @@ }, "sessioninfo": { "Package": "sessioninfo", - "Version": "1.2.2", + "Version": "1.2.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1640,11 +1676,11 @@ "tools", "utils" ], - "Hash": "3f9796a8d0a0e8c6eb49a4b029359d1f" + "Hash": "bf169c6e52cdbded916e448dc1254913" }, "shiny": { "Package": "shiny", - "Version": "1.8.1.1", + "Version": "1.10.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1673,7 +1709,7 @@ "withr", "xtable" ], - "Hash": "54b26646816af9960a4c64d8ceec75d6" + "Hash": "4b4477baa9a939c5577e5ddb4bf01f28" }, "sourcetools": { "Package": "sourcetools", @@ -1687,7 +1723,7 @@ }, "spatial": { "Package": "spatial", - "Version": "7.3-17", + "Version": "7.3-18", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1696,7 +1732,7 @@ "stats", "utils" ], - "Hash": "1229a01b4ec059e9f2396724f2ec9010" + "Hash": "b383e36583d9f80270751c490439189c" }, "stringi": { "Package": "stringi", @@ -1749,7 +1785,7 @@ }, "survival": { "Package": "survival", - "Version": "3.5-8", + "Version": "3.8-3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1761,30 +1797,34 @@ "stats", "utils" ], - "Hash": "184d7799bca4ba8c3be72ea396f4b9a3" + "Hash": "fe42836742a4f065b3f3f5de81fccab9" }, "sys": { "Package": "sys", - "Version": "3.4.2", + "Version": "3.4.3", "Source": "Repository", - "Repository": "CRAN", - "Hash": "3a1be13d68d47a8cd0bfd74739ca1555" + "Repository": "RSPM", + "Hash": "de342ebfebdbf40477d0758d05426646" }, "systemfonts": { "Package": "systemfonts", - "Version": "1.1.0", + "Version": "1.2.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "cpp11", - "lifecycle" + "grid", + "jsonlite", + "lifecycle", + "tools", + "utils" ], - "Hash": "213b6b8ed5afbf934843e6c3b090d418" + "Hash": "f8b2924480a2679e2bad9750646112fe" }, "testthat": { "Package": "testthat", - "Version": "3.2.1.1", + "Version": "3.2.3", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1809,20 +1849,23 @@ "waldo", "withr" ], - "Hash": "3f6e7e5e2220856ff865e4834766bf2b" + "Hash": "42f889439ccb14c55fc3d75c9c755056" }, "textshaping": { "Package": "textshaping", - "Version": "0.4.0", + "Version": "1.0.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "cpp11", "lifecycle", - "systemfonts" + "stats", + "stringi", + "systemfonts", + "utils" ], - "Hash": "5142f8bc78ed3d819d26461b641627ce" + "Hash": "5d44adc8145c718066b0bc374d142ca1" }, "tibble": { "Package": "tibble", @@ -1861,24 +1904,24 @@ }, "tinytex": { "Package": "tinytex", - "Version": "0.51", + "Version": "0.56", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "xfun" ], - "Hash": "d44e2fcd2e4e076f0aac540208559d1d" + "Hash": "68e6032b8c16f33fab8756e40a0dca1a" }, "tzdb": { "Package": "tzdb", - "Version": "0.4.0", + "Version": "0.5.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "cpp11" ], - "Hash": "f561504ec2897f4d46f0c7657e488ae1" + "Hash": "09e3961e87b7bafa4a9340bbb34aeda8" }, "urlchecker": { "Package": "urlchecker", @@ -1896,7 +1939,7 @@ }, "usethis": { "Package": "usethis", - "Version": "2.2.3", + "Version": "3.1.0", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -1918,12 +1961,13 @@ "rprojroot", "rstudioapi", "stats", + "tools", "utils", "whisker", "withr", "yaml" ], - "Hash": "d524fd42c517035027f866064417d7e6" + "Hash": "0d7f5ca181f9b1e68b217bd93b6cc703" }, "utf8": { "Package": "utf8", @@ -1977,21 +2021,18 @@ }, "waldo": { "Package": "waldo", - "Version": "0.5.2", + "Version": "0.6.1", "Source": "Repository", "Repository": "CRAN", "Requirements": [ "R", "cli", "diffobj", - "fansi", "glue", "methods", - "rematch2", - "rlang", - "tibble" + "rlang" ], - "Hash": "c7d3fd6d29ab077cbac8f0e2751449e6" + "Hash": "52f574062a7b66e56926988c3fbdb3b7" }, "whisker": { "Package": "whisker", @@ -2002,7 +2043,7 @@ }, "withr": { "Package": "withr", - "Version": "3.0.0", + "Version": "3.0.2", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2010,23 +2051,24 @@ "grDevices", "graphics" ], - "Hash": "d31b6c62c10dcf11ec530ca6b0dd5d35" + "Hash": "cc2d62c76458d425210d1eb1478b30b4" }, "xfun": { "Package": "xfun", - "Version": "0.44", + "Version": "0.51", "Source": "Repository", "Repository": "CRAN", "Requirements": [ + "R", "grDevices", "stats", "tools" ], - "Hash": "317a0538d32f4a009658bcedb7923f4b" + "Hash": "e1a3c06389a46d065c18bd4bbc27c64c" }, "xml2": { "Package": "xml2", - "Version": "1.3.6", + "Version": "1.3.8", "Source": "Repository", "Repository": "CRAN", "Requirements": [ @@ -2035,7 +2077,7 @@ "methods", "rlang" ], - "Hash": "1d0336142f4cd25d8d23cd3ba7a8fb61" + "Hash": "f5130b2f3d461964bac93cc618013231" }, "xmlparsedata": { "Package": "xmlparsedata", @@ -2072,17 +2114,17 @@ }, "yaml": { "Package": "yaml", - "Version": "2.3.8", + "Version": "2.3.10", "Source": "Repository", "Repository": "CRAN", - "Hash": "29240487a071f535f5e5d5a323b7afbd" + "Hash": "51dab85c6c98e50a18d7551e9d49f76c" }, "zip": { "Package": "zip", - "Version": "2.3.1", + "Version": "2.3.2", "Source": "Repository", "Repository": "CRAN", - "Hash": "fcc4bd8e6da2d2011eb64a5e5cc685ab" + "Hash": "2f2ac1424654714391fe94dd69e196a9" } } } diff --git a/tests/testthat/_snaps/class-asyncjob.md b/tests/testthat/_snaps/class-asyncjob.md new file mode 100644 index 0000000..bc71073 --- /dev/null +++ b/tests/testthat/_snaps/class-asyncjob.md @@ -0,0 +1,18 @@ +# AsyncJob print method works + + Code + setup_async_job_obj$print() + Message + + -- Asynchronous Job ------------------------------------------------------------ + * finished_on: 2025-01-31 + * started_on: 2025-01-31 + * failed_files: 0 + * completed_files: 6 + * total_files: 6 + * result: result + * state: FINISHED + * type: type + * id: some-id + * href: some-href + diff --git a/tests/testthat/_snaps/class-division.md b/tests/testthat/_snaps/class-division.md new file mode 100644 index 0000000..14a3527 --- /dev/null +++ b/tests/testthat/_snaps/class-division.md @@ -0,0 +1,11 @@ +# Division print method works + + Code + setup_division_obj$print() + Message + + -- Division -------------------------------------------------------------------- + * name: my-division + * id: some-id + * href: some-href + diff --git a/tests/testthat/_snaps/class-team.md b/tests/testthat/_snaps/class-team.md new file mode 100644 index 0000000..874322b --- /dev/null +++ b/tests/testthat/_snaps/class-team.md @@ -0,0 +1,11 @@ +# Team print method works + + Code + setup_team_obj$print() + Message + + -- Team ------------------------------------------------------------------------ + * name: my-team + * id: some-id + * href: some-href + diff --git a/tests/testthat/setup.R b/tests/testthat/setup.R index fa4e183..a3891b3 100644 --- a/tests/testthat/setup.R +++ b/tests/testthat/setup.R @@ -837,5 +837,98 @@ list1_to_compare <- structure(list( ), class = "response") +# Setup AsyncJob object +asyncjob_res <- list( + id = "some-id", + href = "some-href", + type = "type", + state = "FINISHED", + result = "result", + total_files = 6, + completed_files = 6, + failed_files = 0, + started_on = "2025-01-31", + finished_on = "2025-01-31" +) + +setup_async_job_obj <- asAsyncJob(x = asyncjob_res, auth = setup_auth_object) + + +# Setup Division object +division_res <- list( + id = "some-id", + href = "some-href", + name = "my-division" +) + +setup_division_obj <- asDivision(x = division_res, auth = setup_auth_object) + +# Setup Divisions obj +setup_divisions_obj <- Divisions$new(auth = setup_auth_object) + +# Setup Team object +team_res <- list( + id = "some-id", + href = "some-href", + name = "my-team" +) + +setup_team_obj <- asTeam(x = team_res, auth = setup_auth_object) + +# Setup Teams obj +setup_teams_obj <- Teams$new(auth = setup_auth_object) + +# Create a division object and override its auth$user method to simulate a +# scenario where the division was fetched by a user with the 'ADMIN' role. +setup_auth_admin <- Auth$new(from = "file", config_file = credentials_path) +setup_div_with_admin <- asDivision(x = division_res, auth = setup_auth_admin) +unlockBinding("user", setup_div_with_admin$auth) +setup_div_with_admin$auth$user <- function() { + list( + username = "albus_dumbledore", + email = "albus.dumbledore@hogwarts.com", + first_name = "Albus", + last_name = "Dumbledore", + affiliation = "Hogwarts", + country = "United Kingdom", + role = "ADMIN" + ) +} + +# Create a division object and override its auth$user method to simulate a +# scenario where the division was fetched by a user with the 'MEMBER' role. +setup_auth_member <- Auth$new(from = "file", config_file = credentials_path) +setup_div_with_member <- asDivision(x = division_res, auth = setup_auth_member) # nolint +unlockBinding("user", setup_div_with_member$auth) +setup_div_with_member$auth$user <- function() { + list( + username = "hermione_granger", + email = "hermione.granger@hogwarts.com", + first_name = "Hermione", + last_name = "Granger", + affiliation = "Hogwarts", + country = "United Kingdom", + role = "MEMBER" + ) +} + +# Create a division object and override its auth$user method to simulate a +# scenario where the division was fetched by a user with the +# 'EXTERNAL_COLLABORATOR' role. +setup_auth_ext_collab <- Auth$new(from = "file", config_file = credentials_path) # nolint +setup_div_with_ext_collab <- asDivision(x = division_res, auth = setup_auth_ext_collab) # nolint +unlockBinding("user", setup_div_with_ext_collab$auth) +setup_div_with_ext_collab$auth$user <- function() { + list( + username = "fleur_delacour", + email = "fleur.delacour@beauxbatons.fr", + first_name = "Fleur", + last_name = "Delacour", + affiliation = "Beauxbatons", + country = "France", + role = "EXTERNAL_COLLABORATOR" + ) +} + # Close session at the end of tests withr::defer(teardown_env()) diff --git a/tests/testthat/test-class-asyncjob.R b/tests/testthat/test-class-asyncjob.R new file mode 100644 index 0000000..9f60708 --- /dev/null +++ b/tests/testthat/test-class-asyncjob.R @@ -0,0 +1,21 @@ +test_that("AsyncJob initialization works", { + # Item object creation works + testthat::expect_no_error(asAsyncJob(auth = setup_auth_object)) + + # Item object class and methods are set + checkmate::assert_r6( + setup_async_job_obj, + classes = c("Item", "AsyncJob"), + public = c( + "id", "type", "state", "result", "total_files", + "completed_files", "failed_files", "started_on", "finished_on", + "print", "reload" + ) + ) +}) + +test_that("AsyncJob print method works", { + testthat::skip_on_ci() + testthat::skip_on_cran() + testthat::expect_snapshot(setup_async_job_obj$print()) +}) diff --git a/tests/testthat/test-class-division.R b/tests/testthat/test-class-division.R new file mode 100644 index 0000000..5e87565 --- /dev/null +++ b/tests/testthat/test-class-division.R @@ -0,0 +1,158 @@ +test_that("Division initialization works", { + # Item object creation works + testthat::expect_no_error(asDivision(auth = setup_auth_object)) + + # Item object class and methods are set + checkmate::assert_r6( + setup_division_obj, + classes = c("Item", "Division"), + public = c( + "id", "name", "print", "reload", "list_teams", "list_members", + "remove_member" + ) + ) +}) + +test_that("Division print method works", { + testthat::skip_on_ci() + testthat::skip_on_cran() + testthat::expect_no_error(setup_division_obj$print()) + testthat::expect_snapshot(setup_division_obj$print()) +}) + +test_that("Division list_teams method throws errors when expected", { + # Setup test parameters for test + test_wrong_list_all_num <- list(list_all = 1234) + test_wrong_list_all_string <- list(list_all = "true") + test_wrong_list_all_list <- list(list_all = list(TRUE)) + + + # Query fails when bad 'list_all' parameters are provided + # nolint start + testthat::expect_error(do.call(setup_div_with_admin$list_teams, test_wrong_list_all_num), + regexp = "Assertion on 'list_all' failed: Must be of type 'logical', not 'double'.", + fixed = TRUE + ) + + testthat::expect_error(do.call(setup_div_with_admin$list_teams, test_wrong_list_all_string), + regexp = "Assertion on 'list_all' failed: Must be of type 'logical', not 'character'.", + fixed = TRUE + ) + + testthat::expect_error(do.call(setup_div_with_admin$list_teams, test_wrong_list_all_list), + regexp = "Assertion on 'list_all' failed: Must be of type 'logical', not 'list'.", + fixed = TRUE + ) + # nolint end +}) + +test_that("Division list_members method throws errors when expected", { + # Setup test parameters for test + test_non_supported_role <- list(role = "MANAGER") + test_invalid_role_param_type <- list(role = 1234) + test_invalid_role_list <- list(role = list("ADMIN")) + test_invalid_role_logical <- list(role = TRUE) + + # Query fails when non-supported 'role' parameter is provided + # nolint start + testthat::expect_error(do.call(setup_div_with_admin$list_members, test_non_supported_role), + regexp = "Assertion on 'role' failed: Must be element of set {'MEMBER','ADMIN','EXTERNAL_COLLABORATOR'}, but is 'MANAGER'.", + fixed = TRUE + ) + # nolint end + + # Query fails when invalid 'role' parameter type is provided + # nolint start + testthat::expect_error(do.call(setup_div_with_admin$list_members, test_invalid_role_param_type), + regexp = "Assertion on 'role' failed: Must be element of set {'MEMBER','ADMIN','EXTERNAL_COLLABORATOR'}, but types do not match (numeric != character).", + fixed = TRUE + ) + + testthat::expect_error(do.call(setup_div_with_admin$list_members, test_invalid_role_list), + regexp = "Assertion on 'role' failed: Must be element of set {'MEMBER','ADMIN','EXTERNAL_COLLABORATOR'}, but is not atomic scalar.", + fixed = TRUE + ) + + testthat::expect_error(do.call(setup_div_with_admin$list_members, test_invalid_role_logical), + regexp = "Assertion on 'role' failed: Must be element of set {'MEMBER','ADMIN','EXTERNAL_COLLABORATOR'}, but types do not match (logical != character).", + fixed = TRUE + ) + # nolint end + + # Limit parameter is not valid + negative_limit <- list(limit = -1) + string_limit <- list(limit = "limit") + big_limit <- list(limit = 1500) + + testthat::expect_error( + do.call(setup_div_with_admin$list_members, negative_limit), + regexp = "Limit must be integer number between 1 and 100.", + fixed = TRUE + ) + testthat::expect_error( + do.call(setup_div_with_admin$list_members, string_limit), + regexp = "Limit must be integer number between 1 and 100.", + fixed = TRUE + ) + testthat::expect_error( + do.call(setup_div_with_admin$list_members, big_limit), + regexp = "Limit must be integer number between 1 and 100.", + fixed = TRUE + ) + + # Offset parameter is not valid + negative_offset <- list(offset = -10) + string_offset <- list(offset = "offset") + + testthat::expect_error( + do.call(setup_div_with_admin$list_members, negative_offset), + regexp = "Offset must be integer number >= 0.", + fixed = TRUE + ) + testthat::expect_error( + do.call(setup_div_with_admin$list_members, string_offset), + regexp = "Offset must be integer number >= 0.", + fixed = TRUE + ) +}) + +test_that("Division remove_member method throws error when expected", { + # Pass invalid user param + # Remover: Division member (user) with the 'ADMIN' role + testthat::expect_error( + setup_div_with_admin$remove_member(user = NULL), + regexp = "Please provide a username or a User object to remove the member from the division.", # nolint + fixed = TRUE + ) + + testthat::expect_error( + setup_div_with_admin$remove_member( + user = setup_file_obj + ), + regexp = "Assertion on 'user' failed: Must inherit from class 'User', but has classes 'File','Item','R6'.", # nolint + fixed = TRUE + ) + + testthat::expect_error( + setup_div_with_admin$remove_member( + user = 1234 + ), + regexp = "Assertion on 'user' failed: Must be of type 'character', not 'double'.", # nolint + fixed = TRUE + ) + + # Remove a division member without having the 'ADMIN' role + # Remover: Division member (user) with 'MEMBER' role + testthat::expect_error( + setup_div_with_member$remove_member(user = "some-id/some-username"), + regexp = "You don't have the required permissions to remove members from this division. Only users with the 'ADMIN' role can perform this action.", # nolint + fixed = TRUE + ) + + # Remover: Division member with 'EXTERNAL_COLLABORATOR' role + testthat::expect_error( + setup_div_with_ext_collab$remove_member(user = "some-id/fleur_delacour"), + regexp = "You don't have the required permissions to remove members from this division. Only users with the 'ADMIN' role can perform this action.", # nolint + fixed = TRUE + ) +}) diff --git a/tests/testthat/test-class-divisions.R b/tests/testthat/test-class-divisions.R new file mode 100644 index 0000000..c06fbeb --- /dev/null +++ b/tests/testthat/test-class-divisions.R @@ -0,0 +1,29 @@ +test_that("Divisions initialization works", { + # Resource object creation works + testthat::expect_no_error(Divisions$new(auth = setup_auth_object)) + + # Resource object class and methods are set + checkmate::assert_r6( + setup_divisions_obj, + classes = c("Resource", "Divisions"), + public = c("URL", "query", "get") + ) +}) + +test_that("Divisions get() throws error when expected", { + # Setup test parameters for test + test_bad_id <- list(id = 123) + test_missing_id <- list(id = NULL) + + # Get fails when id 'division_id' parameter is invalid + testthat::expect_error( + do.call(setup_divisions_obj$get, test_bad_id), + regexp = "Assertion on 'id' failed: Must be of type 'character', not 'double'.", # nolint + fixed = TRUE + ) + testthat::expect_error( + do.call(setup_divisions_obj$get, test_missing_id), + regexp = "Please provide the 'id' parameter.", + fixed = TRUE + ) +}) diff --git a/tests/testthat/test-class-files.R b/tests/testthat/test-class-files.R index 9cd7469..36ec56b 100644 --- a/tests/testthat/test-class-files.R +++ b/tests/testthat/test-class-files.R @@ -97,7 +97,7 @@ test_that("Files query() throws error when expected", { # Query fails when origin param is invalid testthat::expect_error( do.call(setup_files_obj$query, test_bad_tag), - regexp = "Assertion on 'tag' failed: Must be of type 'character' (or 'NULL'), not 'double'.", # nolint + regexp = "Tags parameter must be an unnamed list of tags. For example: tags <- list('my_tag_1', 'my_tag_2')", # nolint fixed = TRUE ) }) @@ -250,7 +250,7 @@ test_that("Files create_folder() throws error when expected", { ) testthat::expect_error( do.call(setup_files_obj$create_folder, bad_name_param2), - regexp = "The folder name cannot contain spaces in the name.", # nolint + regexp = "The folder name cannot contain spaces.", # nolint fixed = TRUE ) testthat::expect_error( @@ -368,3 +368,362 @@ test_that("Files bulk_delete() method throws error when expected", { fixed = TRUE ) }) + + +test_that("Files async_bulk_copy() method throws error when expected", { + # 1. Items is empty/missing + items <- NA + testthat::expect_error( + setup_files_obj$async_bulk_copy(items), + regexp = "The items parameter should be a nested list containing information about the files and folders to be copied." # nolint + ) + + # 2. Items is not a list + items <- 45 + testthat::expect_error( + setup_files_obj$async_bulk_copy(items), + regexp = "Assertion on 'items' failed: Must be of type 'list', not 'double'." # nolint + ) + + # 3. File missing in 2nd element + items <- list( + list( + file = "file-id", + project = "proj-id" + ), + list( + project = "proj-id" + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_copy(items), + regexp = "The file ID must be provided as a string or a File object in the element 2." # nolint + ) + + # 4. File is provided as numeric or other class in 2nd element + items <- list( + list( + file = 123, + project = "proj-id" + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_copy(items) + ) + items <- list( + list( + file = setup_project_obj, + project = "proj-id" + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_copy(items) + ) + + # 5. Both parent and project provided + items <- list( + list( + file = "file-id", + project = "proj-id" + ), + list( + file = setup_file_obj, + project = "proj-id", + parent = "parent-id" + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_copy(items), + regexp = "Either the destination project or the parent parameter must be provided in the element 2, but not both." # nolint + ) + + # 6. Neither parent or project are provided + items <- list( + list( + file = "file-id", + project = "proj-id" + ), + list( + file = setup_file_obj + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_copy(items), + regexp = "Please provide either the destination project or the parent parameter in the element 2." # nolint + ) + + # 7. Project provided as numeric + items <- list( + list( + file = "file-id", + project = 123 + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_copy(items) + ) + + # 8. Parent provided as numeric or File with file type + items <- list( + list( + file = "file-id", + parent = 123 + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_copy(items) + ) + items <- list( + list( + file = "file-id", + parent = setup_file_obj + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_copy(items), + regexp = "The destination parent directory parameter must contain either a folder ID or a File object with type = 'folder' in the element 1." # nolint + ) + + # 9. Name provided is not string + items <- list( + list( + file = "file-id", + parent = "parent-id", + name = 123 + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_copy(items) + ) +}) + +test_that("Files async_get_copy_job() method throws error when expected", { + # Job id is empty/missing or not of right class + job_id <- NA + testthat::expect_error( + setup_files_obj$async_get_copy_job(job_id), + regexp = "Please provide the 'job_id' parameter." # nolint + ) + job_id <- setup_file_obj + testthat::expect_error( + setup_files_obj$async_get_copy_job(job_id), + regexp = "Assertion on 'job_id' failed: Must inherit from class 'AsyncJob', but has classes 'File','Item','R6'." # nolint + ) +}) + +test_that("Files async_bulk_delete() method throws error when expected", { + # 1. Items is empty/missing + items <- NA + testthat::expect_error( + setup_files_obj$async_bulk_delete(items), + regexp = "The 'items' parameter should be a list of file/folder IDs or File objects you want to delete." # nolint + ) + + # 2. Items is not a list + items <- 45 + testthat::expect_error( + setup_files_obj$async_bulk_delete(items), + regexp = "Assertion on 'items' failed: Must be of type 'list', not 'double'." # nolint + ) + + # 3. Object of other class in 2nd element + items <- list("file-id", setup_project_obj) + + testthat::expect_error( + setup_files_obj$async_bulk_delete(items), + regexp = "Assertion on 'item' failed: Must inherit from class 'File', but has classes 'Project','Item','R6'." # nolint + ) +}) + +test_that("Files async_get_delete_job() method throws error when expected", { + # Job id is empty/missing or not of right class + job_id <- NA + testthat::expect_error( + setup_files_obj$async_get_delete_job(job_id), + regexp = "Please provide the 'job_id' parameter." # nolint + ) + job_id <- setup_file_obj + testthat::expect_error( + setup_files_obj$async_get_delete_job(job_id), + regexp = "Assertion on 'job_id' failed: Must inherit from class 'AsyncJob', but has classes 'File','Item','R6'." # nolint + ) +}) + +test_that("Files async_bulk_move() method throws an error when expected", { + # 1. Items is empty/missing + items <- NA + testthat::expect_error( + setup_files_obj$async_bulk_move(items), + regexp = "The items parameter should be a nested list containing information about the files and folders to be moved." # nolint + ) + + # 2. Items is not a list + items <- 45 + testthat::expect_error( + setup_files_obj$async_bulk_move(items), + regexp = "Assertion on 'items' failed: Must be of type 'list', not 'double'." # nolint + ) + + # 3. File missing in 2nd element + items <- list( + list( + file = "file-id", + project = "proj-id" + ), + list( + project = "proj-id" + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_move(items), + regexp = "The file ID must be provided as a string or a File object in the element 2." # nolint + ) + + # 4. File is provided as numeric or other class in 2nd element + items <- list( + list( + file = 123, + project = "proj-id" + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_move(items) + ) + items <- list( + list( + file = setup_project_obj, + project = "proj-id" + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_move(items) + ) + + # 5. Both parent and project provided + items <- list( + list( + file = "file-id", + project = "proj-id" + ), + list( + file = setup_file_obj, + project = "proj-id", + parent = "parent-id" + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_move(items), + regexp = "Either the destination project or the parent parameter must be provided in the element 2, but not both." # nolint + ) + + # 6. Neither parent or project are provided + items <- list( + list( + file = "file-id", + project = "proj-id" + ), + list( + file = setup_file_obj + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_move(items), + regexp = "Please provide either the destination project or the parent parameter in the element 2." # nolint + ) + + # 7. Project provided as numeric + items <- list( + list( + file = "file-id", + project = 123 + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_move(items) + ) + + # 8. Parent provided as numeric or File with file type + items <- list( + list( + file = "file-id", + parent = 123 + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_move(items) + ) + items <- list( + list( + file = "file-id", + parent = setup_file_obj + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_move(items), + regexp = "The destination parent directory parameter must contain either a folder ID or a File object with type = 'folder' in the element 1." # nolint + ) + + # 9. Name provided is not string + items <- list( + list( + file = "file-id", + parent = "parent-id", + name = 123 + ) + ) + testthat::expect_error( + setup_files_obj$async_bulk_move(items) + ) +}) + +test_that("Files async_get_move_job() method throws an error when expected", { + # Job id is empty/missing or not of right class + job_id <- NA + testthat::expect_error( + setup_files_obj$async_get_move_job(job_id), + regexp = "Please provide the 'job_id' parameter." # nolint + ) + job_id <- setup_file_obj + testthat::expect_error( + setup_files_obj$async_get_move_job(job_id), + regexp = "Assertion on 'job_id' failed: Must inherit from class 'AsyncJob', but has classes 'File','Item','R6'." # nolint + ) +}) + +test_that("Files async_list_file_jobs() method throws error when expected", { + # 1. Limit is not valid + negative_limit <- list(limit = -1) + string_limit <- list(limit = "limit") + big_limit <- list(limit = 1500) + + testthat::expect_error( + do.call(setup_files_obj$async_list_file_jobs, negative_limit), + regexp = "Limit must be integer number between 1 and 100.", + fixed = TRUE + ) + testthat::expect_error( + do.call(setup_files_obj$async_list_file_jobs, string_limit), + regexp = "Limit must be integer number between 1 and 100.", + fixed = TRUE + ) + testthat::expect_error( + do.call(setup_files_obj$async_list_file_jobs, big_limit), + regexp = "Limit must be integer number between 1 and 100.", + fixed = TRUE + ) + + # 2. Offset is not valid + negative_offset <- list(offset = -10) + string_offset <- list(offset = "offset") + + testthat::expect_error( + do.call(setup_files_obj$async_list_file_jobs, negative_offset), + regexp = "Offset must be integer number >= 0.", + fixed = TRUE + ) + testthat::expect_error( + do.call(setup_files_obj$async_list_file_jobs, string_offset), + regexp = "Offset must be integer number >= 0.", + fixed = TRUE + ) +}) diff --git a/tests/testthat/test-class-imports.R b/tests/testthat/test-class-imports.R index ac1feac..cee1637 100644 --- a/tests/testthat/test-class-imports.R +++ b/tests/testthat/test-class-imports.R @@ -158,7 +158,7 @@ test_that("Imports submit_import() throws error when needed", { ) testthat::expect_error( do.call(setup_imports_obj$submit_import, proj_parent_provided), - regexp = "Either destination project or parent parameter must be proveded, not both.", # nolint + regexp = "Either destination project or parent parameter must be provided, not both.", # nolint fixed = TRUE ) # 5. Test with invalid project parameter @@ -385,7 +385,7 @@ test_that("Imports bulk_submit_import() throws error when needed", { ) testthat::expect_error( setup_imports_obj$bulk_submit_import(items = list(proj_parent_provided)), - regexp = "Either destination project or parent parameter must be proveded in element 1, not both.", # nolint + regexp = "Either destination project or parent parameter must be provided in element 1, not both.", # nolint fixed = TRUE ) # 6. Test with invalid project parameter diff --git a/tests/testthat/test-class-project.R b/tests/testthat/test-class-project.R index 5bc923f..e1b86c8 100644 --- a/tests/testthat/test-class-project.R +++ b/tests/testthat/test-class-project.R @@ -97,7 +97,7 @@ test_that("Project create_folder method throws error when expected", { # Test with spaces_folder_name testthat::expect_error( do.call(setup_project_obj$create_folder, spaces_folder_name), - regexp = "The folder name cannot contain spaces in the name.", + regexp = "The folder name cannot contain spaces.", fixed = TRUE ) # Test with invalid_folder_name diff --git a/tests/testthat/test-class-resource.R b/tests/testthat/test-class-resource.R index 493831e..8b9482b 100644 --- a/tests/testthat/test-class-resource.R +++ b/tests/testthat/test-class-resource.R @@ -61,7 +61,7 @@ test_that("Resource delete works", { setup_resource_obj$URL <- list() # Query fails when resource doesn't have delete URL testthat::expect_error(setup_resource_obj$delete(id = "some_id"), - regexp = "Resource can not be deleted!", + regexp = "Resource cannot be deleted!", fixed = TRUE ) diff --git a/tests/testthat/test-class-task.R b/tests/testthat/test-class-task.R index df9ce27..56420fb 100644 --- a/tests/testthat/test-class-task.R +++ b/tests/testthat/test-class-task.R @@ -9,7 +9,7 @@ test_that("Task initialization works", { public = c( "output_location", "outputs", "inputs", "price", "warnings", "errors", "execution_status", "execution_settings", "batch_parent", "batch_input", - "batch_group", "batch_by", "batch", "use_interruptable_instances", + "batch_group", "batch_by", "batch", "use_interruptible_instances", "origin", "end_time", "start_time", "created_on", "executed_by", "created_by", "app", "project", "description", "status", "name", "id", "URL", "auth", "clone", "rerun", "delete", "list_batch_children", diff --git a/tests/testthat/test-class-team.R b/tests/testthat/test-class-team.R new file mode 100644 index 0000000..0990963 --- /dev/null +++ b/tests/testthat/test-class-team.R @@ -0,0 +1,137 @@ +test_that("Team initialization works", { + # Item object creation works + testthat::expect_no_error(asTeam(auth = setup_auth_object)) + + # Item object class and methods are set + checkmate::assert_r6( + setup_team_obj, + classes = c("Item", "Team"), + public = c( + "id", "name", "print", "reload", "list_members", "add_member", + "remove_member", "rename", "delete" + ) + ) +}) + +test_that("Team print method works", { + testthat::skip_on_ci() + testthat::skip_on_cran() + testthat::expect_no_error(setup_team_obj$print()) + testthat::expect_snapshot(setup_team_obj$print()) +}) + + +test_that("Team list_members method throws errors when expected", { + # Limit parameter is not valid + negative_limit <- list(limit = -1) + string_limit <- list(limit = "limit") + big_limit <- list(limit = 1500) + + testthat::expect_error( + do.call(setup_team_obj$list_members, negative_limit), + regexp = "Limit must be integer number between 1 and 100.", + fixed = TRUE + ) + testthat::expect_error( + do.call(setup_team_obj$list_members, string_limit), + regexp = "Limit must be integer number between 1 and 100.", + fixed = TRUE + ) + testthat::expect_error( + do.call(setup_team_obj$list_members, big_limit), + regexp = "Limit must be integer number between 1 and 100.", + fixed = TRUE + ) + + # Offset parameter is not valid + negative_offset <- list(offset = -10) + string_offset <- list(offset = "offset") + + testthat::expect_error( + do.call(setup_team_obj$list_members, negative_offset), + regexp = "Offset must be integer number >= 0.", + fixed = TRUE + ) + testthat::expect_error( + do.call(setup_team_obj$list_members, string_offset), + regexp = "Offset must be integer number >= 0.", + fixed = TRUE + ) +}) + + +test_that("Team add_member method throws errors when expected", { + # 1. Missing user parameter + missing_user <- list(user = NULL) + + testthat::expect_error( + do.call(setup_team_obj$add_member, missing_user), + regexp = "Please provide a username or a User object to add the member to the team.", # nolint + fixed = TRUE + ) + + # 2. Pass invalid user parameter + testthat::expect_error( + setup_team_obj$add_member( + user = setup_file_obj + ), + regexp = "Assertion on 'user' failed: Must inherit from class 'User', but has classes 'File','Item','R6'.", # nolint + fixed = TRUE + ) + + testthat::expect_error( + setup_team_obj$add_member( + user = 1234 + ), + regexp = "Assertion on 'user' failed: Must be of type 'character', not 'double'.", # nolint + fixed = TRUE + ) +}) + +test_that("Team remove_member method throws errors when expected", { + # 1. Missing user parameter + missing_user <- list(user = NULL) + + testthat::expect_error( + do.call(setup_team_obj$remove_member, missing_user), + regexp = "Please provide a username or a User object to remove the member from the team.", # nolint + fixed = TRUE + ) + + # 2. Pass invalid user parameter + testthat::expect_error( + setup_team_obj$remove_member( + user = setup_file_obj + ), + regexp = "Assertion on 'user' failed: Must inherit from class 'User', but has classes 'File','Item','R6'.", # nolint + fixed = TRUE + ) + + testthat::expect_error( + setup_team_obj$remove_member( + user = 1234 + ), + regexp = "Assertion on 'user' failed: Must be of type 'character', not 'double'.", # nolint + fixed = TRUE + ) +}) + +test_that("Team rename method throws errors when expected", { + # 1. Missing name parameter + missing_name_param <- list(name = NULL) + + testthat::expect_error( + do.call(setup_team_obj$rename, missing_name_param), + regexp = "Please provide the new name for the team.", # nolint + fixed = TRUE + ) + + # 2. Pass invalid name parameter + testthat::expect_error( + setup_team_obj$rename( + name = 1234 + ), + regexp = "Assertion on 'name' failed: Must be of type 'string', not 'double'.", # nolint + fixed = TRUE + ) +}) diff --git a/tests/testthat/test-class-teams.R b/tests/testthat/test-class-teams.R new file mode 100644 index 0000000..5565193 --- /dev/null +++ b/tests/testthat/test-class-teams.R @@ -0,0 +1,126 @@ +test_that("Teams query() method fails when intended", { + # 1. Missing division parameter + no_division <- list(division = NULL) + testthat::expect_error( + do.call(setup_teams_obj$query, no_division), + regexp = "Please provide the division ID or Division object you're querying.", # nolint + fixed = TRUE + ) + + # 2. Division parameter of wrong type + division_num <- list(division = 123) + testthat::expect_error( + do.call(setup_teams_obj$query, division_num), + regexp = "Assertion on 'division' failed: Must be of type 'character', not 'double'.", # nolint + fixed = TRUE + ) + + # 3. Division parameter of wrong class + division_proj <- list(division = setup_project_obj) + testthat::expect_error( + do.call(setup_teams_obj$query, division_proj), + regexp = "Assertion on 'division' failed: Must inherit from class 'Division', but has classes 'Project','Item','R6'.", # nolint + fixed = TRUE + ) + + # 4. list_all parameter of wrong type + params <- list(division = setup_division_obj, list_all = 123) + testthat::expect_error( + do.call(setup_teams_obj$query, params), + regexp = "Assertion on 'list_all' failed: Must be of type 'logical', not 'double'.", # nolint + fixed = TRUE + ) +}) + +test_that("Teams get() method fails when intended", { + # 1. Missing id parameter + no_id <- list(id = NULL) + testthat::expect_error( + do.call(setup_teams_obj$get, no_id), + regexp = "Please provide the 'id' parameter.", + fixed = TRUE + ) + + # 2. ID parameter of wrong type + id_num <- list(id = 123) + testthat::expect_error( + do.call(setup_teams_obj$get, id_num), + regexp = "Assertion on 'id' failed: Must be of type 'character', not 'double'.", # nolint + fixed = TRUE + ) + + # 3. ID parameter of wrong class + id_proj <- list(id = setup_project_obj) + testthat::expect_error( + do.call(setup_teams_obj$get, id_proj), + regexp = "Assertion on 'id' failed: Must inherit from class 'Team', but has classes 'Project','Item','R6'.", # nolint + fixed = TRUE + ) +}) + +test_that("Teams create() method fails when intended", { + # 1. Missing division or name parameter + no_division <- list(division = NULL, name = "new-name") + testthat::expect_error( + do.call(setup_teams_obj$create, no_division), + regexp = "Division or new team name is missing. Please provide both parameters.", # nolint + fixed = TRUE + ) + + no_name <- list(division = "division-id", name = NULL) + testthat::expect_error( + do.call(setup_teams_obj$create, no_name), + regexp = "Division or new team name is missing. Please provide both parameters.", # nolint + fixed = TRUE + ) + + # 2. Division parameter of wrong type + division_num <- list(division = 123, name = "new-name") + testthat::expect_error( + do.call(setup_teams_obj$create, division_num), + regexp = "Assertion on 'division' failed: Must be of type 'character', not 'double'.", # nolint + fixed = TRUE + ) + + # 3. Division parameter of wrong class + division_proj <- list(division = setup_project_obj, name = "new-name") + testthat::expect_error( + do.call(setup_teams_obj$create, division_proj), + regexp = "Assertion on 'division' failed: Must inherit from class 'Division', but has classes 'Project','Item','R6'.", # nolint + fixed = TRUE + ) + + # 4. name parameter of wrong type + params <- list(division = setup_division_obj, name = 123) + testthat::expect_error( + do.call(setup_teams_obj$create, params), + regexp = "Assertion on 'name' failed: Must be of type 'string', not 'double'.", # nolint + fixed = TRUE + ) +}) + +test_that("Teams delete() method fails when intended", { + # 1. Missing team parameter + no_team <- list(team = NULL) + testthat::expect_error( + do.call(setup_teams_obj$delete, no_team), + regexp = "Please provide the team ID as string or as Team object.", + fixed = TRUE + ) + + # 2. Team parameter of wrong type + team_num <- list(team = 123) + testthat::expect_error( + do.call(setup_teams_obj$delete, team_num), + regexp = "Assertion on 'team' failed: Must be of type 'character', not 'double'.", # nolint + fixed = TRUE + ) + + # 3. Team parameter of wrong class + team_proj <- list(team = setup_project_obj) + testthat::expect_error( + do.call(setup_teams_obj$delete, team_proj), + regexp = "Assertion on 'team' failed: Must inherit from class 'Team', but has classes 'Project','Item','R6'.", # nolint + fixed = TRUE + ) +}) diff --git a/tests/testthat/test-class-volume.R b/tests/testthat/test-class-volume.R index 384bd0c..731872e 100644 --- a/tests/testthat/test-class-volume.R +++ b/tests/testthat/test-class-volume.R @@ -10,9 +10,10 @@ test_that("Volume initialization works", { "URL", "id", "name", "service", "access_mode", "active", "created_on", "modified_on", "get_file", "list_contents", "delete", "reactivate", "deactivate", "update", - "list_members", "get_member", "add_member", "remove_member", - "modify_member_permissions", "list_imports", "reload" - ) + "list_members", "get_member", "add_member", "add_member_team", + "add_member_division", "remove_member", "modify_member_permissions", + "list_imports", "reload" + ), private = c("add_member_general") ) }) @@ -169,7 +170,7 @@ test_that("Volume get_file method throws error when expected", { ) }) -test_that("Volume add_member method throws error when expected", { +test_that("Volume add_member method for USER type throws error when expected", { # Pass invalid user param testthat::expect_error( setup_s3_volume_obj$add_member( @@ -188,124 +189,182 @@ test_that("Volume add_member method throws error when expected", { regexp = "Assertion on 'user' failed: Must be of type 'character', not 'double'.", # nolint fixed = TRUE ) +}) - # Pass invalid permissions params +test_that("Volume remove_member method throws error when expected", { + # Pass invalid member param testthat::expect_error( - setup_s3_volume_obj$add_member( - user = "test-username", - permissions = 1234 + setup_s3_volume_obj$remove_member( + member = setup_file_obj ), - regexp = "Assertion on 'permissions' failed: Must be of type 'list', not 'double'.", # nolint + regexp = "Assertion on 'member' failed: Must inherit from class 'Member', but has classes 'File','Item','R6'.", # nolint + fixed = TRUE + ) + + testthat::expect_error(setup_s3_volume_obj$remove_member(member = 1234), + regexp = "Assertion on 'member' failed: Must be of type 'character', not 'double'.", # nolint fixed = TRUE ) +}) +test_that("Volume get_member() method throws error when expected", { + # Pass invalid 'member' param testthat::expect_error( - setup_s3_volume_obj$add_member( - user = "test-username", - permissions = list() + setup_s3_volume_obj$get_member( + member = setup_file_obj ), - regexp = "Assertion on 'permissions' failed: Must have length 4, but has length 0.", # nolint + regexp = "Assertion on 'member' failed: Must inherit from class 'Member', but has classes 'File','Item','R6'.", # nolint fixed = TRUE ) + testthat::expect_error(setup_s3_volume_obj$get_member(member = 1234), + regexp = "Assertion on 'member' failed: Must be of type 'character', not 'double'.", # nolint + fixed = TRUE + ) +}) + +test_that("Volume modify_member_permissions() method throws error when expected", { # nolint + # Pass invalid member param testthat::expect_error( - setup_s3_volume_obj$add_member( - user = "test-username", - permissions = list(read = 123, copy = FALSE, write = 234, admin = FALSE) + setup_s3_volume_obj$modify_member_permissions( + member = setup_file_obj, + permissions = list(read = TRUE, copy = TRUE) ), - regexp = "Assertion on 'permissions' failed: May only contain the following types: {logical}, but element 1 has type 'numeric'.", # nolint + regexp = "Assertion on 'member' failed: Must inherit from class 'Member', but has classes 'File','Item','R6'.", # nolint fixed = TRUE ) testthat::expect_error( - setup_s3_volume_obj$add_member( - user = "test-username", + setup_s3_volume_obj$modify_member_permissions( + member = 1234, permissions = list(read = TRUE, copy = TRUE) ), - regexp = "Assertion on 'permissions' failed: Must have length 4, but has length 2.", # nolint + regexp = "Assertion on 'member' failed: Must be of type 'character', not 'double'.", # nolint fixed = TRUE ) + # Pass invalid permissions params testthat::expect_error( - setup_s3_volume_obj$add_member( - user = "test-username", - permissions = list( - read = TRUE, copy = TRUE, admin = FALSE, write = FALSE, - run = TRUE - ) + setup_s3_volume_obj$modify_member_permissions( + member = "test-username", + permissions = 1234 ), - regexp = "Assertion on 'permissions' failed: Must have length 4, but has length 5.", # nolint + regexp = "Assertion on 'permissions' failed: Must be of type 'list', not 'double'.", # nolint fixed = TRUE ) testthat::expect_error( - setup_s3_volume_obj$add_member( - user = "test-username", + setup_s3_volume_obj$modify_member_permissions( + member = "test-username", + permissions = list() + ), + regexp = "Assertion on 'names(permissions)' failed: Must be a subset of {'read','copy','write','admin'}, not empty.", # nolint + fixed = TRUE + ) + + testthat::expect_error( + setup_s3_volume_obj$modify_member_permissions( + member = "test-username", + permissions = list(read = 123, copy = FALSE, admin = FALSE) + ), + regexp = "Assertion on 'permissions' failed: May only contain the following types: {logical}, but element 1 has type 'numeric'.", # nolint + fixed = TRUE + ) + + testthat::expect_error( + setup_s3_volume_obj$modify_member_permissions( + member = "test-username", permissions = list( - readme = TRUE, copyme = TRUE, admin = FALSE, write = FALSE + read = TRUE, copy = TRUE, admin = FALSE, write = FALSE, + run = TRUE ) ), - regexp = "Assertion on 'names(permissions)' failed: Must be a subset of {'read','copy','write','admin'}, but has additional elements {'readme','copyme'}", # nolint + regexp = "Assertion on 'permissions' failed: Must have length <= 4, but has length 5.", # nolint fixed = TRUE ) -}) -test_that("Volume remove_member method throws error when expected", { - # Pass invalid user param testthat::expect_error( - setup_s3_volume_obj$remove_member( - user = setup_file_obj + setup_s3_volume_obj$modify_member_permissions( + member = "test-username", + permissions = 1234 ), - regexp = "Assertion on 'user' failed: Must inherit from class 'Member', but has classes 'File','Item','R6'.", # nolint + regexp = "Assertion on 'permissions' failed: Must be of type 'list', not 'double'.", # nolint fixed = TRUE ) - testthat::expect_error(setup_s3_volume_obj$remove_member(user = 1234), - regexp = "Assertion on 'user' failed: Must be of type 'character', not 'double'.", # nolint + testthat::expect_error( + setup_s3_volume_obj$modify_member_permissions( + member = "test-username", + permissions = list(readme = TRUE, copy = TRUE) + ), + regexp = "Assertion on 'names(permissions)' failed: Must be a subset of {'read','copy','write','admin'}, but has additional elements {'readme'}", # nolint fixed = TRUE ) }) -test_that("Volume get_member method throws error when expected", { - # Pass invalid user param +test_that("Volume add_member_team method for TEAM type throws error when expected", { # nolint + # Pass invalid team param testthat::expect_error( - setup_s3_volume_obj$get_member( - user = setup_file_obj + setup_s3_volume_obj$add_member_team( + team = setup_file_obj, + permissions = list(read = TRUE, copy = TRUE) ), - regexp = "Assertion on 'user' failed: Must inherit from class 'Member', but has classes 'File','Item','R6'.", # nolint + regexp = "Assertion on 'team' failed: Must inherit from class 'Team', but has classes 'File','Item','R6'.", # nolint fixed = TRUE ) - testthat::expect_error(setup_s3_volume_obj$get_member(user = 1234), - regexp = "Assertion on 'user' failed: Must be of type 'character', not 'double'.", # nolint + testthat::expect_error( + setup_s3_volume_obj$add_member_team( + team = 1234, + permissions = list(read = TRUE, copy = TRUE) + ), + regexp = "Assertion on 'team' failed: Must be of type 'character', not 'double'.", # nolint fixed = TRUE ) }) -test_that("Volume modify_member_permissions method throws error when expected", { # nolint - # Pass invalid user param +test_that("Volume add_member_division method for DIVISION type throws error when expected", { # nolint + # Pass invalid division param testthat::expect_error( - setup_s3_volume_obj$modify_member_permissions( - user = setup_file_obj, + setup_s3_volume_obj$add_member_division( + division = setup_file_obj, permissions = list(read = TRUE, copy = TRUE) ), - regexp = "Assertion on 'user' failed: Must inherit from class 'Member', but has classes 'File','Item','R6'.", # nolint + regexp = "Assertion on 'division' failed: Must inherit from class 'Division', but has classes 'File','Item','R6'.", # nolint fixed = TRUE ) testthat::expect_error( - setup_s3_volume_obj$modify_member_permissions( - user = 1234, + setup_s3_volume_obj$add_member_division( + division = 1234, permissions = list(read = TRUE, copy = TRUE) ), - regexp = "Assertion on 'user' failed: Must be of type 'character', not 'double'.", # nolint + regexp = "Assertion on 'division' failed: Must be of type 'character', not 'double'.", # nolint fixed = TRUE ) +}) - # Pass invalid permissions params +test_that("Volume add_member_general method for any type throws error when expected", { # nolint + # 1. Pass invalid 'member' param testthat::expect_error( - setup_s3_volume_obj$modify_member_permissions( - user = "test-username", + setup_s3_volume_obj$private$add_member_general( + member = NULL + ), + regexp = "Assertion on 'member' failed: Must be of type 'string', not 'NULL'.", # nolint + fixed = TRUE + ) + testthat::expect_error( + setup_s3_volume_obj$private$add_member_general( + member = 123 + ), + regexp = "Assertion on 'member' failed: Must be of type 'string', not 'double'.", # nolint + fixed = TRUE + ) + + # 2. Pass invalid 'permissions' param + testthat::expect_error( + setup_s3_volume_obj$private$add_member_general( + member = "test-username", permissions = 1234 ), regexp = "Assertion on 'permissions' failed: Must be of type 'list', not 'double'.", # nolint @@ -313,50 +372,89 @@ test_that("Volume modify_member_permissions method throws error when expected", ) testthat::expect_error( - setup_s3_volume_obj$modify_member_permissions( - user = "test-username", + setup_s3_volume_obj$private$add_member_general( + member = "test-username", permissions = list() ), - regexp = "Assertion on 'names(permissions)' failed: Must be a subset of {'read','copy','write','admin'}, not empty.", # nolint + regexp = "Assertion on 'permissions' failed: Must have length 4, but has length 0.", # nolint fixed = TRUE ) testthat::expect_error( - setup_s3_volume_obj$modify_member_permissions( - user = "test-username", - permissions = list(read = 123, copy = FALSE, admin = FALSE) + setup_s3_volume_obj$private$add_member_general( + member = "test-username", + permissions = list(read = 123, copy = FALSE, write = 234, admin = FALSE) ), regexp = "Assertion on 'permissions' failed: May only contain the following types: {logical}, but element 1 has type 'numeric'.", # nolint fixed = TRUE ) testthat::expect_error( - setup_s3_volume_obj$modify_member_permissions( - user = "test-username", + setup_s3_volume_obj$private$add_member_general( + member = "test-username", + permissions = list(read = TRUE, copy = TRUE) + ), + regexp = "Assertion on 'permissions' failed: Must have length 4, but has length 2.", # nolint + fixed = TRUE + ) + + testthat::expect_error( + setup_s3_volume_obj$private$add_member_general( + member = "test-username", permissions = list( read = TRUE, copy = TRUE, admin = FALSE, write = FALSE, run = TRUE ) ), - regexp = "Assertion on 'permissions' failed: Must have length <= 4, but has length 5.", # nolint + regexp = "Assertion on 'permissions' failed: Must have length 4, but has length 5.", # nolint fixed = TRUE ) testthat::expect_error( - setup_s3_volume_obj$modify_member_permissions( - user = "test-username", - permissions = 1234 + setup_s3_volume_obj$private$add_member_general( + member = "test-username", + permissions = list( + readme = TRUE, copyme = TRUE, admin = FALSE, write = FALSE + ) ), - regexp = "Assertion on 'permissions' failed: Must be of type 'list', not 'double'.", # nolint + regexp = "Assertion on 'names(permissions)' failed: Must be a subset of {'read','copy','write','admin'}, but has additional elements {'readme','copyme'}", # nolint fixed = TRUE ) + # 3. Test invalid 'type' param testthat::expect_error( - setup_s3_volume_obj$modify_member_permissions( - user = "test-username", - permissions = list(readme = TRUE, copy = TRUE) + setup_s3_volume_obj$private$add_member_general( + member = "test-username", + permissions = list( + read = TRUE, copy = TRUE, admin = FALSE, write = FALSE + ), + type = NULL ), - regexp = "Assertion on 'names(permissions)' failed: Must be a subset of {'read','copy','write','admin'}, but has additional elements {'readme'}", # nolint + regexp = "Assertion on 'type' failed: Must be a subset of {'USER','TEAM','DIVISION'}, not empty.", # nolint + fixed = TRUE + ) + + testthat::expect_error( + setup_s3_volume_obj$private$add_member_general( + member = "test-username", + permissions = list( + read = TRUE, copy = TRUE, admin = FALSE, write = FALSE + ), + type = "MEMBER" + ), + regexp = "Assertion on 'type' failed: Must be a subset of {'USER','TEAM','DIVISION'}, but has additional elements {'MEMBER'}.", # nolint + fixed = TRUE + ) + + testthat::expect_error( + setup_s3_volume_obj$private$add_member_general( + member = "test-username", + permissions = list( + read = TRUE, copy = TRUE, admin = FALSE, write = FALSE + ), + type = 123 + ), + regexp = "Assertion on 'type' failed: Must be a subset of {'USER','TEAM','DIVISION'}, but has different type.", # nolint fixed = TRUE ) }) diff --git a/tests/testthat/test-utils-validations.R b/tests/testthat/test-utils-validations.R index 6e5d6ed..fbc306d 100644 --- a/tests/testthat/test-utils-validations.R +++ b/tests/testthat/test-utils-validations.R @@ -164,7 +164,7 @@ test_that("check_folder_name function throws error when expected", { ) testthat::expect_error( do.call(check_folder_name, spaces_in_name), - regexp = "The folder name cannot contain spaces in the name.", + regexp = "The folder name cannot contain spaces.", fixed = TRUE ) }) diff --git a/vignettes/Authentication_and_Billing.Rmd b/vignettes/Authentication_and_Billing.Rmd index b1d7ad4..865b25d 100644 --- a/vignettes/Authentication_and_Billing.Rmd +++ b/vignettes/Authentication_and_Billing.Rmd @@ -85,7 +85,7 @@ a <- Auth$new(token = "") ``` The above will use the Seven Bridges Platform on AWS since neither `platform` -nor `url` were explicitly specified. +nor `url` was explicitly specified. ***Note:*** `platform` and `url` should not be specified at the same time. @@ -107,7 +107,7 @@ sevenbridges2:::sbg_set_env( ) ``` -See if the environment variables are correctly set: +You can check whether the environment variables are correctly set: ```{r} # Check environment variables @@ -362,7 +362,7 @@ The `fields` parameter can be used in the following ways: 1. No `fields` parameter specified: returns **all fields** for each resource returned (TBD for Apps). -2. The `fields` parameter can be set to a list of fields: for example, +2. The `fields` parameter can be set to a list of fields. For example, to return a field's id, name and size for files in a project, you may issue the call `p$list_files(fields = c("id" ,"name", "size"))`. @@ -509,7 +509,7 @@ If something changes in the billing group, you can refresh your `Billing` object by reloading it with: ```{r} -# Reload Billing objcet +# Reload Billing object my_billing_group$reload() ``` diff --git a/vignettes/Enterprise_actions.Rmd b/vignettes/Enterprise_actions.Rmd new file mode 100644 index 0000000..e5f3086 --- /dev/null +++ b/vignettes/Enterprise_actions.Rmd @@ -0,0 +1,306 @@ +--- +title: "Enterprise actions reference guide for Seven Bridges API R Client" +date: "`r Sys.Date()`" +output: + rmarkdown::html_document: + toc: true + toc_float: true + toc_depth: 4 + number_sections: false + theme: "flatly" + highlight: "textmate" + css: "sevenbridges.css" +vignette: > + %\VignetteEngine{knitr::rmarkdown} + %\VignetteIndexEntry{Managing Divisions with Seven Bridges API R Client} + %\VignetteEncoding{UTF-8} +--- + + + + +```{r, include = FALSE} +knitr::opts_chunk$set( + collapse = TRUE, + comment = "#>", + eval = FALSE +) +``` + +# Managing Divisions + +Enterprise access to the Platform is available on demand, and allows companies +or organizations to mimic their internal structure and hierarchy on the Seven +Bridges Platform, thus facilitating simpler and more efficient collaboration. + +Enterprise accounts are granted to users through their organizations. The +organization associated with the Enterprise account may create user groups +(`Divisions` and `Teams`) composed of Enterprise account holders, which are +used to enable collaboration between members of the organization. + +A `Division` on the Platform is a subgroup of users within an `Enterprise`. Use +the `Division` entity to replicate the structure and hierarchy of an +organization, such as departmental groups on the Platform. `Enterprise` +administrators create `Divisions`, but they can assign `Division` +administrators to manage them. + +A `Team` is a subgroup within a `Division`. Division administrators can create +`Teams` to simplify adding multiple members to a project at once. A single +`Division` member can belong to multiple `Teams`. + +Division related operations can be accessed through the `divisions` path +from the `Auth` object. + +When fetching a single division, it is represented as a `Division` object, +which contains the following information: + +- `id`: Division ID +- `name`: Division name + +The division object also has additional methods that can be executed directly +on it, such as: `TO BE ADDED` + + + +## List all your divisions + +The following call returns a Collection with a list of all divisions you are a +member of. Each division ID, name and URL on the Seven Bridges Platform will be +returned. + +```{r} +# Authenticate (division authentication token is required) +a <- Auth$new(platform = "aws-us", token = "") + +# Query all divisions of which you are a member +a$divisions$query() +``` + + +## Get details of a division + +The following call returns the details of a specified division. + +```{r} +# Retrieve details of a specified division +a$divisions$get(id = "division-id") +``` + + +## List all your teams in a division + +To retrieve a list of all teams in a division that you are a member of, use the +`list_teams()` method of a `Division` object. This method returns a +`Collection` of `Team` objects, each containing the team's ID and name. + +If you want to list all teams within the division, regardless of whether you +are a member, set the `list_all` parameter to `TRUE`. + +```{r} +# Retrieve details of a specified division +my_division <- a$divisions$get(id = "division-id") + +# List division teams you are a member of +my_division$list_teams() + +# List all teams in the division, including those you are not a member of +my_division$list_teams(list_all = TRUE) +``` + + +## List members of a division + +To retrieve a list of all members in a division, use the `list_members()` +method of a `Division` object. This method returns a `Collection` of `User` +objects, each containing user details. + +If you want to filter members by role, you can specify the `role` parameter. +The supported roles are `"ADMIN"`, `"MEMBER"`, and `"EXTERNAL_COLLABORATOR"`. +The default value for this parameter is `NULL`, meaning that if `role` is not +provided, members of all roles will be included in the results. + +```{r} +# Retrieve details of a specific division +my_division <- a$divisions$get(id = "division-id") + +# List all members in the division +my_division$list_members() + +# List only members with the "ADMIN" role +my_division$list_members(role = "ADMIN") +``` + + +## Remove a member from a division + +To remove a member from a division, use the `remove_member()` method of a +`Division` object. This action revokes the user's membership in the division +but does not delete their Platform account. + +Only users with the `ADMIN` role in the division have permission to remove +members. If a user without `ADMIN` privileges attempts to perform this action, +an error will be raised. + +The user parameter accepts either a username (formatted as +`"division-name/username"`) or a `User` object. + +```{r} +# Retrieve details of a specific division +my_division <- a$divisions$get(id = "division-id") + +# Remove a member using their username +my_division$remove_member(user = "division-name/username") + +# Remove a member using a User object +members <- my_division$list_members(role = "MEMBER") +member_to_remove <- members$items[[1]] +my_division$remove_member(user = member_to_remove) +``` + +# Managing teams + +As mentioned before, the `Team` entity is the subgroup of the `Division` and +enterprise users can perform certain actions on created teams too. + +We have created the `Teams` class as a `Resource` class, just like we have for +`Apps`, `Files`, `Projects`, etc., in addition to the `Team` class, +which stores information about a single team. + +`Teams` class helps us organizing our team methods on `Auth` object, therefore, +on the `auth$teams` path you may find the well known methods for querying teams +(`query()`), fetching a single team (`get()`), creating a new team (`create()`) +and deleting teams (`delete()`). + +Querying teams (`query()`) requires a division parameter provided in form of +string (as division ID) or as `Division` object, and it returns a `Collection` +of teams user has access to. With parameter `list_all` you can control whether +to return all teams regardless of whether you are a member of a team or not. + +Method `get()` fetches a single team by its ID provided. + +Creating new teams (`create()`) requires only a `division` parameter specifying +where to create the team, and a `name` parameter for the new team's name. + +Deleting teams (`delete()`) is possible by providing a team ID or `Team` object. + +Examples of usage are presented below: + +```{r} +# Query all teams in a specific division +my_teams <- a$teams$query(division = "division-id", list_all = TRUE) +print(my_teams) +``` +``` +── 1 ── + +── Team ───────────────────────────────────────────────────────────────────── +• name: +• id: +• href: + +── 2 ── + +── Team ───────────────────────────────────────────────────────────────────── +• name: +• id: +• href: + +``` +```{r} +# Fetch single team by ID +my_test_team <- a$teams$get("my-test-team-id") +print(my_test_team) + +# Create new team +new_team <- a$teams$create(division = "division-id", name = "my-new-team") +print(new_team) + +# Delete a team +a$teams$delete(team = "my-new-team-id") +``` + + +## Team object methods + +When you retrieve a single Team, you can use the following methods to manage +it: + +* list_members() +* add_member() +* remove_member() +* rename() +* delete() + +Your ability to perform these actions depends on your `role` within the +platform division to which the team belongs. Some operations require `ADMIN` +privileges, while users with the `MEMBER` or `EXTERNAL_COLLABORATOR` role may +have limited access. If you attempt an action without sufficient privileges, +you will receive an error message like: + +`Insufficient privileges to access the requested team/member information.` + + +### Listing team members + +To retrieve the members of a specific team, use the `list_members()` method on +a `Team` object: + +```{r} +# Fetch a team by its ID +my_team <- a$teams$get("my-team-id") + +# List the team's members +my_team$list_members() +``` + + +### Adding a member to a team + +You can add a new member to a team using the `add_member()` method on a `Team` +object: + +```{r} +# Add a team member by providing their username +my_team$add_member(user = "division-name/username") +``` + +Alternatively, you can pass a `User` object to the `user` parameter instead of +a username. + + +### Removing a team member + +You can remove a team member using the `remove_member()` method on a `Team` +object: + +```{r} +# Remove a team member by providing their username +my_team$remove_member(user = "division-name/username") +``` + +Providing a `User` object would work as well. + + +### Renaming a team + +To rename an existing team, use the `rename()` method on a `Team` object and +provide the new name via the `name` parameter: + +```{r} +# Rename the team +my_team$rename(name = "new-team-name") +``` + +### Deleting a team + +If you need to delete a team, use the `delete()` method on the corresponding +`Team` object: + +```{r} +# Delete the team +my_team$delete() +``` + +After executing this command, you will see a confirmation message in the console: + +`The team has been deleted.` diff --git a/vignettes/Files_upload_and_Volumes.Rmd b/vignettes/Files_upload_and_Volumes.Rmd index c71a98b..0a5d530 100644 --- a/vignettes/Files_upload_and_Volumes.Rmd +++ b/vignettes/Files_upload_and_Volumes.Rmd @@ -640,9 +640,13 @@ you can use `list_members()` and `get_member()` operations: aws_iam_user_volume$list_members() # limit = 2 # Get single member -aws_iam_user_volume$get_member(user = "") +aws_iam_user_volume$get_member(member = "") ``` +This action works also with teams and divisions as volume members if ran by +user with ADMIN account privileges. The input should be either such Member +object or team/division string ID. + ### Remove members @@ -652,25 +656,30 @@ the `Member` class to the `remove_member()` function: ```{r} # Remove member -aws_iam_user_volume$remove_member("") +aws_iam_user_volume$remove_member(member = "") # Remove member using the Member object members <- aws_iam_user_volume$list_members() aws_iam_user_volume$remove_member(members$items[[3]]) ``` +This action works also with teams and divisions as volume members if ran by +user with ADMIN account privileges. The input should be either such Member +object or team/division string ID. + ### Adding new members -The function for adding new members to the volume can accept a `Member` object -(for example used in a project) or its username. +The function for adding new members to the volume allows a `Member` object +(for example used in a project) or its username as input. ```{r} # Add member via username -aws_iam_user_volume$add_member(user = "", permissions = list( - read = TRUE, copy = TRUE, write = FALSE, admin = FALSE -)) +aws_iam_user_volume$add_member( + user = "", + permissions = list(read = TRUE, copy = TRUE, write = FALSE, admin = FALSE) +) # Add member via Member object aws_iam_user_volume$add_member( @@ -685,6 +694,61 @@ aws_iam_user_volume$add_member( ) ``` +#### Users with ADMIN privileges on divisions or enterprises + +Users with Enterprise account (not linked to any division) can add whole teams +and divisions as members of a specified volume. However, be aware that those +users (if MEMBER role) cannot list divisions or fetch single division/team. + +Users with ADMIN and MEMBER privileges on some Division can add teams from +this division to a volume created in the same division. + +```{r} +# Add team via team ID +aws_iam_user_volume$add_member_team( + team = "", + permissions = list(read = TRUE, copy = TRUE, write = FALSE, admin = FALSE) +) + +# Add member via Team object +# Query teams in division and fetch first team to add to a volume +teams <- a$teams$query(division = "division-id") +team <- teams$items[[1]] + +aws_iam_user_volume$add_member_team( + team = team, + permissions = list( + read = TRUE, copy = TRUE, write = FALSE, + admin = FALSE + ) +) +``` + +Enterprise users with ADMIN privileges that are part of default division can +add both divisions and teams from any division to a volume created in this +default division: + +```{r} +# Add division via division ID +aws_iam_user_volume$add_member_division( + division = "", + permissions = list(read = TRUE, copy = TRUE, write = FALSE, admin = FALSE) +) + +# Add member via Division object +# Query divisions and fetch first division to add to a volume +divisions <- a$divisions$query() +division <- divisions$items[[1]] + +aws_iam_user_volume$add_member_division( + division = division, + permissions = list( + read = TRUE, copy = TRUE, write = FALSE, + admin = FALSE + ) +) +``` + ### Modifying a member's permissions @@ -695,11 +759,15 @@ privileges they want to change: ```{r} # Modify member permissions aws_iam_user_volume$modify_member_permissions( - user = "", + member = "", permissions = list(write = TRUE) ) ``` +This action works also with teams and divisions as volume members if ran by +user with ADMIN account privileges. The input should be either such Member +object or team/division string ID. + ### Deactivate and reactivate the volume @@ -1216,7 +1284,7 @@ The required input should be a nested list of elements for each file you want to export containing specific fields: `source_file`, `destination_volume`, `destination_location`, `overwrite` and `properties` that accepts a list with fields: `sse_algorithm`, -`sse_aws_kms_key_id` and/or `aws_canned_acl`. +`sse_aws_kms_key_Id` and/or `aws_canned_acl`. ```{r} ## First, get the project and files you want to export diff --git a/vignettes/Projects_and_Tasks_execution.Rmd b/vignettes/Projects_and_Tasks_execution.Rmd index 217eb2b..288171a 100644 --- a/vignettes/Projects_and_Tasks_execution.Rmd +++ b/vignettes/Projects_and_Tasks_execution.Rmd @@ -550,6 +550,37 @@ a$files$delete(file = "") +### Asynchronous delete action on multiple files/folders + +To delete multiple files at once, you can use async action for bulk delete. +It can be called from the `Auth$files` path and accepts a list of file/folder +IDs or `File` objects. Deletion of non-empty folders including their content +is allowed. + +```{r} +# Delete multiple files +async_delete_job <- a$files$async_bulk_delete( + items = list("file1-id", "file2-id", file_obj) +) +``` + +Since the response returned is an asynchronous job of class `AsyncJob`, you can +check its status by reloading the object or by calling the function +`a$files$async_get_delete_job()`. + +```{r} +# Reload object to check its status +async_delete_job$reload() +async_delete_job + +# Or fetch async delete job object by id +async_delete_job <- a$files$async_get_delete_job(job_id = "") +async_delete_job +``` + + + + ## Copy files The `copy()` method allows you to copy multiple files between projects at a @@ -573,6 +604,50 @@ a$files$copy( +### Asynchronous bulk copy of multiple files + +This operation lets you perform a bulk copy operation of files and folders. +Any underlying folder structure will be preserved. You can copy: + +- to a folder within the same project +- to another project +- to a folder in another project. + +```{r} +# Fetch files by id to copy into the api-testing project +file1 <- a$files$get(id = "6435367997d9446ecb66cfb2") +file2 <- a$files$get(id = "6435367997d9446ecb66cgr2") + +# Copy files to a project +async_job_copy <- a$files$async_bulk_copy( + items = list( + list( + file = file1, + project = "/api-testing" + ), + list( + file = file2, + parent = "", + name = "copied_file_new_name" + ) + ) +) + +# Reload object to check status +async_job_copy$reload() +async_job_copy + +# Or fetch async copy job object by id +async_job_copy <- a$files$async_get_copy_job(job_id = "") +async_job_copy +``` + +This operation allows you to perform bulk copy action and continue your work +in an R session. The status of the copy operation can be previewed by reloading +the AsyncJob object or by calling the operation `a$files$async_get_copy_job()`. + + + ## Get details of multiple files The `bulk_get()` method allows you to retrieve details for multiple files @@ -695,6 +770,21 @@ a$files$bulk_edit(files = list(file_obj_1, file_obj_2)) +## Get details of all asynchronous file jobs + +The `async_list_file_jobs()` method retrieves details of all asynchronous file +jobs (async_copy, async_delete, async_move) in a single API call. +This method accepts `limit` and `offset` arguments to control the +number of returned results. The output is a `Collection` object containing a +list of `AsyncJob` objects, each with details such as type, ID, status, start +and completion time, etc. + +```{r} +# Get details of all async file jobs +all_jobs <- a$files$async_list_file_jobs() +all_jobs +``` + ## Create a folder within the destination project or parent folder To create a new folder on the Platform, use the `Auth$files` method @@ -745,6 +835,61 @@ demo_folder <- a$files$create_folder( +## Asynchronous bulk move of multiple files + +This operation lets you perform a bulk move operation of files and folders. +You can move: + +- to a root project folder +- to a subfolder within the same project or a different project + +Rules for moving files and folders: + +- The file ID is preserved after the move. +- The folder ID is changed after the move. +- The destination has to be an existing folder. +- If the target folder contains a folder with the same name, the contents of +both folders will be merged. +- If a file with the same name already exists, the source file will be +automatically renamed (by adding a numeric prefix). +- You need to have `WRITE` permissions for both the source and destination +folders. + +```{r} +# Fetch files by ID to move them into the "api-testing" project +file1 <- a$files$get(id = "") +file2 <- a$files$get(id = "") + +# Move files to a project +async_job_move <- a$files$async_bulk_move( + items = list( + list( + file = file1, + project = "/api-testing" + ), + list( + file = file2, + parent = "", + name = "moved_file_new_name" + ) + ) +) + +# Reload the object to check the status +async_job_move$reload() +async_job_move + +# Or fetch the async move job object by id +async_job_move <- a$files$async_get_move_job(job_id = "") +async_job_move +``` + +This operation enables you to perform a bulk move action while continuing your +work in an R session. You can check the status of the move operation by +reloading the `AsyncJob` object or calling `a$files$async_get_move_job()`. + + + ## File object operations Let's see now all available operations on the `File` objects that can be called. @@ -826,7 +971,7 @@ demo_file$update(name = "") # Update file metadata demo_file$update( - metadata = list("" = "" = "") ) # Update file tags diff --git a/vignettes/quickstart.Rmd b/vignettes/quickstart.Rmd index cafb7cc..c565aeb 100644 --- a/vignettes/quickstart.Rmd +++ b/vignettes/quickstart.Rmd @@ -54,8 +54,8 @@ preserved. ## R Client for the Seven Bridges API -In order to use the `sevenbridges2` package users must authenticate themselves -first by creating an Auth object and providing necessary credentials. +In order to use the `sevenbridges2` package, users must authenticate themselves +first by creating an Auth object and providing the necessary credentials. You can read more about the authentication types in our next chapters. The `sevenbridges2` package only supports v2+ versions of the API, since @@ -65,20 +65,20 @@ methods. ## Installation -The `sevenbridges2` package is available on CRAN and Seven Bridges Github +The `sevenbridges2` package is available on CRAN and the Seven Bridges GitHub repository. -To install it from `CRAN`, use simply: +To install it from `CRAN`, simply use: ```{r} # Install package from CRAN install.packages("sevenbridges2") ``` -To install the development version from the `develop` branch on our Github, use +To install the development version from the `develop` branch on our GitHub, use the `remotes` package: ```{r} -# Install package from github +# Install package from GitHub remotes::install_github( "sbg/sevenbridges2", build_vignettes = TRUE, dependencies = TRUE @@ -134,16 +134,16 @@ operation within the `Collection` object you've received as the result. __`Collection`__ -Every API call that returns a list of items (usually the output from `query()` operations), operations), like fetching projects, files, apps etc, wraps the +Every API call that returns a list of items (usually the output from `query()` operations), like fetching projects, files, apps, etc., wraps the results into a general `Collection` class object containing the `items` field from which users may access the items returned. Additional options that the `Collection` class offers are to navigate between pages of results, for example, to load next or previous page of results by calling `next_page()` and `prev_page()` methods. -Moreover, users can fetch all results using `Collection`'s `all()` method which -is a shortcut to send multiple API calls for each next page and collect all -results. Keep in mind the `limit` used, as well as the API rate limit. +Moreover, users can fetch all results using the `Collection`'s `all()` method, +which is a shortcut to send multiple API calls for each next page and collect +all results. Keep in mind the `limit` used, as well as the API rate limit. ```{r} # Create a collection of files @@ -242,7 +242,7 @@ Let's load the package first: library("sevenbridges2") ``` -You have three different ways to provide your token. +You have three different ways of providing your token. Choose from one of the methods below: 1. [Direct authentication.](#method1) Here you should provide your developer @@ -264,8 +264,8 @@ have previously set these environment variables. Alternatively, you can specify the names of the system environment variables you want to be loaded using the `sysenv_token` and `sysenv_url` arguments. -3. [Authentication via the user configuration file.](#method3) This file, by -default `$HOME/.sevenbridges/credentials`, provides an organized way to collect +3. [Authentication via the user configuration file.](#method3) By default, this +file (`$HOME/.sevenbridges/credentials`) provides an organized way to collect and manage all your API authentication information for Seven Bridges platforms. If you need to be logged into multiple accounts at the same time (which can @@ -511,8 +511,8 @@ a$billing_groups$get(id = "") -Please check `vignette("Authentication_and_Billing", package = "sevenbridges2")` for more technical details about -billing informations. +Please check `vignette("Authentication_and_Billing", package = "sevenbridges2")` +for more technical details about billing information. ## List and query projects @@ -540,13 +540,13 @@ demo_projects <- a$projects$query(name = "demo") tagged_projects <- a$projects$query(tags = list("demo")) ``` -Note that the output is the `Collection` object and the results (list of +Note that the output is a `Collection` object and the results (list of `Project` objects) can be found within the `items` field. -Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` for more technical details about -projects. +Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` +for more technical details about projects. ## Create a new project @@ -593,11 +593,11 @@ p <- a$projects$create( The **new project** is created on the platform. Notice also that the variable `p` is an R6 object with fields that contain information about the platform -project. The facility also has several methods that allow you to perform +project. This object also provides several methods that allow you to perform basic platform operations on the project. -Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` for more technical details about -projects. +Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` +for more technical details about projects. ## Get details of a specified project @@ -630,8 +630,8 @@ a$projects$get(id = "/api-testing") • use_elastic_disk: FALSE ``` -Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` for more technical details about -apps. +Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` +for more technical details about apps. ## Copy app into the project @@ -655,11 +655,11 @@ public_apps <- a$apps$query( # Search by ID star_app <- a$apps$get( - id = "admin/sbg-public-data/rna-seq-alignment-star/0" + id = "admin/sbg-public-data/rna-seq-alignment-star-2-7-10a" ) ``` -Now, copy the App your `project` with a new `name`, following this logic. +Now, copy the App to your `project` with a new `name`, following this logic. ```{r} # Copy app into the project @@ -691,7 +691,7 @@ Alternatively, you can copy it from the `App` object. ```{r} # Get public app RNA Sequencing alignment - STAR star_app <- a$apps$get( - id = "admin/sbg-public-data/rna-seq-alignment-star/0" + id = "admin/sbg-public-data/rna-seq-alignment-star-2-7-10a" ) # Copy it into a project @@ -705,15 +705,15 @@ star_app$copy( Next, we would like to run a task with this app. Let's see what is required. -Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` for more technical details about -tasks. +Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` +for more technical details about tasks. ## Execute a new task ### Find your app inputs Once you have copied the public app -`admin/sbg-public-data/rna-seq-alignment-star/0` into your project, +`admin/sbg-public-data/rna-seq-alignment-star-2-7-10a` into your project, `/api-testing`, the app `id` in your current project is `/api-testing/newcopyofstar`. Alternatively, you can use another app you already have in your project for @@ -748,15 +748,15 @@ Locate the IDs of the required inputs. Note that task inputs need to match the expected data type and name. In the above example, we see two required fields: -- **fastq:** This input takes a file array in the following formats: FASTA, +- **in_reads:** This input takes a file array in the following formats: FASTA, FASTQ, FA, FQ etc. -- **genomeFastaFiles:** This is a single reference file in the FASTA, FA, FNA -or TAR format. +- **in_reference_or_sgg_archive:** This is a single reference file in the +FASTA, FA, FNA or TAR format. We also want to provide a gene feature file: -- **sjdbGTFfile:** A file array that can be in the GTF, GFF, GFF2, or GFF3 -format. +- **in_gene_annotation:** A file array that can be in the GTF, GFF, GFF2, or +GFF3 format. You can find a list of possible input types below: @@ -766,7 +766,7 @@ parameter as they are. - **file:** This input is a file. However, while some inputs accept only a single file (`File`), other inputs take more than one file (`File` arrays, `FilesList`, or '`File...`' ). This input requires you to pass a single `File` -object (for a single file input) or list of `File` objects (for inputs which +object (for a single file input) or list of `File` objects (for inputs that accept more than one file). You can search for your file by `id` or by `name`, as shown in the example below. @@ -776,19 +776,19 @@ below. ### Prepare your input files ```{r} -# Get reads (fastq) files and and copy them into a project -reads_1 <- a$files$get(id = "641c48c425ed1842bd0bf799") # file id +# Get reads (fastq) files and copy them into a project +reads_1 <- a$files$get(id = "5772b6f0507c175267448700") # file id reads_1$copy_to(project = p) -reads_2 <- a$files$get(id = "641c48c425ed1842bd0bf835") # file id +reads_2 <- a$files$get(id = "5772b6f2507c175267448703") # file id reads_2$copy_to(project = p) # Get a single file reference file and copy into a project -fasta_in <- a$files$get(id = "641c48c525ed1842bd0bf86a") # file id +fasta_in <- a$files$get(id = "5c614f097369c402a28a3c41") # file id fasta_in$copy_to(project = p) -# Get gtf file and copy into a project -gtf_in <- a$files$get(id = "641c48c425ed1842bd0bf825") # file id +# Get GTF file and copy into a project +gtf_in <- a$files$get(id = "5c614e5e7369c402a18a3c41") # file id gtf_in$copy_to(project = p) # Get copied files @@ -808,9 +808,9 @@ tsk <- p$create_task( description = "STAR test", app = copied_star_app, inputs = list( - "fastq" = c(input_files[[1]], input_files[[2]]), - "genomeFastaFiles" = input_files[[3]], - "sjdbGTFfile" = list(input_files[[4]]) + "in_reads" = c(input_files[[1]], input_files[[2]]), + "in_reference_or_sgg_archive" = input_files[[3]], + "in_gene_annotation" = input_files[[4]] ) ) @@ -832,8 +832,8 @@ copied_star_app$output_matrix() -Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` for more technical details about -tasks. +Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` +for more technical details about tasks. ## Run a Task @@ -894,8 +894,8 @@ Alternatively, you can delete the draft task if you no longer wish to run it. -Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` for more technical details about -running tasks. +Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` +for more technical details about running tasks. ## Run tasks using spot instances @@ -906,8 +906,8 @@ Seven Bridges platforms. Our package follows the same [logic](https://docs.seven as our platform's web interface (the current default setting for spot instances is **on**). -For example, when we create a project using Projects resource's method `create()`, -we can set `use_interruptible = FALSE` to use on-demand instances +For example, when we create a project using the Projects resource's method +`create()`, we can set `use_interruptible = FALSE` to use on-demand instances (non-interruptible but more expensive) instead of the spot instances (interruptible but cheaper): @@ -948,8 +948,8 @@ by setting `use_interruptible_instances = FALSE` in `create_task()` explicitly. -Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` for more technical details about -running tasks using spot instances. +Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` +for more technical details about running tasks using spot instances. ## Execution hints per task run @@ -978,8 +978,8 @@ For details about `execution_settings`, please check [create a new draft task](h -Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` for more technical details about -execution hints. +Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` +for more technical details about execution hints. ## Draft a batch task @@ -1044,5 +1044,5 @@ child2_details <- child_tasks$items[[2]]$get_execution_details() -Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` for more technical details about -running batch tasks. +Please check `vignette("Projects_and_Tasks_execution", package = "sevenbridges2")` +for more technical details about running batch tasks.