---
title: "Get started with zot"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Get started with zot}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(collapse = TRUE, comment = "#>")
```

`zot` connects R to the Zotero Web API and local Zotero data sources. This
article uses an in-memory request performer and does not contact an external
service.

## Configure API access

`zotConfig()` accepts credentials explicitly or reads `ZOTERO_LIBRARY_ID` and
`ZOTERO_API_KEY` from the process environment. The same interface can be used
from interactive R, scripts, automated jobs, and agent-driven workflows. A
non-interactive caller reads no shell profile, so an `Rscript` job takes those
variables from `~/.Renviron`, the file R reads at startup in every session.

```{r}
library(data.table)
library(zot)

Config <- zotConfig(userID = "42", key = "example-key")
Config
```

The configured identifier represents the personal user library. Numeric group
identifiers are supplied explicitly where a function accepts `library`.

```{r}
zotLibraryPath(Config, library = "user")
zotLibraryPath(Config, library = "5107760")
```

## Read API resources

`zotGet()` performs one request. `zotGetAll()` follows Zotero pagination
headers. The performer below returns three records over two pages.

```{r}
Performer <- function(config, method, path, query, body, version) {
  Page <- if (query$start == 0L) {
    list(list(key = "A", title = "One"), list(key = "B", title = "Two"))
  } else {
    list(list(key = "C", title = "Three"))
  }
  list(status = 200L, headers = list(`total-results` = "3"), body = Page)
}

Config$performer <- Performer
Items <- zotGetAll(
  Config,
  path = paste0(zotLibraryPath(Config), "/items/top"),
  limit = 2L
)
vapply(Items, function(Item) Item$key, character(1L))
```

The default transport returns response status, headers, and parsed content.
Patch requests include the supplied item version, and retry handling is limited
to the response classes documented by `zotRequest()`.

## Use local and semantic data

`zotLocalQuery()` opens the local SQLite database in read-only mode.
`zotLocalItems()` returns a compact item table and excludes records in Trash.
Local data can lag the Web API when the desktop client has not synchronized.

`ztSemantic()` queries an optional Chroma index through the companion Python
environment. It does not create or refresh the index. See
`vignette("external-integrations", package = "zot")` for its runtime
requirements.

## Build a plan

Plan builders return data without applying the represented changes. In this
example, `ztRetitle()` includes only the title changed by the transformation.

```{r}
Candidates <- data.table(
  itemKey = c("A", "B"),
  library = "user",
  title = c("Reviewed book (1).pdf", "Existing title")
)

Plan <- ztRetitle(Candidates, transform = ztCleanTitle)
Plan
```

`zotPreview()` validates the plan, copies its rows, and stores a digest and
summary.

```{r}
Preview <- zotPreview(Plan, describe = "Normalize one reviewed title")
Preview
```

`zotApprove()` creates a record for the preview digest. `zotExecute()` can
then apply the rows and maintain a resumable ledger. These functions do not
establish who reviewed a batch; authorization policy belongs to the calling
application.

Continue with `vignette("guarded-workflow", package = "zot")` for an offline
execution example and `vignette("curation-plans", package = "zot")` for the
other plan builders.
