├── .Rbuildignore
├── .covrignore
├── .github
├── .gitignore
├── CODEOWNERS
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.Rmd
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE
│ └── issue_template.md
├── SUPPORT.md
└── workflows
│ ├── R-CMD-check.yaml
│ ├── pkgdown.yaml
│ ├── pr-commands.yaml
│ ├── test-coverage.yaml
│ └── with-auth.yml
├── .gitignore
├── DESCRIPTION
├── LICENSE
├── LICENSE.md
├── NAMESPACE
├── NEWS.md
├── R
├── aaa.R
├── camelCase.R
├── compat-dplyr.R
├── compat-vctrs.R
├── deprecated.R
├── dribble.R
├── drive_about.R
├── drive_auth.R
├── drive_browse.R
├── drive_cp.R
├── drive_create.R
├── drive_download.R
├── drive_endpoints.R
├── drive_examples.R
├── drive_fields.R
├── drive_find.R
├── drive_get.R
├── drive_get_path.R
├── drive_id-class.R
├── drive_ls.R
├── drive_mime_type.R
├── drive_mkdir.R
├── drive_mv.R
├── drive_publish.R
├── drive_put.R
├── drive_read.R
├── drive_rename.R
├── drive_reveal.R
├── drive_rm.R
├── drive_share.R
├── drive_trash.R
├── drive_update.R
├── drive_upload.R
├── drive_user.R
├── googledrive-package.R
├── promote.R
├── request_generate.R
├── request_make.R
├── roxygen-templates.R
├── shared_drive_create.R
├── shared_drive_find.R
├── shared_drive_get.R
├── shared_drive_rm.R
├── shared_drive_update.R
├── shared_drives.R
├── shortcut.R
├── sysdata.rda
├── team_drive.R
├── utils-io.R
├── utils-paths.R
├── utils-pipe.R
├── utils-ui.R
├── utils.R
└── zzz.R
├── README.Rmd
├── README.md
├── _pkgdown.yml
├── codecov.yml
├── cran-comments.md
├── data-raw
├── discovery-doc-ingest.R
├── drive-examples-create.R
├── drive-examples-inventory.R
├── drive-v3_2021-06-21.json
├── export-mime-type-defaults.csv
├── extension-mime-type-defaults.csv
├── file-fields.R
├── mime-types.R
└── old
│ ├── 20170519_drive-v3_discovery-document.json
│ ├── 20170519_drive-v3_endpoints-list.json
│ ├── 20170519_drive-v3_endpoints-list.rds
│ ├── 20170519_drive-v3_endpoints-tibble.rds
│ ├── 20170721_drive-v3_discovery-document.json
│ ├── 20170721_drive-v3_endpoints-list.json
│ ├── 20170721_drive-v3_endpoints-list.rds
│ ├── 20170721_drive-v3_endpoints-tibble.rds
│ ├── 20171110_drive-v3_discovery-document.json
│ ├── 20171110_drive-v3_endpoints-list.json
│ ├── 20171110_drive-v3_endpoints-list.rds
│ ├── 20171110_drive-v3_endpoints-tibble.rds
│ ├── discovery-doc-prep.R
│ ├── drive-v3_2019-02-14.json
│ ├── drive-v3_2019-07-08.json
│ ├── drive-v3_2020-04-17.json
│ └── drive-v3_2021-03-22.json
├── googledrive.Rproj
├── index.Rmd
├── index.md
├── inst
├── WORDLIST
├── extdata
│ ├── data
│ │ ├── client_secret_123.googleusercontent.com.json
│ │ ├── files_fields.csv
│ │ ├── mime_tbl.csv
│ │ ├── remote_example_files.csv
│ │ └── translate_mime_types.csv
│ └── example_files
│ │ ├── chicken.csv
│ │ ├── chicken.jpg
│ │ ├── chicken.pdf
│ │ ├── chicken.txt
│ │ ├── imdb_latin1.csv
│ │ ├── r_about.html
│ │ └── r_logo.jpg
└── secret
│ ├── googledrive-docs.json
│ └── googledrive-testing.json
├── internal
├── 2017-08-googledrive-initial-release.Rmd
├── 2017-08-googledrive-initial-release.md
├── 2019-02-18_tidyverse-meeting.R
├── drive_upload.Rmd
├── drive_upload.md
├── googledrive-og-1280x640.png
├── googledrive.png
├── old
│ ├── 01_big-picture.Rmd
│ ├── 01_big-picture.md
│ ├── 02_sharing_demo.Rmd
│ ├── 02_sharing_demo.md
│ ├── 03_publish_demo.Rmd
│ ├── 03_publish_demo.md
│ ├── 04_map_demo.Rmd
│ ├── 04_map_demo.md
│ ├── 06_dots_demo.Rmd
│ ├── 06_dots_demo.md
│ ├── 07_drive_ls_demo.Rmd
│ └── 07_drive_ls_demo.md
└── tokens.R
├── man-roxygen
├── corpus.R
├── dots-metadata.R
├── file-plural.R
├── file-singular.R
├── media.R
├── n_max.R
├── overwrite.R
├── pattern.R
├── shared-drive-description.R
├── shared_drive-plural.R
├── shared_drive-singular.R
├── team-drives-description.R
├── team_drive-plural.R
├── team_drive-singular.R
└── verbose.R
├── man
├── as_dribble.Rd
├── as_shared_drive.Rd
├── deprecated-team-drive-functions.Rd
├── dribble-checks.Rd
├── dribble.Rd
├── drive_about.Rd
├── drive_auth.Rd
├── drive_auth_configure.Rd
├── drive_browse.Rd
├── drive_cp.Rd
├── drive_create.Rd
├── drive_deauth.Rd
├── drive_download.Rd
├── drive_empty_trash.Rd
├── drive_endpoints.Rd
├── drive_examples.Rd
├── drive_extension.Rd
├── drive_fields.Rd
├── drive_find.Rd
├── drive_get.Rd
├── drive_has_token.Rd
├── drive_id.Rd
├── drive_link.Rd
├── drive_ls.Rd
├── drive_mime_type.Rd
├── drive_mkdir.Rd
├── drive_mv.Rd
├── drive_publish.Rd
├── drive_put.Rd
├── drive_read_string.Rd
├── drive_rename.Rd
├── drive_reveal.Rd
├── drive_rm.Rd
├── drive_scopes.Rd
├── drive_share.Rd
├── drive_token.Rd
├── drive_trash.Rd
├── drive_update.Rd
├── drive_upload.Rd
├── drive_user.Rd
├── expose.Rd
├── figures
│ ├── lifecycle-archived.svg
│ ├── lifecycle-defunct.svg
│ ├── lifecycle-deprecated.svg
│ ├── lifecycle-experimental.svg
│ ├── lifecycle-maturing.svg
│ ├── lifecycle-questioning.svg
│ ├── lifecycle-soft-deprecated.svg
│ ├── lifecycle-stable.svg
│ ├── lifecycle-superseded.svg
│ └── logo.png
├── googledrive-configuration.Rd
├── googledrive-deprecated.Rd
├── googledrive-package.Rd
├── pipe.Rd
├── request_generate.Rd
├── request_make.Rd
├── shared_drive_create.Rd
├── shared_drive_find.Rd
├── shared_drive_get.Rd
├── shared_drive_rm.Rd
├── shared_drive_update.Rd
├── shared_drives.Rd
├── shortcut_create.Rd
└── shortcut_resolve.Rd
├── pkgdown
└── favicon
│ ├── apple-touch-icon-120x120.png
│ ├── apple-touch-icon-60x60.png
│ ├── apple-touch-icon-76x76.png
│ ├── apple-touch-icon.png
│ ├── favicon-16x16.png
│ ├── favicon-32x32.png
│ └── favicon.ico
├── revdep
├── .gitignore
├── README.md
├── cran.md
├── failures.md
└── problems.md
├── tests
├── spelling.R
├── testthat.R
└── testthat
│ ├── .gitignore
│ ├── _snaps
│ ├── deprecated.md
│ ├── dribble.md
│ ├── drive_auth.md
│ ├── drive_cp.md
│ ├── drive_create.md
│ ├── drive_download.md
│ ├── drive_examples.md
│ ├── drive_fields.md
│ ├── drive_find.md
│ ├── drive_get.md
│ ├── drive_id-class.md
│ ├── drive_ls.md
│ ├── drive_mime_type.md
│ ├── drive_mv.md
│ ├── drive_publish.md
│ ├── drive_put.md
│ ├── drive_reveal.md
│ ├── drive_share.md
│ ├── drive_update.md
│ ├── drive_upload.md
│ ├── request_generate.md
│ ├── shared_drives.md
│ ├── shortcut.md
│ ├── utils-paths.md
│ └── utils-ui.md
│ ├── driver.R
│ ├── helper.R
│ ├── setup-testing.R
│ ├── test-camelCase.R
│ ├── test-compat-dplyr.R
│ ├── test-compat-vctrs.R
│ ├── test-deprecated.R
│ ├── test-dribble.R
│ ├── test-drive_auth.R
│ ├── test-drive_browse.R
│ ├── test-drive_cp.R
│ ├── test-drive_create.R
│ ├── test-drive_download.R
│ ├── test-drive_endpoints.R
│ ├── test-drive_examples.R
│ ├── test-drive_fields.R
│ ├── test-drive_find.R
│ ├── test-drive_get.R
│ ├── test-drive_get_path.R
│ ├── test-drive_id-class.R
│ ├── test-drive_ls.R
│ ├── test-drive_mime_type.R
│ ├── test-drive_mv.R
│ ├── test-drive_publish.R
│ ├── test-drive_put.R
│ ├── test-drive_read.R
│ ├── test-drive_reveal.R
│ ├── test-drive_rm.R
│ ├── test-drive_share.R
│ ├── test-drive_trash.R
│ ├── test-drive_update.R
│ ├── test-drive_upload.R
│ ├── test-drive_user.R
│ ├── test-fixtures
│ ├── just_a_dribble.rds
│ └── mix_of_files_and_teamdrives.rds
│ ├── test-promote.R
│ ├── test-request_generate.R
│ ├── test-shared_drives.R
│ ├── test-shortcut.R
│ ├── test-utils-paths.R
│ ├── test-utils-ui.R
│ └── test-utils.R
└── vignettes
├── .gitignore
├── articles
├── .gitignore
├── bring-your-own-client.Rmd
├── example-files.Rmd
├── file-identification.Rmd
├── messages-and-errors.Rmd
├── multiple-files.Rmd
└── permissions.Rmd
└── googledrive.Rmd
/.Rbuildignore:
--------------------------------------------------------------------------------
1 | ^.*\.Rproj$
2 | ^\.Rproj\.user$
3 | ^scratch.R$
4 | ^internal$
5 | ^data-raw$
6 | ^\.httr-oauth$
7 | ^\.httr-oauth-SUSPENDED$
8 | ^\.travis\.yml$
9 | ^codecov\.yml$
10 | ^appveyor\.yml$
11 | ^README\.Rmd$
12 | ^README-.*\.png$
13 | ^man-roxygen$
14 | ^docs$
15 | ^_pkgdown\.yml$
16 | ^index\.Rmd$
17 | ^cran-comments\.md$
18 | ^\.github$
19 | ^pkgdown$
20 | ^vignettes/articles$
21 | ^revdep$
22 | ^index\.md$
23 | ^LICENSE\.md$
24 | ^CRAN-RELEASE$
25 | ^\.covrignore$
26 | ^tests/testthat/all-test.+
27 | ^CRAN-SUBMISSION$
28 |
--------------------------------------------------------------------------------
/.covrignore:
--------------------------------------------------------------------------------
1 | R/aaa.R
2 | R/deprecated.R
3 | R/dplyr-compat.R
4 |
--------------------------------------------------------------------------------
/.github/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 |
--------------------------------------------------------------------------------
/.github/CODEOWNERS:
--------------------------------------------------------------------------------
1 | # CODEOWNERS for googledrive
2 | # https://www.tidyverse.org/development/understudies
3 | .github/CODEOWNERS @jennybc @lucymcgowan
4 |
--------------------------------------------------------------------------------
/.github/ISSUE_TEMPLATE/issue_template.md:
--------------------------------------------------------------------------------
1 | Please briefly describe your problem and what output you expect. If you have a question, please don't use this form. Instead, ask on or .
2 |
3 | Please include a minimal reproducible example (AKA a reprex). If you've never heard of a [reprex](https://reprex.tidyverse.org/) before, start by reading .
4 |
5 | ---
6 |
7 | Brief description of the problem
8 |
9 | ```r
10 | # insert reprex here
11 | ```
12 |
--------------------------------------------------------------------------------
/.github/SUPPORT.md:
--------------------------------------------------------------------------------
1 | # Getting help with googledrive
2 |
3 | Thanks for using googledrive. Before filing an issue, there are a few places
4 | to explore and pieces to put together to make the process as smooth as possible.
5 |
6 | Start by making a minimal **repr**oducible **ex**ample using the
7 | [reprex](https://reprex.tidyverse.org/) package. If you haven't heard of or used
8 | reprex before, you're in for a treat! Seriously, reprex will make all of your
9 | R-question-asking endeavors easier (which is a pretty insane ROI for the five to
10 | ten minutes it'll take you to learn what it's all about). For additional reprex
11 | pointers, check out the [Get help!](https://www.tidyverse.org/help/) section of
12 | the tidyverse site.
13 |
14 | Armed with your reprex, the next step is to figure out [where to ask](https://www.tidyverse.org/help/#where-to-ask).
15 |
16 | * If it's a question: start with [community.rstudio.com](https://community.rstudio.com/),
17 | and/or StackOverflow. There are more people there to answer questions.
18 | * If it's a bug: you're in the right place, file an issue.
19 | * If you're not sure: let the community help you figure it out! If your
20 | problem _is_ a bug or a feature request, you can easily return here and
21 | report it.
22 |
23 | Before opening a new issue, be sure to [search issues and pull requests](https://github.com/tidyverse/googledrive/issues) to make sure the
24 | bug hasn't been reported and/or already fixed in the development version. By
25 | default, the search will be pre-populated with `is:issue is:open`. You can
26 | [edit the qualifiers](https://help.github.com/articles/searching-issues-and-pull-requests/)
27 | (e.g. `is:pr`, `is:closed`) as needed. For example, you'd simply
28 | remove `is:open` to search _all_ issues in the repo, open or closed.
29 |
30 |
31 | If you _are_ in the right place, and need to file an issue, please review the
32 | ["File issues"](https://www.tidyverse.org/contribute/#issues) paragraph from
33 | the tidyverse contributing guidelines.
34 |
35 | Thanks for your help!
36 |
--------------------------------------------------------------------------------
/.github/workflows/R-CMD-check.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | #
4 | # NOTE: This workflow is overkill for most R packages and
5 | # check-standard.yaml is likely a better choice.
6 | # usethis::use_github_action("check-standard") will install it.
7 | on:
8 | push:
9 | branches: [main, master]
10 | pull_request:
11 | branches: [main, master]
12 |
13 | name: R-CMD-check.yaml
14 |
15 | permissions: read-all
16 |
17 | jobs:
18 | R-CMD-check:
19 | runs-on: ${{ matrix.config.os }}
20 |
21 | name: ${{ matrix.config.os }} (${{ matrix.config.r }})
22 |
23 | strategy:
24 | fail-fast: false
25 | matrix:
26 | config:
27 | - {os: macos-latest, r: 'release'}
28 |
29 | - {os: windows-latest, r: 'release'}
30 | # use 4.0 or 4.1 to check with rtools40's older compiler
31 | - {os: windows-latest, r: 'oldrel-4'}
32 |
33 | - {os: ubuntu-latest, r: 'devel', http-user-agent: 'release'}
34 | - {os: ubuntu-latest, r: 'release'}
35 | - {os: ubuntu-latest, r: 'oldrel-1'}
36 | - {os: ubuntu-latest, r: 'oldrel-2'}
37 | - {os: ubuntu-latest, r: 'oldrel-3'}
38 | - {os: ubuntu-latest, r: 'oldrel-4'}
39 |
40 | env:
41 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
42 | R_KEEP_PKG_SOURCE: yes
43 |
44 | steps:
45 | - uses: actions/checkout@v4
46 |
47 | - uses: r-lib/actions/setup-pandoc@v2
48 |
49 | - uses: r-lib/actions/setup-r@v2
50 | with:
51 | r-version: ${{ matrix.config.r }}
52 | http-user-agent: ${{ matrix.config.http-user-agent }}
53 | use-public-rspm: true
54 |
55 | - uses: r-lib/actions/setup-r-dependencies@v2
56 | with:
57 | extra-packages: any::rcmdcheck
58 | needs: check
59 |
60 | - uses: r-lib/actions/check-r-package@v2
61 | with:
62 | upload-snapshots: true
63 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'
64 |
--------------------------------------------------------------------------------
/.github/workflows/pkgdown.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | on:
4 | push:
5 | branches: [main, master]
6 | schedule:
7 | # * is a special character in YAML so we have to quote this string
8 | # 13:30 (UTC) - 7 or 8 (offset for Pacific) = 5:30 or 6:30 am
9 | # try to avoid overlap other jobs in googledrive and googlesheets4 because quota
10 | # https://crontab.guru is your friend
11 | - cron: '30 13 * * *'
12 | release:
13 | types: [published]
14 | workflow_dispatch:
15 |
16 | name: pkgdown.yaml
17 |
18 | permissions: read-all
19 |
20 | jobs:
21 | pkgdown:
22 | runs-on: ubuntu-latest
23 | if: |
24 | github.event_name == 'schedule' ||
25 | github.event_name == 'workflow_dispatch' ||
26 | github.event_name == 'release' ||
27 | contains(github.event.head_commit.message, '[pkgdown]')
28 |
29 | env:
30 | GOOGLEDRIVE_KEY: ${{ secrets.GOOGLEDRIVE_KEY }}
31 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
32 | permissions:
33 | contents: write
34 | steps:
35 | - uses: actions/checkout@v4
36 |
37 | - uses: r-lib/actions/setup-pandoc@v2
38 |
39 | - uses: r-lib/actions/setup-r@v2
40 | with:
41 | use-public-rspm: true
42 |
43 | - uses: r-lib/actions/setup-r-dependencies@v2
44 | with:
45 | extra-packages: any::pkgdown, local::.
46 | needs: website
47 |
48 | - name: Build site
49 | run: pkgdown::build_site_github_pages(new_process = FALSE, install = FALSE)
50 | shell: Rscript {0}
51 |
52 | - name: Deploy to GitHub pages 🚀
53 | if: github.event_name != 'pull_request'
54 | uses: JamesIves/github-pages-deploy-action@v4.5.0
55 | with:
56 | clean: false
57 | branch: gh-pages
58 | folder: docs
59 |
--------------------------------------------------------------------------------
/.github/workflows/test-coverage.yaml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | on:
4 | push:
5 | branches: [main, master]
6 | pull_request:
7 | branches: [main, master]
8 | schedule:
9 | # * is a special character in YAML so we have to quote this string
10 | # 2am Pacific = 10am UTC
11 | # https://crontab.guru is your friend
12 | - cron: '0 10 * * *'
13 |
14 | name: test-coverage.yaml
15 |
16 | permissions: read-all
17 |
18 | jobs:
19 | test-coverage:
20 | runs-on: ubuntu-latest
21 | if: "github.event_name == 'schedule' || contains(github.event.head_commit.message, '[covr]')"
22 |
23 | env:
24 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
25 | GOOGLEDRIVE_KEY: ${{ secrets.GOOGLEDRIVE_KEY }}
26 |
27 | steps:
28 | - uses: actions/checkout@v4
29 |
30 | - uses: r-lib/actions/setup-r@v2
31 | with:
32 | use-public-rspm: true
33 |
34 | - uses: r-lib/actions/setup-r-dependencies@v2
35 | with:
36 | extra-packages: any::covr, any::xml2
37 | needs: coverage
38 |
39 | - name: Test coverage
40 | run: |
41 | cov <- covr::package_coverage(
42 | quiet = FALSE,
43 | clean = FALSE,
44 | install_path = file.path(normalizePath(Sys.getenv("RUNNER_TEMP"), winslash = "/"), "package")
45 | )
46 | covr::to_cobertura(cov)
47 | shell: Rscript {0}
48 |
49 | - uses: codecov/codecov-action@v4
50 | with:
51 | fail_ci_if_error: ${{ github.event_name != 'pull_request' && true || false }}
52 | file: ./cobertura.xml
53 | plugin: noop
54 | disable_search: true
55 | token: ${{ secrets.CODECOV_TOKEN }}
56 |
57 | - name: Show testthat output
58 | if: always()
59 | run: |
60 | ## --------------------------------------------------------------------
61 | find '${{ runner.temp }}/package' -name 'testthat.Rout*' -exec cat '{}' \; || true
62 | shell: bash
63 |
64 | - name: Upload test results
65 | if: failure()
66 | uses: actions/upload-artifact@v4
67 | with:
68 | name: coverage-test-failures
69 | path: ${{ runner.temp }}/package
70 |
--------------------------------------------------------------------------------
/.github/workflows/with-auth.yml:
--------------------------------------------------------------------------------
1 | # Workflow derived from https://github.com/r-lib/actions/tree/v2/examples
2 | # Need help debugging build failures? Start at https://github.com/r-lib/actions#where-to-find-help
3 | on:
4 | push:
5 | branches: [main, master]
6 | pull_request:
7 | branches: [main, master]
8 |
9 | name: with-auth
10 |
11 | permissions: read-all
12 |
13 | jobs:
14 | with-auth:
15 | runs-on: ubuntu-latest
16 |
17 | env:
18 | GITHUB_PAT: ${{ secrets.GITHUB_TOKEN }}
19 |
20 | steps:
21 | - uses: actions/checkout@v4
22 |
23 | - uses: r-lib/actions/setup-pandoc@v2
24 |
25 | - uses: r-lib/actions/setup-r@v2
26 | with:
27 | r-version: release
28 | http-user-agent: 'release'
29 | use-public-rspm: true
30 |
31 | - uses: r-lib/actions/setup-r-dependencies@v2
32 | with:
33 | extra-packages: any::rcmdcheck
34 | needs: check
35 |
36 | - uses: r-lib/actions/check-r-package@v2
37 | env:
38 | GOOGLEDRIVE_KEY: ${{ secrets.GOOGLEDRIVE_KEY }}
39 | with:
40 | upload-snapshots: true
41 | build_args: 'c("--no-manual","--compact-vignettes=gs+qpdf")'
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | sandbox
2 | scratch.R
3 | *.Rproj.user
4 | .Rhistory
5 | .Rproj.user
6 | .RData
7 | .httr-oauth*
8 | .Rapp.history
9 | *token.rds
10 | inst/doc
11 | docs/
12 | internal
13 |
--------------------------------------------------------------------------------
/DESCRIPTION:
--------------------------------------------------------------------------------
1 | Package: googledrive
2 | Title: An Interface to Google Drive
3 | Version: 2.1.1.9000
4 | Authors@R: c(
5 | person("Lucy", "D'Agostino McGowan", , role = "aut"),
6 | person("Jennifer", "Bryan", , "jenny@posit.co", role = c("aut", "cre"),
7 | comment = c(ORCID = "0000-0002-6983-2759")),
8 | person("Posit Software, PBC", role = c("cph", "fnd"))
9 | )
10 | Description: Manage Google Drive files from R.
11 | License: MIT + file LICENSE
12 | URL: https://googledrive.tidyverse.org,
13 | https://github.com/tidyverse/googledrive
14 | BugReports: https://github.com/tidyverse/googledrive/issues
15 | Depends:
16 | R (>= 3.6)
17 | Imports:
18 | cli (>= 3.0.0),
19 | gargle (>= 1.5.0),
20 | glue (>= 1.4.2),
21 | httr,
22 | jsonlite,
23 | lifecycle,
24 | magrittr,
25 | pillar (>= 1.9.0),
26 | purrr (>= 1.0.1),
27 | rlang (>= 1.0.2),
28 | tibble (>= 2.0.0),
29 | utils,
30 | uuid,
31 | vctrs (>= 0.3.0),
32 | withr
33 | Suggests:
34 | curl,
35 | dplyr (>= 1.0.0),
36 | knitr,
37 | mockr,
38 | rmarkdown,
39 | spelling,
40 | testthat (>= 3.1.5)
41 | VignetteBuilder:
42 | knitr
43 | Config/Needs/website:
44 | tidyverse,
45 | tidyverse/tidytemplate
46 | Config/testthat/edition: 3
47 | Encoding: UTF-8
48 | Language: en-US
49 | Roxygen: list(markdown = TRUE)
50 | RoxygenNote: 7.2.3
51 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | YEAR: 2023
2 | COPYRIGHT HOLDER: googledrive authors
3 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | # MIT License
2 |
3 | Copyright (c) 2023 googledrive authors
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/R/aaa.R:
--------------------------------------------------------------------------------
1 | # environment to hold data about the Drive API
2 | .drive <- new.env(parent = emptyenv())
3 |
4 | .drive$translate_mime_types <-
5 | system.file(
6 | "extdata", "data", "translate_mime_types.csv",
7 | package = "googledrive",
8 | mustWork = TRUE
9 | ) %>%
10 | utils::read.csv(stringsAsFactors = FALSE) %>%
11 | as_tibble()
12 |
13 | .drive$mime_tbl <-
14 | system.file(
15 | "extdata", "data", "mime_tbl.csv",
16 | package = "googledrive",
17 | mustWork = TRUE
18 | ) %>%
19 | utils::read.csv(stringsAsFactors = FALSE) %>%
20 | as_tibble()
21 |
22 | .drive$files_fields <-
23 | system.file(
24 | "extdata", "data", "files_fields.csv",
25 | package = "googledrive",
26 | mustWork = TRUE
27 | ) %>%
28 | utils::read.csv(stringsAsFactors = FALSE) %>%
29 | as_tibble()
30 |
31 | # environment to hold other data that is convenient to cache
32 | .googledrive <- new.env(parent = emptyenv())
33 |
--------------------------------------------------------------------------------
/R/camelCase.R:
--------------------------------------------------------------------------------
1 | # camelCase() and toCamel() taken from
2 | # https://github.com/r-dbi/bigrquery/blob/main/R/camelCase.R
3 |
4 | # in theory, belongs in gargle
5 | # but then we'd need to export it and I'm not sure it's worth it
6 | # https://github.com/r-lib/gargle
7 |
8 | # camelCase vs snake_case policy
9 | # ** all arguments in functions exported by googledrive shall be snake_case**
10 | #
11 | # HOWEVER, the Drive API is camelCase
12 | # both wrt parameter names and many of their string values
13 | # examples: `pageSize`, `mimeType`, `corpora = "allDrives"`
14 | # therefore, whenever we pass `...` through, we process with toCamel()
15 | # this means user can say `page_size = 20` and we send `pageSize = 20`
16 | #
17 | # we do not trumpet this snake_case to camelCase conversion in the docs,
18 | # because many of the strings/values we handle are camelCase and we ARE not
19 | # going to alter them
20 | # there's too much potential for confusion
21 | #
22 | # at this point, snake_case to camelCase is a very quiet feature
23 | camelCase <- function(x) {
24 | gsub("_(.)", "\\U\\1", x, perl = TRUE)
25 | }
26 |
27 | toCamel <- function(x) {
28 | if (is.list(x)) {
29 | x[] <- lapply(x, toCamel)
30 | }
31 |
32 | if (!is.null(names(x))) {
33 | names(x) <- camelCase(names(x))
34 | }
35 |
36 | x
37 | }
38 |
39 | # added later
40 | snake_case <- function(x) {
41 | gsub("([a-z0-9])([A-Z])", "\\1_\\L\\2", x, perl = TRUE)
42 | }
43 |
--------------------------------------------------------------------------------
/R/compat-dplyr.R:
--------------------------------------------------------------------------------
1 | dribble_maybe_reconstruct <- function(data, template) {
2 | if (dribble_is_reconstructable(data)) {
3 | # in workflowsets, davis uses new_workflow_set0(x) here
4 | new_dribble(data)
5 | } else {
6 | # @davis tells me there can be internal-to-vctrs-or-dplyr situations where
7 | # reconstruction starts with a conformable list, instead of data.frame
8 | new_tibble0(data)
9 | }
10 | }
11 |
12 | dribble_is_reconstructable <- function(data) {
13 | # see above for why this is is_list() instead of is.data.frame()
14 | is_list(data) &&
15 | has_dribble_cols(data) &&
16 | has_dribble_coltypes(data) &&
17 | id_can_be_drive_id(data$id) &&
18 | has_drive_resource(data)
19 | }
20 |
21 | new_tibble0 <- function(x, ..., class = NULL) {
22 | # Handle the 0-column case correctly by using `new_data_frame()`.
23 | # This also correctly strips any attributes except `names` off `x`.
24 | x <- new_data_frame(x)
25 | tibble::new_tibble(x, nrow = nrow(x), class = class)
26 | }
27 |
--------------------------------------------------------------------------------
/R/deprecated.R:
--------------------------------------------------------------------------------
1 | #' Deprecated googledrive functions
2 | #'
3 | #' @description
4 | #' `r lifecycle::badge("deprecated")`
5 | #'
6 | #' @section `drive_auth_config()`:
7 | #'
8 | #' This function is defunct.
9 | #' * Use [drive_auth_configure()] to configure your own OAuth client or API key.
10 | #' * Use [drive_deauth()] to go into a de-authorized state.
11 | #' * Use [drive_oauth_client()] to retrieve a user-configured client, if it
12 | #' exists.
13 | #' * Use [drive_api_key()] to retrieve a user-configured API key, if it exists.
14 | #'
15 | #' @section `drive_oauth_app()`:
16 | #'
17 | #' In light of the new [gargle::gargle_oauth_client()] constructor and class of
18 | #' the same name, `drive_oauth_app()` is being replaced by
19 | #' [drive_oauth_client()].
20 | #'
21 | #' @section `drive_example()`:
22 | #'
23 | #' This function is defunct. Access example files with [drive_examples_local()],
24 | #' [drive_example_local()], [drive_examples_remote()], and
25 | #' [drive_example_remote()].
26 | #'
27 | #' @keywords internal
28 | #' @name googledrive-deprecated
29 | NULL
30 |
31 | #' @rdname googledrive-deprecated
32 | #' @inheritParams drive_auth_configure
33 | #' @export
34 | drive_auth_config <- function(active, app, path, api_key) {
35 | lifecycle::deprecate_stop(
36 | "1.0.0",
37 | "drive_auth_config()",
38 | details = c(
39 | "Use `drive_auth_configure()` to configure your own OAuth client or API key.",
40 | "Use `drive_deauth()` to go into a de-authorized state.",
41 | "Use `drive_oauth_client()` to retrieve a user-configured client, if it exists.",
42 | "Use `drive_api_key()` to retrieve a user-configured API key, if it exists."
43 | )
44 | )
45 | }
46 |
47 | #' @rdname googledrive-deprecated
48 | #' @export
49 | drive_oauth_app <- function() {
50 | lifecycle::deprecate_warn(
51 | "2.1.0", "drive_oauth_app()", "drive_oauth_client()"
52 | )
53 | drive_oauth_client()
54 | }
55 |
56 | #' @rdname googledrive-deprecated
57 | #' @export
58 | drive_example <- function(path = NULL) {
59 | lifecycle::deprecate_stop(
60 | "2.0.0",
61 | what = "drive_example()",
62 | with = I("`drive_examples_local()` or `drive_example_local()`")
63 | )
64 | }
65 |
--------------------------------------------------------------------------------
/R/drive_about.R:
--------------------------------------------------------------------------------
1 | #' Get info on Drive capabilities
2 | #'
3 | #' Gets information about the user, the user's Drive, and system capabilities.
4 | #' This function mostly exists to power [drive_user()], which extracts the most
5 | #' useful information (the information on current user) and prints it nicely.
6 | #'
7 | #' @seealso Wraps the `about.get` endpoint:
8 | #' *
9 | #'
10 | #' @return A list representation of a Drive
11 | #' [about resource](https://developers.google.com/drive/api/v3/reference/about)
12 | #' @export
13 | #'
14 | #' @examplesIf drive_has_token()
15 | #' drive_about()
16 | #'
17 | #' # explore the export formats available for Drive files, by MIME type
18 | #' about <- drive_about()
19 | #' about[["exportFormats"]] %>%
20 | #' purrr::map(unlist)
21 | drive_about <- function() {
22 | request <- request_generate(
23 | endpoint = "drive.about.get",
24 | params = list(fields = "*")
25 | )
26 | response <- request_make(request)
27 | gargle::response_process(response)
28 | }
29 |
--------------------------------------------------------------------------------
/R/drive_browse.R:
--------------------------------------------------------------------------------
1 | #' Retrieve Drive file links
2 | #'
3 | #' Returns the `"webViewLink"` for one or more files, which is the "link for
4 | #' opening the file in a relevant Google editor or viewer in a browser".
5 | #'
6 | #' @template file-plural
7 | #'
8 | #' @return Character vector of file hyperlinks.
9 | #' @export
10 | #' @examplesIf drive_has_token()
11 | #' # get a few files into a dribble
12 | #' three_files <- drive_find(n_max = 3)
13 | #'
14 | #' # get their browser links
15 | #' drive_link(three_files)
16 | drive_link <- function(file) {
17 | file <- as_dribble(file)
18 | links <- map_chr(
19 | file$drive_resource,
20 | "webViewLink",
21 | .default = NA_character_
22 | )
23 | # no documented, programmatic way to get browser links for shared drives
24 | # but this seems to work ... I won't document it either, though
25 | sd <- is_shared_drive(file)
26 | links[sd] <- glue(
27 | "https://drive.google.com/drive/folders/{id}",
28 | id = as_id(file)[sd]
29 | )
30 | links
31 | }
32 |
33 | #' Visit Drive file in browser
34 | #'
35 | #' Visits a file on Google Drive in your default browser.
36 | #'
37 | #' @template file-singular
38 | #'
39 | #' @return Character vector of file hyperlinks, from [drive_link()], invisibly.
40 | #' @export
41 | #' @examplesIf drive_has_token() && rlang::is_interactive()
42 | #' drive_find(n_max = 1) %>% drive_browse()
43 | drive_browse <- function(file = .Last.value) {
44 | file <- as_dribble(file)
45 | links <- drive_link(file)
46 | if (!interactive() || no_file(file)) {
47 | return(invisible(links))
48 | }
49 | if (!single_file(file)) {
50 | drive_bullets(c("v" = "Browsing the first file of {nrow(file)}."))
51 | }
52 | utils::browseURL(links[1])
53 | invisible(links)
54 | }
55 |
--------------------------------------------------------------------------------
/R/drive_endpoints.R:
--------------------------------------------------------------------------------
1 | #' List Drive endpoints
2 | #'
3 | #' @description
4 | #' The googledrive package stores a named list of Drive API v3 endpoints (or
5 | #' "methods", using Google's vocabulary) internally and these functions expose
6 | #' this data.
7 | #' * `drive_endpoint()` returns one endpoint, i.e. it uses `[[`.
8 | #' * `drive_endpoints()` returns a list of endpoints, i.e. it uses `[`.
9 | #'
10 | #' The names of this list (or the `id` sub-elements) are the nicknames that can
11 | #' be used to specify an endpoint in [request_generate()]. For each endpoint, we
12 | #' store its nickname or `id`, the associated HTTP verb, the `path`, and details
13 | #' about the parameters. This list is derived programmatically from the Drive
14 | #' API v3 Discovery Document
15 | #' (`https://www.googleapis.com/discovery/v1/apis/drive/v3/rest`) using the
16 | #' approach described in the [Discovery Documents
17 | #' section](https://gargle.r-lib.org/articles/request-helper-functions.html#discovery-documents)
18 | #' of the gargle vignette [Request helper
19 | #' functions](https://gargle.r-lib.org/articles/request-helper-functions.html).
20 | #'
21 | #' @param i The name(s) or integer index(ices) of the endpoints to return. `i`
22 | #' is optional for `drive_endpoints()` and, if not given, the entire list is
23 | #' returned.
24 | #'
25 | #' @return One or more of the Drive API v3 endpoints that are used internally by
26 | #' googledrive.
27 | #' @export
28 | #'
29 | #' @examples
30 | #' str(head(drive_endpoints(), 3), max.level = 2)
31 | #' drive_endpoint("drive.files.delete")
32 | #' drive_endpoint(4)
33 | drive_endpoints <- function(i = NULL) {
34 | if (is.null(i) || is_expose(i)) {
35 | i <- seq_along(.endpoints)
36 | }
37 | stopifnot(is.character(i) || (is.numeric(i)))
38 | .endpoints[i]
39 | }
40 |
41 | #' @rdname drive_endpoints
42 | #' @export
43 | drive_endpoint <- function(i) {
44 | stopifnot(is_string(i) || (is.numeric(i) && length(i) == 1))
45 | .endpoints[[i]]
46 | }
47 |
--------------------------------------------------------------------------------
/R/drive_mkdir.R:
--------------------------------------------------------------------------------
1 | #' Create a Drive folder
2 | #'
3 | #' Creates a new Drive folder. To update the metadata of an existing Drive file,
4 | #' including a folder, use [drive_update()].
5 | #'
6 | #' @seealso Wraps the `files.create` endpoint:
7 | #' *
8 | #'
9 | #' @param name Name for the new folder or, optionally, a path that specifies
10 | #' an existing parent folder, as well as the new name.
11 | #' @eval param_path_known_parent("folder")
12 | #' @inheritParams drive_create
13 | #'
14 | #' @eval return_dribble()
15 | #' @export
16 | #' @examplesIf drive_has_token()
17 | #' # Create folder named 'ghi', then another below named it 'jkl' and star it
18 | #' ghi <- drive_mkdir("ghi")
19 | #' jkl <- drive_mkdir("ghi/jkl", starred = TRUE)
20 | #'
21 | #' # is 'jkl' really starred? YES
22 | #' purrr::pluck(jkl, "drive_resource", 1, "starred")
23 | #'
24 | #' # Another way to create folder 'mno' in folder 'ghi'
25 | #' drive_mkdir("mno", path = "ghi")
26 | #'
27 | #' # Yet another way to create a folder named 'pqr' in folder 'ghi',
28 | #' # this time with parent folder stored in a dribble,
29 | #' # and setting the new folder's description
30 | #' pqr <- drive_mkdir("pqr", path = ghi, description = "I am a folder")
31 | #'
32 | #' # Did we really set the description? YES
33 | #' purrr::pluck(pqr, "drive_resource", 1, "description")
34 | #'
35 | #' # `overwrite = FALSE` errors if something already exists at target filepath
36 | #' # THIS WILL ERROR!
37 | #' drive_create("name-squatter-mkdir", path = ghi)
38 | #' drive_mkdir("name-squatter-mkdir", path = ghi, overwrite = FALSE)
39 | #'
40 | #' # `overwrite = TRUE` moves the existing item to trash, then proceeds
41 | #' drive_mkdir("name-squatter-mkdir", path = ghi, overwrite = TRUE)
42 | #'
43 | #' # list everything inside 'ghi'
44 | #' drive_ls("ghi")
45 | #'
46 | #' # Clean up
47 | #' drive_rm(ghi)
48 | drive_mkdir <- function(name,
49 | path = NULL,
50 | ...,
51 | overwrite = NA,
52 | verbose = deprecated()) {
53 | warn_for_verbose(verbose)
54 |
55 | drive_create(
56 | name = name,
57 | path = path,
58 | type = "application/vnd.google-apps.folder",
59 | ...,
60 | overwrite = overwrite
61 | )
62 | }
63 |
--------------------------------------------------------------------------------
/R/drive_rename.R:
--------------------------------------------------------------------------------
1 | #' Rename a Drive file
2 | #'
3 | #' This is a wrapper for [`drive_mv()`] that only renames a file.
4 | #' If you would like to rename AND move the file, see [`drive_mv()`].
5 | #'
6 | #' @template file-singular
7 | #' @param name Character. Name you would like the file to have.
8 | #' @template overwrite
9 | #' @template verbose
10 | #'
11 | #' @eval return_dribble()
12 | #'
13 | #' @examplesIf drive_has_token()
14 | #' # Create a file to rename
15 | #' file <- drive_create("file-to-rename")
16 | #'
17 | #' # Rename it
18 | #' file <- drive_rename(file, name = "renamed-file")
19 | #'
20 | #' # `overwrite = FALSE` errors if something already exists at target filepath
21 | #' # THIS WILL ERROR!
22 | #' drive_create("name-squatter-rename")
23 | #' drive_rename(file, name = "name-squatter-rename", overwrite = FALSE)
24 | #'
25 | #' # `overwrite = TRUE` moves the existing item to trash, then proceeds
26 | #' file <- drive_rename(file, name = "name-squatter-rename", overwrite = TRUE)
27 | #'
28 | #' # Clean up
29 | #' drive_rm(file)
30 | #' @export
31 | drive_rename <- function(file,
32 | name = NULL,
33 | overwrite = NA,
34 | verbose = deprecated()) {
35 | warn_for_verbose(verbose)
36 | drive_mv(file = file, name = name, overwrite = overwrite)
37 | }
38 |
--------------------------------------------------------------------------------
/R/drive_user.R:
--------------------------------------------------------------------------------
1 | #' Get info on current user
2 | #'
3 | #' Reveals information about the user associated with the current token. This is
4 | #' a thin wrapper around [drive_about()] that just extracts the most useful
5 | #' information (the information on current user) and prints it nicely.
6 | #'
7 | #' @seealso Wraps the `about.get` endpoint:
8 | #' *
9 | #'
10 | #' @template verbose
11 | #'
12 | #' @return A list of class `drive_user`.
13 | #' @export
14 | #' @examplesIf drive_has_token()
15 | #' drive_user()
16 | #'
17 | #' # more info is returned than is printed
18 | #' user <- drive_user()
19 | #' str(user)
20 | drive_user <- function(verbose = deprecated()) {
21 | warn_for_verbose(verbose)
22 |
23 | if (!drive_has_token()) {
24 | drive_bullets(c(
25 | "i" = "Not logged in as any specific Google user."
26 | ))
27 | return(invisible())
28 | }
29 | about <- drive_about()
30 | structure(about[["user"]], class = c("drive_user", "list"))
31 | }
32 |
33 | #' @export
34 | format.drive_user <- function(x, ...) {
35 | cli::cli_format_method(
36 | drive_bullets(c(
37 | "Logged in as:",
38 | "*" = "displayName: {.field {x[['displayName']]}}",
39 | "*" = "emailAddress: {.email {x[['emailAddress']]}}"
40 | ))
41 | )
42 | }
43 |
44 | #' @export
45 | print.drive_user <- function(x, ...) {
46 | cli::cat_line(format(x, ...))
47 | invisible(x)
48 | }
49 |
--------------------------------------------------------------------------------
/R/promote.R:
--------------------------------------------------------------------------------
1 | # promote an element in drive_resource into a top-level column
2 | #
3 | # if you request `this_var` or `thisVar`, we look for `thisVar` in
4 | # drive_resource, but use the original input as the variable name
5 | #
6 | # if a column by that name already exists, it is overwritten in place
7 | # otherwise, the new column will be the second column, presumably after `name`
8 | #
9 | # morally, this is a lot like tidyr::hoist(), but with a more specific mandate
10 | promote <- function(d, elem) {
11 | elemCamelCase <- camelCase(elem)
12 |
13 | x <- map(d$drive_resource, elemCamelCase)
14 | absent <- all(map_lgl(x, is_null))
15 |
16 | if (absent) {
17 | # TO DO: do we really want promote() to be this forgiving?
18 | # adds a placeholder column for elem if not present in drive_resource
19 | # ensure elem is added, even if there are zero rows
20 | val <- rep_len(list(NULL), nrow(d))
21 | } else {
22 | val <- simplify_col(x)
23 | }
24 |
25 | put_column(d, nm = elem, val = val, .after = 1)
26 | }
27 |
28 | # simplified version of tidyr:::simplify_col()
29 | simplify_col <- function(x) {
30 | is_list <- map_lgl(x, is_list)
31 | is_vec <- map_lgl(x, ~ vec_is(.x) || is_null(.x))
32 | is_not_vec <- !is_vec
33 | if (any(is_list | is_not_vec)) {
34 | return(x)
35 | }
36 |
37 | n <- map_int(x, vec_size)
38 | is_scalar <- n %in% c(0, 1)
39 | if (any(!is_scalar)) {
40 | return(x)
41 | }
42 |
43 | x[n == 0] <- list(NA)
44 |
45 | tryCatch(
46 | vec_c(!!!x),
47 | vctrs_error_incompatible_type = function(e) x
48 | )
49 | }
50 |
--------------------------------------------------------------------------------
/R/roxygen-templates.R:
--------------------------------------------------------------------------------
1 | # nocov start
2 |
3 | param_path <- function(thing = "THING", default_notes = "") {
4 | glue("
5 | @param path Specifies target destination for the {thing} on Google
6 | Drive. Can be an actual path (character), a file id marked with
7 | [as_id()], or a [`dribble`].
8 |
9 | If `path` is a shortcut to a folder, it is automatically resolved to its
10 | target folder.
11 |
12 | If `path` is given as a path (as opposed to a `dribble` or an id), it is
13 | best to explicitly indicate if it's a folder by including a trailing
14 | slash, since it cannot always be worked out from the context of the call.
15 | {default_notes}")
16 | }
17 |
18 | param_path_known_parent <- function(thing = "item") {
19 | glue("
20 | @param path Target destination for the new {thing}, i.e. a folder or a
21 | shared drive. Can be given as an actual path (character), a file id or URL
22 | marked with [as_id()], or a [`dribble`]. Defaults to your \"My Drive\" root
23 | folder. If `path` is a shortcut to a folder, it is automatically resolved
24 | to its target folder.")
25 | }
26 |
27 | param_name <- function(thing = "THING", default_notes = "") {
28 | glue("
29 | @param name Character, new {thing} name if not specified as part of
30 | `path`. This will force `path` to be interpreted as a folder, even if it
31 | is character and lacks a trailing slash. {default_notes}")
32 | }
33 |
34 | return_dribble <- function(item = "file", extras = "") {
35 | glue("
36 | @return An object of class [`dribble`], a tibble with one row per {item}.
37 | {extras}")
38 | }
39 |
40 | # nocov end
41 |
--------------------------------------------------------------------------------
/R/shared_drive_create.R:
--------------------------------------------------------------------------------
1 | #' Create a new shared drive
2 | #'
3 | #' @template shared-drive-description
4 | #'
5 | #' @seealso Wraps the `drives.create` endpoint:
6 | #' *
7 | #'
8 | #' @param name Character. Name of the new shared drive. Must be non-empty and not
9 | #' entirely whitespace.
10 | #'
11 | #' @eval return_dribble("shared drive")
12 | #' @export
13 | #' @examples
14 | #' \dontrun{
15 | #' shared_drive_create("my-awesome-shared-drive")
16 | #'
17 | #' # Clean up
18 | #' shared_drive_rm("my-awesome-shared-drive")
19 | #' }
20 | shared_drive_create <- function(name) {
21 | stopifnot(is_string(name), isTRUE(nzchar(name)))
22 | request <- request_generate(
23 | "drive.drives.create",
24 | params = list(
25 | requestId = uuid::UUIDgenerate(),
26 | name = name,
27 | fields = "*"
28 | )
29 | )
30 | response <- request_make(request)
31 | out <- as_dribble(list(gargle::response_process(response)))
32 |
33 | drive_bullets(c("Shared drive created:", bulletize(gargle_map_cli(out))))
34 | invisible(out)
35 | }
36 |
--------------------------------------------------------------------------------
/R/shared_drive_find.R:
--------------------------------------------------------------------------------
1 | #' Find shared drives
2 | #'
3 | #' @description This is the closest googledrive function to what you get from
4 | #' visiting and clicking "Shared drives".
5 | #' @template shared-drive-description
6 |
7 | #' @seealso Wraps the `drives.list` endpoint:
8 | #' *
9 |
10 | #' @template pattern
11 | #' @template n_max
12 | #' @param ... Other parameters to pass along in the request, such as `pageSize`
13 | #' or `useDomainAdminAccess`.
14 | #'
15 | #' @eval return_dribble("shared drive")
16 | #' @export
17 | #' @examples
18 | #' \dontrun{
19 | #' shared_drive_find()
20 | #' }
21 | shared_drive_find <- function(pattern = NULL,
22 | n_max = Inf,
23 | ...) {
24 | if (!is.null(pattern) && !(is_string(pattern))) {
25 | drive_abort("{.arg pattern} must be a character string.")
26 | }
27 | stopifnot(is.numeric(n_max), n_max >= 0, length(n_max) == 1)
28 | if (n_max < 1) {
29 | return(dribble())
30 | }
31 |
32 | ## what could possibly come via `...` here? pageSize (or fields)
33 | params <- toCamel(list2(...))
34 | params$fields <- params$fields %||% "*"
35 |
36 | request <- request_generate("drive.drives.list", params = params)
37 | proc_res_list <- do_paginated_request(
38 | request,
39 | n_max = n_max,
40 | n = function(x) length(x$drives)
41 | )
42 |
43 | res_tbl <- proc_res_list %>%
44 | map("drives") %>%
45 | purrr::flatten() %>%
46 | as_dribble()
47 |
48 | if (!is.null(pattern)) {
49 | res_tbl <- res_tbl[grep(pattern, res_tbl$name), ]
50 | }
51 | if (n_max < nrow(res_tbl)) {
52 | res_tbl <- res_tbl[seq_len(n_max), ]
53 | }
54 | res_tbl
55 | }
56 |
--------------------------------------------------------------------------------
/R/shared_drive_get.R:
--------------------------------------------------------------------------------
1 | #' Get shared drives by name or id
2 | #'
3 | #' @description
4 |
5 | #' Retrieve metadata for shared drives specified by name or id. Note that Google
6 | #' Drive does NOT behave like your local file system:
7 |
8 | #' * You can get zero, one, or more shared drives back for each name! Shared
9 | #' drive names need not be unique.
10 | #' @template shared-drive-description
11 |
12 | #' @param name Character vector of names. A character vector marked with
13 | #' [as_id()] is treated as if it was provided via the `id` argument.
14 | #' @param id Character vector of shared drive ids or URLs (it is first processed
15 | #' with [as_id()]). If both `name` and `id` are non-`NULL`, `id` is silently
16 | #' ignored.
17 | #'
18 | #' @eval return_dribble("shared drive")
19 | #' @export
20 | #' @examples
21 | #' \dontrun{
22 | #' shared_drive_get("my-awesome-shared-drive")
23 | #' shared_drive_get(c("apple", "orange", "banana"))
24 | #' shared_drive_get(as_id("KCmiHLXUk9PVA-0AJNG"))
25 | #' shared_drive_get(as_id("https://drive.google.com/drive/u/0/folders/KCmiHLXUk9PVA-0AJNG"))
26 | #' shared_drive_get(id = "KCmiHLXUk9PVA-0AJNG")
27 | #' shared_drive_get(id = "https://drive.google.com/drive/u/0/folders/KCmiHLXUk9PVA-0AJNG")
28 | #' }
29 | shared_drive_get <- function(name = NULL, id = NULL) {
30 | if (length(name) + length(id) == 0) {
31 | return(dribble())
32 | }
33 |
34 | if (!is.null(name) && is_drive_id(name)) {
35 | id <- name
36 | name <- NULL
37 | }
38 |
39 | if (!is.null(name)) {
40 | stopifnot(all(map_lgl(name, is_string)))
41 | return(shared_drive_from_name(name))
42 | }
43 |
44 | stopifnot(is.character(id))
45 | # TODO: use a batch request
46 | as_dribble(map(as_id(id), get_one_shared_drive_id))
47 | }
48 |
49 | get_one_shared_drive_id <- function(id) {
50 | if (is.na(id)) {
51 | drive_abort("
52 | Can't {.fun shared_drive_get} a shared drive when {.arg id} is {.code NA}.")
53 | }
54 | request <- request_generate(
55 | endpoint = "drive.drives.get",
56 | params = list(
57 | driveId = id,
58 | fields = "*"
59 | )
60 | )
61 | response <- request_make(request)
62 | gargle::response_process(response)
63 | }
64 |
65 | shared_drive_from_name <- function(name = NULL) {
66 | if (length(name) == 0) {
67 | return(dribble())
68 | }
69 |
70 | shared_drives <- shared_drive_find()
71 | if (no_file(shared_drives)) {
72 | return(dribble())
73 | }
74 |
75 | shared_drives <- shared_drives[shared_drives$name %in% name, ]
76 | ## TO DO: message if a name matches 0 or multiple shared drives?
77 |
78 | shared_drives[order(match(shared_drives$name, name)), ]
79 | }
80 |
--------------------------------------------------------------------------------
/R/shared_drive_rm.R:
--------------------------------------------------------------------------------
1 | #' Delete shared drives
2 | #'
3 | #' @template shared-drive-description
4 | #'
5 | #' @seealso Wraps the `drives.delete` endpoint:
6 | #' *
7 | #'
8 | #' @template shared_drive-plural
9 | #'
10 | #' @return Logical vector, indicating whether the delete succeeded.
11 | #' @export
12 | #' @examples
13 | #' \dontrun{
14 | #' # Create shared drives to remove in various ways
15 | #' shared_drive_create("testdrive-01")
16 | #' sd02 <- shared_drive_create("testdrive-02")
17 | #' shared_drive_create("testdrive-03")
18 | #' sd04 <- shared_drive_create("testdrive-04")
19 | #'
20 | #' # remove by name
21 | #' shared_drive_rm("testdrive-01")
22 | #' # remove by id
23 | #' shared_drive_rm(as_id(sd02))
24 | #' # remove by URL (or, rather, id found in URL)
25 | #' shared_drive_rm(as_id("https://drive.google.com/drive/u/0/folders/Q5DqUk9PVA"))
26 | #' # remove by dribble
27 | #' shared_drive_rm(sd04)
28 | #' }
29 | shared_drive_rm <- function(drive = NULL) {
30 | shared_drive <- as_shared_drive(drive)
31 | if (no_file(shared_drive)) {
32 | drive_bullets(c(
33 | "!" = "No such shared drive found to delete."
34 | ))
35 | return(invisible(logical(0)))
36 | }
37 |
38 | out <- map_lgl(as_id(shared_drive), delete_one_shared_drive)
39 |
40 | if (any(out)) {
41 | successes <- shared_drive[out, ]
42 | drive_bullets(c(
43 | "Shared drive{?s} deleted:{cli::qty(nrow(successes))}",
44 | bulletize(gargle_map_cli(successes))
45 | ))
46 | }
47 | # I'm not sure this ever comes up IRL?
48 | # Is it even possible that removal fails but there's no error?
49 | if (any(!out)) {
50 | failures <- shared_drive[!out, ]
51 | drive_bullets(c(
52 | "Shared drive{?s} NOT deleted:{cli::qty(nrow(failures))}",
53 | bulletize(gargle_map_cli(failures))
54 | ))
55 | }
56 | invisible(out)
57 | }
58 |
59 | delete_one_shared_drive <- function(id) {
60 | request <- request_generate(
61 | endpoint = "drive.drives.delete",
62 | params = list(driveId = id)
63 | )
64 | response <- request_make(request)
65 | gargle::response_process(response)
66 | }
67 |
--------------------------------------------------------------------------------
/R/shared_drive_update.R:
--------------------------------------------------------------------------------
1 | #' Update a shared drive
2 | #'
3 | #' Update the metadata of an existing shared drive, e.g. its background image or
4 | #' theme.
5 | #' @template shared-drive-description
6 | #'
7 | #' @seealso Wraps the `drives.update` endpoint:
8 | #' *
9 | #'
10 | #' @template shared_drive-singular
11 | #' @param ... Properties to set in `name = value` form. See the "Request
12 | #' body" section of the Drive API docs for this endpoint.
13 | #'
14 | #' @eval return_dribble("shared drive")
15 | #' @export
16 | #' @examples
17 | #' \dontrun{
18 | #' # create a shared drive
19 | #' sd <- shared_drive_create("I love themes!")
20 | #'
21 | #' # see the themes available to you
22 | #' themes <- drive_about()$driveThemes
23 | #' purrr::map_chr(themes, "id")
24 | #'
25 | #' # cycle through various themes for this shared drive
26 | #' sd <- shared_drive_update(sd, themeId = "bok_choy")
27 | #' sd <- shared_drive_update(sd, themeId = "cocktails")
28 | #'
29 | #' # Clean up
30 | #' shared_drive_rm(sd)
31 | #' }
32 | shared_drive_update <- function(shared_drive, ...) {
33 | shared_drive <- as_shared_drive(shared_drive)
34 | if (no_file(shared_drive)) {
35 | drive_bullets(c(
36 | "!" = "No such shared drive found to update."
37 | ))
38 | return(invisible(dribble()))
39 | }
40 | if (!single_file(shared_drive)) {
41 | drive_abort(c(
42 | "Can't update multiple shared drives at once:",
43 | bulletize(gargle_map_cli(shared_drive))
44 | ))
45 | }
46 |
47 | meta <- toCamel(list2(...))
48 | if (length(meta) == 0) {
49 | drive_bullets(c(
50 | "!" = "No updates specified."
51 | ))
52 | return(invisible(shared_drive))
53 | }
54 |
55 | meta$fields <- meta$fields %||% "*"
56 | meta$driveId <- shared_drive$id
57 | request <- request_generate(
58 | endpoint = "drive.drives.update",
59 | params = meta
60 | )
61 | response <- request_make(request)
62 | out <- as_dribble(list(gargle::response_process(response)))
63 |
64 | drive_bullets(c("Shared drive updated:", bulletize(gargle_map_cli(out))))
65 |
66 | invisible(out)
67 | }
68 |
--------------------------------------------------------------------------------
/R/sysdata.rda:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/R/sysdata.rda
--------------------------------------------------------------------------------
/R/team_drive.R:
--------------------------------------------------------------------------------
1 | #' Deprecated Team Drive functions
2 | #'
3 | #' @description
4 | #' `r lifecycle::badge('deprecated')`
5 | #' @template team-drives-description
6 | #'
7 | #' @inheritParams shared_drive_find
8 | #' @inheritParams shared_drive_get
9 | #' @inheritParams as_shared_drive
10 | #' @inheritParams is_shared_drive
11 | #' @template team_drive-plural
12 | #'
13 | #' @eval return_dribble("shared drive")
14 | #'
15 | #' @keywords internal
16 | #' @name deprecated-team-drive-functions
17 | NULL
18 |
19 | #' @export
20 | #' @rdname deprecated-team-drive-functions
21 | team_drive_find <- function(pattern = NULL,
22 | n_max = Inf,
23 | ...,
24 | verbose = deprecated()) {
25 | warn_for_verbose(verbose)
26 | lifecycle::deprecate_warn("2.0.0", "team_drive_find()", "shared_drive_find()")
27 | shared_drive_find(pattern = pattern, n_max = n_max, ...)
28 | }
29 |
30 | #' @export
31 | #' @rdname deprecated-team-drive-functions
32 | team_drive_get <- function(name = NULL, id = NULL, verbose = deprecated()) {
33 | warn_for_verbose(verbose)
34 | lifecycle::deprecate_warn("2.0.0", "team_drive_get()", "shared_drive_get()")
35 | shared_drive_get(name = name, id = id)
36 | }
37 |
38 | #' @export
39 | #' @rdname deprecated-team-drive-functions
40 | team_drive_create <- function(name, verbose = deprecated()) {
41 | warn_for_verbose(verbose)
42 | lifecycle::deprecate_warn("2.0.0", "team_drive_create()", "shared_drive_create()")
43 | shared_drive_create(name = name)
44 | }
45 |
46 | #' @export
47 | #' @rdname deprecated-team-drive-functions
48 | team_drive_rm <- function(team_drive = NULL, verbose = deprecated()) {
49 | warn_for_verbose(verbose)
50 | lifecycle::deprecate_warn("2.0.0", "team_drive_rm()", "shared_drive_rm()")
51 | shared_drive_rm(drive = team_drive)
52 | }
53 |
54 | #' @export
55 | #' @rdname deprecated-team-drive-functions
56 | team_drive_update <- function(team_drive, ..., verbose = deprecated()) {
57 | warn_for_verbose(verbose)
58 | lifecycle::deprecate_warn("2.0.0", "team_drive_update()", "shared_drive_update()")
59 | shared_drive_update(drive = team_drive, ...)
60 | }
61 |
62 | #' @export
63 | #' @rdname deprecated-team-drive-functions
64 | as_team_drive <- function(x, ...) {
65 | lifecycle::deprecate_warn("2.0.0", "as_team_drive()", "as_shared_drive()")
66 | as_shared_drive(x, ...)
67 | }
68 |
69 | #' @export
70 | #' @rdname deprecated-team-drive-functions
71 | is_team_drive <- function(d) {
72 | stopifnot(inherits(d, "dribble"))
73 | map_chr(d$drive_resource, "kind") == "drive#teamDrive"
74 | }
75 |
--------------------------------------------------------------------------------
/R/utils-io.R:
--------------------------------------------------------------------------------
1 | readLines <- function(...) {
2 | drive_abort("In this house, we use {.fun read_utf8} for UTF-8 reasons.")
3 | }
4 |
5 | writeLines <- function(...) {
6 | drive_abort("In this house, we use {.fun write_utf8} for UTF-8 reasons.")
7 | }
8 |
9 | # https://github.com/gaborcsardi/rencfaq#with-base-r
10 | read_utf8 <- function(path) {
11 | opts <- options(encoding = "native.enc")
12 | withr::defer(options(opts))
13 | x <- base::readLines(path, encoding = "UTF-8", warn = FALSE)
14 | x
15 | }
16 |
17 | # https://github.com/gaborcsardi/rencfaq#with-base-r
18 | write_utf8 <- function(text, path = NULL) {
19 | # sometimes we use writeLines() basically to print something for a snapshot
20 | if (is.null(path)) {
21 | return(base::writeLines(text))
22 | }
23 |
24 | # step 1: ensure our text is utf8 encoded
25 | utf8 <- enc2utf8(text)
26 | upath <- enc2utf8(path)
27 |
28 | # step 2: create a connection with 'native' encoding
29 | # this signals to R that translation before writing
30 | # to the connection should be skipped
31 | con <- file(upath, open = "w+", encoding = "native.enc")
32 | withr::defer(close(con))
33 |
34 | # step 3: write to the connection with 'useBytes = TRUE',
35 | # telling R to skip translation to the native encoding
36 | base::writeLines(utf8, con = con, useBytes = TRUE)
37 | }
38 |
39 | # used for building functions that construct Drive file names in tests ----
40 | nm_fun <- function(context, user_run = TRUE) {
41 | user_run <- if (isTRUE(user_run)) nm_user_run() else NULL
42 | y <- purrr::compact(list(context, user_run))
43 | function(x = character()) as.character(glue_collapse(c(x, y), sep = "-"))
44 | }
45 |
46 | nm_user_run <- function() {
47 | if (as.logical(Sys.getenv("GITHUB_ACTIONS", unset = "false"))) {
48 | glue("gha-{Sys.getenv('GITHUB_WORKFLOW')}-{Sys.getenv('GITHUB_RUN_ID')}")
49 | } else {
50 | random_id <- strsplit(uuid::UUIDgenerate(TRUE), "-")[[1]][[1]]
51 | glue("{Sys.info()['user']}-{random_id}")
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/R/utils-pipe.R:
--------------------------------------------------------------------------------
1 | #' Pipe operator
2 | #'
3 | #' See \code{magrittr::\link[magrittr]{\%>\%}} for details.
4 | #'
5 | #' @name %>%
6 | #' @rdname pipe
7 | #' @keywords internal
8 | #' @export
9 | #' @importFrom magrittr %>%
10 | #' @usage lhs \%>\% rhs
11 | NULL
12 |
--------------------------------------------------------------------------------
/R/zzz.R:
--------------------------------------------------------------------------------
1 | .onLoad <- function(libname, pkgname) {
2 |
3 | # .auth is created in R/drive_auth.R
4 | # this is to insure we get an instance of gargle's AuthState using the
5 | # current, locally installed version of gargle
6 | utils::assignInMyNamespace(
7 | ".auth",
8 | gargle::init_AuthState(package = "googledrive", auth_active = TRUE)
9 | )
10 |
11 | if (identical(Sys.getenv("IN_PKGDOWN"), "true")) {
12 | tryCatch(
13 | drive_auth_docs(),
14 | googledrive_auth_internal_error = function(e) NULL
15 | )
16 | }
17 |
18 | # in rlang 0.4.10, `is_installed()` doesn't have `version` arg yet
19 | if (is_installed("dplyr") && utils::packageVersion("dplyr") >= "1.0.0") {
20 | s3_register(
21 | "dplyr::dplyr_reconstruct",
22 | "dribble",
23 | method = dribble_maybe_reconstruct
24 | )
25 | }
26 |
27 | invisible()
28 | }
29 |
30 | release_bullets <- function() {
31 | c(
32 | '`devtools::build_rmd("index.Rmd")`'
33 | )
34 | }
35 |
--------------------------------------------------------------------------------
/README.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | output: github_document
3 | ---
4 |
5 |
6 |
7 |
8 | ```{r setup, include = FALSE}
9 | auth_success <- tryCatch(
10 | googledrive:::drive_auth_docs(),
11 | googledrive_auth_internal_error = function(e) e
12 | )
13 |
14 | knitr::opts_chunk$set(
15 | collapse = TRUE,
16 | comment = "#>",
17 | error = TRUE,
18 | purl = googledrive::drive_has_token(),
19 | eval = googledrive::drive_has_token()
20 | )
21 | ```
22 |
23 | ```{r eval = !googledrive::drive_has_token(), echo = FALSE, comment = NA}
24 | googledrive:::drive_bullets(c(
25 | "Code chunks will not be evaluated, because:",
26 | strsplit(auth_success$message, split = "\n")[[1]]
27 | ))
28 | googledrive::drive_deauth()
29 | ```
30 |
31 | # googledrive
32 |
33 |
34 | [](https://CRAN.R-project.org/package=googledrive)
35 | [](https://github.com/tidyverse/googledrive/actions/workflows/R-CMD-check.yaml)
36 | [](https://app.codecov.io/gh/tidyverse/googledrive?branch=main)
37 |
38 |
39 | ## Overview
40 |
41 | googledrive allows you to interact with files on Google Drive from R.
42 |
43 | ## Installation
44 |
45 | Install the CRAN version:
46 |
47 | ```{r, eval = FALSE}
48 | install.packages("googledrive")
49 | ```
50 |
51 | Or install the development version from GitHub:
52 |
53 | ```{r, eval = FALSE}
54 | # install.packages("pak")
55 | pak::pak("tidyverse/googledrive")
56 | ```
57 |
58 | ## Usage
59 |
60 | Please see the package website:
61 |
62 | Here's a teaser that uses googledrive to view some of the files you see on (up to `n_max = 25`, in this case):
63 |
64 | ```{r}
65 | library("googledrive")
66 | drive_find(n_max = 25)
67 | ```
68 |
69 | ## Contributing
70 |
71 | If you'd like to contribute to the development of googledrive, please read [these guidelines](https://googledrive.tidyverse.org/CONTRIBUTING.html).
72 |
73 | Please note that the googledrive project is released with a [Contributor Code of Conduct](https://googledrive.tidyverse.org/CODE_OF_CONDUCT.html). By contributing to this project, you agree to abide by its terms.
74 |
75 | ## Privacy
76 |
77 | [Privacy policy](https://www.tidyverse.org/google_privacy_policy)
78 |
--------------------------------------------------------------------------------
/codecov.yml:
--------------------------------------------------------------------------------
1 | comment: false
2 |
3 | coverage:
4 | status:
5 | project:
6 | default:
7 | target: auto
8 | threshold: 1%
9 | informational: true
10 | patch:
11 | default:
12 | target: auto
13 | threshold: 1%
14 | informational: true
15 |
--------------------------------------------------------------------------------
/cran-comments.md:
--------------------------------------------------------------------------------
1 | ## R CMD check results
2 |
3 | 0 errors | 0 warnings | 0 notes
4 |
5 | ## revdepcheck results
6 |
7 | We checked 17 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package.
8 |
9 | * We saw 0 new problems
10 | * We failed to check 0 packages
11 |
12 |
--------------------------------------------------------------------------------
/data-raw/discovery-doc-ingest.R:
--------------------------------------------------------------------------------
1 | library(tidyverse)
2 |
3 | source(
4 | system.file("discovery-doc-ingest", "ingest-functions.R", package = "gargle")
5 | )
6 |
7 | existing <- list_discovery_documents("drive")
8 | if (length(existing) > 1) {
9 | rlang::warn("MULTIPLE DISCOVERY DOCUMENTS FOUND. FIX THIS!")
10 | }
11 |
12 | if (length(existing) < 1) {
13 | rlang::inform("Downloading Discovery Document")
14 | x <- download_discovery_document("drive:v3")
15 | } else {
16 | msg <- glue::glue("
17 | Using existing Discovery Document:
18 | * {existing}
19 | ")
20 | rlang::inform(msg)
21 | x <- here::here("data-raw", existing)
22 | }
23 |
24 | dd <- read_discovery_document(x)
25 |
26 | methods <- get_raw_methods(dd)
27 |
28 | methods <- methods %>% map(groom_properties, dd)
29 | methods <- methods %>% map(add_schema_params, dd)
30 | methods <- methods %>% map(add_global_params, dd)
31 |
32 | ## duplicate two methods to create a companion for media
33 | ## simpler to do this here, in data, than in wrapper functions
34 | mediafy <- function(target_id, methods) {
35 | new <- target_method <- methods[[target_id]]
36 |
37 | new$id <- paste0(target_id, ".media")
38 | new$path <-
39 | pluck(target_method, "mediaUpload", "protocols", "simple", "path")
40 | new$parameters <- c(
41 | new$parameters,
42 | uploadType = list(list(type = "string", required = TRUE, location = "query"))
43 | )
44 |
45 | methods[[new$id]] <- new
46 | methods
47 | }
48 |
49 | methods <- mediafy("drive.files.update", methods)
50 | methods <- mediafy("drive.files.create", methods)
51 |
52 | .endpoints <- methods
53 | attr(.endpoints, "base_url") <- dd$rootUrl
54 | # View(.endpoints)
55 |
56 | usethis::use_data(.endpoints, internal = TRUE, overwrite = TRUE)
57 |
--------------------------------------------------------------------------------
/data-raw/drive-examples-create.R:
--------------------------------------------------------------------------------
1 | library(here)
2 | library(glue)
3 | library(googledrive)
4 | library(tidyverse)
5 |
6 | # auth with the special-purpose service account
7 | filename <- glue("~/.R/gargle/googledrive-file-keeper.json")
8 | drive_auth(path = filename)
9 | drive_user()
10 |
11 | # files that are the pre-existing local example files
12 | x <- drive_upload(drive_example_local("chicken.csv"))
13 | drive_share_anyone(x)
14 |
15 | x <- drive_upload(drive_example_local("chicken.jpg"))
16 | drive_share_anyone(x)
17 |
18 | x <- drive_upload(drive_example_local("chicken.pdf"))
19 | drive_share_anyone(x)
20 |
21 | x <- drive_upload(drive_example_local("chicken.txt"))
22 | drive_share_anyone(x)
23 |
24 | # added June 2021; originally from
25 | # https://matthew-brett.github.io/cfd2019/data/imdblet_latin.csv",
26 | x <- drive_upload(drive_example_local("imdb_latin1.csv"))
27 | drive_share_anyone(x)
28 |
29 | # added June 2021; ships with R
30 | # https://stat.ethz.ch/R-manual/R-patched/doc/html/logo.jpg
31 | # r_logo_path <- R.home("doc/html/logo.jpg")
32 | # file.copy(r_logo_path, here("inst", "extdata", "example_files", "r_logo.jpg"))
33 | x <- drive_upload(drive_example_local("r_logo.jpg"))
34 | drive_share_anyone(x)
35 |
36 | # added June 2021; ships with R
37 | # https://stat.ethz.ch/R-manual/R-patched/doc/html/about.html
38 | # r_about_path <- R.home("doc/html/about.html")
39 | # file.copy(r_about_path, here("inst", "extdata", "example_files", "r_about.html"))
40 | x <- drive_upload(drive_example_local("r_about.html"))
41 | drive_share_anyone(x)
42 |
43 | # export 2 local examples for native Google file types
44 | x <- drive_upload(
45 | drive_example_local("chicken.txt"),
46 | type = "document", name = "chicken_doc"
47 | )
48 | drive_share_anyone(x)
49 |
50 | x <- drive_upload(
51 | drive_example_local("chicken.csv"),
52 | type = "spreadsheet",
53 | name = "chicken_sheet"
54 | )
55 | drive_share_anyone(x)
56 |
57 | # files I played with when writing drive_read_string() and drive_read_raw()
58 | # but, so far, have no included
59 | # curl::curl_download("https://httpbin.org/html", destfile = tfile)
60 | # curl::curl_download("https://httpbin.org/xml", destfile = tfile)
61 | # curl::curl_download("https://httpbin.org/json", destfile = tfile)
62 |
--------------------------------------------------------------------------------
/data-raw/drive-examples-inventory.R:
--------------------------------------------------------------------------------
1 | # given the files owned by the googledrive-file-keeper service account,
2 | # create/update an inventory file consulted by drive_examples_remote()
3 |
4 | library(here)
5 | library(glue)
6 | library(googledrive)
7 | library(tidyverse)
8 |
9 | # auth with the special-purpose service account
10 | filename <- glue("~/.R/gargle/googledrive-file-keeper.json")
11 | drive_auth(path = filename)
12 | # user should be googledrive-file-keeper
13 | drive_user()
14 |
15 | # exclude the inventory file ... too meta!
16 | dat <- drive_find(q = "not name contains 'drive_examples_remote'")
17 |
18 | if (anyDuplicated(dat$name)) {
19 | stop("Duplicated file names! You are making a huge mistake.")
20 | }
21 |
22 | dat <- dat %>%
23 | drive_reveal("mime_type") %>%
24 | select(name, mime_type, id) %>%
25 | arrange(name, mime_type)
26 |
27 | # record in local csv, because the visibility afforded by a plain old csv file
28 | # is useful to me, e.g. easy to see change over time
29 | write_csv(
30 | dat,
31 | file = here("inst", "extdata", "data", "remote_example_files.csv")
32 | )
33 |
34 | # keep just (name, id) for the official lookup Sheet
35 | dat2 <- dat %>%
36 | select(name, id)
37 | dat2
38 |
39 | # PUT into official inventory csv
40 | x <- tempfile(fileext = ".csv")
41 | write_csv(dat2, file = x)
42 |
43 | y <- drive_put(x, "drive_examples_remote.csv")
44 | drive_share_anyone(y)
45 | # drive_browse(y)
46 | as_id(y)
47 | # "1XiwJJdoqoZ876OoSTjsnBZ5SxxUg6gUC"
48 |
--------------------------------------------------------------------------------
/data-raw/export-mime-type-defaults.csv:
--------------------------------------------------------------------------------
1 | mime_type_google, mime_type_local
2 | application/vnd.google-apps.document,application/vnd.openxmlformats-officedocument.wordprocessingml.document
3 | application/vnd.google-apps.drawing,image/png
4 | application/vnd.google-apps.form,application/zip
5 | application/vnd.google-apps.presentation,application/vnd.openxmlformats-officedocument.presentationml.presentation
6 | application/vnd.google-apps.script,application/vnd.google-apps.script+json
7 | application/vnd.google-apps.spreadsheet,application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
8 |
--------------------------------------------------------------------------------
/data-raw/extension-mime-type-defaults.csv:
--------------------------------------------------------------------------------
1 | mime_type,ext
2 | text/tab-separated-values,tsv
3 | image/jpeg,jpeg
4 | image/gif,gif
5 | application/vnd.openxmlformats-officedocument.wordprocessingml.template,dotx
6 | application/vnd.openxmlformats-officedocument.wordprocessingml.document,docx
7 | application/vnd.ms-excel,xls
8 | application/vnd.sun.xml.writer,sxw
9 | text/plain,txt
10 | application/vnd.oasis.opendocument.spreadsheet,ods
11 | image/png,png
12 | application/msword,doc
13 | application/pdf,pdf
14 | application/json,json
15 | application/vnd.openxmlformats-officedocument.spreadsheetml.template,xltx
16 | application/vnd.ms-powerpoint,ppt
17 | application/rtf,rtf
18 | application/vnd.openxmlformats-officedocument.presentationml.template,potx
19 | text/html,html
20 | application/vnd.oasis.opendocument.text,odt
21 | application/vnd.openxmlformats-officedocument.presentationml.presentation,pptx
22 | application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,xlsx
23 | application/vnd.openxmlformats-officedocument.presentationml.slideshow,ppsx
24 | text/csv,csv
25 | application/vnd.oasis.opendocument.presentation,odp
26 | text/richtext,rtx
27 | application/zip,zip
28 | image/svg+xml,svg
--------------------------------------------------------------------------------
/data-raw/file-fields.R:
--------------------------------------------------------------------------------
1 | library(here)
2 | library(jsonlite)
3 | library(tidyverse)
4 | library(fs)
5 |
6 | json_fname <- dir_ls(here("data-raw"), regexp = "drive-v3")
7 | stopifnot(length(json_fname) == 1)
8 | dd_content <- fromJSON(json_fname)
9 |
10 | ff <- pluck(dd_content, "schemas", "File", "properties")
11 | df <- tibble(
12 | name = names(ff),
13 | desc = map_chr(ff, "description")
14 | )
15 |
16 | write_csv(df, here("inst", "extdata", "data", "files_fields.csv"))
17 |
--------------------------------------------------------------------------------
/data-raw/old/20170519_drive-v3_endpoints-list.rds:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/data-raw/old/20170519_drive-v3_endpoints-list.rds
--------------------------------------------------------------------------------
/data-raw/old/20170519_drive-v3_endpoints-tibble.rds:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/data-raw/old/20170519_drive-v3_endpoints-tibble.rds
--------------------------------------------------------------------------------
/data-raw/old/20170721_drive-v3_endpoints-list.rds:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/data-raw/old/20170721_drive-v3_endpoints-list.rds
--------------------------------------------------------------------------------
/data-raw/old/20170721_drive-v3_endpoints-tibble.rds:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/data-raw/old/20170721_drive-v3_endpoints-tibble.rds
--------------------------------------------------------------------------------
/data-raw/old/20171110_drive-v3_endpoints-list.rds:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/data-raw/old/20171110_drive-v3_endpoints-list.rds
--------------------------------------------------------------------------------
/data-raw/old/20171110_drive-v3_endpoints-tibble.rds:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/data-raw/old/20171110_drive-v3_endpoints-tibble.rds
--------------------------------------------------------------------------------
/googledrive.Rproj:
--------------------------------------------------------------------------------
1 | Version: 1.0
2 |
3 | RestoreWorkspace: Default
4 | SaveWorkspace: Default
5 | AlwaysSaveHistory: Default
6 |
7 | EnableCodeIndexing: Yes
8 | UseSpacesForTab: Yes
9 | NumSpacesForTab: 2
10 | Encoding: UTF-8
11 |
12 | RnwWeave: Sweave
13 | LaTeX: pdfLaTeX
14 |
15 | AutoAppendNewline: Yes
16 | StripTrailingWhitespace: Yes
17 |
18 | BuildType: Package
19 | PackageUseDevtools: Yes
20 | PackageInstallArgs: --no-multiarch --with-keep.source
21 | PackageCheckArgs: --no-vignettes --no-build-vignettes
22 | PackageRoxygenize: rd,collate,namespace
23 |
--------------------------------------------------------------------------------
/inst/WORDLIST:
--------------------------------------------------------------------------------
1 | API's
2 | Auth
3 | AuthState
4 | CLI
5 | CMD
6 | Codecov
7 | Colaboratory
8 | D'Agostino
9 | GCE
10 | GCP
11 | IDEs
12 | JSON
13 | OAuth
14 | OOB
15 | ORCID
16 | PBC
17 | PUTs
18 | RESTful
19 | RStudio
20 | Tidyverse
21 | VMs
22 | appdata
23 | auth
24 | behaviour
25 | bigrquery
26 | cli
27 | cli's
28 | commenter
29 | csv
30 | de
31 | determinine
32 | dev
33 | dplyr
34 | fileOrganizer
35 | filepath
36 | funder
37 | ggplot
38 | gmailr
39 | googleapis
40 | googledrive's
41 | googlesheets
42 | https
43 | httr
44 | httr's
45 | ing
46 | lifecycle
47 | lowerCamel
48 | magrittr
49 | mockr
50 | pkgdown
51 | pre
52 | programmatically
53 | purrr
54 | readonly
55 | rebranded
56 | recency
57 | reprexes
58 | rlang's
59 | rprojroot
60 | setwise
61 | targetted
62 | testthat
63 | th
64 | threshhold
65 | tibble
66 | tibble's
67 | tidyverse
68 | un
69 | unexamined
70 | vctrs
71 | vectorization
72 | vectorized
73 | withr
74 | www
75 |
--------------------------------------------------------------------------------
/inst/extdata/data/client_secret_123.googleusercontent.com.json:
--------------------------------------------------------------------------------
1 | {"installed":{"client_id":"abc.apps.googleusercontent.com","project_id":"a_project","auth_uri":"https://accounts.google.com/o/oauth2/auth","token_uri":"https://accounts.google.com/o/oauth2/token","auth_provider_x509_cert_url":"https://www.googleapis.com/oauth2/v1/certs","client_secret":"ssshh-i-am-a-secret","redirect_uris":["http://localhost"]}}
2 |
--------------------------------------------------------------------------------
/inst/extdata/data/remote_example_files.csv:
--------------------------------------------------------------------------------
1 | name,mime_type,id
2 | chicken_doc,application/vnd.google-apps.document,1X9pd4nOjl33zDFfTjw-_eFL7Qb9_g6VfVFDp1PPae94
3 | chicken_sheet,application/vnd.google-apps.spreadsheet,1SeFXkr3XdzPSuWauzPdN-XnaryOYmZ7sFiUF5t-wSVU
4 | chicken.csv,text/csv,1VOh6wWbRfuQLxbLg87o58vxJt95SIiZ7
5 | chicken.jpg,image/jpeg,1b2_ZjzgvrSw0hBMgn-rnEbjp3Uq0XTKJ
6 | chicken.pdf,application/pdf,13OQcAo8hkh0Ja5Wxlmi4a8aNvPK7pDkO
7 | chicken.txt,text/plain,1wOLeWVRkTb6lDmLRiOhg9iKM7DlN762Y
8 | imdb_latin1.csv,text/csv,1YJSVa0LTaVtGrZ4eVXYrSQ4y50uFl5bw
9 | r_about.html,text/html,1sfCT0zqDz3vpZZlv_4nFlhq2WMaKqjow
10 | r_logo.jpg,image/jpeg,1J4v-iyydf1Cad3GjDkGRrynauV9JFOyW
11 |
--------------------------------------------------------------------------------
/inst/extdata/example_files/chicken.csv:
--------------------------------------------------------------------------------
1 | chicken,breed,sex,motto
2 | Foghorn Leghorn,Leghorn,rooster,"That's a joke, ah say, that's a joke, son."
3 | Chicken Little,unknown,hen,"The sky is falling!"
4 | Ginger,Rhode Island Red,hen,"Listen. We'll either die free chickens or we die trying."
5 | Camilla the Chicken,Chantecler,hen,"Bawk, buck, ba-gawk."
6 | Ernie The Giant Chicken,Brahma,rooster,"Put Captain Solo in the cargo hold."
7 |
--------------------------------------------------------------------------------
/inst/extdata/example_files/chicken.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/inst/extdata/example_files/chicken.jpg
--------------------------------------------------------------------------------
/inst/extdata/example_files/chicken.pdf:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/inst/extdata/example_files/chicken.pdf
--------------------------------------------------------------------------------
/inst/extdata/example_files/chicken.txt:
--------------------------------------------------------------------------------
1 | A chicken whose name was Chantecler
2 | Clucked in iambic pentameter
3 | It sat on a shelf, reading Song of Myself
4 | And laid eggs with a perfect diameter.
5 |
6 | —Richard Maxson
7 |
--------------------------------------------------------------------------------
/inst/extdata/example_files/imdb_latin1.csv:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/inst/extdata/example_files/imdb_latin1.csv
--------------------------------------------------------------------------------
/inst/extdata/example_files/r_about.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | R: About R
5 |
6 |
7 |
8 |
9 |
10 |
11 |
About
12 |
13 |
14 |
15 |
Introduction
16 |
17 |
R is a computer language not entirely unlike the S
18 | language developed at AT&T Bell Laboratories by Rick Becker,
19 | John Chambers and Allan Wilks. The two languages are implemented
20 | quite differently, but bear enough superficial resemblance that
21 | users should be able to switch between the two with relative ease.
22 | Currently the software is undergoing active development. Discussion
23 | of the development process is carried out on the "r-devel" mailing
24 | list. See the resources page for
25 | details on how to subscribe to this list.
26 |
27 |
We have implemented R in what we hope is a very portable
28 | fashion and in way which requires relatively little in the way of
29 | machine resources. Implementations exist for many for many members
30 | of the Unix family of operating systems, including AIX,
31 | FreeBSD, GNU/Linux, HPUX, Irix,
32 | macOS, Solaris, and Tru64. In addition there
33 | is a version for Microsoft Windows (9x, ME, NT4, 2000,
34 | XP).
35 |
36 |
Present Status
37 |
38 | The present version implements most of the functionality in the
39 | 1988 S book (the "Blue Book") and many of the applications. In
40 | addition, we have implemented much of the functionality from the
41 | 1992 S book (the "White Book"). In particular we have versions of
42 | "lm", "glm", "aov" and "loess", and versions of "gam" and "tree"
43 | are available in contributed packages. There are several manuals in
44 | the distribution, plus a comprehensive set of help pages in "output
45 | independent" form which can be used to create versions for HTML,
46 | LaTeX, text, PDF etc.
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/inst/extdata/example_files/r_logo.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/inst/extdata/example_files/r_logo.jpg
--------------------------------------------------------------------------------
/internal/2019-02-18_tidyverse-meeting.R:
--------------------------------------------------------------------------------
1 | ## live demo from group meeting re: gargle stuff
2 | load_all(".")
3 |
4 | ## present myself as "RStudio Jenny"
5 | drive_find(n_max = 10)
6 | drive_find(type = "spreadsheet")
7 |
8 | ## what token am I sending?
9 | drive_token()
10 | .auth$cred
11 |
12 | ## explicitly declare this: "I want to send unauthorized requests"
13 | drive_deauth()
14 |
15 | ## what token do I send now? NONE!
16 | drive_token()
17 |
18 | ## access a world-readable document = gapminder Sheet
19 | (gapminder <- googlesheets::gs_gap_url())
20 |
21 | (ss <- drive_get(as_id(gapminder)))
22 |
23 | drive_download(ss, "gapminder.csv", overwrite = TRUE)
24 | readLines("gapminder.csv", n = 6)
25 |
26 | ## now I want to be "Gmail Jenny"
27 | drive_auth(email = "jenny.f.bryan@gmail.com")
28 |
29 | ## notice I see different documents from "Rstudio Jenny"
30 | drive_find(n_max = 10)
31 | drive_find(type = "spreadsheet")
32 |
33 | library(googlesheets4)
34 |
35 | ## let's switch back to RStudio Jenny via a token choose
36 | drive_auth(email = NA)
37 |
38 | ## Find the 'Families' spreadsheet Hadley let us make
39 | families_ss <- drive_find("Families", type = "spreadsheet")
40 |
41 | families <- sheets_read(families_ss, n_max = 13)
42 | families
43 | View(families)
44 |
45 | ## go back to slides here
46 |
47 | ## inspect internally stored endpoints
48 |
49 | ## googledrive
50 | View(.endpoints)
51 |
52 | ## googlesheets4
53 | View(googlesheets4:::.endpoints)
54 |
--------------------------------------------------------------------------------
/internal/googledrive-og-1280x640.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/internal/googledrive-og-1280x640.png
--------------------------------------------------------------------------------
/internal/googledrive.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/internal/googledrive.png
--------------------------------------------------------------------------------
/internal/old/02_sharing_demo.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "sharing demo"
3 | author: "Lucy D’Agostino McGowan"
4 | date: "5/3/2017"
5 | output:
6 | github_document:
7 | toc: true
8 | ---
9 |
10 | This is a little demo to show how we may view sharing.
11 |
12 | ```{r, message = FALSE, warning = FALSE}
13 | library('dplyr')
14 | library('googledrive')
15 | drive_auth("drive-token.rds")
16 | ```
17 |
18 | ```{r}
19 | write.table("This is a little demo", "demo.txt")
20 | drive_upload(from = "demo.txt", up_name = "Happy Little Demo")
21 | ```
22 |
23 | ```{r}
24 | my_file <- drive_list("Happy Little Demo")$id %>%
25 | drive_file()
26 | ```
27 |
28 | ## check current permissions
29 | ```{r}
30 | my_file
31 | ```
32 |
33 | cool beans - it's private!
34 |
35 | ## change permissions (anyone with link)
36 |
37 | *all functions that will somehow change the file will output a new file, overwrite the old file with this to avoid confusion*
38 | ```{r}
39 | my_file<- my_file %>%
40 | drive_share(role = "reader", type = "anyone")
41 | ```
42 |
43 | Let's see what that did
44 |
45 | ```{r}
46 | my_file
47 | ```
48 |
49 | Now anyone with the link can view it
50 |
51 | ## change permissions (anyone in the `r emo::ji('world')`)
52 |
53 | ```{r}
54 | my_file <- my_file %>%
55 | drive_share(role = "reader", type = "anyone", allowFileDiscovery = "true")
56 | ```
57 |
58 | Let's see what that did
59 |
60 | ```{r}
61 | my_file
62 | ```
63 |
64 | ## make it easier to see
65 |
66 | I've added `access` to the Google Drive file object
67 | ```{r}
68 | my_file$access
69 | ```
70 |
71 | ## share link
72 |
73 | you can also output a link to share
74 | ```{r}
75 | drive_share_link(my_file)
76 | ```
77 |
78 | ## clean up
79 |
80 | ```{r}
81 | drive_delete(my_file)
82 | ```
83 |
84 | ```{r, echo = FALSE}
85 | rm <- file.remove("demo.txt")
86 | ```
87 |
88 |
--------------------------------------------------------------------------------
/internal/old/03_publish_demo.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "publish"
3 | author: "Lucy D’Agostino McGowan"
4 | date: "5/3/2017"
5 | output:
6 | github_document:
7 | toc: true
8 | ---
9 | ```{r setup, include=FALSE}
10 | library("googledrive")
11 | library("googlesheets")
12 | library("dplyr")
13 | library("readr")
14 | ```
15 |
16 |
17 | ## Motivation
18 |
19 | Push a table into a Sheet.
20 |
21 | Try to read it _as another user_
22 | Assume you even have the key.
23 | You will fail.
24 |
25 | Now, as the user who owns the Sheet, publish it.
26 |
27 | Now, as the other user, try again to read it via googlesheets. You should succeed.
28 |
29 |
30 | ## Push a file into a Sheet
31 | ```{r}
32 | drive_auth("drive-token.rds")
33 | file <- drive_upload(
34 | R.home('doc/BioC_mirrors.csv'),
35 | type = "spreadsheet"
36 | )
37 | ```
38 |
39 | ## Check publication status (should be FALSE)
40 | ```{r}
41 | drive_show_publish(file)
42 | ```
43 |
44 | ## get URL
45 | ```{r}
46 | url <- drive_share_link(file)
47 | url
48 | ```
49 |
50 | ## it's published, not shared
51 |
52 | ```{r}
53 | file
54 | ```
55 |
56 | ```{r}
57 | key <- file$id
58 | ```
59 |
60 | ## switch to different account
61 | ```{r, eval = FALSE}
62 | gs_auth("sheets-token.rds")
63 | ```
64 |
65 |
66 | ## this shouldn't work
67 | ```{r}
68 | try(gs_url(url, visibility = "private", lookup = FALSE))
69 | geterrmessage()
70 | ```
71 |
72 | ## publish it on Drive
73 | ```{r}
74 | file <- drive_publish(file)
75 | drive_show_publish(file)
76 | ```
77 |
78 | ## try again!
79 | ```{r}
80 | gs_url(url, lookup = FALSE)
81 | ```
82 |
83 | check again that the access - it is not shared, but it is published.
84 |
85 | ```{r}
86 | promote(file, "shared")
87 | ```
88 |
89 | ## clean up
90 |
91 | ```{r}
92 | drive_rm(file)
93 | ```
94 |
95 | ## Now let's try shared but not published
96 |
97 | ```{r}
98 | file <- drive_upload(
99 | R.home('doc/BioC_mirrors.csv'),
100 | type = "spreadsheet"
101 | )
102 | ```
103 |
104 | ```{r}
105 | file <- drive_share(file, role = "reader", type = "anyone")
106 | ```
107 |
108 | ```{r}
109 | url <- drive_share_link(file)
110 | url
111 | ```
112 |
113 | ## this should work!
114 | ```{r}
115 | gs_url(url, visibility = "private", lookup = FALSE)
116 | ```
117 |
118 | It is not published, but it is shared.
119 |
120 | ```{r}
121 | file <- drive_show_publish(file)
122 | ```
123 |
124 |
--------------------------------------------------------------------------------
/internal/old/04_map_demo.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Map Demo"
3 | author: "Lucy D’Agostino McGowan"
4 | date: "5/5/2017"
5 | output:
6 | github_document:
7 | toc: true
8 | ---
9 |
10 | ```{r, message = FALSE, warning = FALSE}
11 | library("dplyr")
12 | library("googledrive")
13 | drive_auth("drive-token.rds")
14 | ```
15 |
16 |
17 | ## we can also pull out multiple files
18 | ```{r}
19 | list_of_ids <- drive_list(pattern = "test")$id[1:10]
20 | list_of_files <- list_of_ids %>%
21 | purrr::map(drive_file)
22 | ```
23 |
24 | ## change access
25 | ```{r}
26 | list_of_files <- list_of_files %>%
27 | purrr::map(drive_share, role = "reader", type = "anyone")
28 | ```
29 |
30 | ## check access
31 | ```{r}
32 | list_of_files %>% purrr::map_chr("access")
33 | ```
34 |
35 | ## delete them all!
36 |
37 | ```{r}
38 | list_of_files <- list_of_files %>%
39 | purrr::map(drive_delete)
40 | ```
41 |
42 |
--------------------------------------------------------------------------------
/internal/old/07_drive_ls_demo.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "folders_are_weird"
3 | author: "Lucy D’Agostino McGowan"
4 | date: "5/11/2017"
5 | output: github_document
6 | ---
7 |
8 | very brief demo
9 |
10 | ```{r}
11 | library(googledrive)
12 | ```
13 |
14 | ## here is what my most recent files look like:
15 | ```{r}
16 | drive_ls()
17 | ```
18 | Notice I have lots of folders named the same name!
19 |
20 | ## now we can query by path
21 |
22 | ```{r}
23 | drive_ls(path = "foo/bar/baz")
24 | ```
25 | In this subdirectory, I have 2 things, a folder named `yo` and a file named `my_file`.
26 |
27 | ## can still pass other query parameters
28 | ```{r}
29 | drive_ls(path = "foo/bar/baz",q = "mimeType='application/vnd.google-apps.folder'")
30 | ```
31 |
32 | ## can also pass patterns
33 |
34 | ```{r}
35 | drive_ls(path = "foo/bar/baz", pattern = "my_file")
36 | ```
37 |
38 |
--------------------------------------------------------------------------------
/internal/tokens.R:
--------------------------------------------------------------------------------
1 | token <- drive_auth(cache = FALSE)
2 | saveRDS(token, file = "internal/drive-token.rds")
3 | token <- gs_auth(cache = FALSE, new_user = TRUE)
4 | saveRDS(token, file = "internal/sheets-token.rds")
5 | token <- drive_auth(cache = FALSE)
6 | saveRDS(token, file = "tidyverse-noncaching-token.rds")
7 |
--------------------------------------------------------------------------------
/man-roxygen/corpus.R:
--------------------------------------------------------------------------------
1 | #' @param corpus Character, specifying which collections of items to search.
2 | #' Relevant to those who work with shared drives and/or Google Workspace
3 | #' domains. If specified, must be one of `"user"`, `"drive"` (requires that
4 | #' `shared_drive` also be specified), `"allDrives"`, or `"domain"`. Read more
5 | #' about [shared drives][shared_drives].
6 |
--------------------------------------------------------------------------------
/man-roxygen/dots-metadata.R:
--------------------------------------------------------------------------------
1 | #' @param ... Named parameters to pass along to the Drive API. Has [dynamic
2 | #' dots][rlang::dyn-dots] semantics. You can affect the metadata of the target file by
3 | #' specifying properties of the Files resource via `...`. Read the "Request
4 | #' body" section of the Drive API docs for the associated endpoint to learn
5 | #' about relevant parameters.
6 |
--------------------------------------------------------------------------------
/man-roxygen/file-plural.R:
--------------------------------------------------------------------------------
1 | #' @param file Something that identifies the file(s) of interest on your Google
2 | #' Drive. Can be a character vector of names/paths, a character vector of file
3 | #' ids or URLs marked with [as_id()], or a [`dribble`].
4 |
--------------------------------------------------------------------------------
/man-roxygen/file-singular.R:
--------------------------------------------------------------------------------
1 | #' @param file Something that identifies the file of interest on your Google
2 | #' Drive. Can be a name or path, a file id or URL marked with [as_id()], or a
3 | #' [`dribble`].
4 |
--------------------------------------------------------------------------------
/man-roxygen/media.R:
--------------------------------------------------------------------------------
1 | #' @param media Character, path to the local file to upload.
2 |
--------------------------------------------------------------------------------
/man-roxygen/n_max.R:
--------------------------------------------------------------------------------
1 | #' @param n_max Integer. An upper bound on the number of items to return. This
2 | #' applies to the results requested from the API, which may be further
3 | #' filtered locally, via the `pattern` argument.
4 |
--------------------------------------------------------------------------------
/man-roxygen/overwrite.R:
--------------------------------------------------------------------------------
1 | #' @param overwrite Logical, indicating whether to check for a pre-existing file
2 | #' at the targetted "filepath". The quotes around "filepath" refer to the fact
3 | #' that Drive does not impose a 1-to-1 relationship between filepaths and files,
4 | #' like a typical file system; read more about that in [drive_get()].
5 | #'
6 | #' * `NA` (default): Just do the operation, even if it results in multiple
7 | #' files with the same filepath.
8 | #' * `TRUE`: Check for a pre-existing file at the filepath. If there is
9 | #' zero or one, move a pre-existing file to the trash, then carry on. Note
10 | #' that the new file does not inherit any properties from the old one, such
11 | #' as sharing or publishing settings. It will have a new file ID. An error is
12 | #' thrown if two or more pre-existing files are found.
13 | #' * `FALSE`: Error if there is any pre-existing file at the filepath.
14 | #'
15 | #' Note that existence checks, based on filepath, are expensive operations, i.e.
16 | #' they require additional API calls.
17 |
18 |
--------------------------------------------------------------------------------
/man-roxygen/pattern.R:
--------------------------------------------------------------------------------
1 | #' @param pattern Character. If provided, only the items whose names match this
2 | #' regular expression are returned. This is implemented locally on the results
3 | #' returned by the API.
4 |
--------------------------------------------------------------------------------
/man-roxygen/shared-drive-description.R:
--------------------------------------------------------------------------------
1 | #' @description
2 |
3 | #' A shared drive supports files owned by an organization rather than an
4 | #' individual user. Shared drives follow different sharing and ownership models
5 | #' from a specific user's "My Drive". Shared drives are the successors to the
6 | #' earlier concept of Team Drives. Learn more about [shared
7 | #' drives][shared_drives].
8 |
--------------------------------------------------------------------------------
/man-roxygen/shared_drive-plural.R:
--------------------------------------------------------------------------------
1 | #' @param drive Anything that identifies the shared drive(s) of interest. Can
2 | #' be a character vector of names, a character vector of file ids or URLs
3 | #' marked with [as_id()], or a [`dribble`] consisting only of shared drives.
4 |
--------------------------------------------------------------------------------
/man-roxygen/shared_drive-singular.R:
--------------------------------------------------------------------------------
1 | #' @param shared_drive Anything that identifies one specific shared drive: its
2 | #' name, its id or URL marked with [as_id()], or a [`dribble`]. The value
3 | #' provided to `shared_drive` is pre-processed with [as_shared_drive()]. Read
4 | #' more about [shared drives][shared_drives].
5 |
--------------------------------------------------------------------------------
/man-roxygen/team-drives-description.R:
--------------------------------------------------------------------------------
1 | #' @description
2 |
3 | #' Team Drives have been rebranded as *shared drives* and, as of googledrive
4 | #' v2.0.0, all `team_drive_*()` functions have been deprecated, in favor of
5 | #' `shared_drive_*()` successors.
6 | #'
7 | #' The changes in googledrive reflect that the Team Drives resource collection
8 | #' has been deprecated in the Drive API v3, in favor of the new (shared) Drives
9 | #' resource collection. Read more
10 |
11 | #' *
12 |
13 |
14 |
--------------------------------------------------------------------------------
/man-roxygen/team_drive-plural.R:
--------------------------------------------------------------------------------
1 | #' @param team_drive `r lifecycle::badge("deprecated")` Google Drive and the
2 | #' Drive API have replaced Team Drives with shared drives.
3 |
--------------------------------------------------------------------------------
/man-roxygen/team_drive-singular.R:
--------------------------------------------------------------------------------
1 | #' @param team_drive `r lifecycle::badge("deprecated")` Google Drive and the
2 | #' Drive API have replaced Team Drives with shared drives.
3 |
--------------------------------------------------------------------------------
/man-roxygen/verbose.R:
--------------------------------------------------------------------------------
1 | #' @param verbose `r lifecycle::badge("deprecated")` This logical argument to
2 | #' individual googledrive functions is deprecated. To globally suppress
3 | #' googledrive messaging, use `options(googledrive_quiet = TRUE)` (the default
4 | #' behaviour is to emit informational messages). To suppress messaging in a
5 | #' more limited way, use the helpers [`local_drive_quiet()`] or
6 | #' [`with_drive_quiet()`].
7 |
--------------------------------------------------------------------------------
/man/as_shared_drive.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/shared_drives.R
3 | \name{as_shared_drive}
4 | \alias{as_shared_drive}
5 | \title{Coerce to shared drive}
6 | \usage{
7 | as_shared_drive(x, ...)
8 | }
9 | \arguments{
10 | \item{x}{A vector of shared drive names, a vector of shared drive ids marked
11 | with \code{\link[=as_id]{as_id()}}, a list of Drives resource objects, or a suitable data
12 | frame.}
13 |
14 | \item{...}{Other arguments passed down to methods. (Not used.)}
15 | }
16 | \description{
17 | Converts various representations of a shared drive into a
18 | \code{\link{dribble}}, the object used by googledrive to hold Drive file metadata.
19 | Shared drives can be specified via
20 | \itemize{
21 | \item Name
22 | \item Shared drive id, marked with \code{\link[=as_id]{as_id()}} to distinguish from name
23 | \item Data frame or \code{\link{dribble}} consisting solely of shared drives
24 | \item List representing \href{https://developers.google.com/drive/api/v3/reference/drives#resource-representations}{Drives resource}
25 | objects (mostly for internal use)
26 | }
27 |
28 | A shared drive supports files owned by an organization rather than an
29 | individual user. Shared drives follow different sharing and ownership models
30 | from a specific user's "My Drive". Shared drives are the successors to the
31 | earlier concept of Team Drives. Learn more about \link[=shared_drives]{shared drives}.
32 |
33 | This is a generic function.
34 | }
35 | \examples{
36 | \dontrun{
37 | # specify the name
38 | as_shared_drive("abc")
39 |
40 | # specify the id (substitute one of your own!)
41 | as_shared_drive(as_id("0AOPK1X2jaNckUk9PVA"))
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/man/dribble-checks.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/dribble.R
3 | \name{dribble-checks}
4 | \alias{dribble-checks}
5 | \alias{is_dribble}
6 | \alias{no_file}
7 | \alias{single_file}
8 | \alias{some_files}
9 | \alias{confirm_dribble}
10 | \alias{confirm_single_file}
11 | \alias{confirm_some_files}
12 | \alias{is_folder}
13 | \alias{is_shortcut}
14 | \alias{is_folder_shortcut}
15 | \alias{is_native}
16 | \alias{is_parental}
17 | \alias{is_mine}
18 | \alias{is_shared_drive}
19 | \title{Check facts about a dribble}
20 | \usage{
21 | is_dribble(d)
22 |
23 | no_file(d)
24 |
25 | single_file(d)
26 |
27 | some_files(d)
28 |
29 | confirm_dribble(d)
30 |
31 | confirm_single_file(d)
32 |
33 | confirm_some_files(d)
34 |
35 | is_folder(d)
36 |
37 | is_shortcut(d)
38 |
39 | is_folder_shortcut(d)
40 |
41 | is_native(d)
42 |
43 | is_parental(d)
44 |
45 | is_mine(d)
46 |
47 | is_shared_drive(d)
48 | }
49 | \arguments{
50 | \item{d}{A \code{\link{dribble}}.}
51 | }
52 | \description{
53 | Sometimes you need to check things about a \code{\link{dribble}}` or about the files it
54 | represents, such as:
55 | \itemize{
56 | \item Is it even a dribble?
57 | \item Size: Does the dribble hold exactly one file? At least one file? No file?
58 | \item File type: Is this file a folder?
59 | \item File ownership and access: Is it mine? Published? Shared?
60 | }
61 | }
62 | \examples{
63 | \dontshow{if (drive_has_token()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
64 | ## most of us have multiple files or folders on Google Drive
65 | d <- drive_find()
66 | is_dribble(d)
67 | no_file(d)
68 | single_file(d)
69 | some_files(d)
70 |
71 | # this will error
72 | # confirm_single_file(d)
73 |
74 | confirm_some_files(d)
75 | is_folder(d)
76 | is_mine(d)
77 | \dontshow{\}) # examplesIf}
78 | }
79 |
--------------------------------------------------------------------------------
/man/dribble.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/dribble.R
3 | \name{dribble}
4 | \alias{dribble}
5 | \title{dribble object}
6 | \description{
7 | googledrive stores the metadata for one or more Drive files or
8 | shared drives as a \code{dribble}. It is a "Drive
9 | \link[tibble:tibble-package]{tibble}" with one row per file or shared drive
10 | and, at a minimum, these columns:
11 | \itemize{
12 | \item \code{name}: a character column containing file or shared drive names
13 | \item \code{id}: a character column of file or shared drive ids
14 | \item \code{drive_resource}: a list-column, each element of which is either a
15 | \href{https://developers.google.com/drive/api/v3/reference/files#resource-representations}{Files resource}
16 | or a \href{https://developers.google.com/drive/api/v3/reference/drives#resource-representations}{Drives resource}
17 | object. Note there is no guarantee that all documented fields are always
18 | present. We do check if the \code{kind} field is present and equal to one of
19 | \code{drive#file} or \code{drive#drive}.
20 | }
21 |
22 | The \code{dribble} format is handy because it exposes the file name,
23 | which is good for humans, but keeps it bundled with the file's unique id
24 | and other metadata, which are needed for API calls.
25 |
26 | In general, the \code{dribble} class will be retained even after
27 | manipulation, as long as the required variables are present and of the
28 | correct type. This works best for manipulations via the dplyr and vctrs
29 | packages.
30 | }
31 | \seealso{
32 | \code{\link[=as_dribble]{as_dribble()}}
33 | }
34 |
--------------------------------------------------------------------------------
/man/drive_about.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_about.R
3 | \name{drive_about}
4 | \alias{drive_about}
5 | \title{Get info on Drive capabilities}
6 | \usage{
7 | drive_about()
8 | }
9 | \value{
10 | A list representation of a Drive
11 | \href{https://developers.google.com/drive/api/v3/reference/about}{about resource}
12 | }
13 | \description{
14 | Gets information about the user, the user's Drive, and system capabilities.
15 | This function mostly exists to power \code{\link[=drive_user]{drive_user()}}, which extracts the most
16 | useful information (the information on current user) and prints it nicely.
17 | }
18 | \examples{
19 | \dontshow{if (drive_has_token()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
20 | drive_about()
21 |
22 | # explore the export formats available for Drive files, by MIME type
23 | about <- drive_about()
24 | about[["exportFormats"]] \%>\%
25 | purrr::map(unlist)
26 | \dontshow{\}) # examplesIf}
27 | }
28 | \seealso{
29 | Wraps the \code{about.get} endpoint:
30 | \itemize{
31 | \item \url{https://developers.google.com/drive/api/v3/reference/about/get}
32 | }
33 | }
34 |
--------------------------------------------------------------------------------
/man/drive_browse.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_browse.R
3 | \name{drive_browse}
4 | \alias{drive_browse}
5 | \title{Visit Drive file in browser}
6 | \usage{
7 | drive_browse(file = .Last.value)
8 | }
9 | \arguments{
10 | \item{file}{Something that identifies the file of interest on your Google
11 | Drive. Can be a name or path, a file id or URL marked with \code{\link[=as_id]{as_id()}}, or a
12 | \code{\link{dribble}}.}
13 | }
14 | \value{
15 | Character vector of file hyperlinks, from \code{\link[=drive_link]{drive_link()}}, invisibly.
16 | }
17 | \description{
18 | Visits a file on Google Drive in your default browser.
19 | }
20 | \examples{
21 | \dontshow{if (drive_has_token() && rlang::is_interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
22 | drive_find(n_max = 1) \%>\% drive_browse()
23 | \dontshow{\}) # examplesIf}
24 | }
25 |
--------------------------------------------------------------------------------
/man/drive_deauth.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_auth.R
3 | \name{drive_deauth}
4 | \alias{drive_deauth}
5 | \title{Suspend authorization}
6 | \usage{
7 | drive_deauth()
8 | }
9 | \description{
10 | Put googledrive into a de-authorized state. Instead of sending a token,
11 | googledrive will send an API key. This can be used to access public
12 | resources for which no Google sign-in is required. This is handy for using
13 | googledrive in a non-interactive setting to make requests that do not
14 | require a token. It will prevent the attempt to obtain a token
15 | interactively in the browser. The user can configure their own API key
16 | via \code{\link[=drive_auth_configure]{drive_auth_configure()}} and retrieve that key via
17 | \code{\link[=drive_api_key]{drive_api_key()}}.
18 | In the absence of a user-configured key, a built-in default key is used.
19 | }
20 | \examples{
21 | \dontshow{if (rlang::is_interactive()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
22 | drive_deauth()
23 | drive_user()
24 |
25 | # in a deauth'ed state, we can still get metadata on a world-readable file
26 | public_file <- drive_example_remote("chicken.csv")
27 | public_file
28 | # we can still download it too
29 | drive_download(public_file)
30 | \dontshow{\}) # examplesIf}
31 | }
32 | \seealso{
33 | Other auth functions:
34 | \code{\link{drive_auth_configure}()},
35 | \code{\link{drive_auth}()},
36 | \code{\link{drive_scopes}()}
37 | }
38 | \concept{auth functions}
39 |
--------------------------------------------------------------------------------
/man/drive_empty_trash.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_trash.R
3 | \name{drive_empty_trash}
4 | \alias{drive_empty_trash}
5 | \title{Empty Drive Trash}
6 | \usage{
7 | drive_empty_trash(verbose = deprecated())
8 | }
9 | \arguments{
10 | \item{verbose}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} This logical argument to
11 | individual googledrive functions is deprecated. To globally suppress
12 | googledrive messaging, use \code{options(googledrive_quiet = TRUE)} (the default
13 | behaviour is to emit informational messages). To suppress messaging in a
14 | more limited way, use the helpers \code{\link[=local_drive_quiet]{local_drive_quiet()}} or
15 | \code{\link[=with_drive_quiet]{with_drive_quiet()}}.}
16 | }
17 | \description{
18 | Caution, this will permanently delete files in your Drive trash.
19 | }
20 |
--------------------------------------------------------------------------------
/man/drive_endpoints.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_endpoints.R
3 | \name{drive_endpoints}
4 | \alias{drive_endpoints}
5 | \alias{drive_endpoint}
6 | \title{List Drive endpoints}
7 | \usage{
8 | drive_endpoints(i = NULL)
9 |
10 | drive_endpoint(i)
11 | }
12 | \arguments{
13 | \item{i}{The name(s) or integer index(ices) of the endpoints to return. \code{i}
14 | is optional for \code{drive_endpoints()} and, if not given, the entire list is
15 | returned.}
16 | }
17 | \value{
18 | One or more of the Drive API v3 endpoints that are used internally by
19 | googledrive.
20 | }
21 | \description{
22 | The googledrive package stores a named list of Drive API v3 endpoints (or
23 | "methods", using Google's vocabulary) internally and these functions expose
24 | this data.
25 | \itemize{
26 | \item \code{drive_endpoint()} returns one endpoint, i.e. it uses \code{[[}.
27 | \item \code{drive_endpoints()} returns a list of endpoints, i.e. it uses \code{[}.
28 | }
29 |
30 | The names of this list (or the \code{id} sub-elements) are the nicknames that can
31 | be used to specify an endpoint in \code{\link[=request_generate]{request_generate()}}. For each endpoint, we
32 | store its nickname or \code{id}, the associated HTTP verb, the \code{path}, and details
33 | about the parameters. This list is derived programmatically from the Drive
34 | API v3 Discovery Document
35 | (\verb{https://www.googleapis.com/discovery/v1/apis/drive/v3/rest}) using the
36 | approach described in the \href{https://gargle.r-lib.org/articles/request-helper-functions.html#discovery-documents}{Discovery Documents section}
37 | of the gargle vignette \href{https://gargle.r-lib.org/articles/request-helper-functions.html}{Request helper functions}.
38 | }
39 | \examples{
40 | str(head(drive_endpoints(), 3), max.level = 2)
41 | drive_endpoint("drive.files.delete")
42 | drive_endpoint(4)
43 | }
44 |
--------------------------------------------------------------------------------
/man/drive_examples.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_examples.R
3 | \name{drive_examples}
4 | \alias{drive_examples}
5 | \alias{drive_examples_local}
6 | \alias{drive_examples_remote}
7 | \alias{drive_example_local}
8 | \alias{drive_example_remote}
9 | \title{Example files}
10 | \usage{
11 | drive_examples_local(matches)
12 |
13 | drive_examples_remote(matches)
14 |
15 | drive_example_local(matches)
16 |
17 | drive_example_remote(matches)
18 | }
19 | \arguments{
20 | \item{matches}{A regular expression that matches the name of the desired
21 | example file(s). This argument is optional for the plural forms
22 | (\code{drive_examples_local()} and \code{drive_examples_remote()}) and, if provided,
23 | multiple matches are allowed. The single forms (\code{drive_example_local()} and
24 | \code{drive_example_remote()}) require this argument and require that there is
25 | exactly one match.}
26 | }
27 | \value{
28 | \itemize{
29 | \item For \code{drive_example_local()} and \code{drive_examples_local()}, one or more local
30 | filepaths.
31 | \item For \code{drive_example_remote()} and \code{drive_examples_remote()}, a \code{dribble}.
32 | }
33 | }
34 | \description{
35 | googledrive makes a variety of example files -- both local and remote --
36 | available for use in examples and reprexes. These functions help you access
37 | the example files. See \code{vignette("example-files", package = "googledrive")}
38 | for more.
39 | }
40 | \examples{
41 | drive_examples_local() \%>\% basename()
42 | drive_examples_local("chicken") \%>\% basename()
43 | drive_example_local("imdb")
44 |
45 | \dontshow{if (drive_has_token()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
46 | drive_examples_remote()
47 | drive_examples_remote("chicken")
48 | drive_example_remote("chicken_doc")
49 | \dontshow{\}) # examplesIf}
50 | }
51 |
--------------------------------------------------------------------------------
/man/drive_extension.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_mime_type.R
3 | \name{drive_extension}
4 | \alias{drive_extension}
5 | \title{Lookup extension from MIME type}
6 | \usage{
7 | drive_extension(type = NULL)
8 | }
9 | \arguments{
10 | \item{type}{Character. MIME type or file extension.}
11 | }
12 | \value{
13 | Character. File extension.
14 | }
15 | \description{
16 | This is a helper to determinine which extension should be used
17 | for a file. Two types of input are acceptable:
18 | \itemize{
19 | \item MIME types accepted by Google Drive.
20 | \item File extensions, such as "pdf", "csv", etc. (these are simply passed through).
21 | }
22 | }
23 | \examples{
24 |
25 | ## get the extension for mime type image/jpeg
26 | drive_extension("image/jpeg")
27 |
28 | ## it's vectorized
29 | drive_extension(c("text/plain", "pdf", "image/gif"))
30 | }
31 |
--------------------------------------------------------------------------------
/man/drive_fields.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_fields.R
3 | \name{drive_fields}
4 | \alias{drive_fields}
5 | \alias{prep_fields}
6 | \title{Request partial resources}
7 | \usage{
8 | drive_fields(fields = NULL, resource = "files")
9 |
10 | prep_fields(fields, resource = "files")
11 | }
12 | \arguments{
13 | \item{fields}{Character vector of field names. If \code{resource = "files"}, they
14 | are checked for validity. Otherwise, they are passed through.}
15 |
16 | \item{resource}{Character, naming the API resource of interest. Currently,
17 | only the Files resource is anticipated.}
18 | }
19 | \value{
20 | \code{drive_fields()}: Character vector of field names. \code{prep_fields()}: a
21 | string.
22 | }
23 | \description{
24 | You may be able to improve the performance of your API calls by
25 | requesting only the metadata that you actually need. This function is
26 | primarily for internal use and is currently focused on the \href{https://developers.google.com/drive/api/v3/reference/files}{Files resource}. Note
27 | that high-level googledrive functions assume that the \code{name}, \code{id}, and
28 | \code{kind} fields are included, at a bare minimum. Assuming that \code{resource = "files"} (the default), input provided via \code{fields} is checked for validity
29 | against the known field names and the validated fields are returned. To see
30 | a tibble containing all possible fields and a short description of each,
31 | call \code{drive_fields(expose())}.
32 |
33 | \code{prep_fields()} prepares fields for inclusion as query
34 | parameters.
35 | }
36 | \examples{
37 | # get a tibble of all fields for the Files resource + indicator of defaults
38 | drive_fields(expose())
39 |
40 | # invalid fields are removed and throw warning
41 | drive_fields(c("name", "parents", "ownedByMe", "pancakes!"))
42 |
43 | # prepare fields for query
44 | prep_fields(c("name", "parents", "kind"))
45 | }
46 | \seealso{
47 | \href{https://developers.google.com/drive/api/v3/performance}{Improve performance}, in
48 | the Drive API documentation.
49 | }
50 |
--------------------------------------------------------------------------------
/man/drive_has_token.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_auth.R
3 | \name{drive_has_token}
4 | \alias{drive_has_token}
5 | \title{Is there a token on hand?}
6 | \usage{
7 | drive_has_token()
8 | }
9 | \value{
10 | Logical.
11 | }
12 | \description{
13 | Reports whether googledrive has stored a token, ready for use in downstream
14 | requests.
15 | }
16 | \examples{
17 | drive_has_token()
18 | }
19 | \seealso{
20 | Other low-level API functions:
21 | \code{\link{drive_token}()},
22 | \code{\link{request_generate}()},
23 | \code{\link{request_make}()}
24 | }
25 | \concept{low-level API functions}
26 |
--------------------------------------------------------------------------------
/man/drive_id.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_id-class.R
3 | \name{drive_id}
4 | \alias{drive_id}
5 | \alias{as_id}
6 | \title{\code{drive_id} class}
7 | \usage{
8 | as_id(x, ...)
9 | }
10 | \arguments{
11 | \item{x}{A character vector of file or shared drive ids or URLs, a
12 | \code{\link{dribble}}, or a suitable data frame.}
13 |
14 | \item{...}{Other arguments passed down to methods. (Not used.)}
15 | }
16 | \value{
17 | A character vector bearing the S3 class \code{drive_id}.
18 | }
19 | \description{
20 | \code{drive_id} is an S3 class to mark strings as Drive file ids, in order to
21 | distinguish them from Drive file names or paths. \code{as_id()} converts various
22 | inputs into an instance of \code{drive_id}.
23 |
24 | \code{as_id()} is a generic function.
25 | }
26 | \examples{
27 | \dontshow{if (drive_has_token()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
28 | as_id("123abc")
29 | as_id("https://docs.google.com/spreadsheets/d/qawsedrf16273849/edit#gid=12345")
30 |
31 | x <- drive_find(n_max = 3)
32 | as_id(x)
33 | \dontshow{\}) # examplesIf}
34 | }
35 |
--------------------------------------------------------------------------------
/man/drive_link.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_browse.R
3 | \name{drive_link}
4 | \alias{drive_link}
5 | \title{Retrieve Drive file links}
6 | \usage{
7 | drive_link(file)
8 | }
9 | \arguments{
10 | \item{file}{Something that identifies the file(s) of interest on your Google
11 | Drive. Can be a character vector of names/paths, a character vector of file
12 | ids or URLs marked with \code{\link[=as_id]{as_id()}}, or a \code{\link{dribble}}.}
13 | }
14 | \value{
15 | Character vector of file hyperlinks.
16 | }
17 | \description{
18 | Returns the \code{"webViewLink"} for one or more files, which is the "link for
19 | opening the file in a relevant Google editor or viewer in a browser".
20 | }
21 | \examples{
22 | \dontshow{if (drive_has_token()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
23 | # get a few files into a dribble
24 | three_files <- drive_find(n_max = 3)
25 |
26 | # get their browser links
27 | drive_link(three_files)
28 | \dontshow{\}) # examplesIf}
29 | }
30 |
--------------------------------------------------------------------------------
/man/drive_ls.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_ls.R
3 | \name{drive_ls}
4 | \alias{drive_ls}
5 | \title{List contents of a folder or shared drive}
6 | \usage{
7 | drive_ls(path = NULL, ..., recursive = FALSE)
8 | }
9 | \arguments{
10 | \item{path}{Specifies a single folder on Google Drive whose contents you want
11 | to list. Can be an actual path (character), a file id or URL marked with
12 | \code{\link[=as_id]{as_id()}}, or a \code{\link{dribble}}. If it is a shared drive or is a folder on a
13 | shared drive, it must be passed as a \code{\link{dribble}}. If \code{path} is a shortcut
14 | to a folder, it is automatically resolved to its target folder.}
15 |
16 | \item{...}{Any parameters that are valid for \code{\link[=drive_find]{drive_find()}}.}
17 |
18 | \item{recursive}{Logical, indicating if you want only direct children of
19 | \code{path} (\code{recursive = FALSE}, the default) or all children, including
20 | indirect (\code{recursive = TRUE}).}
21 | }
22 | \value{
23 | An object of class \code{\link{dribble}}, a tibble with one row per file.
24 | }
25 | \description{
26 | List the contents of a folder or shared drive, recursively or not. This is a
27 | thin wrapper around \code{\link[=drive_find]{drive_find()}}, that simply adds one constraint: the
28 | search is limited to direct or indirect children of \code{path}.
29 | }
30 | \examples{
31 | \dontrun{
32 | # get contents of the folder 'abc' (non-recursive)
33 | drive_ls("abc")
34 |
35 | # get contents of folder 'abc' whose names contain the letters 'def'
36 | drive_ls(path = "abc", pattern = "def")
37 |
38 | # get all Google spreadsheets in folder 'abc'
39 | # whose names contain the letters 'def'
40 | drive_ls(path = "abc", pattern = "def", type = "spreadsheet")
41 |
42 | # get all the files below 'abc', recursively, that are starred
43 | drive_ls(path = "abc", q = "starred = true", recursive = TRUE)
44 | }
45 | }
46 |
--------------------------------------------------------------------------------
/man/drive_mime_type.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_mime_type.R
3 | \name{drive_mime_type}
4 | \alias{drive_mime_type}
5 | \title{Lookup MIME type}
6 | \usage{
7 | drive_mime_type(type = NULL)
8 | }
9 | \arguments{
10 | \item{type}{Character. Google Drive file type, file extension, or MIME type.
11 | Pass the sentinel \code{\link[=expose]{expose()}} if you want to get the full table used for
12 | validation and lookup, i.e. all MIME types known to be relevant to the
13 | Drive API.}
14 | }
15 | \value{
16 | Character. MIME type.
17 | }
18 | \description{
19 | This is a helper to determine which MIME type should be used
20 | for a file. Three types of input are acceptable:
21 | \itemize{
22 | \item Native Google Drive file types. Important examples:
23 | \itemize{
24 | \item "document" for Google Docs
25 | \item "folder" for folders
26 | \item "presentation" for Google Slides
27 | \item "spreadsheet" for Google Sheets
28 | }
29 | \item File extensions, such as "pdf", "csv", etc.
30 | \item MIME types accepted by Google Drive (these are simply passed through).
31 | }
32 | }
33 | \examples{
34 | ## get the mime type for Google Spreadsheets
35 | drive_mime_type("spreadsheet")
36 |
37 | ## get the mime type for jpegs
38 | drive_mime_type("jpeg")
39 |
40 | ## it's vectorized
41 | drive_mime_type(c("presentation", "pdf", "image/gif"))
42 |
43 | ## see the internal tibble of MIME types known to the Drive API
44 | drive_mime_type(expose())
45 | }
46 |
--------------------------------------------------------------------------------
/man/drive_publish.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_publish.R
3 | \name{drive_publish}
4 | \alias{drive_publish}
5 | \alias{drive_unpublish}
6 | \title{Publish native Google files}
7 | \usage{
8 | drive_publish(file, ..., verbose = deprecated())
9 |
10 | drive_unpublish(file, ..., verbose = deprecated())
11 | }
12 | \arguments{
13 | \item{file}{Something that identifies the file(s) of interest on your Google
14 | Drive. Can be a character vector of names/paths, a character vector of file
15 | ids or URLs marked with \code{\link[=as_id]{as_id()}}, or a \code{\link{dribble}}.}
16 |
17 | \item{...}{Name-value pairs to add to the API request body (see API docs
18 | linked below for details). For \code{drive_publish()}, we include
19 | \code{publishAuto = TRUE} and \code{publishedOutsideDomain = TRUE}, if user does not
20 | specify other values.}
21 |
22 | \item{verbose}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} This logical argument to
23 | individual googledrive functions is deprecated. To globally suppress
24 | googledrive messaging, use \code{options(googledrive_quiet = TRUE)} (the default
25 | behaviour is to emit informational messages). To suppress messaging in a
26 | more limited way, use the helpers \code{\link[=local_drive_quiet]{local_drive_quiet()}} or
27 | \code{\link[=with_drive_quiet]{with_drive_quiet()}}.}
28 | }
29 | \value{
30 | An object of class \code{\link{dribble}}, a tibble with one row per file.
31 | There will be extra columns, \code{published} and
32 | \code{revisions_resource}.
33 | }
34 | \description{
35 | Publish (or un-publish) native Google files to the web. Native Google files
36 | include Google Docs, Google Sheets, and Google Slides. The returned
37 | \code{\link{dribble}} will have extra columns, \code{published} and \code{revisions_resource}.
38 | Read more in \code{\link[=drive_reveal]{drive_reveal()}}.
39 | }
40 | \examples{
41 | \dontshow{if (drive_has_token()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
42 | # Create a file to publish
43 | file <- drive_example_remote("chicken_sheet") \%>\%
44 | drive_cp()
45 |
46 | # Publish file
47 | file <- drive_publish(file)
48 | file$published
49 |
50 | # Unpublish file
51 | file <- drive_unpublish(file)
52 | file$published
53 |
54 | # Clean up
55 | drive_rm(file)
56 | \dontshow{\}) # examplesIf}
57 | }
58 | \seealso{
59 | Wraps the \code{revisions.update} endpoint:
60 | \itemize{
61 | \item \url{https://developers.google.com/drive/api/v3/reference/revisions/update}
62 | }
63 | }
64 |
--------------------------------------------------------------------------------
/man/drive_read_string.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_read.R
3 | \name{drive_read_string}
4 | \alias{drive_read_string}
5 | \alias{drive_read_raw}
6 | \title{Read the content of a Drive file}
7 | \usage{
8 | drive_read_string(file, type = NULL, encoding = NULL)
9 |
10 | drive_read_raw(file, type = NULL)
11 | }
12 | \arguments{
13 | \item{file}{Something that identifies the file of interest on your Google
14 | Drive. Can be a name or path, a file id or URL marked with \code{\link[=as_id]{as_id()}}, or a
15 | \code{\link{dribble}}.}
16 |
17 | \item{type}{Character. Only consulted if \code{file} is a native Google file.
18 | Specifies the desired type of the exported file. Will be processed via
19 | \code{\link[=drive_mime_type]{drive_mime_type()}}, so either a file extension like \code{"pdf"} or a full MIME
20 | type like \code{"application/pdf"} is acceptable.}
21 |
22 | \item{encoding}{Passed along to \code{\link[httr:content]{httr::content()}}. Describes the encoding of
23 | the \emph{input} \code{file}.}
24 | }
25 | \value{
26 | \itemize{
27 | \item \code{read_drive_string()}: a UTF-8 encoded string
28 | \item \code{read_drive_raw()}: a \code{\link[=raw]{raw()}} vector
29 | }
30 | }
31 | \description{
32 | These functions return the content of a Drive file as either a
33 | string or raw bytes. You will likely need to do additional work to parse
34 | the content into a useful R object.
35 |
36 | \code{\link[=drive_download]{drive_download()}} is the more generally useful function, but for certain
37 | file types, such as comma-separated values (MIME type \code{text/csv}), it can
38 | be handy to read data directly from Google Drive and avoid writing to disk.
39 |
40 | Just as for \code{\link[=drive_download]{drive_download()}}, native Google file types, such as Google
41 | Sheets or Docs, must be exported as a conventional MIME type. See the help
42 | for \code{\link[=drive_download]{drive_download()}} for more.
43 | }
44 | \examples{
45 | \dontshow{if (drive_has_token()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
46 | # comma-separated values --> data.frame or tibble
47 | (chicken_csv <- drive_example_remote("chicken.csv"))
48 | chicken_csv \%>\%
49 | drive_read_string() \%>\%
50 | read.csv(text = .)
51 |
52 | # Google Doc --> character vector
53 | (chicken_doc <- drive_example_remote("chicken_doc"))
54 | chicken_doc \%>\%
55 | # NOTE: we must specify an export MIME type
56 | drive_read_string(type = "text/plain") \%>\%
57 | strsplit(split = "(\r\n|\r|\n)") \%>\%
58 | .[[1]]
59 | \dontshow{\}) # examplesIf}
60 | }
61 |
--------------------------------------------------------------------------------
/man/drive_rm.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_rm.R
3 | \name{drive_rm}
4 | \alias{drive_rm}
5 | \title{Delete files from Drive}
6 | \usage{
7 | drive_rm(..., verbose = deprecated())
8 | }
9 | \arguments{
10 | \item{...}{One or more Drive files, specified in any valid way, i.e. as a
11 | \code{\link{dribble}}, by name or path, or by file id or URL marked with \code{\link[=as_id]{as_id()}}. Or
12 | any combination thereof. Elements are processed with \code{\link[=as_dribble]{as_dribble()}} and
13 | row-bound prior to deletion.}
14 |
15 | \item{verbose}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} This logical argument to
16 | individual googledrive functions is deprecated. To globally suppress
17 | googledrive messaging, use \code{options(googledrive_quiet = TRUE)} (the default
18 | behaviour is to emit informational messages). To suppress messaging in a
19 | more limited way, use the helpers \code{\link[=local_drive_quiet]{local_drive_quiet()}} or
20 | \code{\link[=with_drive_quiet]{with_drive_quiet()}}.}
21 | }
22 | \value{
23 | Logical vector, indicating whether the delete succeeded.
24 | }
25 | \description{
26 | Caution: this will permanently delete your files! For a safer, reversible
27 | option, see \code{\link[=drive_trash]{drive_trash()}}.
28 | }
29 | \examples{
30 | \dontshow{if (drive_has_token()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
31 | # Target one of the official example files to copy (then remove)
32 | (src_file <- drive_example_remote("chicken.txt"))
33 |
34 | # Create a copy, then remove it by name
35 | src_file \%>\%
36 | drive_cp(name = "chicken-rm.txt")
37 | drive_rm("chicken-rm.txt")
38 |
39 | # Create several more copies
40 | x1 <- src_file \%>\%
41 | drive_cp(name = "chicken-abc.txt")
42 | drive_cp(src_file, name = "chicken-def.txt")
43 | x2 <- src_file \%>\%
44 | drive_cp(name = "chicken-ghi.txt")
45 |
46 | # Remove the copies all at once, specified in different ways
47 | drive_rm(x1, "chicken-def.txt", as_id(x2))
48 | \dontshow{\}) # examplesIf}
49 | }
50 | \seealso{
51 | Wraps the \code{files.delete} endpoint:
52 | \itemize{
53 | \item \url{https://developers.google.com/drive/api/v3/reference/files/delete}
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/man/drive_scopes.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_auth.R
3 | \name{drive_scopes}
4 | \alias{drive_scopes}
5 | \title{Produce scopes specific to the Drive API}
6 | \usage{
7 | drive_scopes(scopes = NULL)
8 | }
9 | \arguments{
10 | \item{scopes}{One or more API scopes. Each scope can be specified in full or,
11 | for Drive API-specific scopes, in an abbreviated form that is recognized by
12 | \code{\link[=drive_scopes]{drive_scopes()}}:
13 | \itemize{
14 | \item "drive" = "https://www.googleapis.com/auth/drive" (the default)
15 | \item "full" = "https://www.googleapis.com/auth/drive" (same as "drive")
16 | \item "drive.readonly" = "https://www.googleapis.com/auth/drive.readonly"
17 | \item "drive.file" = "https://www.googleapis.com/auth/drive.file"
18 | \item "drive.appdata" = "https://www.googleapis.com/auth/drive.appdata"
19 | \item "drive.metadata" = "https://www.googleapis.com/auth/drive.metadata"
20 | \item "drive.metadata.readonly" = "https://www.googleapis.com/auth/drive.metadata.readonly"
21 | \item "drive.photos.readonly" = "https://www.googleapis.com/auth/drive.photos.readonly"
22 | \item "drive.scripts" = "https://www.googleapis.com/auth/drive.scripts
23 | }
24 |
25 | See \url{https://developers.google.com/drive/api/guides/api-specific-auth} for
26 | details on the permissions for each scope.}
27 | }
28 | \value{
29 | A character vector of scopes.
30 | }
31 | \description{
32 | When called with no arguments, \code{drive_scopes()} returns a named character vector
33 | of scopes associated with the Drive API. If \code{drive_scopes(scopes =)} is given,
34 | an abbreviated entry such as \code{"drive.readonly"} is expanded to a full scope
35 | (\code{"https://www.googleapis.com/auth/drive.readonly"} in this case).
36 | Unrecognized scopes are passed through unchanged.
37 | }
38 | \examples{
39 | drive_scopes("full")
40 | drive_scopes("drive.readonly")
41 | drive_scopes()
42 | }
43 | \seealso{
44 | \url{https://developers.google.com/drive/api/guides/api-specific-auth} for details on
45 | the permissions for each scope.
46 |
47 | Other auth functions:
48 | \code{\link{drive_auth_configure}()},
49 | \code{\link{drive_auth}()},
50 | \code{\link{drive_deauth}()}
51 | }
52 | \concept{auth functions}
53 |
--------------------------------------------------------------------------------
/man/drive_token.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_auth.R
3 | \name{drive_token}
4 | \alias{drive_token}
5 | \title{Produce configured token}
6 | \usage{
7 | drive_token()
8 | }
9 | \value{
10 | A \code{request} object (an S3 class provided by \link[httr:httr-package]{httr}).
11 | }
12 | \description{
13 | For internal use or for those programming around the Drive API.
14 | Returns a token pre-processed with \code{\link[httr:config]{httr::config()}}. Most users
15 | do not need to handle tokens "by hand" or, even if they need some
16 | control, \code{\link[=drive_auth]{drive_auth()}} is what they need. If there is no current
17 | token, \code{\link[=drive_auth]{drive_auth()}} is called to either load from cache or
18 | initiate OAuth2.0 flow.
19 | If auth has been deactivated via \code{\link[=drive_deauth]{drive_deauth()}}, \code{drive_token()}
20 | returns \code{NULL}.
21 | }
22 | \examples{
23 | \dontshow{if (drive_has_token()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
24 | req <- request_generate(
25 | "drive.files.get",
26 | list(fileId = "abc"),
27 | token = drive_token()
28 | )
29 | req
30 | \dontshow{\}) # examplesIf}
31 | }
32 | \seealso{
33 | Other low-level API functions:
34 | \code{\link{drive_has_token}()},
35 | \code{\link{request_generate}()},
36 | \code{\link{request_make}()}
37 | }
38 | \concept{low-level API functions}
39 |
--------------------------------------------------------------------------------
/man/drive_trash.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_trash.R
3 | \name{drive_trash}
4 | \alias{drive_trash}
5 | \alias{drive_untrash}
6 | \title{Move Drive files to or from trash}
7 | \usage{
8 | drive_trash(file, verbose = deprecated())
9 |
10 | drive_untrash(file, verbose = deprecated())
11 | }
12 | \arguments{
13 | \item{file}{Something that identifies the file(s) of interest on your Google
14 | Drive. Can be a character vector of names/paths, a character vector of file
15 | ids or URLs marked with \code{\link[=as_id]{as_id()}}, or a \code{\link{dribble}}.}
16 |
17 | \item{verbose}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} This logical argument to
18 | individual googledrive functions is deprecated. To globally suppress
19 | googledrive messaging, use \code{options(googledrive_quiet = TRUE)} (the default
20 | behaviour is to emit informational messages). To suppress messaging in a
21 | more limited way, use the helpers \code{\link[=local_drive_quiet]{local_drive_quiet()}} or
22 | \code{\link[=with_drive_quiet]{with_drive_quiet()}}.}
23 | }
24 | \value{
25 | An object of class \code{\link{dribble}}, a tibble with one row per file.
26 | }
27 | \description{
28 | Move Drive files to or from trash
29 | }
30 | \examples{
31 | \dontshow{if (drive_has_token()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
32 | # Create a file and put it in the trash.
33 | file <- drive_example_remote("chicken.txt") \%>\%
34 | drive_cp("chicken-trash.txt")
35 | drive_trash("chicken-trash.txt")
36 |
37 | # Confirm it's in the trash
38 | drive_find(trashed = TRUE)
39 |
40 | # Remove it from the trash and confirm
41 | drive_untrash("chicken-trash.txt")
42 | drive_find(trashed = TRUE)
43 |
44 | # Clean up
45 | drive_rm("chicken-trash.txt")
46 | \dontshow{\}) # examplesIf}
47 | }
48 |
--------------------------------------------------------------------------------
/man/drive_user.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/drive_user.R
3 | \name{drive_user}
4 | \alias{drive_user}
5 | \title{Get info on current user}
6 | \usage{
7 | drive_user(verbose = deprecated())
8 | }
9 | \arguments{
10 | \item{verbose}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} This logical argument to
11 | individual googledrive functions is deprecated. To globally suppress
12 | googledrive messaging, use \code{options(googledrive_quiet = TRUE)} (the default
13 | behaviour is to emit informational messages). To suppress messaging in a
14 | more limited way, use the helpers \code{\link[=local_drive_quiet]{local_drive_quiet()}} or
15 | \code{\link[=with_drive_quiet]{with_drive_quiet()}}.}
16 | }
17 | \value{
18 | A list of class \code{drive_user}.
19 | }
20 | \description{
21 | Reveals information about the user associated with the current token. This is
22 | a thin wrapper around \code{\link[=drive_about]{drive_about()}} that just extracts the most useful
23 | information (the information on current user) and prints it nicely.
24 | }
25 | \examples{
26 | \dontshow{if (drive_has_token()) (if (getRversion() >= "3.4") withAutoprint else force)(\{ # examplesIf}
27 | drive_user()
28 |
29 | # more info is returned than is printed
30 | user <- drive_user()
31 | str(user)
32 | \dontshow{\}) # examplesIf}
33 | }
34 | \seealso{
35 | Wraps the \code{about.get} endpoint:
36 | \itemize{
37 | \item \url{https://developers.google.com/drive/api/v3/reference/about/get}
38 | }
39 | }
40 |
--------------------------------------------------------------------------------
/man/expose.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/utils.R
3 | \name{expose}
4 | \alias{expose}
5 | \title{An expose object}
6 | \usage{
7 | expose()
8 | }
9 | \description{
10 | \code{expose()} returns a sentinel object, similar in spirit to \code{NULL}, that tells
11 | the calling function to return its internal data structure. googledrive
12 | stores a lot of information about the Drive API, MIME types, etc., internally
13 | and then exploits it in helper functions, like \code{\link[=drive_mime_type]{drive_mime_type()}},
14 | \code{\link[=drive_fields]{drive_fields()}}, \code{\link[=drive_endpoints]{drive_endpoints()}}, etc. We use these objects to
15 | provide nice defaults, check input validity, or lookup something cryptic,
16 | like MIME type, based on something friendlier, like a file extension. Pass
17 | \code{expose()} to such a function if you want to inspect its internal object, in
18 | its full glory. This is inspired by the \code{waiver()} object in ggplot2.
19 | }
20 | \examples{
21 | drive_mime_type(expose())
22 | drive_fields(expose())
23 | }
24 | \keyword{internal}
25 |
--------------------------------------------------------------------------------
/man/figures/lifecycle-archived.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/man/figures/lifecycle-defunct.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/man/figures/lifecycle-deprecated.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/man/figures/lifecycle-experimental.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/man/figures/lifecycle-maturing.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/man/figures/lifecycle-questioning.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/man/figures/lifecycle-soft-deprecated.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/man/figures/lifecycle-stable.svg:
--------------------------------------------------------------------------------
1 |
30 |
--------------------------------------------------------------------------------
/man/figures/lifecycle-superseded.svg:
--------------------------------------------------------------------------------
1 |
22 |
--------------------------------------------------------------------------------
/man/figures/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/man/figures/logo.png
--------------------------------------------------------------------------------
/man/googledrive-deprecated.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/deprecated.R
3 | \name{googledrive-deprecated}
4 | \alias{googledrive-deprecated}
5 | \alias{drive_auth_config}
6 | \alias{drive_oauth_app}
7 | \alias{drive_example}
8 | \title{Deprecated googledrive functions}
9 | \usage{
10 | drive_auth_config(active, app, path, api_key)
11 |
12 | drive_oauth_app()
13 |
14 | drive_example(path = NULL)
15 | }
16 | \arguments{
17 | \item{app}{\ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}} Replaced by the \code{client}
18 | argument.}
19 |
20 | \item{path}{JSON downloaded from \href{https://console.cloud.google.com}{Google Cloud Console}, containing a client id and
21 | secret, in one of the forms supported for the \code{txt} argument of
22 | \code{\link[jsonlite:fromJSON]{jsonlite::fromJSON()}} (typically, a file path or JSON string).}
23 |
24 | \item{api_key}{API key.}
25 | }
26 | \description{
27 | \ifelse{html}{\href{https://lifecycle.r-lib.org/articles/stages.html#deprecated}{\figure{lifecycle-deprecated.svg}{options: alt='[Deprecated]'}}}{\strong{[Deprecated]}}
28 | }
29 | \section{\code{drive_auth_config()}}{
30 |
31 |
32 | This function is defunct.
33 | \itemize{
34 | \item Use \code{\link[=drive_auth_configure]{drive_auth_configure()}} to configure your own OAuth client or API key.
35 | \item Use \code{\link[=drive_deauth]{drive_deauth()}} to go into a de-authorized state.
36 | \item Use \code{\link[=drive_oauth_client]{drive_oauth_client()}} to retrieve a user-configured client, if it
37 | exists.
38 | \item Use \code{\link[=drive_api_key]{drive_api_key()}} to retrieve a user-configured API key, if it exists.
39 | }
40 | }
41 |
42 | \section{\code{drive_oauth_app()}}{
43 |
44 |
45 | In light of the new \code{\link[gargle:gargle_oauth_client_from_json]{gargle::gargle_oauth_client()}} constructor and class of
46 | the same name, \code{drive_oauth_app()} is being replaced by
47 | \code{\link[=drive_oauth_client]{drive_oauth_client()}}.
48 | }
49 |
50 | \section{\code{drive_example()}}{
51 |
52 |
53 | This function is defunct. Access example files with \code{\link[=drive_examples_local]{drive_examples_local()}},
54 | \code{\link[=drive_example_local]{drive_example_local()}}, \code{\link[=drive_examples_remote]{drive_examples_remote()}}, and
55 | \code{\link[=drive_example_remote]{drive_example_remote()}}.
56 | }
57 |
58 | \keyword{internal}
59 |
--------------------------------------------------------------------------------
/man/googledrive-package.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/googledrive-package.R
3 | \docType{package}
4 | \name{googledrive-package}
5 | \alias{googledrive}
6 | \alias{googledrive-package}
7 | \title{googledrive: An Interface to Google Drive}
8 | \description{
9 | googledrive allows you to interact with files on Google Drive
10 | from R.
11 |
12 | \code{googledrive::drive_find(n_max = 50)} lists up to 50 of the files you see
13 | in \href{https://drive.google.com}{My Drive}. You can expect to be sent to your
14 | browser here, to authenticate yourself and authorize the googledrive
15 | package to deal on your behalf with Google Drive.
16 |
17 | Most functions begin with the prefix \code{drive_}.
18 |
19 | The goal is to allow Drive access that feels similar to Unix file system
20 | utilities, e.g., \code{find}, \code{ls}, \code{mv}, \code{cp}, \code{mkdir}, and \code{rm}.
21 |
22 | The metadata for one or more Drive files is held in a \code{\link{dribble}}, a "Drive
23 | tibble". This is a data frame with one row per file. A dribble is returned
24 | (and accepted) by almost every function in googledrive. It is designed to
25 | give people what they want (file name), track what the API wants (file id),
26 | and to hold the metadata needed for general file operations.
27 |
28 | googledrive is "pipe-friendly" and, in fact, re-exports \verb{\%>\%}, but does not
29 | require its use.
30 |
31 | Please see the googledrive website for full documentation:
32 | \itemize{
33 | \item \url{https://googledrive.tidyverse.org/index.html}
34 | }
35 |
36 | In addition to function-specific help, there are several articles which are
37 | indexed here:
38 | \itemize{
39 | \item \href{https://googledrive.tidyverse.org/articles/index.html}{Article index}
40 | }
41 | }
42 | \seealso{
43 | Useful links:
44 | \itemize{
45 | \item \url{https://googledrive.tidyverse.org}
46 | \item \url{https://github.com/tidyverse/googledrive}
47 | \item Report bugs at \url{https://github.com/tidyverse/googledrive/issues}
48 | }
49 |
50 | }
51 | \author{
52 | \strong{Maintainer}: Jennifer Bryan \email{jenny@posit.co} (\href{https://orcid.org/0000-0002-6983-2759}{ORCID})
53 |
54 | Authors:
55 | \itemize{
56 | \item Lucy D'Agostino McGowan
57 | }
58 |
59 | Other contributors:
60 | \itemize{
61 | \item Posit Software, PBC [copyright holder, funder]
62 | }
63 |
64 | }
65 | \keyword{internal}
66 |
--------------------------------------------------------------------------------
/man/pipe.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/utils-pipe.R
3 | \name{\%>\%}
4 | \alias{\%>\%}
5 | \title{Pipe operator}
6 | \usage{
7 | lhs \%>\% rhs
8 | }
9 | \description{
10 | See \code{magrittr::\link[magrittr]{\%>\%}} for details.
11 | }
12 | \keyword{internal}
13 |
--------------------------------------------------------------------------------
/man/shared_drive_create.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/shared_drive_create.R
3 | \name{shared_drive_create}
4 | \alias{shared_drive_create}
5 | \title{Create a new shared drive}
6 | \usage{
7 | shared_drive_create(name)
8 | }
9 | \arguments{
10 | \item{name}{Character. Name of the new shared drive. Must be non-empty and not
11 | entirely whitespace.}
12 | }
13 | \value{
14 | An object of class \code{\link{dribble}}, a tibble with one row per shared drive.
15 | }
16 | \description{
17 | A shared drive supports files owned by an organization rather than an
18 | individual user. Shared drives follow different sharing and ownership models
19 | from a specific user's "My Drive". Shared drives are the successors to the
20 | earlier concept of Team Drives. Learn more about \link[=shared_drives]{shared drives}.
21 | }
22 | \examples{
23 | \dontrun{
24 | shared_drive_create("my-awesome-shared-drive")
25 |
26 | # Clean up
27 | shared_drive_rm("my-awesome-shared-drive")
28 | }
29 | }
30 | \seealso{
31 | Wraps the \code{drives.create} endpoint:
32 | \itemize{
33 | \item \url{https://developers.google.com/drive/api/v3/reference/drives/create}
34 | }
35 | }
36 |
--------------------------------------------------------------------------------
/man/shared_drive_find.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/shared_drive_find.R
3 | \name{shared_drive_find}
4 | \alias{shared_drive_find}
5 | \title{Find shared drives}
6 | \usage{
7 | shared_drive_find(pattern = NULL, n_max = Inf, ...)
8 | }
9 | \arguments{
10 | \item{pattern}{Character. If provided, only the items whose names match this
11 | regular expression are returned. This is implemented locally on the results
12 | returned by the API.}
13 |
14 | \item{n_max}{Integer. An upper bound on the number of items to return. This
15 | applies to the results requested from the API, which may be further
16 | filtered locally, via the \code{pattern} argument.}
17 |
18 | \item{...}{Other parameters to pass along in the request, such as \code{pageSize}
19 | or \code{useDomainAdminAccess}.}
20 | }
21 | \value{
22 | An object of class \code{\link{dribble}}, a tibble with one row per shared drive.
23 | }
24 | \description{
25 | This is the closest googledrive function to what you get from
26 | visiting \url{https://drive.google.com} and clicking "Shared drives".
27 |
28 | A shared drive supports files owned by an organization rather than an
29 | individual user. Shared drives follow different sharing and ownership models
30 | from a specific user's "My Drive". Shared drives are the successors to the
31 | earlier concept of Team Drives. Learn more about \link[=shared_drives]{shared drives}.
32 | }
33 | \examples{
34 | \dontrun{
35 | shared_drive_find()
36 | }
37 | }
38 | \seealso{
39 | Wraps the \code{drives.list} endpoint:
40 | \itemize{
41 | \item \url{https://developers.google.com/drive/api/v3/reference/drives/list}
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/man/shared_drive_get.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/shared_drive_get.R
3 | \name{shared_drive_get}
4 | \alias{shared_drive_get}
5 | \title{Get shared drives by name or id}
6 | \usage{
7 | shared_drive_get(name = NULL, id = NULL)
8 | }
9 | \arguments{
10 | \item{name}{Character vector of names. A character vector marked with
11 | \code{\link[=as_id]{as_id()}} is treated as if it was provided via the \code{id} argument.}
12 |
13 | \item{id}{Character vector of shared drive ids or URLs (it is first processed
14 | with \code{\link[=as_id]{as_id()}}). If both \code{name} and \code{id} are non-\code{NULL}, \code{id} is silently
15 | ignored.}
16 | }
17 | \value{
18 | An object of class \code{\link{dribble}}, a tibble with one row per shared drive.
19 | }
20 | \description{
21 | Retrieve metadata for shared drives specified by name or id. Note that Google
22 | Drive does NOT behave like your local file system:
23 | \itemize{
24 | \item You can get zero, one, or more shared drives back for each name! Shared
25 | drive names need not be unique.
26 | }
27 |
28 | A shared drive supports files owned by an organization rather than an
29 | individual user. Shared drives follow different sharing and ownership models
30 | from a specific user's "My Drive". Shared drives are the successors to the
31 | earlier concept of Team Drives. Learn more about \link[=shared_drives]{shared drives}.
32 | }
33 | \examples{
34 | \dontrun{
35 | shared_drive_get("my-awesome-shared-drive")
36 | shared_drive_get(c("apple", "orange", "banana"))
37 | shared_drive_get(as_id("KCmiHLXUk9PVA-0AJNG"))
38 | shared_drive_get(as_id("https://drive.google.com/drive/u/0/folders/KCmiHLXUk9PVA-0AJNG"))
39 | shared_drive_get(id = "KCmiHLXUk9PVA-0AJNG")
40 | shared_drive_get(id = "https://drive.google.com/drive/u/0/folders/KCmiHLXUk9PVA-0AJNG")
41 | }
42 | }
43 |
--------------------------------------------------------------------------------
/man/shared_drive_rm.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/shared_drive_rm.R
3 | \name{shared_drive_rm}
4 | \alias{shared_drive_rm}
5 | \title{Delete shared drives}
6 | \usage{
7 | shared_drive_rm(drive = NULL)
8 | }
9 | \arguments{
10 | \item{drive}{Anything that identifies the shared drive(s) of interest. Can
11 | be a character vector of names, a character vector of file ids or URLs
12 | marked with \code{\link[=as_id]{as_id()}}, or a \code{\link{dribble}} consisting only of shared drives.}
13 | }
14 | \value{
15 | Logical vector, indicating whether the delete succeeded.
16 | }
17 | \description{
18 | A shared drive supports files owned by an organization rather than an
19 | individual user. Shared drives follow different sharing and ownership models
20 | from a specific user's "My Drive". Shared drives are the successors to the
21 | earlier concept of Team Drives. Learn more about \link[=shared_drives]{shared drives}.
22 | }
23 | \examples{
24 | \dontrun{
25 | # Create shared drives to remove in various ways
26 | shared_drive_create("testdrive-01")
27 | sd02 <- shared_drive_create("testdrive-02")
28 | shared_drive_create("testdrive-03")
29 | sd04 <- shared_drive_create("testdrive-04")
30 |
31 | # remove by name
32 | shared_drive_rm("testdrive-01")
33 | # remove by id
34 | shared_drive_rm(as_id(sd02))
35 | # remove by URL (or, rather, id found in URL)
36 | shared_drive_rm(as_id("https://drive.google.com/drive/u/0/folders/Q5DqUk9PVA"))
37 | # remove by dribble
38 | shared_drive_rm(sd04)
39 | }
40 | }
41 | \seealso{
42 | Wraps the \code{drives.delete} endpoint:
43 | \itemize{
44 | \item \url{https://developers.google.com/drive/api/v3/reference/drives/delete}
45 | }
46 | }
47 |
--------------------------------------------------------------------------------
/man/shared_drive_update.Rd:
--------------------------------------------------------------------------------
1 | % Generated by roxygen2: do not edit by hand
2 | % Please edit documentation in R/shared_drive_update.R
3 | \name{shared_drive_update}
4 | \alias{shared_drive_update}
5 | \title{Update a shared drive}
6 | \usage{
7 | shared_drive_update(shared_drive, ...)
8 | }
9 | \arguments{
10 | \item{shared_drive}{Anything that identifies one specific shared drive: its
11 | name, its id or URL marked with \code{\link[=as_id]{as_id()}}, or a \code{\link{dribble}}. The value
12 | provided to \code{shared_drive} is pre-processed with \code{\link[=as_shared_drive]{as_shared_drive()}}. Read
13 | more about \link[=shared_drives]{shared drives}.}
14 |
15 | \item{...}{Properties to set in \code{name = value} form. See the "Request
16 | body" section of the Drive API docs for this endpoint.}
17 | }
18 | \value{
19 | An object of class \code{\link{dribble}}, a tibble with one row per shared drive.
20 | }
21 | \description{
22 | Update the metadata of an existing shared drive, e.g. its background image or
23 | theme.
24 |
25 | A shared drive supports files owned by an organization rather than an
26 | individual user. Shared drives follow different sharing and ownership models
27 | from a specific user's "My Drive". Shared drives are the successors to the
28 | earlier concept of Team Drives. Learn more about \link[=shared_drives]{shared drives}.
29 | }
30 | \examples{
31 | \dontrun{
32 | # create a shared drive
33 | sd <- shared_drive_create("I love themes!")
34 |
35 | # see the themes available to you
36 | themes <- drive_about()$driveThemes
37 | purrr::map_chr(themes, "id")
38 |
39 | # cycle through various themes for this shared drive
40 | sd <- shared_drive_update(sd, themeId = "bok_choy")
41 | sd <- shared_drive_update(sd, themeId = "cocktails")
42 |
43 | # Clean up
44 | shared_drive_rm(sd)
45 | }
46 | }
47 | \seealso{
48 | Wraps the \code{drives.update} endpoint:
49 | \itemize{
50 | \item \url{https://developers.google.com/drive/api/v3/reference/drives/update}
51 | }
52 | }
53 |
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-120x120.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/pkgdown/favicon/apple-touch-icon-120x120.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-60x60.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/pkgdown/favicon/apple-touch-icon-60x60.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon-76x76.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/pkgdown/favicon/apple-touch-icon-76x76.png
--------------------------------------------------------------------------------
/pkgdown/favicon/apple-touch-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/pkgdown/favicon/apple-touch-icon.png
--------------------------------------------------------------------------------
/pkgdown/favicon/favicon-16x16.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/pkgdown/favicon/favicon-16x16.png
--------------------------------------------------------------------------------
/pkgdown/favicon/favicon-32x32.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/pkgdown/favicon/favicon-32x32.png
--------------------------------------------------------------------------------
/pkgdown/favicon/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/pkgdown/favicon/favicon.ico
--------------------------------------------------------------------------------
/revdep/.gitignore:
--------------------------------------------------------------------------------
1 | checks
2 | library
3 | checks.noindex
4 | library.noindex
5 | data.sqlite
6 | *.html
7 | cloud.noindex
8 |
--------------------------------------------------------------------------------
/revdep/README.md:
--------------------------------------------------------------------------------
1 | # Revdeps
2 |
3 |
--------------------------------------------------------------------------------
/revdep/cran.md:
--------------------------------------------------------------------------------
1 | ## revdepcheck results
2 |
3 | We checked 17 reverse dependencies, comparing R CMD check results across CRAN and dev versions of this package.
4 |
5 | * We saw 0 new problems
6 | * We failed to check 0 packages
7 |
8 |
--------------------------------------------------------------------------------
/revdep/failures.md:
--------------------------------------------------------------------------------
1 | *Wow, no problems at all. :)*
--------------------------------------------------------------------------------
/revdep/problems.md:
--------------------------------------------------------------------------------
1 | *Wow, no problems at all. :)*
--------------------------------------------------------------------------------
/tests/spelling.R:
--------------------------------------------------------------------------------
1 | if (requireNamespace("spelling", quietly = TRUE)) {
2 | spelling::spell_check_test(
3 | vignettes = TRUE, error = FALSE,
4 | skip_on_cran = TRUE
5 | )
6 | }
7 |
--------------------------------------------------------------------------------
/tests/testthat.R:
--------------------------------------------------------------------------------
1 | library(testthat)
2 | library(googledrive)
3 |
4 | test_check("googledrive")
5 |
--------------------------------------------------------------------------------
/tests/testthat/.gitignore:
--------------------------------------------------------------------------------
1 | .httr-oauth
2 | testing-token.rds
3 | .Rapp.history
4 | all-test-clean.*
5 | all-test-setup.*
6 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/deprecated.md:
--------------------------------------------------------------------------------
1 | # drive_auth_config() is deprecated
2 |
3 | Code
4 | drive_auth_config()
5 | Condition
6 | Error:
7 | ! `drive_auth_config()` was deprecated in googledrive 1.0.0 and is now defunct.
8 | i Use `drive_auth_configure()` to configure your own OAuth client or API key.
9 | i Use `drive_deauth()` to go into a de-authorized state.
10 | i Use `drive_oauth_client()` to retrieve a user-configured client, if it exists.
11 | i Use `drive_api_key()` to retrieve a user-configured API key, if it exists.
12 |
13 | # drive_oauth_app() is deprecated
14 |
15 | Code
16 | absorb <- drive_oauth_app()
17 | Condition
18 | Warning:
19 | `drive_oauth_app()` was deprecated in googledrive 2.1.0.
20 | i Please use `drive_oauth_client()` instead.
21 |
22 | # drive_auth_configure(app =) is deprecated in favor of client
23 |
24 | Code
25 | drive_auth_configure(app = client)
26 | Condition
27 | Warning:
28 | The `app` argument of `drive_auth_configure()` is deprecated as of googledrive 2.1.0.
29 | i Please use the `client` argument instead.
30 |
31 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_auth.md:
--------------------------------------------------------------------------------
1 | # drive_auth_configure works
2 |
3 | Code
4 | drive_auth_configure(client = gargle::gargle_client(), path = "PATH")
5 | Condition
6 | Error in `drive_auth_configure()`:
7 | ! Must supply exactly one of `client` or `path`, not both
8 |
9 | # drive_scopes() reveals Drive scopes
10 |
11 | Code
12 | drive_scopes()
13 | Output
14 | drive
15 | "https://www.googleapis.com/auth/drive"
16 | full
17 | "https://www.googleapis.com/auth/drive"
18 | drive.readonly
19 | "https://www.googleapis.com/auth/drive.readonly"
20 | drive.file
21 | "https://www.googleapis.com/auth/drive.file"
22 | drive.appdata
23 | "https://www.googleapis.com/auth/drive.appdata"
24 | drive.metadata
25 | "https://www.googleapis.com/auth/drive.metadata"
26 | drive.metadata.readonly
27 | "https://www.googleapis.com/auth/drive.metadata.readonly"
28 | drive.photos.readonly
29 | "https://www.googleapis.com/auth/drive.photos.readonly"
30 | drive.scripts
31 | "https://www.googleapis.com/auth/drive.scripts"
32 |
33 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_cp.md:
--------------------------------------------------------------------------------
1 | # drive_cp() can copy file in place
2 |
3 | Code
4 | write_utf8(drive_cp_message)
5 | Output
6 | Original file:
7 | * 'i-am-a-file-TEST-drive_cp'
8 | Copied to file:
9 | * '{cp_name}'
10 |
11 | # drive_cp() can copy a file into a different folder
12 |
13 | Code
14 | write_utf8(drive_cp_message)
15 | Output
16 | Original file:
17 | * 'i-am-a-file-TEST-drive_cp'
18 | Copied to file:
19 | * 'i-am-a-folder-TEST-drive_cp/{cp_name}'
20 |
21 | # drive_cp() doesn't tolerate ambiguity in `path`
22 |
23 | Code
24 | drive_cp(file, nm_("i-am-a-folder"))
25 | Condition
26 | Error in `confirm_clear_path()`:
27 | ! Unclear if `path` specifies parent folder or full path to the new file, including its name.
28 | See `?as_dribble()` for advice on how to make this clear.
29 |
30 | # drive_cp() errors if asked to copy a folder
31 |
32 | Code
33 | drive_cp(nm_("i-am-a-folder"))
34 | Condition
35 | Error in `drive_cp()`:
36 | ! The Drive API does not copy folders or shared drives.
37 |
38 | # drive_cp() takes name, assumes path is folder if both are specified
39 |
40 | Code
41 | write_utf8(drive_cp_message)
42 | Output
43 | Original file:
44 | * 'i-am-a-file-TEST-drive_cp'
45 | Copied to file:
46 | * 'i-am-a-folder-TEST-drive_cp/{cp_name}'
47 |
48 | ---
49 |
50 | Code
51 | file_cp <- drive_cp(nm_("i-am-a-file"), path = nm_("file-name"), name = nm_(
52 | "file-name"))
53 | Condition
54 | Error in `as_parent()`:
55 | ! Parent specified via `path` is invalid:
56 | x Does not exist.
57 |
58 | ---
59 |
60 | Code
61 | file_cp <- drive_cp(nm_("i-am-a-file"), append_slash(nm_("not-unique-folder")))
62 | Condition
63 | Error in `as_parent()`:
64 | ! Parent specified via `path` is invalid:
65 | x Doesn't uniquely identify exactly one folder or shared drive.
66 |
67 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_create.md:
--------------------------------------------------------------------------------
1 | # drive_create() errors for bad input (before hitting Drive API)
2 |
3 | Code
4 | drive_create()
5 | Condition
6 | Error in `drive_create()`:
7 | ! `name` is absent but must be supplied.
8 |
9 | ---
10 |
11 | Code
12 | drive_create(letters)
13 | Condition
14 | Error in `drive_create()`:
15 | ! is_string(name) is not TRUE
16 |
17 | # drive_create() errors if parent path does not exist
18 |
19 | Code
20 | drive_create("a", path = "qweruiop")
21 | Condition
22 | Error in `as_parent()`:
23 | ! Parent specified via `path` is invalid:
24 | x Does not exist.
25 |
26 | # drive_create() errors if parent exists but is not a folder
27 |
28 | Code
29 | drive_create("a", path = x)
30 | Condition
31 | Error in `as_parent()`:
32 | ! Parent specified via `path` is invalid:
33 | x Is neither a folder nor a shared drive.
34 |
35 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_download.md:
--------------------------------------------------------------------------------
1 | # drive_download() won't overwrite existing file
2 |
3 | Code
4 | withr::with_dir(tmpdir, drive_download(dribble(), path = precious_filepath))
5 | Condition
6 | Error in `drive_download()`:
7 | ! Local `path` already exists and overwrite is `FALSE`:
8 | * 'precious-TEST-drive_download.txt'
9 |
10 | # drive_download() downloads a file and adds local_path column
11 |
12 | Code
13 | write_utf8(drive_download_message)
14 | Output
15 | File downloaded:
16 | * '{file_to_download}'
17 | Saved locally as:
18 | * '{download_filepath}'
19 |
20 | # drive_download() errors if file does not exist on Drive
21 |
22 | Code
23 | drive_download(nm_("this-should-not-exist"))
24 | Condition
25 | Error in `confirm_single_file()`:
26 | ! `file` does not identify at least one Drive file.
27 |
28 | # drive_download() converts with explicit `type`
29 |
30 | Code
31 | write_utf8(drive_download_message)
32 | Output
33 | File downloaded:
34 | * '{file_to_download}'
35 | Saved locally as:
36 | * '{download_filename}'
37 |
38 | # drive_download() converts with type implicit in `path`
39 |
40 | Code
41 | write_utf8(drive_download_message)
42 | Output
43 | File downloaded:
44 | * '{file_to_download}'
45 | Saved locally as:
46 | * '{download_filename}'
47 |
48 | # drive_download() converts using default MIME type, if necessary
49 |
50 | Code
51 | write_utf8(drive_download_message)
52 | Output
53 | File downloaded:
54 | * '{file_to_download}'
55 | Saved locally as:
56 | * '{download_filename}'
57 |
58 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_examples.md:
--------------------------------------------------------------------------------
1 | # drive_example_remote() errors when >1 match
2 |
3 | Code
4 | drive_example_remote("chicken")
5 | Condition
6 | Error in `one_file()`:
7 | ! Found multiple matching remote files:
8 | * 'chicken_doc'
9 | * 'chicken_sheet'
10 | * 'chicken.csv'
11 | * 'chicken.jpg'
12 | * 'chicken.pdf'
13 | * 'chicken.txt'
14 | i Make the `matches` regular expression more specific.
15 |
16 | # drive_example_local() errors when >1 match
17 |
18 | Code
19 | drive_example_local("chicken")
20 | Condition
21 | Error in `one_file()`:
22 | ! Found multiple matching local files:
23 | * 'chicken.csv'
24 | * 'chicken.jpg'
25 | * 'chicken.pdf'
26 | * 'chicken.txt'
27 | i Make the `matches` regular expression more specific.
28 |
29 | # drive_examples_local() errors when no match
30 |
31 | Code
32 | drive_examples_local("platypus")
33 | Condition
34 | Error in `many_files()`:
35 | ! Can't find a local example file with a name that matches "platypus".
36 |
37 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_fields.md:
--------------------------------------------------------------------------------
1 | # drive_fields() admits it only knows about Files fields
2 |
3 | Code
4 | out <- drive_fields(x, resource = "foo")
5 | Message
6 | ! Currently only fields for the 'files' resource can be checked for validity.
7 | Nothing done.
8 |
9 | # drive_fields() detects bad fields
10 |
11 | Code
12 | out <- drive_fields(c("name", "parents", "ownedByMe", "pancakes!"))
13 | Condition
14 | Warning:
15 | Omitting fields that are not recognized as part of the Files resource:
16 | * 'pancakes!'
17 |
18 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_find.md:
--------------------------------------------------------------------------------
1 | # drive_find() errors for nonsense in `n_max`
2 |
3 | Code
4 | drive_find(n_max = "a")
5 | Condition
6 | Error in `drive_find()`:
7 | ! is.numeric(n_max) is not TRUE
8 |
9 | ---
10 |
11 | Code
12 | drive_find(n_max = 1:3)
13 | Condition
14 | Error in `drive_find()`:
15 | ! length(n_max) == 1 is not TRUE
16 |
17 | ---
18 |
19 | Code
20 | drive_find(n_max = -2)
21 | Condition
22 | Error in `drive_find()`:
23 | ! n_max >= 0 is not TRUE
24 |
25 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_get.md:
--------------------------------------------------------------------------------
1 | # drive_get() 'no input' edge cases
2 |
3 | Code
4 | drive_get(id = NA_character_)
5 | Condition
6 | Error in `map()`:
7 | i In index: 1.
8 | Caused by error in `.f()`:
9 | ! Can't `drive_get()` a file when `id` is `NA`.
10 |
11 | ---
12 |
13 | Code
14 | drive_get(id = "")
15 | Condition
16 | Error in `validate_drive_id()`:
17 | ! A must match this regular expression: `^[a-zA-Z0-9_-]+$`
18 | Invalid input:
19 | x '""'
20 |
21 | ---
22 |
23 | Code
24 | dat <- drive_get("")
25 | Message
26 | ! Problem with 1 path: path is empty string
27 | ! No path resolved to exactly 1 file.
28 |
29 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_ls.md:
--------------------------------------------------------------------------------
1 | # drive_ls() errors if `path` does not exist
2 |
3 | Code
4 | drive_ls(nm_("this-should-not-exist"))
5 | Condition
6 | Error in `as_parent()`:
7 | ! Parent specified via `path` is invalid:
8 | x Does not exist.
9 |
10 | # drive_ls() list contents of the target of a folder shortcut
11 |
12 | Code
13 | write_utf8(drive_ls_message)
14 | Output
15 | i Parent specified via `path` is a shortcut; resolving to its target folder
16 | i Resolved 1 shortcut found in 1 file:
17 | * '{shortcut_name}' -> '{target_name}'
18 |
19 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_mime_type.md:
--------------------------------------------------------------------------------
1 | # drive_mime_type() errors for invalid input
2 |
3 | Code
4 | drive_mime_type(1)
5 | Condition
6 | Error in `drive_mime_type()`:
7 | ! `type` must be character.
8 |
9 | ---
10 |
11 | Code
12 | drive_mime_type(dribble())
13 | Condition
14 | Error in `drive_mime_type()`:
15 | ! `type` must be character.
16 |
17 | # drive_mime_type() errors for single unrecognized input
18 |
19 | Code
20 | drive_mime_type("nonsense")
21 | Condition
22 | Error in `drive_mime_type()`:
23 | ! Unrecognized `type`:
24 | x 'nonsense'
25 |
26 | # drive_extension() errors for invalid input
27 |
28 | Code
29 | drive_extension(1)
30 | Condition
31 | Error in `drive_extension()`:
32 | ! is.character(type) is not TRUE
33 |
34 | ---
35 |
36 | Code
37 | drive_extension(dribble())
38 | Condition
39 | Error in `drive_extension()`:
40 | ! is.character(type) is not TRUE
41 |
42 | # drive_extension() errors for single unrecognized input
43 |
44 | Code
45 | drive_extension("nonsense")
46 | Condition
47 | Error in `drive_mime_type()`:
48 | ! Unrecognized `type`:
49 | x 'nonsense'
50 |
51 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_mv.md:
--------------------------------------------------------------------------------
1 | # drive_mv() can rename file
2 |
3 | Code
4 | write_utf8(drive_mv_message)
5 | Output
6 | Original file:
7 | * '{name_1}'
8 | Has been renamed:
9 | * '{name_2}'
10 |
11 | # drive_mv() can move a file into a folder given as path
12 |
13 | Code
14 | write_utf8(drive_mv_message)
15 | Output
16 | Original file:
17 | * '{mv_name}'
18 | Has been moved:
19 | * 'move-files-into-me-TEST-drive_mv/{mv_name}'
20 |
21 | # drive_mv() can move a file into a folder given as dribble
22 |
23 | Code
24 | write_utf8(drive_mv_message)
25 | Output
26 | Original file:
27 | * '{mv_name}'
28 | Has been moved:
29 | * 'move-files-into-me-TEST-drive_mv/{mv_name}'
30 |
31 | # drive_mv() can rename and move, using `path` and `name`
32 |
33 | Code
34 | write_utf8(drive_mv_message)
35 | Output
36 | Original file:
37 | * '{name_1}'
38 | Has been renamed and moved:
39 | * 'move-files-into-me-TEST-drive_mv/{name_2}'
40 |
41 | # drive_mv() can rename and move, using `path` only
42 |
43 | Code
44 | write_utf8(drive_mv_message)
45 | Output
46 | Original file:
47 | * '{name_1}'
48 | Has been renamed and moved:
49 | * 'move-files-into-me-TEST-drive_mv/{name_2}'
50 |
51 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_publish.md:
--------------------------------------------------------------------------------
1 | # drive_publish() fails for non-native file type
2 |
3 | Code
4 | drive_publish(drive_pdf)
5 | Condition
6 | Error in `drive_change_publish()`:
7 | ! Only native Google files can be published.
8 | `file` includes a file with non-native MIME type
9 | * 'foo_pdf-TEST-drive_publish': 'application/pdf'
10 | i You can use `drive_share()` to change a file's sharing permissions.
11 |
12 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_put.md:
--------------------------------------------------------------------------------
1 | # drive_put() works
2 |
3 | Code
4 | write_utf8(first_put)
5 | Output
6 | i No pre-existing Drive file at this path. Calling `drive_upload()`.
7 | Local file:
8 | * '{local_file}'
9 | Uploaded into Drive file:
10 | * '{put_file}'
11 | With MIME type:
12 | * 'text/plain'
13 |
14 | ---
15 |
16 | Code
17 | write_utf8(second_put)
18 | Output
19 | i A Drive file already exists at this path. Calling `drive_update()`.
20 | File updated:
21 | * '{put_file}'
22 |
23 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_reveal.md:
--------------------------------------------------------------------------------
1 | # drive_reveal() works
2 |
3 | Code
4 | print(out <- drive_reveal(dat, "starred")[c("name", "starred")])
5 | Output
6 | # A tibble: 3 x 2
7 | name starred
8 |
9 | 1 i-am-a-google-doc-TEST-drive_reveal FALSE
10 | 2 i-have-a-description-TEST-drive_reveal FALSE
11 | 3 i-am-starred-TEST-drive_reveal TRUE
12 |
13 | ---
14 |
15 | Code
16 | print(out <- drive_reveal(dat, "description")[c("name", "description")])
17 | Output
18 | # A tibble: 3 x 2
19 | name description
20 |
21 | 1 i-am-a-google-doc-TEST-drive_reveal
22 | 2 i-have-a-description-TEST-drive_reveal description!
23 | 3 i-am-starred-TEST-drive_reveal
24 |
25 | ---
26 |
27 | Code
28 | print(out <- drive_reveal(dat, "mimeType")[c("name", "mime_type")])
29 | Output
30 | # A tibble: 3 x 2
31 | name mime_type
32 |
33 | 1 i-am-a-google-doc-TEST-drive_reveal application/vnd.google-apps.document
34 | 2 i-have-a-description-TEST-drive_reveal text/plain
35 | 3 i-am-starred-TEST-drive_reveal text/plain
36 |
37 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_share.md:
--------------------------------------------------------------------------------
1 | # drive_share() errors for invalid `role` or `type`
2 |
3 | Code
4 | drive_share(dribble(), role = "chef")
5 | Condition
6 | Error in `match.arg()`:
7 | ! 'arg' should be one of "reader", "commenter", "writer", "fileOrganizer", "owner", "organizer"
8 |
9 | ---
10 |
11 | Code
12 | drive_share(dribble(), type = "pet")
13 | Condition
14 | Error in `match.arg()`:
15 | ! 'arg' should be one of "user", "group", "domain", "anyone"
16 |
17 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_update.md:
--------------------------------------------------------------------------------
1 | # drive_update() errors if local media does not exist
2 |
3 | Code
4 | drive_update(dribble(), "nope123")
5 | Condition
6 | Error in `drive_update()`:
7 | ! No file exists at the local `media` path:
8 | x 'nope123'
9 |
10 | # drive_update() informatively errors if the path does not exist
11 |
12 | Code
13 | drive_update(nm_("does-not-exist"), system.file("DESCRIPTION"))
14 | Condition
15 | Error in `confirm_single_file()`:
16 | ! `file` does not identify at least one Drive file.
17 |
18 | # drive_update() informatively errors if the path is not unique
19 |
20 | Code
21 | drive_update(nm_("not-unique"), system.file("DESCRIPTION"))
22 | Condition
23 | Error in `confirm_single_file()`:
24 | ! `file` identifies more than one Drive file.
25 |
26 | # no op if no media, no metadata
27 |
28 | Code
29 | out <- drive_update(nm_("update-fodder"))
30 | Message
31 | ! No updates specified.
32 |
33 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/drive_upload.md:
--------------------------------------------------------------------------------
1 | # drive_upload() detects non-existent file
2 |
3 | Code
4 | drive_upload("no-such-file", "File does not exist")
5 | Condition
6 | Error in `drive_upload()`:
7 | ! No file exists at the local `media` path:
8 | x 'no-such-file'
9 |
10 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/request_generate.md:
--------------------------------------------------------------------------------
1 | # request_generate() errors for unrecognized parameters
2 |
3 | Code
4 | (expect_error(request_generate(endpoint = "drive.files.list", params = params,
5 | token = NULL), class = "gargle_error_bad_params"))
6 | Output
7 |
8 | Error in `gargle::request_develop()`:
9 | ! These parameters are unknown:
10 | x 'chicken'
11 | x 'bunny'
12 | i API endpoint: 'drive.files.list'
13 |
14 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/shared_drives.md:
--------------------------------------------------------------------------------
1 | # new_corpus() checks type and length, if not-NULL
2 |
3 | Code
4 | new_corpus(driveId = c("1", "2"))
5 | Condition
6 | Error in `new_corpus()`:
7 | ! length(driveId) == 1 is not TRUE
8 |
9 | ---
10 |
11 | Code
12 | new_corpus(corpora = c("a", "b"))
13 | Condition
14 | Error in `new_corpus()`:
15 | ! is_string(corpora) is not TRUE
16 |
17 | ---
18 |
19 | Code
20 | new_corpus(includeItemsFromAllDrives = c(TRUE, FALSE))
21 | Condition
22 | Error in `new_corpus()`:
23 | ! length(includeItemsFromAllDrives) == 1 is not TRUE
24 |
25 | # `corpora` is checked for validity
26 |
27 | Code
28 | shared_drive_params(corpora = "foo")
29 | Condition
30 | Error in `validate_corpora()`:
31 | ! Invalid value for `corpus`:
32 | x 'foo'
33 | These are the only acceptable values:
34 | * 'user'
35 | * 'drive'
36 | * 'allDrives'
37 | * 'domain'
38 |
39 | # `corpora = "drive"` requires shared drive specification
40 |
41 | Code
42 | shared_drive_params(corpora = "drive")
43 | Condition
44 | Error in `rationalize_corpus()`:
45 | ! When `corpus = "drive"`, you must also specify the `shared_drive`.
46 |
47 | # `corpora != "drive"` rejects shared drive specification
48 |
49 | Code
50 | shared_drive_params(corpora = "user", driveId = "123")
51 | Condition
52 | Error in `rationalize_corpus()`:
53 | ! When `corpus != "drive"`, you must not specify a `shared_drive`.
54 |
55 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/shortcut.md:
--------------------------------------------------------------------------------
1 | # shortcut_create() works
2 |
3 | Code
4 | write_utf8(shortcut_create_message)
5 | Output
6 | Created Drive file:
7 | * '{sc_name}'
8 | With MIME type:
9 | * 'application/vnd.google-apps.shortcut'
10 |
11 | # shortcut_create() requires `name` to control `overwrite`
12 |
13 | Code
14 | shortcut_create(nm_("top-level-file"), overwrite = FALSE)
15 | Condition
16 | Error in `shortcut_create()`:
17 | ! You must specify the shortcut's `name` in order to specify `overwrite` behaviour.
18 |
19 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/utils-paths.md:
--------------------------------------------------------------------------------
1 | # root_folder() and root_id() work
2 |
3 | Code
4 | root_folder()
5 | Output
6 | # A dribble: 1 x 3
7 | name id drive_resource
8 |
9 | 1 My Drive 0AK935f1rlmIZUk9PVA
10 |
11 | ---
12 |
13 | Code
14 | root_id()
15 | Output
16 |
17 | [1] 0AK935f1rlmIZUk9PVA
18 |
19 | # rootize_path() errors for leading slash
20 |
21 | Code
22 | rootize_path("/")
23 | Condition
24 | Error in `rootize_path()`:
25 | ! googledrive does not allow paths to start with `/`
26 |
27 | # partition_path() fails for bad input
28 |
29 | Code
30 | partition_path(letters)
31 | Condition
32 | Error in `partition_path()`:
33 | ! is_string(path) is not TRUE
34 |
35 | ---
36 |
37 | Code
38 | partition_path(dribble())
39 | Condition
40 | Error in `partition_path()`:
41 | ! is_string(path) is not TRUE
42 |
43 | ---
44 |
45 | Code
46 | partition_path(as_id("123"))
47 | Condition
48 | Error in `partition_path()`:
49 | ! is_string(path) is not TRUE
50 |
51 | # rationalize_path_name() errors for bad `name`, before hitting API
52 |
53 | Code
54 | rationalize_path_name(name = letters)
55 | Condition
56 | Error in `rationalize_path_name()`:
57 | ! is_string(name) is not TRUE
58 |
59 |
--------------------------------------------------------------------------------
/tests/testthat/_snaps/utils-ui.md:
--------------------------------------------------------------------------------
1 | # warn_for_verbose() warns for `verbose = FALSE` w/ good message
2 |
3 | Code
4 | drive_something()
5 | Condition
6 | Warning:
7 | The `verbose` argument of `drive_something()` is deprecated as of googledrive 2.0.0.
8 | i Set `options(googledrive_quiet = TRUE)` to suppress all googledrive messages.
9 | i For finer control, use `local_drive_quiet()` or `with_drive_quiet()`.
10 | i googledrive's `verbose` argument will be removed in the future.
11 |
12 | # warn_for_verbose(FALSE) makes googledrive quiet, in scope
13 |
14 | Code
15 | drive_bullets("chatty before")
16 | Message
17 | chatty before
18 | Code
19 | drive_something()
20 | drive_bullets("chatty after")
21 | Message
22 | chatty after
23 |
24 |
--------------------------------------------------------------------------------
/tests/testthat/driver.R:
--------------------------------------------------------------------------------
1 | # this script extracts code from all individual test files to do:
2 | # * test setup = create the files/folders our tests expect to find on Drive
3 | # * test cleanup = delete the above files/folder from Drive
4 | # execute this to get two R scripts:
5 | # * all-test-setup.R
6 | # * all-test-clean.R
7 |
8 | library(purrr)
9 | library(glue)
10 | library(testthat)
11 |
12 | ## grabs code from two chunks: 'nm_fun' and chunk ('clean' or 'setup')
13 | do_one <- function(r_file, chunk) {
14 | knitr::read_chunk(r_file)
15 | out <- c(
16 | knitr:::knit_code$get("nm_fun"),
17 | knitr:::knit_code$get(chunk)
18 | )
19 | knitr:::knit_code$restore()
20 | if (length(out) == 0) {
21 | return(NULL)
22 | }
23 | c(paste("#' ##", basename(r_file)), out)
24 | }
25 |
26 | test_files <- list.files(
27 | path = test_path(),
28 | pattern = "test-.+\\.R",
29 | full.names = TRUE
30 | )
31 |
32 | clean_code <- test_files %>%
33 | map(do_one, chunk = "clean") %>%
34 | compact()
35 | setup_code <- test_files %>%
36 | map(do_one, chunk = "setup") %>%
37 | compact()
38 |
39 | header <- "
40 | #' ---
41 | #' title: googledrive test {action}
42 | #' date: '`r format(Sys.time())`'
43 | #' output: html_document
44 | #' ---
45 |
46 | #' This script aggregates the test-related {action} code from all test files.
47 |
48 | #+ setup, include = FALSE, cache = FALSE
49 | knitr::opts_chunk$set(collapse = TRUE, comment = '#>', error = TRUE)
50 |
51 | #+ body
52 | pkgload::load_all(here::here())
53 | source(here::here('tests', 'testthat', 'helper.R'))
54 | drive_user()
55 |
56 | ## change this to TRUE when you are really ready to do this!
57 | {ACTION} <- FALSE
58 |
59 | "
60 |
61 | writeLines(
62 | c(
63 | glue_data(list(action = "clean", ACTION = "CLEAN"), header),
64 | unlist(clean_code)
65 | ),
66 | test_path("all-test-clean.R")
67 | )
68 | writeLines(
69 | c(
70 | glue_data(list(action = "setup", ACTION = "SETUP"), header),
71 | unlist(setup_code)
72 | ),
73 | test_path("all-test-setup.R")
74 | )
75 |
--------------------------------------------------------------------------------
/tests/testthat/helper.R:
--------------------------------------------------------------------------------
1 | auth_success <- tryCatch(
2 | drive_auth_testing(),
3 | googledrive_auth_internal_error = function(e) NULL
4 | )
5 | if (!isTRUE(auth_success)) {
6 | drive_bullets(c(
7 | "!" = "Internal auth failed; calling {.fun drive_deauth}."
8 | ))
9 | drive_deauth()
10 | }
11 |
12 | skip_if_no_token <- function() {
13 | testthat::skip_if_not(drive_has_token(), "No Drive token")
14 | }
15 |
16 | with_mock <- function(..., .parent = parent.frame()) {
17 | mockr::with_mock(..., .parent = .parent, .env = "googledrive")
18 | }
19 |
20 | # usage:
21 | # test_fixture("something.rds")
22 | test_fixture <- function(name) testthat::test_path("test-fixtures", name)
23 |
24 | defer_drive_rm <- function(..., env = parent.frame()) {
25 | withr::defer(
26 | with_drive_quiet(drive_rm(...)),
27 | envir = env
28 | )
29 | }
30 |
31 | # used to replace volatile filepaths and file ids in snapshot tests
32 | # may eventually be unnecessary, depending on how this works out:
33 | # https://github.com/r-lib/testthat/issues/1345
34 | # @param replace_me Should be a bare symbol that holds a fixed string
35 | scrub_filepath <- function(message, replace_me) {
36 | x <- ensym(replace_me)
37 | gsub(replace_me, paste0("{", as_string(x), "}"), message, fixed = TRUE)
38 | }
39 |
40 | scrub_file_id <- function(message) {
41 | gsub("", "", message, perl = TRUE)
42 | }
43 |
44 | expect_dribble <- function(x) {
45 | expect_s3_class(x, "dribble")
46 | }
47 |
48 | expect_bare_tibble <- function(x) {
49 | expect_s3_class(x, c("tbl_df", "tbl", "data.frame"), exact = TRUE)
50 | }
51 |
--------------------------------------------------------------------------------
/tests/testthat/setup-testing.R:
--------------------------------------------------------------------------------
1 | CLEAN <- SETUP <- FALSE
2 | isFALSE <- function(x) identical(x, FALSE)
3 |
4 | with_drive_loud({
5 | nm_ <- nm_fun("TEST-drive_something", user_run = FALSE)
6 | me_ <- nm_fun("TEST-drive_something")
7 |
8 | drive_bullets(c(
9 | "Test file naming scheme:",
10 | "*" = nm_("foo"),
11 | "*" = me_("foo")
12 | ))
13 | flush.console()
14 | Sys.sleep(1) # without this, the message still gets mixed in w/ test results
15 | })
16 |
--------------------------------------------------------------------------------
/tests/testthat/test-camelCase.R:
--------------------------------------------------------------------------------
1 | test_that("snake_case() works", {
2 | expect_equal(snake_case("name"), "name")
3 | expect_equal(snake_case("drive_resource"), "drive_resource")
4 |
5 | expect_equal(snake_case("mimeType"), "mime_type")
6 | expect_equal(snake_case("viewedByMeTime"), "viewed_by_me_time")
7 | expect_equal(snake_case("md5Checksum"), "md5_checksum")
8 | })
9 |
--------------------------------------------------------------------------------
/tests/testthat/test-deprecated.R:
--------------------------------------------------------------------------------
1 | test_that("drive_auth_config() is deprecated", {
2 | withr::local_options(lifecycle_verbosity = "warning")
3 | expect_snapshot(
4 | error = TRUE,
5 | drive_auth_config()
6 | )
7 | })
8 |
9 | test_that("drive_oauth_app() is deprecated", {
10 | withr::local_options(lifecycle_verbosity = "warning")
11 | expect_snapshot(absorb <- drive_oauth_app())
12 | })
13 |
14 | test_that("drive_auth_configure(app =) is deprecated in favor of client", {
15 | withr::local_options(lifecycle_verbosity = "warning")
16 | (original_client <- drive_oauth_client())
17 | withr::defer(drive_auth_configure(client = original_client))
18 |
19 | client <- gargle::gargle_oauth_client_from_json(
20 | system.file(
21 | "extdata", "client_secret_installed.googleusercontent.com.json",
22 | package = "gargle"
23 | ),
24 | name = "test-client"
25 | )
26 | expect_snapshot(
27 | drive_auth_configure(app = client)
28 | )
29 | expect_equal(drive_oauth_client()$name, "test-client")
30 | expect_equal(drive_oauth_client()$id, "abc.apps.googleusercontent.com")
31 | })
32 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_auth.R:
--------------------------------------------------------------------------------
1 | test_that("drive_auth_configure works", {
2 | old_client <- drive_oauth_client()
3 | old_api_key <- drive_api_key()
4 | withr::defer(
5 | drive_auth_configure(client = old_client, api_key = old_api_key)
6 | )
7 |
8 | expect_no_error(drive_oauth_client())
9 | expect_no_error(drive_api_key())
10 |
11 | expect_snapshot(
12 | drive_auth_configure(client = gargle::gargle_client(), path = "PATH"),
13 | error = TRUE
14 | )
15 |
16 | drive_auth_configure(client = gargle::gargle_client())
17 | expect_s3_class(drive_oauth_client(), "gargle_oauth_client")
18 |
19 | drive_auth_configure(path = system.file(
20 | "extdata", "client_secret_installed.googleusercontent.com.json",
21 | package = "gargle"
22 | ))
23 | expect_s3_class(drive_oauth_client(), "gargle_oauth_client")
24 |
25 | drive_auth_configure(client = NULL)
26 | expect_null(drive_oauth_client())
27 |
28 | drive_auth_configure(api_key = "API_KEY")
29 | expect_identical(drive_api_key(), "API_KEY")
30 |
31 | drive_auth_configure(api_key = NULL)
32 | expect_null(drive_api_key())
33 | })
34 |
35 | # drive_scopes() ----
36 | test_that("drive_scopes() reveals Drive scopes", {
37 | expect_snapshot(drive_scopes())
38 | })
39 |
40 | test_that("drive_scopes() substitutes actual scope for short form", {
41 | expect_equal(
42 | drive_scopes(c(
43 | "full",
44 | "drive",
45 | "drive.readonly"
46 | )),
47 | c(
48 | "https://www.googleapis.com/auth/drive",
49 | "https://www.googleapis.com/auth/drive",
50 | "https://www.googleapis.com/auth/drive.readonly"
51 | )
52 | )
53 | })
54 |
55 | test_that("drive_scopes() passes unrecognized scopes through", {
56 | expect_equal(
57 | drive_scopes(c(
58 | "email",
59 | "drive.metadata.readonly",
60 | "https://www.googleapis.com/auth/cloud-platform"
61 | )),
62 | c(
63 | "email",
64 | "https://www.googleapis.com/auth/drive.metadata.readonly",
65 | "https://www.googleapis.com/auth/cloud-platform"
66 | )
67 | )
68 | })
69 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_browse.R:
--------------------------------------------------------------------------------
1 | # ---- other ----
2 | if (FALSE) {
3 | # how the test file was created
4 | # using shared-drive-capable token ...
5 | files <- drive_find(corpus = "allDrives", n_max = 10)
6 | sds <- shared_drive_find()
7 | x <- vec_rbind(files, sds)
8 | saveRDS(x, test_fixture("mix_of_files_and_teamdrives.rds"), version = 2)
9 | }
10 |
11 | # ---- tests ----
12 | test_that("drive_link() extracts links for files and Team Drives, alike", {
13 | x <- readRDS(test_fixture("mix_of_files_and_teamdrives.rds"))
14 | links <- drive_link(x)
15 | expect_true(all(grepl("^https://.*\\.google\\.com/", links)))
16 | expect_identical(as_id(links), as_id(x))
17 | })
18 |
19 | test_that("drive_browse() passes links through", {
20 | if (interactive()) skip("interactive() is TRUE")
21 | x <- readRDS(test_fixture("mix_of_files_and_teamdrives.rds"))
22 | expect_identical(drive_browse(x), drive_link(x))
23 | })
24 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_endpoints.R:
--------------------------------------------------------------------------------
1 | test_that("drive_endpoint(s)() work(s)", {
2 | expect_length(drive_endpoints(), length(.endpoints))
3 | expect_length(drive_endpoints(c(1, 3, 5)), 3)
4 | nms <- names(drive_endpoints())
5 | expect_identical(drive_endpoints(c(1, 3, 5)), drive_endpoints(nms[c(1, 3, 5)]))
6 | expect_identical(drive_endpoints(2)[[1]], drive_endpoint(2))
7 | expect_identical(drive_endpoints(nms[2])[[1]], drive_endpoint(nms[2]))
8 | })
9 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_examples.R:
--------------------------------------------------------------------------------
1 | test_that("drive_examples_remote() lists the remote example files", {
2 | skip_if_offline()
3 | skip_on_cran()
4 |
5 | dat <- drive_examples_remote()
6 | expect_s3_class(dat, "dribble")
7 | expect_true(nrow(dat) > 0)
8 |
9 | dat <- drive_examples_remote("chicken")
10 | expect_s3_class(dat, "dribble")
11 | expect_true(nrow(dat) > 0)
12 | })
13 |
14 | test_that("drive_example_remote() errors when >1 match", {
15 | skip_if_offline()
16 | skip_on_cran()
17 |
18 | expect_snapshot(
19 | drive_example_remote("chicken"),
20 | error = TRUE
21 | )
22 | })
23 |
24 | test_that("drive_examples_local() lists the local example files", {
25 | all_files <- drive_examples_local()
26 | expect_true(all(file.exists(all_files)))
27 |
28 | chicken_files <- drive_examples_local("chicken")
29 | expect_match(chicken_files, "chicken")
30 | })
31 |
32 | test_that("drive_example_local() errors when >1 match", {
33 | expect_snapshot(
34 | drive_example_local("chicken"),
35 | error = TRUE
36 | )
37 | })
38 |
39 | test_that("drive_examples_local() errors when no match", {
40 | expect_snapshot(
41 | drive_examples_local("platypus"),
42 | error = TRUE
43 | )
44 | })
45 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_fields.R:
--------------------------------------------------------------------------------
1 | # ---- tests ----
2 | test_that("drive_fields() returns nothing, if no input", {
3 | expect_identical(drive_fields(), character())
4 | })
5 |
6 | test_that("drive_fields(expose()) returns full tibble of Files fields", {
7 | expect_identical(
8 | drive_fields(expose()),
9 | .drive$files_fields
10 | )
11 | out <- drive_fields(expose(), resource = "foo")
12 | expect_identical(out, drive_fields(expose()))
13 | })
14 |
15 | test_that("drive_fields() admits it only knows about Files fields", {
16 | local_drive_loud_and_wide()
17 |
18 | x <- letters[1:6]
19 | expect_snapshot(
20 | out <- drive_fields(x, resource = "foo")
21 | )
22 | expect_identical(out, x)
23 | })
24 |
25 | test_that("drive_fields() detects bad fields", {
26 | local_drive_loud_and_wide()
27 | expect_snapshot(
28 | out <- drive_fields(c("name", "parents", "ownedByMe", "pancakes!"))
29 | )
30 | expect_identical(out, c("name", "parents", "ownedByMe"))
31 | })
32 |
33 | test_that("prep_fields() concatenates input", {
34 | expect_identical(
35 | prep_fields(letters[1:2]),
36 | "files/a,files/b"
37 | )
38 | expect_identical(
39 | prep_fields(letters[1:2], resource = NULL),
40 | "a,b"
41 | )
42 | expect_identical(
43 | prep_fields(letters[1:2], resource = "blah"),
44 | "blah/a,blah/b"
45 | )
46 | })
47 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_put.R:
--------------------------------------------------------------------------------
1 | # ---- nm_fun ----
2 | me_ <- nm_fun("TEST-drive_put")
3 | nm_ <- nm_fun("TEST-drive_put", user_run = FALSE)
4 |
5 | # ---- clean ----
6 | if (CLEAN) {
7 | drive_trash(c(
8 | # no current need
9 | ))
10 | }
11 |
12 | # ---- setup ----
13 | if (SETUP) {
14 | # no current need
15 | }
16 |
17 | # ---- tests ----
18 |
19 | test_that("drive_put() works", {
20 | skip_if_no_token()
21 | skip_if_offline()
22 |
23 | local_file <- tempfile(me_("foo"), fileext = ".txt")
24 | put_file <- basename(local_file)
25 | download_target <- tempfile(me_("download"), fileext = ".txt")
26 | withr::defer({
27 | unlink(local_file)
28 | unlink(download_target)
29 | })
30 | defer_drive_rm(drive_find(me_("foo")))
31 |
32 | write_utf8(c("beginning", "middle"), local_file)
33 |
34 | local_drive_loud_and_wide()
35 | first_put <- capture.output(
36 | original <- drive_put(local_file),
37 | type = "message"
38 | )
39 | first_put <- first_put %>%
40 | scrub_filepath(local_file) %>%
41 | scrub_filepath(put_file) %>%
42 | scrub_file_id()
43 | expect_snapshot(
44 | write_utf8(first_put)
45 | )
46 | expect_dribble(original)
47 |
48 | with_drive_quiet(
49 | drive_download(original, path = download_target)
50 | )
51 | expect_identical(
52 | read_utf8(local_file),
53 | read_utf8(download_target)
54 | )
55 |
56 | cat("end", file = local_file, sep = "\n", append = TRUE)
57 |
58 | second_put <- capture.output(
59 | second <- drive_put(local_file),
60 | type = "message"
61 | )
62 | second_put <- second_put %>%
63 | scrub_filepath(put_file) %>%
64 | scrub_file_id()
65 | expect_snapshot(
66 | write_utf8(second_put)
67 | )
68 | expect_identical(original$id, second$id)
69 |
70 | with_drive_quiet(
71 | drive_download(original, path = download_target, overwrite = TRUE)
72 | )
73 | expect_identical(
74 | read_utf8(local_file),
75 | read_utf8(download_target)
76 | )
77 |
78 | with_drive_quiet(
79 | name_collider <- drive_create(basename(local_file))
80 | )
81 |
82 | # not easy to convert to snapshot, due to volatile file ids
83 | expect_error(
84 | drive_put(local_file),
85 | "Multiple items"
86 | )
87 | })
88 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_read.R:
--------------------------------------------------------------------------------
1 | # ---- nm_fun ----
2 | nm_ <- nm_fun("TEST-drive_read", user_run = FALSE)
3 |
4 | # ---- clean ----
5 | if (CLEAN) {
6 | drive_trash(c(
7 | nm_("DESC"),
8 | nm_("chicken_doc"),
9 | nm_("imdb_latin1_csv")
10 | ))
11 | }
12 |
13 | # ---- setup ----
14 | if (SETUP) {
15 | drive_upload(system.file("DESCRIPTION"), name = nm_("DESC"))
16 |
17 | drive_upload(
18 | drive_example_local("chicken.txt"),
19 | name = nm_("chicken_doc"),
20 | type = "document"
21 | )
22 |
23 | tfile <- tempfile(fileext = ".csv")
24 | curl::curl_download(
25 | "https://matthew-brett.github.io/cfd2019/data/imdblet_latin.csv",
26 | destfile = tfile
27 | )
28 | drive_upload(tfile, name = nm_("imdb_latin1_csv"))
29 | }
30 |
31 | # ---- tests ----
32 | test_that("drive_read_string() extracts text", {
33 | skip_if_no_token()
34 | skip_if_offline()
35 |
36 | suppressMessages(
37 | r_desc <- drive_read_string(nm_("DESC"))
38 | )
39 | r_desc <- as.list(read.dcf(textConnection(r_desc))[1, ])
40 | expect_equal(r_desc$Package, "base")
41 | expect_equal(r_desc$Title, "The R Base Package")
42 | })
43 |
44 | test_that("drive_read_raw() returns bytes", {
45 | skip_if_no_token()
46 | skip_if_offline()
47 |
48 | suppressMessages(
49 | r_desc_raw <- drive_read_raw(nm_("DESC"))
50 | )
51 | suppressMessages(
52 | r_desc_string <- drive_read_string(nm_("DESC"))
53 | )
54 | expect_equal(rawToChar(r_desc_raw), r_desc_string)
55 | })
56 |
57 | test_that("drive_read() works on a native Google file", {
58 | skip_if_no_token()
59 | skip_if_offline()
60 |
61 | suppressMessages(
62 | chicken_poem <- drive_read_string(nm_("chicken_doc"), type = "text/plain")
63 | )
64 | chicken_poem <- strsplit(chicken_poem, split = "(\r\n|\r|\n)")[[1]]
65 | expect_setequal(
66 | chicken_poem,
67 | read_utf8(drive_example_local("chicken.txt"))
68 | )
69 | })
70 |
71 | test_that("drive_read() can handle non UTF-8 input, if informed", {
72 | skip_if_no_token()
73 | skip_if_offline()
74 |
75 | suppressMessages(
76 | imdb <- drive_read_string(nm_("imdb_latin1_csv"), encoding = "latin1")
77 | )
78 | imdb <- utils::read.csv(text = imdb, stringsAsFactors = FALSE, encoding = "UTF-8")
79 | expect_equal(
80 | names(imdb),
81 | c("Votes", "Rating", "Title", "Year", "Decade")
82 | )
83 | leon <- "\u004C\u00E9\u006F\u006E"
84 | expect_equal(imdb$Title[[1]], leon)
85 | eight_and_a_half <- "\u0038\u00BD"
86 | expect_equal(imdb$Title[[31]], eight_and_a_half)
87 | })
88 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_reveal.R:
--------------------------------------------------------------------------------
1 | # ---- nm_fun ----
2 | nm_ <- nm_fun("TEST-drive_reveal", user_run = FALSE)
3 |
4 | # ---- clean ----
5 | if (CLEAN) {
6 | drive_trash(c(
7 | nm_("i-am-starred"),
8 | nm_("i-have-a-description"),
9 | nm_("i-am-a-google-doc")
10 | ))
11 | }
12 |
13 | # ---- setup ----
14 | if (SETUP) {
15 | # some "simple" cases of digging info out of `drive_resource`
16 | f <- drive_example_local("chicken.txt")
17 | drive_upload(f, nm_("i-am-starred"), starred = TRUE)
18 | drive_upload(f, nm_("i-have-a-description"), description = "description!")
19 | drive_upload(f, nm_("i-am-a-google-doc"), type = "document")
20 | }
21 |
22 | # ---- tests ----
23 | test_that("drive_reveal() works", {
24 | skip_if_no_token()
25 | skip_if_offline()
26 |
27 | dat <- drive_find(nm_(""))
28 |
29 | expect_snapshot(
30 | print(out <- drive_reveal(dat, "starred")[c("name", "starred")])
31 | )
32 | expect_true(out$starred[grepl("starred", out$name)])
33 |
34 | expect_snapshot(
35 | print(out <- drive_reveal(dat, "description")[c("name", "description")])
36 | )
37 | expect_equal(out$description[grepl("description", out$name)], "description!")
38 |
39 | expect_snapshot(
40 | print(out <- drive_reveal(dat, "mimeType")[c("name", "mime_type")])
41 | )
42 | expect_equal(
43 | out$mime_type[grepl("google-doc", out$name)],
44 | drive_mime_type("document")
45 | )
46 | })
47 |
48 | test_that("drive_reveal() can return date-times", {
49 | skip_if_no_token()
50 | skip_if_offline()
51 |
52 | dat <- drive_find(nm_(""))
53 |
54 | out <- drive_reveal(dat, "created_time")
55 | expect_s3_class(out$created_time, "POSIXct")
56 | })
57 |
58 | test_that("drive_reveal() returns list-column for non-existent `what`", {
59 | skip_if_no_token()
60 | skip_if_offline()
61 |
62 | dat <- drive_find(nm_(""))
63 |
64 | out <- drive_reveal(dat, "i_do_not_exist")
65 | expect_true(all(map_lgl(out$i_do_not_exist, is_null)))
66 |
67 | out <- drive_reveal(dat, "non_existent_time")
68 | expect_true(all(map_lgl(out$non_existent_time, is_null)))
69 | })
70 |
71 | test_that("drive_reveal() inserts columns, even with 0 rows", {
72 | x <- dribble()
73 | x <- drive_reveal(x, "mime_type")
74 | x <- drive_reveal(x, "starred")
75 | expect_equal(
76 | names(x),
77 | c("name", "starred", "mime_type", "id", "drive_resource")
78 | )
79 | })
80 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_rm.R:
--------------------------------------------------------------------------------
1 | # ---- tests ----
2 | test_that("drive_rm() copes with no input", {
3 | expect_identical(drive_rm(), dribble())
4 | })
5 |
6 | test_that("drive_rm() copes when there are no matching files", {
7 | skip_if_no_token()
8 | skip_if_offline()
9 |
10 | expect_identical(drive_rm("non-existent-file-name"), dribble())
11 | })
12 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_share.R:
--------------------------------------------------------------------------------
1 | # ---- nm_fun ----
2 | me_ <- nm_fun("TEST-drive_share")
3 | nm_ <- nm_fun("TEST-drive_share", user_run = FALSE)
4 |
5 | # ---- clean ----
6 | if (CLEAN) {
7 | drive_trash(c(
8 | nm_("mirrors-to-share"),
9 | nm_("DESC")
10 | ))
11 | }
12 |
13 | # ---- setup ----
14 | if (SETUP) {
15 | drive_upload(system.file("DESCRIPTION"), nm_("DESC"))
16 | }
17 |
18 | # ---- tests ----
19 |
20 | test_that("drive_share() errors for invalid `role` or `type`", {
21 | expect_snapshot(drive_share(dribble(), role = "chef"), error = TRUE)
22 | expect_snapshot(drive_share(dribble(), type = "pet"), error = TRUE)
23 | })
24 |
25 | test_that("drive_share() adds permissions", {
26 | skip_if_no_token()
27 | skip_if_offline()
28 | defer_drive_rm(me_("mirrors-to-share"))
29 |
30 | file <- drive_upload(
31 | file.path(R.home("doc"), "BioC_mirrors.csv"),
32 | name = me_("mirrors-to-share")
33 | )
34 | expect_false(file$drive_resource[[1]]$shared)
35 |
36 | file <- drive_share(file, role = "commenter", type = "anyone")
37 | expect_true(file$shared)
38 | perms <- file[["permissions_resource"]][[1]][["permissions"]]
39 | expect_setequal(map_chr(perms, "role"), c("owner", "commenter"))
40 | expect_setequal(map_chr(perms, "type"), c("user", "anyone"))
41 | })
42 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_trash.R:
--------------------------------------------------------------------------------
1 | # ---- nm_fun ----
2 | me_ <- nm_fun("TEST-drive_trash")
3 | nm_ <- nm_fun("TEST-drive_trash", user_run = FALSE)
4 |
5 | # ---- setup ----
6 | if (SETUP) {
7 | drive_upload(
8 | system.file("DESCRIPTION"),
9 | nm_("trash-fodder")
10 | )
11 | }
12 |
13 | # ---- clean ----
14 | if (CLEAN) {
15 | drive_trash(c(
16 | nm_("trash-fodder"),
17 | me_("trashee-1"),
18 | me_("trashee-2")
19 | ))
20 | }
21 |
22 | # ---- tests ----
23 | test_that("drive_trash() moves files to trash and drive_untrash() undoes", {
24 | skip_if_no_token()
25 | skip_if_offline()
26 | defer_drive_rm(drive_find(me_("trashee-[12]")))
27 |
28 | trashee1 <- drive_cp(nm_("trash-fodder"), name = me_("trashee-1"))
29 | trashee2 <- drive_cp(nm_("trash-fodder"), name = me_("trashee-2"))
30 |
31 | out <- drive_trash(c(me_("trashee-1"), me_("trashee-2")))
32 | expect_dribble(out)
33 | expect_setequal(out$name, c(me_("trashee-1"), me_("trashee-2")))
34 | expect_true(all(drive_reveal(out, "trashed")[["trashed"]]))
35 |
36 | out <- drive_untrash(c(me_("trashee-1"), me_("trashee-2")))
37 | expect_dribble(out)
38 | expect_setequal(out$name, c(me_("trashee-1"), me_("trashee-2")))
39 | expect_false(any(drive_reveal(out, "trashed")[["trashed"]]))
40 | })
41 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_update.R:
--------------------------------------------------------------------------------
1 | # ---- nm_fun ----
2 | me_ <- nm_fun("TEST-drive_update")
3 | nm_ <- nm_fun("TEST-drive_update", user_run = FALSE)
4 |
5 | # ---- clean ----
6 | if (CLEAN) {
7 | drive_trash(c(
8 | nm_("update-fodder"),
9 | nm_("not-unique"),
10 | nm_("does-not-exist")
11 | ))
12 | }
13 |
14 | # ---- setup ----
15 | if (SETUP) {
16 | drive_upload(system.file("DESCRIPTION"), nm_("update-fodder"))
17 | drive_upload(system.file("DESCRIPTION"), nm_("not-unique"))
18 | drive_upload(system.file("DESCRIPTION"), nm_("not-unique"))
19 | }
20 |
21 | # ---- tests ----
22 | test_that("drive_update() errors if local media does not exist", {
23 | expect_snapshot(drive_update(dribble(), "nope123"), error = TRUE)
24 | })
25 |
26 | test_that("drive_update() informatively errors if the path does not exist", {
27 | skip_if_no_token()
28 | skip_if_offline()
29 | expect_snapshot(
30 | drive_update(nm_("does-not-exist"), system.file("DESCRIPTION")),
31 | error = TRUE
32 | )
33 | })
34 |
35 | test_that("drive_update() informatively errors if the path is not unique", {
36 | skip_if_no_token()
37 | skip_if_offline()
38 | expect_snapshot(
39 | drive_update(nm_("not-unique"), system.file("DESCRIPTION")),
40 | error = TRUE
41 | )
42 | })
43 |
44 | test_that("no op if no media, no metadata", {
45 | skip_if_no_token()
46 | skip_if_offline()
47 |
48 | local_drive_loud_and_wide()
49 | expect_snapshot(
50 | out <- drive_update(nm_("update-fodder")),
51 | )
52 | expect_dribble(out)
53 | })
54 |
55 | test_that("drive_update() can update metadata only", {
56 | skip_if_no_token()
57 | skip_if_offline()
58 | defer_drive_rm(me_("update-me"))
59 |
60 | updatee <- drive_cp(nm_("update-fodder"), name = me_("update-me"))
61 | out <- drive_update(updatee, starred = TRUE) %>% promote("starred")
62 | expect_true(out$starred)
63 | })
64 |
65 | test_that("drive_update() uses multipart request to update media + metadata", {
66 | skip_if_no_token()
67 | skip_if_offline()
68 | defer_drive_rm(c(me_("update-me"), me_("update-me-new")))
69 |
70 | updatee <- drive_cp(nm_("update-fodder"), name = me_("update-me"))
71 | tmp <- tempfile()
72 | now <- as.character(Sys.time())
73 | write_utf8(now, tmp)
74 |
75 | out <- drive_update(updatee, media = tmp, name = me_("update-me-new"))
76 | expect_identical(out$id, updatee$id)
77 | drive_download(updatee, tmp, overwrite = TRUE)
78 | now_out <- read_utf8(tmp)
79 | expect_identical(now, now_out)
80 | expect_identical(out$name, me_("update-me-new"))
81 | })
82 |
--------------------------------------------------------------------------------
/tests/testthat/test-drive_user.R:
--------------------------------------------------------------------------------
1 | test_that("drive_user() reports on the user", {
2 | skip_if_no_token()
3 | skip_if_offline()
4 |
5 | user <- drive_user()
6 | expect_s3_class(user, "drive_user")
7 | expect_true(all(c("displayName", "emailAddress") %in% names(user)))
8 | })
9 |
--------------------------------------------------------------------------------
/tests/testthat/test-fixtures/just_a_dribble.rds:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/tests/testthat/test-fixtures/just_a_dribble.rds
--------------------------------------------------------------------------------
/tests/testthat/test-fixtures/mix_of_files_and_teamdrives.rds:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/tidyverse/googledrive/f806c49e62b34fc0150a7bd67fde1885ae479b9e/tests/testthat/test-fixtures/mix_of_files_and_teamdrives.rds
--------------------------------------------------------------------------------
/tests/testthat/test-promote.R:
--------------------------------------------------------------------------------
1 | test_that("promote() works when input has zero rows", {
2 | dib <- dribble()
3 | tib <- as_tibble(dib)
4 | tib_out <- tibble::add_column(tib, bar = list(), .after = 1)
5 | dib_out <- as_dribble(tib_out)
6 |
7 | expect_identical(promote(tib, "bar"), tib_out)
8 | expect_identical(promote(dib, "bar"), dib_out)
9 | })
10 |
11 | test_that("promote() works when elem uniformly present or absent", {
12 | x <- tibble(
13 | name = c("a", "b", "c"),
14 | id = c("1", "2", "3"),
15 | drive_resource = list(
16 | list(foo = "a1"),
17 | list(foo = "b2"),
18 | list(foo = "c3")
19 | )
20 | )
21 |
22 | expect_identical(
23 | promote(x, "foo"),
24 | tibble::add_column(x, foo = c("a1", "b2", "c3"), .after = 1)
25 | )
26 |
27 | expect_identical(
28 | promote(x, "bar"),
29 | tibble::add_column(x, bar = list(NULL, NULL, NULL), .after = 1)
30 | )
31 | })
32 |
33 | test_that("promote() works when elem is partially present", {
34 | x <- tibble(
35 | name = c("a", "b", "c"),
36 | id = c("1", "2", "3"),
37 | drive_resource = list(
38 | list(foo = "a1", bar = TRUE),
39 | list(foo = "b2", qux = list(letter = "b")),
40 | list(foo = "c3", baz = "c3")
41 | )
42 | )
43 |
44 | expect_identical(
45 | promote(x, "bar"),
46 | tibble::add_column(x, bar = c(TRUE, NA, NA), .after = 1)
47 | )
48 | expect_identical(
49 | promote(x, "qux"),
50 | tibble::add_column(x, qux = list(NULL, list(letter = "b"), NULL), .after = 1)
51 | )
52 | expect_identical(
53 | promote(x, "baz"),
54 | tibble::add_column(x, baz = c(NA, NA, "c3"), .after = 1)
55 | )
56 | })
57 |
58 | test_that("promote() replaces existing element in situ", {
59 | x <- tibble(
60 | name = "a",
61 | foo = "b",
62 | bar = "c",
63 | id = "1",
64 | drive_resource = list(
65 | list(foo = "d", bar = "e")
66 | )
67 | )
68 | x2 <- promote(x, "foo")
69 | x3 <- promote(x2, "bar")
70 | expect_identical(x3$foo, "d")
71 | expect_identical(x3$bar, "e")
72 | })
73 |
74 | test_that("promote() does snake_case to camelCase conversion internally", {
75 | x <- tibble(
76 | name = "name",
77 | id = "id",
78 | drive_resource = list(
79 | list(thisThat = "hi")
80 | )
81 | )
82 |
83 | out <- promote(x, "this_that")
84 | expect_identical(out[2], tibble(this_that = "hi"))
85 |
86 | out <- promote(x, "thisThat")
87 | expect_identical(out[2], tibble(thisThat = "hi"))
88 | })
89 |
--------------------------------------------------------------------------------
/tests/testthat/test-shared_drives.R:
--------------------------------------------------------------------------------
1 | test_that("new_corpus() checks type and length, if not-NULL", {
2 | expect_silent(new_corpus())
3 | expect_silent(
4 | new_corpus(driveId = "1", corpora = "b", includeItemsFromAllDrives = FALSE)
5 | )
6 | expect_snapshot(new_corpus(driveId = c("1", "2")), error = TRUE)
7 | expect_snapshot(new_corpus(corpora = c("a", "b")), error = TRUE)
8 | expect_snapshot(new_corpus(includeItemsFromAllDrives = c(TRUE, FALSE)), error = TRUE)
9 | })
10 |
11 | test_that("`corpora` is checked for validity", {
12 | expect_silent(shared_drive_params(corpora = "user"))
13 | expect_silent(shared_drive_params(corpora = "allDrives"))
14 | expect_silent(shared_drive_params(corpora = "domain"))
15 | expect_snapshot(shared_drive_params(corpora = "foo"), error = TRUE)
16 | })
17 |
18 | test_that('`corpora = "drive"` requires shared drive specification', {
19 | expect_snapshot(shared_drive_params(corpora = "drive"), error = TRUE)
20 | })
21 |
22 | test_that('`corpora != "drive"` rejects shared drive specification', {
23 | expect_snapshot(
24 | shared_drive_params(corpora = "user", driveId = "123"),
25 | error = TRUE
26 | )
27 | })
28 |
29 | test_that("a shared drive can be specified w/ corpora", {
30 | expect_silent(shared_drive_params(corpora = "drive", driveId = "123"))
31 | })
32 |
33 | test_that('`corpora = "drive" is inferred from shared drive specification', {
34 | out <- shared_drive_params(driveId = "123")
35 | expect_identical(out$corpora, "drive")
36 | })
37 |
--------------------------------------------------------------------------------
/tests/testthat/test-shortcut.R:
--------------------------------------------------------------------------------
1 | # ---- nm_fun ----
2 | me_ <- nm_fun("TEST-shortcut")
3 | nm_ <- nm_fun("TEST-shortcut", user_run = FALSE)
4 |
5 | # ---- clean ----
6 | if (CLEAN) {
7 | drive_trash(c(
8 | nm_("top-level-file"),
9 | nm_("i-am-a-folder"),
10 | nm_("good-shortcut"),
11 | nm_("bad-shortcut")
12 | ))
13 | }
14 |
15 | # ---- setup ----
16 | if (SETUP) {
17 | good_target <- drive_upload(
18 | system.file("DESCRIPTION"),
19 | nm_("top-level-file")
20 | )
21 | shortcut_create(good_target, name = nm_("good-shortcut"), overwrite = FALSE)
22 |
23 | drive_mkdir(nm_("i-am-a-folder"), overwrite = FALSE)
24 |
25 | bad_target <- drive_upload(
26 | system.file("DESCRIPTION"),
27 | nm_("target-to-delete")
28 | )
29 | shortcut_create(bad_target, name = nm_("bad-shortcut"), overwrite = FALSE)
30 | drive_rm(bad_target)
31 | }
32 |
33 | # ---- tests ----
34 | test_that("shortcut_create() works", {
35 | skip_if_no_token()
36 | skip_if_offline()
37 |
38 | target_file <- drive_get(nm_("top-level-file"))
39 | folder <- drive_get(nm_("i-am-a-folder"))
40 | sc_name <- me_("custom-named-shortcut")
41 |
42 | local_drive_loud_and_wide()
43 | shortcut_create_message <- capture.output(
44 | sc <- shortcut_create(target_file, path = folder, name = sc_name),
45 | type = "message"
46 | )
47 | defer_drive_rm(sc)
48 | shortcut_create_message <- shortcut_create_message %>%
49 | scrub_filepath(sc_name) %>%
50 | scrub_file_id()
51 | expect_snapshot(
52 | write_utf8(shortcut_create_message)
53 | )
54 |
55 | expect_true(is_shortcut(sc))
56 | expect_equal(
57 | drive_reveal(sc, "parent")$id_parent,
58 | folder$id
59 | )
60 | expect_match(sc$name, "custom-named-shortcut")
61 | })
62 |
63 | test_that("shortcut_create() requires `name` to control `overwrite`", {
64 | skip_if_no_token()
65 | skip_if_offline()
66 |
67 | expect_snapshot(
68 | shortcut_create(nm_("top-level-file"), overwrite = FALSE),
69 | error = TRUE
70 | )
71 | })
72 |
73 | test_that("shortcut_resolve() works", {
74 | skip_if_no_token()
75 | skip_if_offline()
76 |
77 | target_file <- drive_get(nm_("top-level-file"))
78 | dat <- drive_find(nm_(""), type = "shortcut")
79 | dat <- shortcut_resolve(dat)
80 |
81 | expect_true(is.na(dat$name[grep("bad", dat$name_shortcut)]))
82 | expect_equal(
83 | dat$name[grep("good", dat$name_shortcut)],
84 | target_file$name
85 | )
86 | })
87 |
--------------------------------------------------------------------------------
/tests/testthat/test-utils-ui.R:
--------------------------------------------------------------------------------
1 | test_that("warn_for_verbose() does nothing for `verbose = TRUE`", {
2 | expect_warning(warn_for_verbose(TRUE), NA)
3 | })
4 |
5 | test_that("warn_for_verbose() warns for `verbose = FALSE` w/ good message", {
6 | drive_something <- function() {
7 | withr::local_options(lifecycle_verbosity = "warning")
8 | warn_for_verbose(FALSE)
9 | }
10 | expect_snapshot(
11 | drive_something()
12 | )
13 | })
14 |
15 | test_that("warn_for_verbose(FALSE) makes googledrive quiet, in scope", {
16 | withr::local_options(lifecycle_verbosity = "quiet")
17 | local_drive_loud_and_wide()
18 | drive_something <- function() {
19 | warn_for_verbose(verbose = FALSE)
20 | drive_bullets("this message should not be emitted")
21 | }
22 |
23 | expect_snapshot({
24 | drive_bullets("chatty before")
25 | drive_something()
26 | drive_bullets("chatty after")
27 | })
28 | })
29 |
--------------------------------------------------------------------------------
/tests/testthat/test-utils.R:
--------------------------------------------------------------------------------
1 | # ---- tests ----
2 | test_that("put_column() adds a column in the right place", {
3 | df <- tibble(v1 = 1, v2 = 2)
4 | expect_identical(
5 | put_column(df, nm = "insert", val = 3, .after = "v1"),
6 | tibble(v1 = 1, insert = 3, v2 = 2)
7 | )
8 | })
9 |
10 | test_that("put_column() updates an existing column", {
11 | df <- tibble(v1 = 1, v2 = 2)
12 | expect_identical(
13 | put_column(df, nm = "v3", val = "hi"),
14 | tibble(v1 = 1, v2 = 2, v3 = "hi")
15 | )
16 | })
17 |
18 | test_that("put_column() works with an expression", {
19 | df <- tibble(v1 = 1, v2 = 2)
20 | stuff <- "stuff"
21 | expect_identical(
22 | put_column(df, nm = "v3", val = stuff),
23 | tibble(v1 = 1, v2 = 2, v3 = "stuff")
24 | )
25 | })
26 |
27 | test_that("and() protects its inputs with parentheses", {
28 | x <- c("organizerCount > 5", "memberCount > 20")
29 | expect_identical(
30 | as.character(and(c("createdTime > '2019-01-01T12:00:00'", or(x)))),
31 | "(createdTime > '2019-01-01T12:00:00') and (organizerCount > 5 or memberCount > 20)"
32 | )
33 | })
34 |
--------------------------------------------------------------------------------
/vignettes/.gitignore:
--------------------------------------------------------------------------------
1 | *.html
2 | *.R
3 |
--------------------------------------------------------------------------------
/vignettes/articles/.gitignore:
--------------------------------------------------------------------------------
1 | *_cache
2 |
--------------------------------------------------------------------------------
/vignettes/articles/bring-your-own-client.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "Bring your own OAuth client or API key"
3 | ---
4 |
5 | ```{r setup, include = FALSE}
6 | knitr::opts_chunk$set(
7 | collapse = TRUE,
8 | comment = "#>",
9 | error = TRUE
10 | )
11 | ```
12 |
13 | ## Role of the OAuth client and API key
14 |
15 | googledrive helps you obtain a token to work with the Google Drive API from R primarily through the `drive_auth()` function. Under the hood, that process relies on an OAuth client and secret, a.k.a. an "OAuth client".
16 |
17 | googledrive can also make unauthorized calls to the Google Drive API, for example accessing a file available to "Anyone with a link", by sending an API key, instead of a user token.
18 |
19 | If there is a problem with googledrive's internal OAuth client or API key or if you would prefer to use your own, you can configure this. Below we describe how.
20 |
21 | ## Get an OAuth client and tell googledrive about it
22 |
23 | Follow the instructions in the gargle article [How to get your own API credentials](https://gargle.r-lib.org/articles/get-api-credentials.html) to get an OAuth client ID and secret. Now register it with googledrive.
24 |
25 | Preferred method: Provide the path to the JSON file downloaded from the [Google Cloud Platform Console](https://console.cloud.google.com).
26 |
27 | ```{r eval = FALSE}
28 | drive_auth_configure(
29 | path = "/path/to/the/JSON/you/downloaded/from/google/dev/console.json"
30 | )
31 | ```
32 |
33 | It is also possible, though discouraged, to directly use the constructor `gargle::gargle_oauth_client()`.
34 |
35 | Confirm success and carry on! You can see the currently configured OAuth client like so:
36 |
37 | ```{r eval = FALSE}
38 | drive_oauth_client()
39 | ```
40 |
41 | You should see your own client there now.
42 |
43 | For the rest of this R session, when you get a new token with `drive_auth()`, your OAuth client is used.
44 |
45 | ## Get an API key and tell googledrive about it
46 |
47 | Follow the instructions in the gargle article [How to get your own API credentials](https://gargle.r-lib.org/articles/get-api-credentials.html) to get an API key. You probably want to use the same GCP project to create both your OAuth client (above) and your API key. Now register it with googledrive.
48 |
49 | ```{r eval = FALSE}
50 | drive_auth_configure(api_key = "YOUR_API_KEY_GOES_HERE")
51 | ```
52 |
53 | Confirm success and carry on! You can see the currently configured API key like so:
54 |
55 | ```{r eval = FALSE}
56 | drive_api_key()
57 | ```
58 |
59 | You should see your own API key now.
60 |
61 | For the rest of this R session, if you go into a de-authorized state via `drive_deauth()`, your API key will be sent with the request.
62 |
--------------------------------------------------------------------------------
/vignettes/googledrive.Rmd:
--------------------------------------------------------------------------------
1 | ---
2 | title: "googledrive"
3 | output: rmarkdown::html_vignette
4 | vignette: >
5 | %\VignetteIndexEntry{googledrive}
6 | %\VignetteEngine{knitr::rmarkdown}
7 | %\VignetteEncoding{UTF-8}
8 | ---
9 |
10 | Please see the googledrive website for full documentation:
11 |
12 | *
13 |
14 | In addition to function-specific help, there are several articles which are indexed here:
15 |
16 | * [Article index](https://googledrive.tidyverse.org/articles/index.html)
17 |
--------------------------------------------------------------------------------