A future-proof media management suite, designed to be your last.
  • Rust 89.3%
  • Markdown 4.7%
  • SCSS 3%
  • CSS 2.8%
  • Nix 0.1%
Find a file
NotAShelf 520489ab48
docs: finalize hacking guidelines
Signed-off-by: NotAShelf <raf@notashelf.dev>
Change-Id: I2d3a5a9d745630f5da305664f0bdc66e6a6a6964
2026-03-23 03:30:56 +03:00
.cargo chore: add cargo xtask alias 2026-03-22 22:04:53 +03:00
crates meta: move public crates to packages/ 2026-03-23 03:30:53 +03:00
docs docs: finalize hacking guidelines 2026-03-23 03:30:56 +03:00
migrations nix: set up project-wide formatter 2026-03-22 23:58:28 +03:00
nix nix: drop sccache 2026-03-23 03:30:47 +03:00
packages meta: move public crates to packages/ 2026-03-23 03:30:53 +03:00
xtask chore: generate a documentation index for REST API docs in docs/api 2026-03-23 03:30:55 +03:00
.clippy.toml chore: enforce rustc_hash over std hashers 2026-03-22 22:04:36 +03:00
.deny.toml chore: simplify cargo-deny configuration 2026-03-19 20:06:09 +03:00
.editorconfig meta: set up editorconfig 2026-03-22 23:58:29 +03:00
.envrc initial commit 2026-01-31 15:20:30 +03:00
.gitattributes meta: configure gitattributes; don't diff churn 2026-03-22 22:05:03 +03:00
.gitignore meta: ignore Nix build results properly 2026-03-22 22:04:37 +03:00
.rustfmt.toml chore: force explicit ABI in rustfmt 2026-03-08 15:48:03 +03:00
Cargo.lock meta: move public crates to packages/ 2026-03-23 03:30:53 +03:00
Cargo.toml meta: move public crates to packages/ 2026-03-23 03:30:53 +03:00
flake.lock nix: set up project-wide formatter 2026-03-22 23:58:28 +03:00
flake.nix nix: set up project-wide formatter 2026-03-22 23:58:28 +03:00
justfile meta: set up Just for general maintenance tasks 2026-03-22 23:58:26 +03:00
LICENSE meta: release under EUPL v1.2 2026-03-23 03:30:52 +03:00
pinakes.example.toml chore: update sample configuration with new plugin fields 2026-03-08 15:25:12 +03:00

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

This project uses Just as its command runner to help run cargo with a consistent interface. You are recommended to get it with Nix, using the default devshell which provides Just.

# Build everything (core crates + UI)
$ just build

# Build only core crates (cargo)
$ just build-core

# Build only the UI (uses dx - see note below)
$ just build-ui

Important

The Dioxus UI (pinakes-ui) must be built with dx (Dioxus CLI) to compile SCSS stylesheets. Using cargo build -p pinakes-ui will not work correctly as it skips the SCSS compilation step. This was previously "remedied" with an intermediate build wrapper, which turned out to be fragile. It is highly recommended that you prefer just to build.

Manual build commands if not using Just:

# Core crates (standard cargo)
$ cargo build -p pinakes-core -p pinakes-server -p pinakes-tui

# UI (requires Dioxus CLI for SCSS compilation)
$ dx build -p pinakes-ui

# System dependencies for the UI:
# 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 :)

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:

# 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

All commands are available via Just. Run just --list to see all available recipes.

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.

# Using Just
$ just run-server

# Or manually:
$ cargo run -p pinakes-server -- 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.

# Using Just
$ just run-tui

# Or manually:
$ cargo run -p pinakes-tui

Keybindings

The TUI component of Pinakes is designed to be keyboard-centric, as it is designed for the terminal. The keybindings are as follows:

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

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.

Important

The UI must be run with dx (Dioxus CLI), not cargo run.

# Using Just
$ just run-ui

# Or manually with dx:
$ dx serve -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.

Extending Pinakes

While Pinakes does aim to be as comprehensive as humanly possible, it is not feasible to maintain all features in one gigantic repository without taking on an immense technical debt. To avoid this kind of resource mismanagement while still allowing for all kinds of extension, Pinakes features two features at your convenience:

  • REST API Routes
  • Plugin API

REST 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.

The server API is, of course, a part of Pinakes core design but it is also how first-party interfaces like pinakes-ui and pinakes-tui interact with the server. You may write your own interfaces for a running Pinakes server with minimal effort by simply sending requests to the API through your preferred means. See REST API documentation on available routes and tips on how to interact with the API.

Plugin API

The other method, which is by far the most powerful but also perhaps the least polished as of writing is the plugin system. This is designed as a means of implementing various user-facing features to Pinakes server by writing your own plugins that can modify certain elements. While this system is not as stable as the server API, it is generally in good shape and example plugins are provided. Please see the Plugin API documentation for more details, examples and design.

Storage Backends

Two storage backends are supported. For convenience, SQLite is the default backend out of the box but for production deployments, with improved search and scaling capabilities you may choose to prefer PostgreSQL. Both backends are considered first-class citizens, and will be developed as such going further. If your needs for Pinakes are modest, or if you are simply testing it out, SQLite is the recommended database.

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.

Contributing

Pinakes, despite all the work going into it, is still in an early beta. Some of the features still lack the polish they deserve and there may be breaking changes to the UI, databases, and the APIs. You may find a comprehensive introduction to developing Pinakes in the HACKING document.

It is generally advisable that you familiarize yourself with the codebase before proposing or contributing changes. Pinakes consists of many moving parts, and it is better for the contributor experience to approach issues slowly and discuss them beforehand.

License

This project is made available under European Union Public Licence (EUPL) version 1.2. See LICENSE for more details on the exact conditions. An online copy is provided here.