Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions NAMESPACE
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ export(Dataset)
export(create_dataset)
export(create_distribution)
export(create_file)
export(dataset_is_valid_for_status)
export(get_api_key)
export(get_dataset)
export(get_keywords)
Expand Down
21 changes: 19 additions & 2 deletions R/create_dataset.R
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
#' @param description Optional description string
#' @param contact_email Optional contact email
#' @param landing_page Optional landing page URL
#' @param start_date Optional ISO datetime string or POSIXct
#' @param start_date ISO datetime string or POSIXct
#' @param end_date Optional ISO datetime string or POSIXct
#' @param modified_next Optional ISO datetime string or POSIXct
#' @param keyword_ids Optional character vector
Expand Down Expand Up @@ -94,7 +94,24 @@ create_dataset <- function(

# Dispatch create method
if (!preview) {
create(ds, api_key, use_dev, verbosity = verbosity)

# collect response
resp <- create(ds, api_key, use_dev, verbosity = verbosity)

# extract ID from response
id <- resp$id

# ---- run post-create validation check ----
dataset_is_valid_for_status(
id,
api_key = api_key,
use_dev = use_dev,
verbosity = verbosity,
fail_on_invalid = FALSE
)

invisible(resp)

} else {
return(ds)
}
Expand Down
3 changes: 2 additions & 1 deletion R/create_distribution.R
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
#' @param access_url Optional URL to access the distribution (must start with http:// or https://).
#' @param byte_size Optional file size in bytes (must be a positive number).
#' @param status_id Optional character; status ID (will be set via follow-up PATCH).
#' @param license_id Optional integer; license ID.
#' @param license_id integer; license ID.
#' Use `1` = "CC BY 4.0 (Attribution required)" or `2` = "CC0 (No attribution required)".
#' @param file_format_id Optional file format ID.
#' @param periodicity_id Optional character periodicity ID.
#' @param file_path Optional local file path; if provided, the file will be uploaded and linked.
Expand Down
75 changes: 73 additions & 2 deletions R/helpers.R
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ object_to_payload <- function(object) {
fmt_date <- function(d) format(d, "%Y-%m-%d")

# 2. Transform properties:
# - POSIXct/Date YYYY-MM-DD
# - POSIXct/Date -> YYYY-MM-DD
p <- purrr::map(p, function(x) {
if (inherits(x, c("POSIXct", "Date"))) {
# if no date at all or only NA, emit a single NA_character_
Expand Down Expand Up @@ -155,10 +155,81 @@ to_date <- function(x) {

to_list <- function(vec_var) {
if (!inherits(vec_var, "S7_missing")) {
# c(42) list(42); c(1,2,3) list(1,2,3)
# c(42) -> list(42); c(1,2,3) -> list(1,2,3)
as.list(vec_var)
} else {
S7::class_missing
}
}



#' Check if a dataset is valid for the next status (generic handling)
#'
#' @param id integer; dataset ID
#' @param api_key API key (optional; falls back to env var)
#' @param use_dev logical; use dev environment
#' @param verbosity integer; passed to httr2::req_perform()
#' @param fail_on_invalid logical; abort if server says not valid (default TRUE)
#' @return Invisibly returns parsed response list (type, errors, is_valid, can_delete, next_status)
#' @export
dataset_is_valid_for_status <- function(
id,
api_key = NULL,
use_dev = TRUE,
verbosity = 0,
fail_on_invalid = TRUE
) {
endpoint <- sprintf("/api/v1/datasets/%s/is-valid-for-status", as.integer(id))

api_key <- get_api_key(api_key)


resp <- api_request(
method = "GET",
endpoint = endpoint,
object = NULL, # kein Payload
object_label = "Dataset Validation",
api_key = api_key,
verbosity = verbosity,
use_dev = use_dev
)

is_valid <- isTRUE(resp$is_valid)
errs <- resp$errors %||% list()

if (is_valid) {
cli::cli_alert_success("Dataset ID {.val {id}} ist {cli::col_green('valid')} fuer den naechsten Status.")
} else {
cli::cli_alert_warning("Dataset ID {.val {id}} ist {cli::col_yellow('nicht valid')} fuer den naechsten Status. Das Dataset wurde angelegt, kann aber so nicht veroeffentlicht werden.")

if (length(errs) > 0) {
cli::cli_h2("Fehlerdetails:")
for (e in errs) {
code <- e$code %||% ""
attr <- e$attr %||% ""
det <- e$detail %||% ""

# Formatting
if (nzchar(attr) && nzchar(code)) {
cli::cli_bullets(c("x" = "{det} [{cli::col_silver(code)} @ {cli::col_cyan(attr)}]"))
} else if (nzchar(attr)) {
cli::cli_bullets(c("x" = "{det} [@ {cli::col_cyan(attr)}]"))
} else if (nzchar(code)) {
cli::cli_bullets(c("x" = "{det} [{cli::col_silver(code)}]"))
} else {
cli::cli_bullets(c("x" = "{det}"))
}
}
} else {
cli::cli_bullets(c("x" = "Server lieferte keine Fehlerdetails."))
}

if (isTRUE(fail_on_invalid)) {
cli::cli_abort("Servervalidierung fehlgeschlagen - Statuswechsel nicht moeglich.")
}
}

invisible(resp)
}

20 changes: 19 additions & 1 deletion R/update_dataset.R
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,25 @@ update_dataset <- function(

# Dispatch the update method
if (!preview) {
update(ds, api_key, use_dev, verbosity = verbosity)

# collect response
resp <- update(ds, api_key, use_dev, verbosity = verbosity)

# extract ID from response
id <- resp$id

# ---- run post-create validation check ----
dataset_is_valid_for_status(
id,
api_key = api_key,
use_dev = use_dev,
verbosity = verbosity,
fail_on_invalid = FALSE
)

invisible(resp)


} else {
return(ds)
}
Expand Down
1 change: 1 addition & 0 deletions R/update_distribution.R
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#' @param byte_size Optional file size in bytes (must be a positive number).
#' @param status_id Optional status ID (applied via PATCH after update).
#' @param license_id Optional license ID.
#' Use `1` = "CC BY 4.0 (Attribution required)" or `2` = "CC0 (No attribution required)".
#' @param file_format_id Optional file format ID.
#' @param periodicity_id Optional update frequency ID.
#' @param file_path Optional local file path; if provided, the file will be uploaded and linked.
Expand Down
14 changes: 12 additions & 2 deletions README.Rmd
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ knitr::opts_chunk$set(
)
```

# 📦 zhapir <a href="https://github.com/openZH/zhapir"><img src="man/figures/zhapir_hex.png" align="right" height="138" alt="zhapir Hex-Sticker" /></a>
# 📦 zhapir <a href="https://github.com/openZH/zhapir"><img src="man/figures/zhapir_hex.png" alt="zhapir Hex-Sticker" align="right" height="138"/></a>

<!-- badges: start -->

Expand All @@ -25,7 +25,6 @@ knitr::opts_chunk$set(

Damit können Inhalte für [zh.ch/opendata](https://zh.ch/opendata) und [opendata.swiss](https://opendata.swiss) effizient gepflegt werden.


## 🚀 Installation

Das Paket wird über GitHub installiert:
Expand Down Expand Up @@ -87,6 +86,7 @@ ds <- zhapir::create_dataset(
contact_email = "team@example.org",
theme_ids = c("Verkehr"),
periodicity_id = "Jährlich",
start_date = "2020-01-01", # 🟢 Startdatum ist für Veröffentlichung erforderlich
use_dev = FALSE
)
```
Expand All @@ -96,6 +96,8 @@ Eine Publikation ist nur über die grafische Oberfläche möglich und erfolgt im

ℹ️ Es ist nicht notwendig das Ergebnis der Funktionen (z.B. `zhapir::create_distribution()`) per `<-` zuzuweisen. Wir nutzen dies hier, um mit der ID eines Datensatzes oder einer Distribution weiterzuarbeiten.

🟢 Nach dem Erstellen oder Aktualisieren prüft `zhapir` automatisch, ob der Datensatz valid für den nächsten Status ist (z. B. ob Pflichtfelder wie `start_date` oder `keywords` gesetzt sind). Fehlende Felder werden im CLI mit entsprechenden Hinweisen ausgegeben.

### Distribution hinzufügen

```{r eval=FALSE}
Expand All @@ -110,10 +112,18 @@ dist <- zhapir::create_distribution(
file_path = tmpfile,
ogd_flag = TRUE,
zh_web_flag = TRUE,
license_id = 1, # 🟢 Lizenz-ID (siehe unten)
use_dev = FALSE
)
```

🟢 Lizenztypen (license_id)

| ID | Bedeutung | Entspricht |
|-------------|---------------------------------------------|--------------|
| 1 | kommerzielle & nicht-kommerzielle Nutzung **mit Quellenangabe** | ≈ CC BY 4.0 |
| 2 | kommerzielle & nicht-kommerzielle Nutzung **ohne Quellenangabe** | ≈ CC0 1.0 Public Domain |

👉 **Kniff:** Über `update_distribution()` kannst du auch **Parameter auf Dataset-Ebene** anpassen, ohne separat `update_dataset()` aufzurufen – z. B. `end_date` oder `modified_next`:

```{r eval=FALSE}
Expand Down
16 changes: 15 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@

<!-- README.md is generated from README.Rmd. Please edit that file -->

# 📦 zhapir <a href="https://github.com/openZH/zhapir"><img src="man/figures/zhapir_hex.png" align="right" height="138" alt="zhapir Hex-Sticker" /></a>
# 📦 zhapir <a href="https://github.com/openZH/zhapir"><img src="man/figures/zhapir_hex.png" alt="zhapir Hex-Sticker" align="right" height="138"/></a>

<!-- badges: start -->

Expand Down Expand Up @@ -83,6 +83,7 @@ ds <- zhapir::create_dataset(
contact_email = "team@example.org",
theme_ids = c("Verkehr"),
periodicity_id = "Jährlich",
start_date = "2020-01-01", # 🟢 Startdatum ist für Veröffentlichung erforderlich
use_dev = FALSE
)
```
Expand All @@ -98,6 +99,11 @@ aber vollständig über die API/R erledigen.
hier, um mit der ID eines Datensatzes oder einer Distribution
weiterzuarbeiten.

🟢 Nach dem Erstellen oder Aktualisieren prüft `zhapir` automatisch, ob
der Datensatz valid für den nächsten Status ist (z. B. ob Pflichtfelder
wie `start_date` oder `keywords` gesetzt sind). Fehlende Felder werden
im CLI mit entsprechenden Hinweisen ausgegeben.

### Distribution hinzufügen

``` r
Expand All @@ -112,10 +118,18 @@ dist <- zhapir::create_distribution(
file_path = tmpfile,
ogd_flag = TRUE,
zh_web_flag = TRUE,
license_id = 1, # 🟢 Lizenz-ID (siehe unten)
use_dev = FALSE
)
```

🟢 Lizenztypen (license_id)

| ID | Bedeutung | Entspricht |
|----|----|----|
| 1 | kommerzielle & nicht-kommerzielle Nutzung **mit Quellenangabe** | ≈ CC BY 4.0 |
| 2 | kommerzielle & nicht-kommerzielle Nutzung **ohne Quellenangabe** | ≈ CC0 1.0 Public Domain |

👉 **Kniff:** Über `update_distribution()` kannst du auch **Parameter
auf Dataset-Ebene** anpassen, ohne separat `update_dataset()` aufzurufen
– z. B. `end_date` oder `modified_next`:
Expand Down
2 changes: 1 addition & 1 deletion man/create_dataset.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/create_distribution.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

31 changes: 31 additions & 0 deletions man/dataset_is_valid_for_status.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion man/update_distribution.Rd

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading