Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
16 commits
Select commit Hold shift + click to select a range
95de3c0
Laid the foundation for the complete notes API with a shared request …
i2h3 Oct 6, 2026
4dea0a2
Modelled the path, the shares and the newer settings of notes and tau…
i2h3 Oct 6, 2026
058150e
Surfaced the sync headers of the notes listing and added a conditiona…
i2h3 Oct 6, 2026
89acc4b
Added the chunked listing of changed notes as single chunks and as a …
i2h3 Oct 6, 2026
4bb5f1e
Added the retrieval of a single note by its identifier, also conditio…
i2h3 Oct 6, 2026
fbfff70
Added creating, changing and deleting notes and turned the notes comm…
i2h3 Oct 6, 2026
e74187c
Added changing the settings of the notes app and taught the notes-set…
i2h3 Oct 6, 2026
6e42744
Added retrieving, downloading, adding and deleting the attachments of…
i2h3 Oct 6, 2026
cc11def
Added pure helpers which predict the title and category of a note and…
i2h3 Oct 6, 2026
9246e93
Added listing the summaries of changed notes without their text, in a…
i2h3 Oct 6, 2026
0e7b0c7
Added a choice of transport for server events and made the automatic …
i2h3 Oct 6, 2026
77747eb
Added polling a login flow which returns nil while it is pending and …
i2h3 Oct 6, 2026
771affa
Added looking up the identifier and the display name of the authentic…
i2h3 Oct 6, 2026
06979ba
Prepared the release of 5.0.0 with articles on synchronizing notes an…
i2h3 Oct 6, 2026
084719e
Addressed the review of the complete notes API support
i2h3 Oct 6, 2026
0b70229
Redacted the login flow tokens and app passwords left in the login fi…
i2h3 Oct 6, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
31 changes: 21 additions & 10 deletions AGENTS.md

Large diffs are not rendered by default.

