From d4970c92278686251dd50c29aaf831859ad23fba Mon Sep 17 00:00:00 2001 From: Sanne Govaert <44606923+sannegovaert@users.noreply.github.com> Date: Tue, 1 Sep 2026 17:37:52 +0200 Subject: [PATCH 1/9] Update roxygen2 version --- DESCRIPTION | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/DESCRIPTION b/DESCRIPTION index 533b0a9a..8d4c3d81 100644 --- a/DESCRIPTION +++ b/DESCRIPTION @@ -46,4 +46,4 @@ Suggests: Config/testthat/edition: 3 Encoding: UTF-8 Roxygen: list(markdown = TRUE) -Config/roxygen2/version: 8.0.0 +Config/roxygen2/version: 8.1.0 From e29b0bd14b6da9a90c5d2af12272dd17ba30fcf0 Mon Sep 17 00:00:00 2001 From: Sanne Govaert <44606923+sannegovaert@users.noreply.github.com> Date: Tue, 1 Sep 2026 17:38:07 +0200 Subject: [PATCH 2/9] Create downgrade_package.R --- R/downgrade_package.R | 49 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 R/downgrade_package.R diff --git a/R/downgrade_package.R b/R/downgrade_package.R new file mode 100644 index 00000000..fcea0402 --- /dev/null +++ b/R/downgrade_package.R @@ -0,0 +1,49 @@ +#' Downgrade a Camera Trap Data Package object from v2 to v1 +#' +#' Downgrade the descriptor and the associated resources. +#' +#' @param x Camera Trap Data Package object, as returned by [read_camtrapdp()]. +#' @returns Downgraded `x`. +#' @family downgrade functions +#' @noRd +downgrade_package <- function(x) { + frictionless::check_package(x) + + # No quick return for v2 package + # Packages could be mixed versions + + # Downgrade descriptor, by removing $schema property + x$`$schema` <- NULL + + # Downgrade resources + for (resource_name in frictionless::resource_names(x)) { + resource <- downgrade_resource(frictionless::resource(x, resource_name)) + frictionless::resource(x, resource_name) <- resource + } + + return(x) +} + +#' Downgrade a Data Resource object from v2 to v1 +#' +#' @param resource List describing a Data Resource, as returned by [frictionless::resource()]. +#' @returns Downgraded `resource`. +#' @family downgrade functions +#' @noRd +downgrade_resource <- function(resource) { + version <- frictionless::version(resource) + + # Leave resource as is if data package version 1.0 + if (version == "1.0") { + return(resource) + } + + # Set profile back to "tabular-data-resource" + resource$profile <- "tabular-data-resource" + + # Remove type and $schema + resource$type <- NULL + resource$`$schema` <- NULL + + return(resource) +} From 1360231cb1eaba2dd356fcc275053865f8879a57 Mon Sep 17 00:00:00 2001 From: Sanne Govaert <44606923+sannegovaert@users.noreply.github.com> Date: Tue, 1 Sep 2026 17:39:01 +0200 Subject: [PATCH 3/9] Use downgrade_package() in write_camtrapdp() --- R/write_camtrapdp.R | 3 +++ 1 file changed, 3 insertions(+) diff --git a/R/write_camtrapdp.R b/R/write_camtrapdp.R index 49cd1384..0d0f8d58 100644 --- a/R/write_camtrapdp.R +++ b/R/write_camtrapdp.R @@ -66,6 +66,9 @@ write_camtrapdp <- function(x, directory, ...) { recursive = TRUE ) + # Downgrade to data package 1.0 if necessary + x <- downgrade_package(x) + # Write files frictionless::write_package(x, directory, ...) From b915758c70fa57674659a8d46c054ff6e7f58a31 Mon Sep 17 00:00:00 2001 From: Peter Desmet <600993+peterdesmet@users.noreply.github.com> Date: Wed, 9 Sep 2026 13:43:48 +0200 Subject: [PATCH 4/9] Update downgrade_package doc + family x --- R/downgrade_package.R | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/R/downgrade_package.R b/R/downgrade_package.R index fcea0402..43d21b81 100644 --- a/R/downgrade_package.R +++ b/R/downgrade_package.R @@ -1,10 +1,12 @@ -#' Downgrade a Camera Trap Data Package object from v2 to v1 +#' Downgrade a Camera Trap Data Package to Data Package v1 #' -#' Downgrade the descriptor and the associated resources. +#' Packages, schemas and resources created with frictionless >=2.0.0 follow the +#' v2 specification of Data Package, while Camtrap DP follows v1. +#' This function downgrades a package and its resources to v1. #' -#' @param x Camera Trap Data Package object, as returned by [read_camtrapdp()]. +#' @inheritParams print.camtrapdp #' @returns Downgraded `x`. -#' @family downgrade functions +#' @family helper functions #' @noRd downgrade_package <- function(x) { frictionless::check_package(x) @@ -18,7 +20,13 @@ downgrade_package <- function(x) { # Downgrade resources for (resource_name in frictionless::resource_names(x)) { resource <- downgrade_resource(frictionless::resource(x, resource_name)) - frictionless::resource(x, resource_name) <- resource + if (frictionless::version(resource) != "1.0") { + # Set profile, remove $schema and type + resource$profile <- "tabular-data-resource" + resource$`$schema` <- NULL + resource$type <- NULL + frictionless::resource(x, resource_name) <- resource + } } return(x) From a4dc12b9faa3a99326f738f14543365e826d1ba8 Mon Sep 17 00:00:00 2001 From: Peter Desmet <600993+peterdesmet@users.noreply.github.com> Date: Wed, 9 Sep 2026 13:49:03 +0200 Subject: [PATCH 5/9] Update function - Don't run check_package(): it's a helper function, it's expected to have correct input - Don't have downgrade_resource() helper function, keep it contained to one helper --- R/downgrade_package.R | 35 +++-------------------------------- R/write_camtrapdp.R | 2 +- 2 files changed, 4 insertions(+), 33 deletions(-) diff --git a/R/downgrade_package.R b/R/downgrade_package.R index 43d21b81..c861b1a6 100644 --- a/R/downgrade_package.R +++ b/R/downgrade_package.R @@ -9,17 +9,12 @@ #' @family helper functions #' @noRd downgrade_package <- function(x) { - frictionless::check_package(x) - - # No quick return for v2 package - # Packages could be mixed versions - - # Downgrade descriptor, by removing $schema property - x$`$schema` <- NULL + # Downgrade descriptor + x$`$schema` <- NULL # Profile expected to be present # Downgrade resources for (resource_name in frictionless::resource_names(x)) { - resource <- downgrade_resource(frictionless::resource(x, resource_name)) + resource <- frictionless::resource(x, resource_name) if (frictionless::version(resource) != "1.0") { # Set profile, remove $schema and type resource$profile <- "tabular-data-resource" @@ -31,27 +26,3 @@ downgrade_package <- function(x) { return(x) } - -#' Downgrade a Data Resource object from v2 to v1 -#' -#' @param resource List describing a Data Resource, as returned by [frictionless::resource()]. -#' @returns Downgraded `resource`. -#' @family downgrade functions -#' @noRd -downgrade_resource <- function(resource) { - version <- frictionless::version(resource) - - # Leave resource as is if data package version 1.0 - if (version == "1.0") { - return(resource) - } - - # Set profile back to "tabular-data-resource" - resource$profile <- "tabular-data-resource" - - # Remove type and $schema - resource$type <- NULL - resource$`$schema` <- NULL - - return(resource) -} diff --git a/R/write_camtrapdp.R b/R/write_camtrapdp.R index 0d0f8d58..30a652bc 100644 --- a/R/write_camtrapdp.R +++ b/R/write_camtrapdp.R @@ -66,7 +66,7 @@ write_camtrapdp <- function(x, directory, ...) { recursive = TRUE ) - # Downgrade to data package 1.0 if necessary + # Downgrade to Data Package v1 x <- downgrade_package(x) # Write files From 24868ce724b25c56d8a8b338c6e00d3af98cc295 Mon Sep 17 00:00:00 2001 From: Peter Desmet <600993+peterdesmet@users.noreply.github.com> Date: Wed, 9 Sep 2026 13:56:02 +0200 Subject: [PATCH 6/9] Suppress upgrade_taxon message --- tests/testthat/test-write_camtrapdp.R | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/testthat/test-write_camtrapdp.R b/tests/testthat/test-write_camtrapdp.R index 3e61256f..b51a2a15 100644 --- a/tests/testthat/test-write_camtrapdp.R +++ b/tests/testthat/test-write_camtrapdp.R @@ -100,8 +100,9 @@ test_that("write_camtrapdp() returns the expected datapackage.json for the on.exit(unlink(temp_dir, recursive = TRUE)) # Adapt x$taxonomic and x$contributors to test for https://github.com/inbo/camtrapdp/issues/185 - x <- x |> + x <- suppressMessages( update_taxon( + x, from = "Anas platyrhynchos", to = list( scientificName = "Anas platyrhynchos", @@ -110,6 +111,7 @@ test_that("write_camtrapdp() returns the expected datapackage.json for the vernacularNames.nld = "wilde eend" # Assigns NA for vernacularNames.eng ) ) + ) contributors(x) <- contributors(x) # Assigns NA for e.g. firstName of INBO write_camtrapdp(x, temp_dir) From 16f6ca02cb30a97fe2214bd73fa5d96e98a548fc Mon Sep 17 00:00:00 2001 From: Peter Desmet <600993+peterdesmet@users.noreply.github.com> Date: Wed, 9 Sep 2026 14:01:07 +0200 Subject: [PATCH 7/9] Keep profile in right place --- R/downgrade_package.R | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/R/downgrade_package.R b/R/downgrade_package.R index c861b1a6..f6c0890b 100644 --- a/R/downgrade_package.R +++ b/R/downgrade_package.R @@ -16,8 +16,10 @@ downgrade_package <- function(x) { for (resource_name in frictionless::resource_names(x)) { resource <- frictionless::resource(x, resource_name) if (frictionless::version(resource) != "1.0") { - # Set profile, remove $schema and type - resource$profile <- "tabular-data-resource" + # Set profile (after name and description). Note: also removes attributes + resource <- append(resource, list(profile = "tabular-data-resource"), 2) + + # Remove $schema and type resource$`$schema` <- NULL resource$type <- NULL frictionless::resource(x, resource_name) <- resource From 113e269ad0d028c0317f1b102986c5e57ca0c407 Mon Sep 17 00:00:00 2001 From: Peter Desmet <600993+peterdesmet@users.noreply.github.com> Date: Wed, 9 Sep 2026 14:28:03 +0200 Subject: [PATCH 8/9] Add extra test for downgrade_package --- tests/testthat/test-write_camtrapdp.R | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/tests/testthat/test-write_camtrapdp.R b/tests/testthat/test-write_camtrapdp.R index b51a2a15..4b7dbee4 100644 --- a/tests/testthat/test-write_camtrapdp.R +++ b/tests/testthat/test-write_camtrapdp.R @@ -117,3 +117,27 @@ test_that("write_camtrapdp() returns the expected datapackage.json for the expect_snapshot_file(file.path(temp_dir, "datapackage.json")) }) + +test_that("write_camtrapdp() returns a datapackage.json as a Data Package v1", { + skip_if_offline() + x <- example_dataset() + x$`$schema` <- "https://datapackage.org/profiles/2.0/datapackage.json" + temp_dir <- tempdir() + on.exit(unlink(temp_dir, recursive = TRUE)) + write_camtrapdp(x, temp_dir) + + # datapackage.json + written_datapackage <- jsonlite::fromJSON( + file.path(temp_dir, "datapackage.json"), + simplifyDataFrame = FALSE, simplifyVector = TRUE + ) + expect_identical(frictionless::version(written_datapackage), "1.0") + expect_null(written_datapackage$`$schema`) + + # deployments resource + written_resource <- written_datapackage$resources[[1]] + expect_identical(frictionless::version(written_resource), "1.0") + expect_identical(written_resource$profile, "tabular-data-resource") + expect_null(written_resource$`$schema`) + expect_null(written_resource$type) +}) From 627bc2e6985b1bdc0303e93efe68b3d67e729c72 Mon Sep 17 00:00:00 2001 From: Peter Desmet <600993+peterdesmet@users.noreply.github.com> Date: Wed, 9 Sep 2026 14:36:49 +0200 Subject: [PATCH 9/9] Revert "Add extra test for downgrade_package" This reverts commit 113e269ad0d028c0317f1b102986c5e57ca0c407. --- tests/testthat/test-write_camtrapdp.R | 24 ------------------------ 1 file changed, 24 deletions(-) diff --git a/tests/testthat/test-write_camtrapdp.R b/tests/testthat/test-write_camtrapdp.R index 4b7dbee4..b51a2a15 100644 --- a/tests/testthat/test-write_camtrapdp.R +++ b/tests/testthat/test-write_camtrapdp.R @@ -117,27 +117,3 @@ test_that("write_camtrapdp() returns the expected datapackage.json for the expect_snapshot_file(file.path(temp_dir, "datapackage.json")) }) - -test_that("write_camtrapdp() returns a datapackage.json as a Data Package v1", { - skip_if_offline() - x <- example_dataset() - x$`$schema` <- "https://datapackage.org/profiles/2.0/datapackage.json" - temp_dir <- tempdir() - on.exit(unlink(temp_dir, recursive = TRUE)) - write_camtrapdp(x, temp_dir) - - # datapackage.json - written_datapackage <- jsonlite::fromJSON( - file.path(temp_dir, "datapackage.json"), - simplifyDataFrame = FALSE, simplifyVector = TRUE - ) - expect_identical(frictionless::version(written_datapackage), "1.0") - expect_null(written_datapackage$`$schema`) - - # deployments resource - written_resource <- written_datapackage$resources[[1]] - expect_identical(frictionless::version(written_resource), "1.0") - expect_identical(written_resource$profile, "tabular-data-resource") - expect_null(written_resource$`$schema`) - expect_null(written_resource$type) -})