docs: move README to docs directory
Signed-off-by: NotAShelf <raf@notashelf.dev> Change-Id: Ib33692d5571e50cc86dcab0b881278206a6a6964
This commit is contained in:
parent
79d0eadb65
commit
034d688be7
2 changed files with 239 additions and 239 deletions
239
docs/README.md
Normal file
239
docs/README.md
Normal file
|
|
@ -0,0 +1,239 @@
|
|||
# Pinakes
|
||||
|
||||
[first known library cataloging system]: https://en.wikipedia.org/wiki/Pinakes
|
||||
|
||||
Pinakes, named after the [first known library cataloging system] designed to be
|
||||
the _last library cataloging system you will ever need_. Pinakes indexes files
|
||||
across configured directories, extracts metadata from audio, video, document and
|
||||
text files, and provides full-text search with tagging, collections, roles,
|
||||
audit logging and more. It supports both SQlite (for easy bootstrapping) and
|
||||
PostgreSQL (production deployments) as available database backends.
|
||||
|
||||
## Building
|
||||
|
||||
```bash
|
||||
# Build all compilable crates
|
||||
$ cargo build -p pinakes-core -p pinakes-server -p pinakes-tui
|
||||
|
||||
# The Dioxus UI requires GTK3 and libsoup system libraries:
|
||||
# On Debian/Ubuntu: apt install libgtk-3-dev libsoup-3.0-dev libwebkit2gtk-4.1-dev
|
||||
# On Fedora: dnf install gtk3-devel libsoup3-devel webkit2gtk4.1-devel
|
||||
# On Nix: Use the dev shell, everything is provided :)
|
||||
$ cargo build -p pinakes-ui
|
||||
|
||||
# Alternatively, while app deps are in PATH, you may simply build the entire
|
||||
# workspace.
|
||||
$ cargo build --workspace
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Pinakes runs with its own built-in configuration file out of the box. While
|
||||
using the default configuration, you will not be able to edit the configuration
|
||||
but it will provide the minimum required configuration values to get you going
|
||||
with Pinakes. If you are more interested in fully configuring Pinakes, you must
|
||||
create your own configuration. You may copy the example config and edit it to
|
||||
your needs:
|
||||
|
||||
```bash
|
||||
# Copy the sample config
|
||||
$ cp pinakes.example.toml pinakes.toml
|
||||
```
|
||||
|
||||
Key settings:
|
||||
|
||||
- `storage.backend` - `"sqlite"` or `"postgres"`
|
||||
- `storage.sqlite.path` - Path to the SQLite database file
|
||||
- `storage.postgres.*` - PostgreSQL connection parameters
|
||||
- `directories.roots` - Directories to scan for media files
|
||||
- `scanning.watch` - Enable filesystem watching for automatic imports
|
||||
- `scanning.ignore_patterns` - Patterns to skip during scanning (e.g., `".*"`,
|
||||
`"node_modules"`)
|
||||
- `server.host` / `server.port` - Server bind address
|
||||
|
||||
## Running
|
||||
|
||||
### Server
|
||||
|
||||
To use Pinakes, you will need the server to be running. The GUI on its own will
|
||||
work, but it will not be functional without the server.
|
||||
|
||||
```sh
|
||||
# Start the server first
|
||||
$ cargo run -p pinakes-server -- pinakes.toml
|
||||
|
||||
# or:
|
||||
$ cargo run -p pinakes-server -- --config pinakes.toml
|
||||
```
|
||||
|
||||
The server starts on the configured host:port (default `127.0.0.1:3000`). In a
|
||||
production scenario you are encouraged to reverse proxy the service, and prefer
|
||||
SSL.
|
||||
|
||||
### TUI
|
||||
|
||||
The Pinakes TUI can be used to manage your collections from the comfort of your
|
||||
terminal. While the server is running you may connect to it using the `--server`
|
||||
flag.
|
||||
|
||||
```bash
|
||||
# Using defaults
|
||||
$ cargo run -p pinakes-tui
|
||||
|
||||
# or with a custom server URL:
|
||||
$ cargo run -p pinakes-tui -- --server http://localhost:3000
|
||||
```
|
||||
|
||||
#### Keybindings
|
||||
|
||||
The TUI component of Pinakes is designed to be keyboard-centric, as it is
|
||||
designed for the terminal. The keybindings are as follows:
|
||||
|
||||
<!-- markdownlint-disable MD013-->
|
||||
|
||||
| Key | Action |
|
||||
| --------------------- | -------------------------------------------------------- |
|
||||
| `q` / `Ctrl-C` | Quit |
|
||||
| `j` / `k` | Navigate down / up |
|
||||
| `Enter` | Select / confirm |
|
||||
| `Esc` | Back |
|
||||
| `/` | Search |
|
||||
| `i` | Import file |
|
||||
| `o` | Open file |
|
||||
| `d` | Delete (media in library, tag/collection in their views) |
|
||||
| `t` | Tags view |
|
||||
| `c` | Collections view |
|
||||
| `a` | Audit log view |
|
||||
| `s` | Trigger scan |
|
||||
| `r` | Refresh current view |
|
||||
| `n` | Create new tag (in tags view) |
|
||||
| `+` | Tag selected media (in detail view) |
|
||||
| `-` | Untag selected media (in detail view) |
|
||||
| `Tab` / `Shift-Tab` | Next / previous tab |
|
||||
| `PageUp` / `PageDown` | Paginate |
|
||||
|
||||
<!-- markdownlint-enable MD013-->
|
||||
|
||||
### Desktop/Web UI
|
||||
|
||||
Pinakes features a fully fledged Desktop and Web UI powered by Dioxus. Those two
|
||||
components are meant as a GUI frontend for the Pinakes server, and are
|
||||
interchangeable in terms of usage.
|
||||
|
||||
```bash
|
||||
# Build the UI
|
||||
$ cargo run -p pinakes-ui
|
||||
```
|
||||
|
||||
> [!TIP]
|
||||
> By default Pinakes GUI will assume the server to be running on localhost and
|
||||
> bound to port 3000. Set `PINAKES_SERVER_URL` to point at the server if it is
|
||||
> not on `localhost:3000`.
|
||||
|
||||
## API
|
||||
|
||||
There exists a comprehensive UI for the server component that you may query
|
||||
directly from the `/api/v1` endpoint. All other endpoints are under `/api/v1`.
|
||||
|
||||
### Media
|
||||
|
||||
| Method | Path | Description |
|
||||
| -------- | -------------------- | ------------------------------------- |
|
||||
| `POST` | `/media/import` | Import a file (`{"path": "..."}`) |
|
||||
| `GET` | `/media` | List media (query: `offset`, `limit`) |
|
||||
| `GET` | `/media/{id}` | Get media item |
|
||||
| `PATCH` | `/media/{id}` | Update metadata |
|
||||
| `DELETE` | `/media/{id}` | Delete media item |
|
||||
| `GET` | `/media/{id}/stream` | Stream file content |
|
||||
| `POST` | `/media/{id}/open` | Open with system viewer |
|
||||
|
||||
### Search
|
||||
|
||||
| Method | Path | Description |
|
||||
| ------ | --------------- | ---------------------------------------------- |
|
||||
| `GET` | `/search?q=...` | Search (query: `q`, `sort`, `offset`, `limit`) |
|
||||
|
||||
Search syntax: `term`, `"exact phrase"`, `field:value`, `type:pdf`, `tag:music`,
|
||||
`prefix*`, `fuzzy~`, `-excluded`, `a b` (AND), `a OR b`, `(grouped)`.
|
||||
|
||||
### Tags
|
||||
|
||||
<!-- markdownlint-disable MD013-->
|
||||
|
||||
| Method | Path | Description |
|
||||
| -------- | --------------------------- | ------------------------------------------------ |
|
||||
| `POST` | `/tags` | Create tag (`{"name": "...", "parent_id": ...}`) |
|
||||
| `GET` | `/tags` | List all tags |
|
||||
| `GET` | `/tags/{id}` | Get tag |
|
||||
| `DELETE` | `/tags/{id}` | Delete tag |
|
||||
| `POST` | `/media/{id}/tags` | Tag media (`{"tag_id": "..."}`) |
|
||||
| `GET` | `/media/{id}/tags` | List media's tags |
|
||||
| `DELETE` | `/media/{id}/tags/{tag_id}` | Untag media |
|
||||
|
||||
<!-- markdownlint-enable MD013-->
|
||||
|
||||
### Collections
|
||||
|
||||
| Method | Path | Description |
|
||||
| -------- | ---------------------------------- | ----------------- |
|
||||
| `POST` | `/collections` | Create collection |
|
||||
| `GET` | `/collections` | List collections |
|
||||
| `GET` | `/collections/{id}` | Get collection |
|
||||
| `DELETE` | `/collections/{id}` | Delete collection |
|
||||
| `POST` | `/collections/{id}/members` | Add member |
|
||||
| `GET` | `/collections/{id}/members` | List members |
|
||||
| `DELETE` | `/collections/{cid}/members/{mid}` | Remove member |
|
||||
|
||||
Virtual collections (kind `"virtual"`) evaluate their `filter_query` as a search
|
||||
query when listing members, returning results dynamically.
|
||||
|
||||
### Audit & Scanning
|
||||
|
||||
<!-- markdownlint-disable MD013-->
|
||||
|
||||
| Method | Path | Description |
|
||||
| ------ | -------- | ----------------------------------------------------------------------------- |
|
||||
| `GET` | `/audit` | List audit log (query: `offset`, `limit`) |
|
||||
| `POST` | `/scan` | Trigger directory scan (`{"path": "/..."}` or `{"path": null}` for all roots) |
|
||||
|
||||
<!-- markdownlint-enable MD013-->
|
||||
|
||||
## Testing
|
||||
|
||||
```sh
|
||||
# Unit and integration tests for the core library (SQLite in-memory)
|
||||
cargo test -p pinakes-core
|
||||
|
||||
# API integration tests for the server
|
||||
cargo test -p pinakes-server
|
||||
```
|
||||
|
||||
## Supported Media Types
|
||||
|
||||
| Category | Formats |
|
||||
| -------- | ------------------------------- |
|
||||
| Audio | MP3, FLAC, OGG, WAV, AAC, Opus |
|
||||
| Video | MP4, MKV, AVI, WebM |
|
||||
| Document | PDF, EPUB, DjVu |
|
||||
| Text | Markdown, Plain text |
|
||||
| Image | JPEG, PNG, GIF, WebP, SVG, AVIF |
|
||||
|
||||
Metadata extraction uses lofty (audio, MP4), matroska (MKV), lopdf (PDF), epub
|
||||
(EPUB), and gray_matter (Markdown frontmatter).
|
||||
|
||||
## Storage Backends
|
||||
|
||||
Two storage backends are supported. For convenience, SQLite is the default
|
||||
backend out of the box but for production deployments you may choose to prefer
|
||||
PostgreSQL.
|
||||
|
||||
### **SQLite** (default)
|
||||
|
||||
Single-file database with WAL mode and FTS5 full-text search. Bundled SQLite
|
||||
guarantees FTS5 availability.
|
||||
|
||||
### **PostgreSQL**
|
||||
|
||||
Native async with connection pooling (deadpool-postgres). Uses tsvector with
|
||||
weighted columns for full-text search and pg_trgm for fuzzy matching. Requires
|
||||
the `pg_trgm` extension.
|
||||
Loading…
Add table
Add a link
Reference in a new issue