10 changes: 9 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,17 @@
[![Tests](https://github.com/i2h3/rainmaker/actions/workflows/test.yml/badge.svg)](https://github.com/i2h3/rainmaker/actions/workflows/test.yml)
[![REUSE](https://api.reuse.software/badge/github.com/i2h3/rainmaker)](https://api.reuse.software/info/github.com/i2h3/rainmaker)

A simple Swift library and CLI to access [Nextcloud](https://www.nextcloud.com) programmatically: files, notifications, activities, notes, collectives and Talk conversations.
A simple Swift library and CLI to access [Nextcloud](https://www.nextcloud.com) programmatically: files, notifications, activities, notes (including incremental and chunked synchronization, summaries without their text, conflict detection, attachments, and helpers which predict a note's title and category and reference attachments from its content the way the notes and Text apps do), collectives, Talk conversations and the current user.
The library keeps no state between calls and needs no synchronization engine, so it suits a single action such as one of Shortcuts as well as a client keeping its own copy of an account's data.
For further information, see [the documentation which is built from the source code and deployed to GitHub pages](https://i2h3.github.io/rainmaker/).

## Requirements

- Swift 6.2 or newer.
- iOS 15, macOS 12, tvOS 15, visionOS 1 or watchOS 8 or newer.
- A Nextcloud server. Every release is verified against the versions listed in `ServerVersion` in `Sources/RainmakerTestServerTags/`, currently Nextcloud 31, 32, 33 and 34.
- For the notes features, the notes app serving its API in version 1.4 or newer, which it does since release 4.12.3. Deleting attachments and keeping them in a folder per note require release 6.1.0 or newer.

## Testing

The test suite uses static fixtures committed under `Tests/RainmakerTests/Responses/` and isolated request doubles, so `swift test` needs no server and runs on every platform.
Expand Down
138 changes: 134 additions & 4 deletions Sources/Rainmaker/Documentation.docc/CommandLineInterface.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ This package also provides a convenient executable to leverage the features of t

## Overview

You can get an overview by running the command line interface itself or any subcommand with the `--help` option in the package root directory like this:
You can get an overview by running the command line interface itself or any subcommand with the `--help` option in the package root directory like this, shown here and below without the line wrapping a terminal applies:

```plaintext
$ swift run rainmaker-cli --help
Expand All @@ -20,6 +20,7 @@ SUBCOMMANDS:
collectives List the collectives of the authenticated user and their pages. Requires authentication and the server's collectives app.
conversations List the Talk conversations of the authenticated user and retrieve their images. Requires authentication and the server's Talk app.
create-directory Create a directory on the server.
current-user Show the identifier and the display name of the authenticated account. Requires authentication.
delete Delete a file or directory from the server.
delete-app-password Delete the app password currently used to authenticate, ending the session on the server side.
download Download a file or directory from the server.
Expand All @@ -28,17 +29,146 @@ SUBCOMMANDS:
login Fetch the login flow information from a server.
move Move or rename a remote file or directory on the server.
navigation List the apps navigation entries advertised by a server. Requires authentication.
notes List the notes of the authenticated user. Requires authentication and the server's notes app.
notes-settings Show where the notes app stores the notes of the authenticated user. Requires authentication and the server's notes app.
notes List, retrieve, create, change and delete the notes of the authenticated user and their attachments. Requires authentication and the server's notes app.
notes-settings Show or change where and how the notes app stores the notes of the authenticated user. Requires authentication and the server's notes app.
notifications List the notifications queued for the authenticated user. Requires authentication and the server's notifications app.
poll Poll the status of a previously initiated login flow.
trash Manage the server trash bin.
upload Upload a file or directory to a folder on the server.
watch Observe server-side changes over notify_push (or polling when unavailable) and print each event. Runs until interrupted.
watch Observe server-side changes over notify_push (or polling when unavailable or asked to) and print each event. Runs until interrupted.
record-fixtures Record test fixtures by deploying Nextcloud containers and running the test suite against them.

See 'rainmaker help <subcommand>' for detailed help.
```

## Notes

The `notes` command is a group of subcommands, of which `list` is the default, so `notes --changed-since` keeps working as before.
Attachments are managed by the nested `notes attachment` group, and the settings of the notes app by the separate `notes-settings` command.
In the plain output, a listing of changes ends with a `#cursor` line while more chunks follow, an `#etag` line and a `#last-modified` line in whole seconds since the Unix epoch, which are what `--cursor`, `--if-none-match` and `--changed-since` take for the next listing, while `notes get` writes the note's `#etag` line to standard error so that standard output stays the text of the note.

```plaintext
$ swift run rainmaker-cli notes --help
OVERVIEW: List, retrieve, create, change and delete the notes of the authenticated user and their attachments. Requires authentication and the server's notes app.

USAGE: rainmaker notes <subcommand>

OPTIONS:
-h, --help Show help information.

SUBCOMMANDS:
list (default) List the notes of the authenticated user, all of them, those changed since a moment, or one chunk of those.
get Retrieve a single note of the authenticated user by its identifier.
create Create a note for the authenticated user and print its identifier, entity tag and title.
update Change a note of the authenticated user and print its identifier, entity tag and title.
delete Delete a note of the authenticated user.
attachment Retrieve, add and delete the files attached to a note of the authenticated user.

See 'rainmaker help notes <subcommand>' for detailed help.
```

```plaintext
$ swift run rainmaker-cli notes attachment --help
OVERVIEW: Retrieve, add and delete the files attached to a note of the authenticated user.

USAGE: rainmaker notes attachment <subcommand>

OPTIONS:
-h, --help Show help information.

SUBCOMMANDS:
get Retrieve a file attached to a note of the authenticated user.
add Attach a local file to a note of the authenticated user and print the path the server stored it at.
delete Delete a file attached to a note of the authenticated user. Requires the notes app 6.1.0 or newer.

See 'rainmaker help notes attachment <subcommand>' for detailed help.
```

```plaintext
$ swift run rainmaker-cli notes-settings --help
OVERVIEW: Show or change where and how the notes app stores the notes of the authenticated user. Requires authentication and the server's notes app.

USAGE: rainmaker notes-settings [--user <user>] [--password <password>] [--output-format <output-format>] [--host <host>] [--notes-path <notes-path>] [--file-suffix <file-suffix>] [--note-mode <note-mode>] [--show-hidden-files <show-hidden-files>] [--load-recent-note-on-start-up <load-recent-note-on-start-up>]

OPTIONS:
-u, --user <user> The user account name to authenticate with. Can also be set via RAINMAKER_USER environment variable.
-p, --password <password>
The password to authenticate with. Can also be set via RAINMAKER_PASSWORD environment variable.
--output-format <output-format>
In what form to render the output. (default: plain)
-h, --host <host> The Nextcloud instance to connect to. Can also be set via RAINMAKER_HOST environment variable.
--notes-path <notes-path>
Store the notes in this folder, relative to the account's files, with an empty string for the root folder. Existing notes are not moved.
--file-suffix <file-suffix>
Give the notes created from now on this file extension, such as '.md' or '.txt'.
--note-mode <note-mode> Open notes in the web interface in this mode. (values: rich, edit, preview)
--show-hidden-files <show-hidden-files>
Whether files and folders whose names start with a dot are listed as notes and categories, 'true' or 'false'. Requires notes app 6.1.0 or newer.
--load-recent-note-on-start-up <load-recent-note-on-start-up>
Whether the web interface opens the most recently edited note when it starts, 'true' or 'false'. Requires notes app 6.1.0 or newer.
-h, --help Show help information.
```

## Current User

```plaintext
$ swift run rainmaker-cli current-user --help
OVERVIEW: Show the identifier and the display name of the authenticated account. Requires authentication.

USAGE: rainmaker current-user [--user <user>] [--password <password>] [--output-format <output-format>] [--host <host>]

OPTIONS:
-u, --user <user> The user account name to authenticate with. Can also be set via RAINMAKER_USER environment variable.
-p, --password <password>
The password to authenticate with. Can also be set via RAINMAKER_PASSWORD environment variable.
--output-format <output-format>
In what form to render the output. (default: plain)
-h, --host <host> The Nextcloud instance to connect to. Can also be set via RAINMAKER_HOST environment variable.
-h, --help Show help information.
```

## Login

`login` starts a login flow and prints the login page to open in a browser together with the poll address and the poll token, which `poll` takes to wait for the app password.
While the flow is pending, `poll` tries again every second, and any real failure, such as an unreachable server or an address which is not a login flow endpoint, ends it with that error.

```plaintext
$ swift run rainmaker-cli poll --help
OVERVIEW: Poll the status of a previously initiated login flow.

USAGE: rainmaker poll [--output-format <output-format>] <endpoint> <token> [--tries <tries>]

ARGUMENTS:
<endpoint> The address which to poll for login flow status.
<token> The token to identify the login flow.

OPTIONS:
--output-format <output-format>
In what form to render the output. (default: plain)
--tries <tries> How many times the endpoint should be polled before failing. (default: 300)
-h, --help Show help information.
```

## Observing Changes

```plaintext
$ swift run rainmaker-cli watch --help
OVERVIEW: Observe server-side changes over notify_push (or polling when unavailable or asked to) and print each event. Runs until interrupted.

USAGE: rainmaker watch [--user <user>] [--password <password>] [--host <host>] [--poll-interval <poll-interval>] [--transport <transport>] [--listen-file-ids]

OPTIONS:
-u, --user <user> The user account name to authenticate with. Can also be set via RAINMAKER_USER environment variable.
-p, --password <password>
The password to authenticate with. Can also be set via RAINMAKER_PASSWORD environment variable.
-h, --host <host> The Nextcloud instance to connect to. Can also be set via RAINMAKER_HOST environment variable.
--poll-interval <poll-interval>
The polling interval in seconds used when notify_push is unavailable or not used. (default: 30.0)
--transport <transport> How to learn about changes: 'automatic' prefers notify_push and polls when it is unavailable, 'polling' only polls. (values: automatic, polling; default: automatic)
--listen-file-ids Request per-file identifiers via notify_file_id.
-h, --help Show help information.
```

## Authentication

You can provide credentials directly as command-line options:
Expand Down
Loading
Loading