- Python 72.8%
- HTML 24.8%
- CSS 2.4%
| src/staythefuckaway | ||
| tests | ||
| .env.example | ||
| .gitignore | ||
| .woodpecker.yaml | ||
| pyproject.toml | ||
| README.md | ||
| staythefuckaway.spec | ||
staythefuckaway
Automatically block Tumblr users who reblog your posts using specific tags or content you don't want associated with your work.
What it does
staythefuckaway is a local desktop application that runs quietly in the background and:
- Monitors your Tumblr blog(s) for new reblogs via the Tumblr notifications API
- Checks each reblog's tags and commentary against filters you define
- Automatically blocks anyone whose reblog matches a filter
- Logs everything (who was blocked, why, when) to a local SQLite database
- Provides a browser-based dashboard to manage filters, view blocks, and monitor activity
Filter types
| Type | Behavior | Example |
|---|---|---|
| Tag (exact match) | Blocks if any tag on the reblog is an exact, case-insensitive match | Filter dni matches tag dni but not dni list |
| String (partial match) | Blocks if any tag or the reblog commentary contains the string | Filter hate matches tags hateful, i hate this, and commentary containing hate |
Quick Start
Option A: Download a release (recommended)
- Grab the latest executable for your platform from
Releases (
staythefuckaway-linux-amd64orstaythefuckaway-windows-amd64.exe) - Run it — a browser window will open automatically at
http://localhost:8727
Option B: Run from source
Requires Python 3.10+.
git clone https://your-forgejo-instance/youruser/staythefuckaway.git
cd staythefuckaway
python -m venv .venv && source .venv/bin/activate
pip install .
staythefuckaway
First-time Setup
1. Create a Tumblr OAuth application
- Go to tumblr.com/oauth/apps
- Click Register application
- Fill in the details:
- Application name: anything you like (e.g.,
staythefuckaway) - Application description: anything
- Default callback URL:
http://localhost:8727/oauth/callback - OAuth2 redirect URL: same as the callback URL above
- Application name: anything you like (e.g.,
- Save and copy your OAuth Consumer Key and Secret Key
2. Enter credentials in the web UI
- The dashboard opens in your browser automatically when you launch the app
(or visit
http://localhost:8727) - You'll be redirected to the setup page on first launch
- Paste your Consumer Key and Secret
- Click Save Credentials
3. Add a blog
- Click + Add Blog in the navigation bar
- You'll be redirected to Tumblr to authorize the application
- After authorizing, select which of your blogs to monitor
- Done! The blog is now being watched
4. Add filters
- Navigate to your blog's Filters page
- Add tag or string filters
- The scanner will start checking new reblogs against your filters within a few minutes
How it Works
┌─────────────────────────────────────────────────┐
│ Web UI (Flask) │
│ http://localhost:8727 │
├─────────────────────┬───────────────────────────┤
│ Scanner │ Blocker │
│ (every 2 min) │ (every 30 sec) │
│ │ │
│ Polls Tumblr │ Processes block queue │
│ /notifications │ POST /blocks │
│ endpoint for │ with rate-limit │
│ new reblogs │ awareness │
├─────────────────────┴───────────────────────────┤
│ SQLite Database │
│ blogs · filters · block_queue · blocked_users │
│ activity_log · app_config │
└─────────────────────────────────────────────────┘
Rate limit handling
Tumblr enforces the following relevant limits:
- Block endpoint: 60 requests/minute
- General API: 300 calls/minute, 1,000/hour per consumer key
staythefuckaway handles this by:
- Spacing block operations at ~1.5 seconds apart (≈40/min, well under the 60/min cap)
- Detecting HTTP 429 responses and pausing until the rate limit resets
- Automatically retrying failed blocks every 10 minutes
Token refresh
OAuth2 access tokens expire (typically after ~42 minutes). The service automatically refreshes tokens using the stored refresh token before they expire.
CLI Options
staythefuckaway [--host HOST] [--port PORT] [--verbose] [--no-scheduler]
| Flag | Default | Description |
|---|---|---|
--host |
127.0.0.1 |
Bind address for the web server |
--port |
8727 |
Port for the web server |
--verbose / -v |
off | Enable debug logging |
--no-scheduler |
off | Disable background scanner/blocker (web UI only) |
Data Storage
All data is stored in a single SQLite database at ./data/staythefuckaway.db (relative to where you run the executable).
You can override the location with the STFA_DATA_DIR environment variable:
export STFA_DATA_DIR=/path/to/data # Linux / macOS
set STFA_DATA_DIR=C:\my\data # Windows
Database tables
| Table | Purpose |
|---|---|
app_config |
OAuth app credentials, Flask secret key |
blogs |
Monitored blogs with OAuth2 tokens and settings |
filters |
Tag/string filter rules per blog |
block_queue |
Pending and processed block operations |
blocked_users |
Permanent record of all blocks with reasons |
activity_log |
Timestamped log of all scanner/blocker activity |
Building
Release builds are automated via Woodpecker CI on the Forgejo repo.
CI pipeline (.woodpecker.yaml)
| Step | Trigger | What it does |
|---|---|---|
| validate | every push / PR | Installs the package, verifies imports, smoke-tests filter logic |
| build-linux | tags (v*) |
Builds staythefuckaway-linux-amd64 via PyInstaller |
| build-windows | tags (v*) |
Builds staythefuckaway-windows-amd64.exe via PyInstaller + Wine |
| release | tags (v*) |
Uploads both executables to a Forgejo release |
Required Woodpecker secret
| Secret | Value |
|---|---|
forgejo_token |
Forgejo API token with write:repository + read:misc scopes |
Creating a release
git tag v1.0.0
git push --tags
Woodpecker will build both executables and attach them to the Forgejo release for v1.0.0.
Building locally
pip install pyinstaller
pyinstaller --clean --noconfirm staythefuckaway.spec
# Output: dist/staythefuckaway (or dist/staythefuckaway.exe on Windows)
Multi-blog Support
Each blog you add gets completely independent:
- 🔒 Tokens — separate OAuth2 credentials
- 🏷️ Filters — independent tag/string rules
- 📊 Metrics — separate block counts and queue
- 📝 Logs — individual activity history
- ⚙️ Settings — independent poll intervals and enable/disable
You can authenticate multiple blogs in a single OAuth flow (if they're on the same Tumblr account) or add blogs from different accounts by running the OAuth flow again.
License
MIT