Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update NEWS + assorted minor refactoring + add download_attachment_field() #18

Open
wants to merge 10 commits into
base: dev
Choose a base branch
from
14 changes: 8 additions & 6 deletions DESCRIPTION
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,13 @@ Maintainer: Matthew Rogers <[email protected]>
Description: Create, read, update, and delete Airtable records or read
base metadata using the Airtable Web API.
License: MIT + file LICENSE
URL: https://matthewjrogers.github.io/rairtable/
URL: https://github.com/matthewjrogers/rairtable,
https://matthewjrogers.github.io/rairtable/
BugReports: https://github.com/matthewjrogers/rairtable/issues
Depends:
R (>= 2.10)
Imports:
cli,
cli (>= 2.5.0),
glue,
httr2 (>= 0.2.3),
lifecycle,
Expand All @@ -33,8 +36,7 @@ VignetteBuilder:
knitr
Config/testthat/edition: 3
Encoding: UTF-8
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.2.3
Depends:
R (>= 2.10)
Language: en-US
LazyData: true
Roxygen: list(markdown = TRUE)
RoxygenNote: 7.3.2
1 change: 0 additions & 1 deletion NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ importFrom(rlang,call_name)
importFrom(rlang,caller_call)
importFrom(rlang,current_env)
importFrom(rlang,exec)
importFrom(rlang,expr)
importFrom(rlang,with_options)
importFrom(rlang,zap)
importFrom(tibble,as_tibble)
Expand Down
30 changes: 29 additions & 1 deletion NEWS.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,30 @@
# rairtable (development)

This is a major update of the original version of the rairtable package. The package has been refactored to use the `{httr2}` package, a large number of new functions have been added, along with new features for existing functions.

General changes:

* Add cli, glue, httr2, lifecycle, rlang, tibble, tidyselect, and vctrs to Imports.
* Remove httr, jsonlite, tibble, dplyr, crayon, parallel, and progress from Imports.
* Add httptest2, knitr, rmarkdown, and testthat to Suggests.

New functions for working with several components of the Airtable Web API:

* Bases: `create_base()`, `list_bases()`, and `get_base_schema()`
* Records: `list_records()` and `get_record()`
* Tables and table configurations: `create_table()`, `get_table_model()`, `get_table_models()`, `make_table_config()`, and `copy_table_config()`
* Fields and field configurations: `create_field()`, `update_field()`, `get_field_config()`, and `make_field_config()`
* Comments: `list_comments()`, `create_comment()`, `delete_comment()`

Updated functions:

* `airtable()` now supports parsing Airtable URLs to derive Airtable base, table, and view ID values. Support for parsing URLs is now available for most functions in the package.
* `read_airtable()` (along with `list_records()`) now supports the full range of parameters for the record query API.

Other changes:

* Add @elipousson as co-author.

# rairtable 0.1.1
Basic Airtable CRUD functionality

* Basic Airtable CRUD functionality
16 changes: 10 additions & 6 deletions R/airtable.R
Original file line number Diff line number Diff line change
Expand Up @@ -181,20 +181,24 @@ vec_ptype_full.airtable <- function(x, ...) {
print.airtable <- function(x, ...) {
cli::cli_text("{.cls {class(x)}}")

rule_msg <- ""

if (!is_empty(x$description)) {
cli::cli_rule("{.valuel {x$description}}")
} else {
cli::cli_rule()
rule_msg <- "{.valuel {x$description}}"
}

cli::cli_rule(rule_msg)

text <- c("*" = "Base: {.field {x$base}}")

if (!is_empty(x$table)) {
tbl_msg <- "Table: {.val {x$name}} - {.field {x$table}}"

if (is_empty(x$name)) {
text <- c(text, "*" = "Table: {.field {x$table}}")
} else {
text <- c(text, "*" = "Table: {.val {x$name}} - {.field {x$table}}")
tbl_msg <- "Table: {.field {x$table}}"
}

text <- c(text, "*" = tbl_msg)
}

if (!is_empty(x$view)) {
Expand Down
67 changes: 67 additions & 0 deletions R/attachments.R
Original file line number Diff line number Diff line change
@@ -0,0 +1,67 @@
#' Download files from an Airtable attachment field
#'
#' @description
#' Learn more about the attachment field type:
#' <https://airtable.com/developers/web/api/field-model#multipleattachment>
#'
#' Learn more about attachments in Airtable:
#' <https://support.airtable.com/docs/airtable-attachment-url-behavior>
#'
#' @param data An Airtable data frame with an attachment list column selected
#' with the field parameter *or* an attachment list column.
#' @param field Attachment field or column name as string or tidyselect function.
#' @param path Path to download file.
#' @inheritParams rlang::args_error_context
#' @keywords internal
download_attachment_field <- function(data,
field = NULL,
path = NULL,
...,
call = caller_env()) {
if (!is.null(field)) {
check_data_frame(data, call = call)
data <- select_cols(tidyselect::any_of(field), .data = data, call = call)
ncol_data <- ncol(data)

if (ncol_data > 1) {
cli::cli_abort(
"{.arg field} must select only one attachment column, not {ncol_data}.",
call = call
)
}

data <- data[[1]]
}

url_list <- attachment_to_url_list(data)

walk(
seq_along(url_list),
\(i) {
download.file(
url = url_list[[i]],
destfile = file.path(
path %||% getwd(),
names(url_list)[[i]]
),
...
)
}
)
}

#' Convert attachment column to named vector of URLs named with file names
#'
#' @param data Attachment data frame list column.
#' @noRd
attachment_to_url_list <- function(.l, filename = NULL) {
url <- map(.l, \(x) {
x[["url"]]
})

filename <- filename %||% map(.l, \(x) {
x[["filename"]]
})

set_names(unlist(url), unlist(filename))
}
2 changes: 1 addition & 1 deletion R/field_config.R
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ make_list_of_lists <- function(data,
data <- select_cols(
tidyselect::any_of(cols),
.data = data,
call = call
error_call = call
)
}

Expand Down
Loading