# foobar2000-catbox — User Guide

## 1. Quick Start

**foobar2000-catbox** is a small Rust command-line utility that receives an image file path on stdin, optionally resizes and/or re-encodes the image, then uploads it to [catbox.moe](https://catbox.moe) (permanent) or [litterbox.catbox.moe](https://litterbox.catbox.moe) (temporary), printing the resulting URL to stdout. It is designed to be piped into from tools like foobar2000 components that emit a file path to album art.

**Key features:**
- Reads the image file path from stdin — drop-in companion for any automation or media player integration
- Uploads to catbox.moe (permanent) or litterbox.catbox.moe (auto-expiring)
- Optional image resizing: scales down to a power-of-two maximum resolution while preserving aspect ratio
- Optional re-encoding to JPG, PNG, or WebP
- Adjustable JPG quality (1–100)
- Optional catbox user account association via `user_hash`
- Zero runtime arguments — all settings live in `settings.yml` next to the binary

**Prerequisites:** A pre-built binary or Rust toolchain (edition 2021). No additional runtime required.

**Run it:**

```bash
echo "/path/to/cover.jpg" | ./foobar2000-catbox
```

```text
https://files.catbox.moe/ab1cd2.jpg
```

> [!TIP]
> Drop the binary and `settings.yml` into the same directory and it works immediately with all defaults. No flags, no environment variables needed.

**What to try next:** See [Configuration](#3-configuration) to set your catbox user hash or enable image resizing.

---

## 2. Installation

### System Requirements

| Item | Requirement |
|---|---|
| OS | Any (Linux, macOS, Windows) |
| Architecture | Matches build target |
| Runtime deps | None (statically linked release binary) |
| Network | Outbound HTTPS to `catbox.moe` or `litterbox.catbox.moe` |

### Install Methods

=== "Pre-built binary"
    Download the release binary for your platform from the repository releases page. Place `foobar2000-catbox` (or `foobar2000-catbox.exe` on Windows) in a directory of your choice. Copy `settings.yml` into the same directory.

=== "Build from source"
    ```bash
    git clone https://github.com/realoksi/foobar2000-catbox
    cd foobar2000-catbox
    cargo build --release
    ```

    ```text
    Compiling foobar2000-catbox v1.0.9
    Finished release [optimized] target(s) in ...
    ```

    The binary lands at `target/release/foobar2000-catbox`. Copy it alongside `settings.yml`.

> [!IMPORTANT]
> The binary looks for `settings.yml` **in the same directory as itself**, not the working directory. If the file is missing or unreadable, all settings fall back to their defaults silently — no error is shown.

### Post-Install Verification

```bash
echo "/path/to/any/image.jpg" | ./foobar2000-catbox
```

A successful install prints a catbox URL. A network or settings error prints a message to stderr and exits non-zero.

---

## 3. Configuration

All configuration lives in `settings.yml`, placed next to the binary. The file is optional — missing or empty settings use built-in defaults.

**Annotated `settings.yml`:**

```yaml
# Upload target
enable_litterbox: false       # true = litterbox.catbox.moe (temporary), false = catbox.moe (permanent)
litterbox_expire_time: "24h"  # Options: "1h", "12h", "24h", "72h" — only used when enable_litterbox: true

# Image re-encoding
enable_encode: false          # Re-encode the image before uploading
encode_format: "JPG"          # Options: "JPG", "PNG", "WEBP"
encode_format_quality: 80     # 1–100; only applies to JPG format

# Image resizing
enable_resize: false          # Scale down oversized images before uploading
resize_max_resolution:        # Maximum width and height (must be powers of two)
    - 1024
    - 1024

# Catbox account (optional)
# user_hash: "f3c9a4e81d2b76f59e40c8a3d"  # 25-char hash from catbox.moe/user/manage.php

# HTTP
user_agent: "Mozilla/5.0 (X11; Linux x86_64; rv:133.0) Gecko/20100101 Firefox/133.0"
```

### Settings Reference

| Key | Type | Default | Description |
|---|---|---|---|
| `enable_litterbox` | bool | `false` | Upload to litterbox (temporary) instead of catbox (permanent) |
| `litterbox_expire_time` | string | `"24h"` | Expiry for litterbox uploads: `"1h"`, `"12h"`, `"24h"`, `"72h"` |
| `enable_encode` | bool | `false` | Re-encode the image in `encode_format` before uploading |
| `encode_format` | string | `"JPG"` | Output format: `"JPG"`, `"PNG"`, `"WEBP"` |
| `encode_format_quality` | number | `80` | JPG quality (1–100). Ignored for PNG and WEBP. |
| `enable_resize` | bool | `false` | Downscale images exceeding `resize_max_resolution` |
| `resize_max_resolution` | sequence | `[1024, 1024]` | Max `[width, height]` in pixels — both must be powers of two |
| `user_hash` | string | `""` | 25-character catbox user hash; associates uploads with your account |
| `user_agent` | string | Firefox UA | HTTP User-Agent sent with upload requests |

> [!NOTE]
> `encode_format_quality` only affects JPG output. PNG uses lossless compression. WebP always uses lossless encoding (`WebPEncoder::new_lossless`).

> [!WARNING]
> `resize_max_resolution` values must both be powers of two (512, 1024, 2048, etc.) and greater than zero. Invalid values cause startup failure with exit code 2 or 3.

See the Admin Guide for a full configuration reference including validation rules and exit codes.

---

## 4. Core Usage

### Basic Upload

Pipe any supported image file path to the binary:

```bash
echo "/home/user/music/album/cover.jpg" | ./foobar2000-catbox
```

```text
https://files.catbox.moe/ab1cd2.jpg
```

The URL is printed to stdout. Errors go to stderr. The binary exits 0 on success.

### Supported Input Formats

The `image` crate auto-detects format from file contents (not extension). Supported formats include JPEG, PNG, and WebP.

### Temporary Uploads with Litterbox

Enable litterbox mode to upload images that automatically expire:

```yaml
enable_litterbox: true
litterbox_expire_time: "1h"   # or "12h", "24h", "72h"
```

```bash
echo "/path/to/cover.png" | ./foobar2000-catbox
```

```text
https://litter.catbox.moe/xyz789.png
```

> [!WARNING]
> After the expiry time, the URL becomes permanently invalid. Any system caching litterbox URLs (such as a Discord bot) will display a broken image. Use catbox (`enable_litterbox: false`) for permanent links.

### Resize Before Upload

Reduce bandwidth and storage by downscaling large album art:

```yaml
enable_resize: true
resize_max_resolution:
    - 1024
    - 1024
```

Images with either dimension exceeding the limit are scaled down using nearest-neighbor filtering while preserving aspect ratio. Images already within the limit are passed through unchanged.

### Re-encode to JPG

Normalize format and reduce file size:

```yaml
enable_encode: true
encode_format: "JPG"
encode_format_quality: 85
```

> [!TIP]
> Combine `enable_resize` and `enable_encode` for the smallest possible upload — resize first, then re-encode. Both operations happen in-memory before the upload; the original file is never modified.

---

## 5. Common Tasks

### Upload album art with your catbox account

**Goal:** Associate uploads with your catbox.moe account so they appear in your file manager.

**Prerequisites:** A catbox.moe account. Find your user hash at `https://catbox.moe/user/manage.php`.

**Steps:**
1. Open `settings.yml`.
2. Uncomment (or add) the `user_hash` line with your 25-character hash:
   ```yaml
   user_hash: "f3c9a4e81d2b76f59e40c8a3d"
   ```
3. Run a test upload:
   ```bash
   echo "/path/to/cover.jpg" | ./foobar2000-catbox
   ```
4. Verify the file appears in your catbox account at `https://catbox.moe/user/manage.php`.

**If it fails:** Check that your hash is exactly 25 characters. A wrong-length hash causes exit code 4 and an error message: `user_hash isn't 25 characters (N)`.

---

### Upload in WebP format

**Goal:** Upload images re-encoded as lossless WebP.

**Steps:**
1. Edit `settings.yml`:
   ```yaml
   enable_encode: true
   encode_format: "WEBP"
   ```
2. Run as normal. The uploaded file will be `.webp`.

> [!NOTE]
> WebP encoding is always lossless regardless of `encode_format_quality`. The quality setting is silently ignored for WebP and PNG.

---

### Keep uploads temporary (auto-expiring)

**Goal:** Upload images that auto-delete after a set time.

**Steps:**
1. Edit `settings.yml`:
   ```yaml
   enable_litterbox: true
   litterbox_expire_time: "1h"
   ```
2. Run as normal.

**Verify:** The URL returned starts with `https://litter.catbox.moe/`.

---

### Pipe from a shell script

```bash
#!/bin/bash
ART_PATH="$1"
URL=$(echo "$ART_PATH" | /opt/foobar2000-catbox/foobar2000-catbox)
if [ $? -eq 0 ]; then
    echo "Uploaded: $URL"
else
    echo "Upload failed" >&2
fi
```

---

## 6. Troubleshooting

### Error: `"path/to/file" doesn't exist.`

**Cause:** The file path received on stdin does not point to an existing file.

**Solution:**
1. Verify the path is correct and the file exists on disk.
2. Ensure no extra whitespace or newline characters are appended — the tool trims the input line, but the path itself must be valid.

**Prevention:** Validate the path before piping it to the binary.

---

### Error: `Failed to load image from memory`

**Cause:** The file exists but could not be decoded as a supported image format (JPEG, PNG, WebP).

**Solution:**
1. Confirm the file is a valid image, not a corrupt or non-image file.
2. Try opening the file in another image viewer to confirm it loads.

---

### Error: `encode_format_quality is out-of-bounds (N)`

**Cause:** `encode_format_quality` in `settings.yml` is outside the range 1–100.

**Solution:**
1. Open `settings.yml`.
2. Set `encode_format_quality` to a value between 1 and 100.
   ```yaml
   encode_format_quality: 80
   ```

---

### Error: `resize_max_resolution values must be larger than 0 (W, H)`

**Cause:** One or both `resize_max_resolution` values is zero.

**Solution:** Set both values to a positive power-of-two integer:

```yaml
resize_max_resolution:
    - 1024
    - 1024
```

---

### Error: `both values of resize_max_resolution must be a power-of-two (W, H)`

**Cause:** One or both `resize_max_resolution` values is not a power of two (e.g. 513 instead of 512).

**Solution:** Use only power-of-two values: 128, 256, 512, 1024, 2048, etc.

> [!WARNING]
> This validation runs at startup, before any image is read. An invalid `settings.yml` means no uploads succeed until fixed.

---

### Error: `user_hash isn't 25 characters (N)`

**Cause:** The `user_hash` value in `settings.yml` is not exactly 25 characters.

**Solution:**
1. Re-copy your hash from `https://catbox.moe/user/manage.php`.
2. Confirm the value in `settings.yml` is exactly 25 characters (no trailing spaces).

---

### Upload network error (curl error on stderr)

**Cause:** The upload request to catbox.moe or litterbox.catbox.moe failed. This can be a transient network issue, the service being down, or the user-agent being blocked.

**Solution:**
1. Check outbound HTTPS connectivity to `catbox.moe`.
2. If the service is down, wait and retry.
3. If repeatedly blocked, try adjusting `user_agent` in `settings.yml`.

---

## 7. FAQ

**Q: Does the tool modify the original image file?**

No. All resizing and re-encoding is performed in memory. The original file is read-only and never written to.

---

**Q: What image formats can I upload?**

Input: any format the `image` crate can decode, including JPEG, PNG, and WebP. Output when `enable_encode: false`: same format as the input. Output when `enable_encode: true`: the format set by `encode_format` (JPG, PNG, or WebP).

---

**Q: How do I find my catbox user hash?**

Log in at catbox.moe, then visit `https://catbox.moe/user/manage.php`. Your user hash is shown there. It must be exactly 25 characters.

---

**Q: What happens if `settings.yml` is missing?**

All settings revert to their built-in defaults. The tool runs as if the file contained:
- catbox.moe upload (not litterbox)
- no resizing
- no re-encoding
- empty `user_hash` (anonymous upload)

---

**Q: What does `litterbox_expire_time` accept?**

Exactly four case-sensitive strings: `"1h"`, `"12h"`, `"24h"`, `"72h"`. Any other value will fail YAML deserialization.

---

**Q: Is WebP encoding lossy or lossless?**

Always lossless. The code uses `WebPEncoder::new_lossless`. `encode_format_quality` has no effect on WebP output.

---

**Q: Can I use this on Windows?**

Yes. The binary is cross-platform. On Windows, provide the file path in the format your shell uses (backslashes or forward slashes both work with Rust's `Path`).

---

**Q: Where is the settings file looked up?**

Always in the same directory as the executable binary, not the current working directory. If you move the binary, move `settings.yml` with it.

---

_Generated May 2026 from realoksi/foobar2000-catbox at f47db1a. AI-generated documentation. The library is checked by sampling (three repositories so far); this guide was not individually reviewed. Verify against the project before relying on it. Unofficial; not affiliated with or reviewed by the project._
