Skip to content

Commit

Permalink
Merge branch 'improve-api-docs'
Browse files Browse the repository at this point in the history
  • Loading branch information
madadam committed Oct 21, 2024
2 parents 92fca51 + 6826e4c commit 2bfb8fd
Show file tree
Hide file tree
Showing 10 changed files with 160 additions and 85 deletions.
2 changes: 2 additions & 0 deletions .github/workflows/docs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ concurrency:
jobs:
# Build job
build:
if: github.repository == "equalitie/ouisync" # Only run this in the main repo
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
Expand Down Expand Up @@ -74,6 +75,7 @@ jobs:
mkdir -p _site
cp -r target/doc _site/rust
cp -r bindings/kotlin/build/lib/dokka/html _site/kotlin
cp doc/index.html _site/
- name: Upload artifact
uses: actions/upload-pages-artifact@v3
Expand Down
68 changes: 13 additions & 55 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,69 +3,27 @@
[![CI](https://github.com/equalitie/ouisync/actions/workflows/ci.yml/badge.svg)](https://github.com/equalitie/ouisync/actions/workflows/ci.yml)
[![dependency status](https://deps.rs/repo/github/equalitie/ouisync/status.svg)](https://deps.rs/repo/github/equalitie/ouisync)

## Components
This repository contains the Ouisync library and the Ouisync Command Line Interface (CLI) app. The
GUI app is hosted in a [separate repository](https://github.com/equalitie/ouisync-app),

This repository contains two main components: the Ouisync library
([`lib/`](./lib)) containing the core functionality and a command line utility
as a user interface (CLI) for the library ([`cli/`](./cli), currently Linux
only).
## What is Ouisync?

There is also a Graphical User Interface (GUI) app for the library hosted in a
[separate repository](https://github.com/equalitie/ouisync-app).
[Ouisync](https://ouisync.net) is a secure peer-to-peer file syncing app. It's free, open source and
available for all major desktop and mobile platforms.

Apart from the above, this repository also contains a C Foreign Function
Interface (FFI) for use by other languages. An example of its use can be found
in the [Flutter based Ouisync
plugin](https://github.com/equalitie/ouisync-plugin) used by the GUI app.
## Library and bindings

## Building
The Ouisync library is written in rust and is located in the [`lib/`](lib) folder. There are also
bindings available for the following languages:

Note, if you want to build only the CLI application, use the instructions
outlined in the [README.md](./cli/README.md#building) document located in the
[`cli/`](./cli) directory.
- [Dart](bindings/dart/)
- [Kotlin](bindings/kotlin)
- [Swift](bindings/swift) (work in progress)

Ouisync uses a number of other Rust libraries that are downloaded during the
build process. However, to build and use the Ouisync application (as opposed to
just the library), one will additionally need to install the
[FUSE](https://www.kernel.org/doc/html/latest/filesystems/fuse.html) library
and development files.
## The Command Line App

$ sudo apt install pkg-config libfuse-dev

Install Rust using instructions from [rust-lang.org](https://www.rust-lang.org/tools/install).

Build

$ cargo build --release

The results will then be found in the `./target/release/` directory.

## Debugging tests

Use the `tracing::[level]!` macros for easier debugging.

The format for [`RUST_LOG`](https://docs.rs/env_logger/latest/env_logger/) is either

```
RUST_LOG=[level]
```

or

```
RUST_LOG=[target]=[level],[target]=[level],...
```

Where `level` can be one of `error`, `warn`, `info`, `debug` or `trace`. The
`target` can be obtained from the list given by `cargo test --package` and by
replacing dashes (`-`) with underscores (`_`) in the package names.

Ouisync uses
[`tracing_subscriber`](https://docs.rs/tracing-subscriber/latest/tracing_subscriber/filter/struct.EnvFilter.html)
to include information where individual output lines originated from. To enable
this functionality, set the `level` to either `info`, `debug` or `trace`.
The CLI is located in the [`cli/`](cli) folder.

## Testing help acknowlegement

This project is tested with BrowserStack.

39 changes: 27 additions & 12 deletions bindings/kotlin/README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,45 @@
# Ouisync library Kotlin bindings

![Maven Central Version](https://img.shields.io/maven-central/v/ie.equalit.ouinet/ouisync-omni)

This project provides kotlin bindings for the ouisync library in the form of self-contained AAR
package to be used in android apps.

## Prerequisities
## Usage

The Ousiync native library is built automatically but it requires a rust toolchain. The easiest way
to get it is using [rustup](https://rustup.rs/).
Include ouisync with Gradle by adding the following to your `build.gradle` file:

## Build the AAR
```groovy
implementation 'ie.equalit.ouinet:ouisync-omni:$ouisyncVersion'
```

Run `gradle lib:assembleRelease` (or `lib:assembleDebug` for the debug variant), then find the aar
in `build/lib/outputs/aar/lib-release.aar` (or `lib-debug.aar`).
## Documentation

## Run unit tests

Run `gradle lib:test` (See also https://docs.gradle.org/current/userguide/java_testing.html#test_filtering)
API documentation is available at https://docs.ouisync.net/kotlin/.

## Example app

There is a simple example app in the `example` folder. To build it run
There is a simple example app in the [example/](example) folder. To build it run
`gradle example:assembleDebug`, then find the apk in
`build/example/outputs/apk/debug/example-debug.apk`, install and run it on a device or an emulator.

## API documentation
## Build from source

### Prerequisities

The Ousiync native library is built automatically but it requires a rust toolchain. The easiest way
to get it is using [rustup](https://rustup.rs/).

### Build the AAR

Run `gradle lib:assembleRelease` (or `lib:assembleDebug` for the debug variant), then find the aar
in `build/lib/outputs/aar/lib-release.aar` (or `lib-debug.aar`).

### Run unit tests

Run `gradle lib:test` (To run a specific test, see [test filtering](https://docs.gradle.org/current/userguide/java_testing.html#test_filtering)).

### Build the API documentation

Generate the documentation with [dokka](https://kotlinlang.org/docs/dokka-introduction.html#0):
`gradle lib:dokkaHtml` (or use any of the supported formats) then find it in `build/lib/dokka`.

10 changes: 5 additions & 5 deletions bindings/kotlin/example/README.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
# Ouisync Kotlin bindings example app

This is an example app that shows basic usage of the Ouisync library. It's a simple[Jetpack Compose]
This is an example app that shows basic usage of the Ouisync library. It's a simple [Jetpack Compose]
(https://developer.android.com/compose) app. It's structured as follows:

The `ViewModel` demonstates how to initialize Ouisync `Session`, how to configure it, handle errors
The `ViewModel` demonstrates how to initialize Ouisync `Session`, how to configure it, handle errors
and how to close it when the app exists. Additionally it shows how to create new repository
(including importing it with a share token), opening existing repositories from disk, closing
repositories and deleting them.

The UI iself consist of three screens:
The UI itself consist of three screens:

`RepositoryListScreen` is for managing the repositories. It shows how to open/create/import
repositories, how to share repositories using Android Sharesheet and how to delete repositories.
Expand All @@ -18,7 +18,7 @@ subfolders and files. It also shows how to show a "live" view of a folder which
refreshes whenever the repository gets updated by a peer.

Finally `FileScreen` shows how to open a file, monitor it's sync progress and how to read it's
content. Similarry to the `FolderScreen`, it also shows how to automatically refresh the screen
content. Similarly to the `FolderScreen`, it also shows how to automatically refresh the screen
when the file gets updated.

For more andvanced usage, refer to the API docs (TODO: link).
For more advanced usage, refer to the [API docs](https://docs.ouisync.net/kotlin/)
6 changes: 6 additions & 0 deletions bindings/kotlin/lib/docs/module.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,12 @@

## Quick start

Include ouisync with Gradle by adding the following to your `build.gradle` file:

```
implementation "ie.equalit.ouinet:ouisync-omni:$ouisyncVersion"
```

The entry point to Ouisync is the [Session](org.equalitie.ouisync.lib.Session) class. [Create]
(org.equalitie.ouisync.lib.Session.Companion.create) it near the start of the app and make effort
to [close](org.equalitie.ouisync.lib.Session.close) it on app shutdown. Afterwards, use the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@ class Directory private constructor(private val entries: List<DirectoryEntry>) :
}

/**
* Removes file at the given path from the repository.
* Removes a directory at the given path from the repository.
*/
suspend fun remove(repo: Repository, path: String, recursive: Boolean = false) {
repo.client.invoke(DirectoryRemove(repo.handle, path, recursive))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ class File private constructor(private val handle: Long, private val client: Cli
}

/**
* Removes file at the given path from the repository.
* Removes a file at the given path from the repository.
*/
suspend fun remove(repo: Repository, path: String) {
repo.client.invoke(FileRemove(repo.handle, path))
Expand Down Expand Up @@ -62,8 +62,12 @@ class File private constructor(private val handle: Long, private val client: Cli
suspend fun truncate(length: Long) = client.invoke(FileTruncate(handle, length))

/**
* Returns the sync progress of this file, that is, what part of this file (in bytes) is
* available locally.
* Returns the sync progress of this file, that is, the total byte size of all the blocks of
* this file that's already been downloaded.
*
* Note that Ouisync downloads the blocks in random order, so until the file's been completely
* downloaded, the already downloaded blocks are not guaranteed to continuous (they might be
* gaps).
*/
suspend fun progress() = client.invoke(FileProgress(handle)) as Long
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import java.security.SecureRandom
*
* A Ouisync repository.
*
* Example usage:
* ## Example usage:
*
* ```
* // Create a new repo:
Expand All @@ -16,16 +16,47 @@ import java.security.SecureRandom
* // or open an existing one:
* val repo = Repository.open(session, "path/to/the/repo.ouisyncdb")
*
* // Enable syncing with other replicas
*
* repo.setSyncEnabled(true)
*
* // Access the repository files (see File, Directory) ...
*
* val file = File.open(repo, "path/to/file")
*
* // Close it when done:
* repo.close()
* ```
*
* ## Access repository content
*
* For info about how to access and modify the repository content see [File] and [Directory].
*
* ## Share repository with peers
*
* To share a repository, create the share token with [createShareToken], send it to the peer
* (e.g., via a secure instant messenger, encode as QR code and scan, ...), then create a
* repository on the peer's device with [create], passing the share token to it.
*
* ## Sync repository with peers
*
* Enable syncing with [setSyncEnabled]. Afterwards Ouisync will try to automatically find peers to
* sync with using various peer discovery methods (Local Discovery, DHT, PEX). Additionally, peers
* can be added manually with [Session.addUserProvidedPeer].
*
* ## Local secrets
*
* Local secrets protect the repository against unauthorized access on the same device and should
* never be shared with anyone (to share the repository with peers, use the *share token*). To
* change the local secrets, use [setAccess]. To check whether the repository is read or write
* protected, use [requiresLocalSecretForReading] and [requiresLocalSecretForWriting] respectively.
*
* ## Cache servers
*
* Cache servers relay traffic between peers who can't directly connect to each other. They also
* temporarily cache the repository content in order to allow peers to sync even when they are not
* online at the same time. See [createMirror], [deleteMirror] and [mirrorExists] for more details.
*
* @see Session
* @see File
* @see Directory
Expand Down Expand Up @@ -183,6 +214,10 @@ class Repository private constructor(internal val handle: Long, internal val cli

/**
* Switches the repository to the given access mode.
*
* @param accessMode desired access mode to switch to.
* @param secret [local secret](setAccess) protecting the desired access mode. Can be `null` if
* no local secret is used.
*/
suspend fun setAccessMode(
accessMode: AccessMode,
Expand All @@ -206,6 +241,29 @@ class Repository private constructor(internal val handle: Long, internal val cli
/**
* Sets, unsets or changes local secrets for accessing the repository or disables the given
* access mode.
*
* ## Examples
*
* To protect both read and write access with the same password:
*
* ```
* val password = LocalPassword("supersecret")
* repo.setAccess(read: EnableAccess(password), write: EnableAccess(password))
* ```
*
* To require password only for writing:
*
* ```
* repo.setAccess(read: EnableAccess(null), write: EnableAccess(password))
* ```
*
* To competelly disable write access but leave read access as it was. Warning: this operation
* is currently irreversibe.
*
* ```
* repo.setAccess(write: DisableAccess)
* ```
*
*/
suspend fun setAccess(read: AccessChange? = null, write: AccessChange? = null) =
client.invoke(RepositorySetAccess(handle, read, write))
Expand Down Expand Up @@ -242,32 +300,38 @@ class Repository private constructor(internal val handle: Long, internal val cli
client.invoke(RepositorySetPexEnabled(handle, enabled))

/**
* Returns the synchronization progress of this repository
* Returns the synchronization progress of this repository as the number of bytes already
* synced ([Progress.value]) vs the total size of the repository in bytes ([Progress.total]).
*/
suspend fun syncProgress() = client.invoke(RepositorySyncProgress(handle)) as Progress

/**
* Create mirror of this repository on the cache server.
*
* Cache servers relay traffic between Ouisync peers and also temporarily store data. They are
* Requires the repository to be opened in write mode.
* useful when direct P2P connection fails (e.g. due to restrictive NAT) and also to allow
* syncing when the peers are not online at the same time (they still need to be online within
* ~24 hours of each other).
*
* Requires the repository to be opened in write mode.
*
* @param host hostname (or ip address + port) of the cache server.
*/
suspend fun createMirror(host: String) = client.invoke(RepositoryCreateMirror(handle, host))

/**
* Delete mirrors of this repository from the cache server.
* Delete mirror of this repository from the cache server.
*
* Requires the repository to be opened in write mode.
*
* @param host hostname (or ip address + port) of the cache server.
*/
suspend fun deleteMirror(host: String) = client.invoke(RepositoryDeleteMirror(handle, host))

/**
* Check if this repository is mirrored on the cache server.
*
* @param host hostname (or ip address + port) of the cache server.
*/
suspend fun mirrorExists(host: String) = client.invoke(RepositoryMirrorExists(handle, host))

Expand Down
Loading

0 comments on commit 2bfb8fd

Please sign in to comment.