blob: 182bf97653aa42ad7b99dbca8207d50da9d5cfc9 [file] [log] [blame]
Marc Kupietz6dfeed92025-06-03 11:58:06 +02001#' @include logging.R
2setGeneric("textMetadata", function(kco, ...) standardGeneric("textMetadata"))
Marc Kupietz6ddece42023-12-18 17:02:36 +01003
4#' Retrieve metadata for a text, identified by its sigle (id)
5#'
6#' @aliases textMetadata
7#'
8#' @description
9#' Retrieves metadata for a text, identified by its sigle (id) using the corresponding KorAP API
10#' (see [Kustvakt Wiki](https://github.com/KorAP/Kustvakt/wiki/Service:-Metadata-Retrieval)).
Marc Kupietza267c422025-06-26 10:16:20 +020011#' To retrieve the metadata for every text in a virtual corpus, use [corpusQuery()]
12#' with `<base/s=t>` as query, instead.
Marc Kupietz6ddece42023-12-18 17:02:36 +010013#'
14#'
Marc Kupietz617266d2025-02-27 10:43:07 +010015#' @param kco [KorAPConnection()] object (obtained e.g. from `KorAPConnection()`)
Marc Kupietz6ddece42023-12-18 17:02:36 +010016#' @param textSigle unique text id (concatenation of corpus, document and text ids, separated by `/`, e.g. ) or vector thereof
17#' @param verbose logical. If `TRUE`, additional diagnostics are printed. Defaults to `kco@verbose`.
Marc Kupietza3a8cd92026-09-08 07:59:04 +020018#' @param cacheAs path to an RDS file to keep the result in. If the file exists and records the same call, it is read back instead of contacting the server; otherwise the query is run and its result stored there. Unlike the connection's `cache`, this file belongs to the caller, which is what keeps an analysis reproducible once the corpus has grown or the scores have changed. Defaults to \code{NULL} (no file).
Marc Kupietz6ddece42023-12-18 17:02:36 +010019#'
Marc Kupietz3687a8c2024-01-24 16:18:36 +010020#' @return Tibble with columns for each metadata property. In case of errors, such as non-existing texts/sigles, the tibble will also contain a column called `errors`.
21#' If there are metadata columns you cannot make sense of, please ignore them. The function simply returns all the metadata it gets from the server.
Marc Kupietz6ddece42023-12-18 17:02:36 +010022#'
23#' @importFrom urltools url_encode
Marc Kupietza7a8f1b2024-12-18 15:56:19 +010024#' @importFrom dplyr across bind_rows relocate mutate where
Marc Kupietz2a8ab822024-06-26 21:13:37 +020025#' @importFrom tibble as_tibble
26#' @importFrom tidyr pivot_wider
Marc Kupietz6ddece42023-12-18 17:02:36 +010027#'
28#' @examples
29#' \dontrun{
Marc Kupietza267c422025-06-26 10:16:20 +020030#' KorAPConnection() |> textMetadata(c("WUD17/A97/08542", "WUD17/B96/57558", "WUD17/A97/08541"))
Marc Kupietz6ddece42023-12-18 17:02:36 +010031#' }
32#'
33#' @export
Marc Kupietz6dfeed92025-06-03 11:58:06 +020034setMethod(
35 "textMetadata", "KorAPConnection",
Marc Kupietza3a8cd92026-09-08 07:59:04 +020036 function(kco, textSigle, verbose = kco@verbose, cacheAs = NULL) {
37 cacheRecord <- NULL
38 if (!is.null(cacheAs)) {
39 cacheAs <- cacheAsFileName(cacheAs)
40 cacheRecord <- cacheAsRecord(environment(), NULL, kco)
41 cached <- readCacheAs(cacheAs, kco, cacheRecord, "text metadata")
42 if (!is.null(cached)) {
43 return(cached)
44 }
45 }
46
Marc Kupietz6dfeed92025-06-03 11:58:06 +020047 # https://stackoverflow.com/questions/8096313/no-visible-binding-for-global-variable-note-in-r-cmd-check
48 key <- 0
Marc Kupietza3a8cd92026-09-08 07:59:04 +020049 metadata <- if (length(textSigle) > 1) {
Marc Kupietz6dfeed92025-06-03 11:58:06 +020050 do.call(bind_rows, Map(function(atomicSigle) {
51 textMetadata(kco, atomicSigle)
52 }, textSigle))
Marc Kupietz6ddece42023-12-18 17:02:36 +010053 } else {
Marc Kupietz6dfeed92025-06-03 11:58:06 +020054 url <-
55 paste0(
56 kco@apiUrl, "corpus/",
57 URLencode(enc2utf8(textSigle), reserved = TRUE)
58 )
59 log_info(verbose, "Getting metadata for ", textSigle, sep = "")
60 res <- apiCall(kco, url)
61 log_info(verbose, ifelse(is.null(res) || "errors" %in% names(res), " [error]\n", "\n"))
62
63 if (is.null(res)) {
64 res <- tibble(errors = "API request failed")
Marc Kupietz2a8ab822024-06-26 21:13:37 +020065 } else {
Marc Kupietz6dfeed92025-06-03 11:58:06 +020066 if ("document" %in% names(res) & "fields" %in% names(res$document) && length(res$document$fields) > 0) {
67 res <- as_tibble(res$document$fields) %>%
68 dplyr::mutate(across(where(is.list), ~ purrr::map(.x, ~ if (length(.x) < 2) unlist(.x) else paste(.x, collapse = "\\t")))) %>%
69 select(key, value) %>%
70 tidyr::pivot_wider(names_from = key, values_from = value, names_repair = "unique") %>%
71 mutate(
72 textSigle = as.character(textSigle),
73 requestUrl = url,
74 webUIRequestUrl = paste0(kco@KorAPUrl, sprintf('?q=<base/s=t>&cq=textSigle+%%3D+"%s"', url_encode(enc2utf8(textSigle))))
75 ) %>%
76 mutate(across(everything(), as.character)) %>%
77 relocate(textSigle)
78 } else {
79 res <- lapply(res, function(x) paste0(x, collapse = "\\t")) # flatten list
80 res <- as_tibble(res) %>%
81 head(n = 1) %>%
82 mutate(
83 requestUrl = url,
84 textSigle = textSigle,
85 webUIRequestUrl = paste0(kco@KorAPUrl, sprintf('?q=<base/s=t>&cq=textSigle+%%3D+"%s"', url_encode(enc2utf8(textSigle))))
86 ) %>%
87 relocate(textSigle)
88 }
Marc Kupietz2a8ab822024-06-26 21:13:37 +020089 }
Marc Kupietz6dfeed92025-06-03 11:58:06 +020090 res
Marc Kupietz6ddece42023-12-18 17:02:36 +010091 }
Marc Kupietza3a8cd92026-09-08 07:59:04 +020092
93 if (!is.null(cacheAs)) {
94 writeCacheAs(cacheAs, kco, cacheRecord, "text metadata", metadata)
95 }
96 metadata
Marc Kupietz6ddece42023-12-18 17:02:36 +010097 }
Marc Kupietz6dfeed92025-06-03 11:58:06 +020098)