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.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file brybox-0.11.0.tar.gz.
File metadata
- Download URL: brybox-0.11.0.tar.gz
- Upload date:
- Size: 106.8 kB
- Tags: Source
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
3025d991e6613d87fea862a7a0289050ca2d0a7eb8e2ea52e65eb9ec1d7f39d6
|
|
| MD5 |
a0b8bb4ff709f5ae1e73261bd5ce513e
|
|
| BLAKE2b-256 |
0c913f5150d2f1a10ac4b2c609636ff8e6342e5d06e8ec5d3e6b73c4c18a12d4
|
File details
Details for the file brybox-0.11.0-py3-none-any.whl.
File metadata
- Download URL: brybox-0.11.0-py3-none-any.whl
- Upload date:
- Size: 155.1 kB
- Tags: Python 3
- Uploaded using 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}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b594504f7c1008736c0fd453680d4cdc3263d04a500e526d687b2183b0b2427c
|
|
| MD5 |
1fe81dc2d0a16650eeace6c1a420e4f2
|
|
| BLAKE2b-256 |
26b3730fffcf0de2eb921ac476eb1c6620155a5ba6a738e6512c8ec34bfa910a
|