brybox
A personal automation toolkit for PC organization. Brybox replaces a pile of one-off scripts with a single, cohesive library that sorts PDFs, normalizes photo and video libraries, triages an email inbox, and pulls documents out of web portals that don't offer a real API — all driven by config files instead of hardcoded paths.
It is not a general-purpose framework: several subsystems are wired to specific, personal accounts (a Gmail inbox, a handful of German insurance / banking / utility portals, Amazon.de). Treat it as a working example of the architecture as much as a tool to run as-is.
What it does
| Subsystem | Problem it solves |
|---|---|
| PixelPorter / MotionPorter | Ingest a camera-roll dump: stage → dedup → normalize filenames/metadata for photos and videos in one pass. |
| SnapJedi | Convert HEIC/HEIF to JPG and rename to a timestamped, timezone-aware filename. Deletes Apple sidecar files (.aae, .xmp, ._*). |
| VideoSith | Convert MOV to MP4 (stream-copy, falls back to re-encode), rewrite EXIF/GPS/creation-date metadata, rename by timestamp. |
| Doctopus | Classify PDFs (bills, statements, ...) by keyword triggers, extract a date and invoice ID, file them into category folders. |
| DoiSmith | Resolve an academic PDF's DOI against the CrossRef API and rename it Author (Year) - Title.pdf. |
| Audiora | Sort loose audio recordings into category/date session_name.ext using trigger-word rules and EXIF-style metadata. |
| ZipWarden | Extract and flatten ZIP archives (e.g. bank statement bundles) before handing the contents to another processor. |
| InboxKraken | Poll a Gmail inbox over IMAP, classify messages by rule, and dispatch to a handler: download a PDF/attachment, grab a Dropbox link, trigger a web scraper, or delete. |
| web_marionette | Playwright-driven browser automation that logs into real portals (Gothaer, KfW, Techem, Amazon.de) and downloads documents a plain HTTP scraper couldn't reach. |
Every file-mutating operation across these subsystems publishes to an
internal event bus; DirectoryVerifier subscribes to it and can diff the
events a batch job claimed to perform against what's actually on disk —
useful for confirming a pipeline run did what it said it did.
Requirements
- Python 3.12+
- uv for dependency management
- System binaries on
PATH:exiftool, ImageMagick,ffmpeg - Playwright's Chromium build (not installed by
uv sync— see below)
Installation
git clone https://github.com/bryanbarcelona/brybox.git
cd brybox
uv sync
uv run playwright install chromium
Configuration
Brybox is entirely config- and env-var-driven; nothing is hardcoded to a path or account.
Config files — copy each template under configs/ and drop the
.example, then fill in real values:
| Template | Feeds |
|---|---|
audiora_rules.example.json |
Audiora category/trigger rules |
doctopus_sorting_rules.example.json |
Doctopus category/trigger rules |
extraction_rules.example.json |
Doctopus date/invoice-ID extraction regexes |
metadata_triggers.example.json |
Doctopus metadata trigger keywords |
email_rules.example.json |
InboxKraken classification rules |
email_delete_list.example.json / .example.csv |
InboxKraken unconditional-delete senders |
paths.example.json |
Email save directory, DoiSmith literature directory |
pixelporter_paths.example.json |
PixelPorter / MotionPorter source and target folders |
Files are resolved in priority order: an explicit path, then the OS user
config directory (platformdirs.user_config_dir('brybox')), then
./configs relative to the working directory. A single logical config can
be split across multiple files/formats (e.g. both .json and .csv) — the
loader merges them and the most recently modified source wins on conflicts.
Environment variables — create a .env file (loaded via
python-dotenv):
# Gmail IMAP (InboxKraken) — required, needs a Google App Password
EMAIL=
APP_PWD=
IMAP_SERVER=imap.gmail.com
IMAP_PORT=993
# web_marionette portal logins — only required for the scrapers you use
USER_MAIN=
TECHEM_PWD=
USER_KFW=
KFW_PWD=
USER_GOTHAER=
GOTHAER_PWD=
USER_AMAZON=
AMAZON_PWD=
AMAZON_TOTP_SECRET=
Usage
Everything is re-exported from the package root:
from brybox import push_photos, push_videos, SnapJedi, Doctopus, InboxKraken
# Ingest a camera-roll dump: stage, dedup, normalize
push_photos('D:/Camera Uploads', 'D:/Photos')
push_videos('D:/Camera Uploads', 'D:/Videos')
# Sort a single PDF into its category folder
DoctopusPrime('D:/Downloads/invoice.pdf').process()
# Triage the inbox without touching anything (dry_run is the default)
with InboxKraken() as kraken:
kraken.preview()
Batch variants follow a <Thing>Nexus naming pattern
(AudioraNexus, DoctopusPrimeNexus, ZipWardenNexus, ...) — same
processing logic, applied to every file in a directory, with per-file error
isolation so one bad file doesn't abort the run.
Development
uv sync --all-extras --dev
uv run ruff check .
uv run ruff format .
uv run ty check
uv run pytest
Commits follow Conventional Commits;
commitizen derives the version bump and changelog entry from commit
messages, and releases to PyPI are cut automatically from main via GitHub
Actions.
Metadata
Release files for brybox 0.11.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| brybox-0.11.0.tar.gz | 106.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| brybox-0.11.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 261.9 kB
Release files / brybox-0.11.0.tar.gz
| Download URL | brybox-0.11.0.tar.gz |
|---|---|
| Size | 106.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
3025d991e6613d87fea862a7a0289050ca2d0a7eb8e2ea52e65eb9ec1d7f39d6
|
|
BLAKE2b-256 checksum How to use checksums |
0c913f5150d2f1a10ac4b2c609636ff8e6342e5d06e8ec5d3e6b73c4c18a12d4
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|
Release files / brybox-0.11.0-py3-none-any.whl
| Download URL | brybox-0.11.0-py3-none-any.whl |
|---|---|
| Size | 155.1 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
b594504f7c1008736c0fd453680d4cdc3263d04a500e526d687b2183b0b2427c
|
|
BLAKE2b-256 checksum How to use checksums |
26b3730fffcf0de2eb921ac476eb1c6620155a5ba6a738e6512c8ec34bfa910a
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
uv/0.12.5 {"installer":{"name":"uv","version":"0.12.5","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
|