Metadata-Version: 2.3
Name: zhongli
Version: 2026.5.1
Summary: Bot to boost/reblog posts with specified tags
Author: marvin8
Author-email: marvin8 <marvin8@tuta.io>
License: AGPL-3.0-or-later
Classifier: Development Status :: 5 - Production/Stable
Classifier: Environment :: Console
Classifier: Programming Language :: Python
Classifier: Programming Language :: Python :: 3.12
Classifier: Programming Language :: Python :: 3.13
Classifier: Programming Language :: Python :: 3.14
Requires-Dist: aiosqlite~=0.22.1
Requires-Dist: cyclopts~=4.11.0
Requires-Dist: httpx[http2]~=0.28.1
Requires-Dist: imagehash~=4.3.2
Requires-Dist: loguru~=0.7.3
Requires-Dist: longwei~=1.4.3
Requires-Dist: msgspec~=0.21.1
Requires-Dist: pybreaker~=1.4.1
Requires-Dist: stamina~=26.1.0
Requires-Dist: tomli-w~=1.2.0
Requires-Dist: pillow~=12.2.0
Requires-Python: >=3.12, <3.15
Description-Content-Type: text/markdown

# Zhongli

Automatically boost/reblog Fediverse posts. Formerly **Fedibooster**.

[![Repo](https://img.shields.io/badge/repo-Codeberg.org-blue)](https://codeberg.org/MarvinsMastodonTools/zhongli) [![CI](https://ci.codeberg.org/api/badges/13923/status.svg)](https://ci.codeberg.org/repos/13923) [![Downloads](https://pepy.tech/badge/zhongli)](https://pepy.tech/project/zhongli) [![AGPL](https://www.gnu.org/graphics/agplv3-with-text-162x68.png)](https://codeberg.org/MarvinsMastodonTools/zhongli/src/branch/main/LICENSE.md)

## Overview

Zhongli consumes pre-filtered posts from [FenLiu](https://codeberg.org/marvinsmastodontools/fenliu)'s queue and automatically reblogs them to your Fediverse account. FenLiu handles the heavy lifting (filtering, spam detection, curation); Zhongli handles the reblogging and duplicate prevention.

**FenLiu configuration is required.** There is no legacy mode.

## Status

| Phase | Status | Notes |
|-------|--------|-------|
| 1: Infrastructure | ✅ Complete | FenLiu client, models, tests |
| 2: FenLiu-Only Mode | ✅ Complete | ReblogService, queue polling, attachments |
| 3: Validation Optimization | ✅ Complete | MinimalValidator, pre-filtered posts |
| 4: Documentation | ✅ Complete | FenLiu-only, updated config |
| 5: UX Polish | ⏳ Optional | Metrics, dry-run, progress indicators |

## Install

```bash
pip install zhongli
```

Or from source:
```bash
git clone https://codeberg.org/marvinsmastodontools/zhongli.git
cd zhongli
uv sync
uv run zhongli
```

## Configuration

Zhongli requires FenLiu and a Fediverse account:

```toml
[fediverse]
domain_name = "mastodon.social"
api_token = "your-token"

[fenliu]
base_url = "https://fenliu.example.com"
api_key = "your-api-key"

# Optional
run_continuously = false
delay_between_posts = 300
reblog_sensitive = false
max_reblog = 5
```

**Configuration explained**:
- `[fediverse]` - Your Mastodon/Pixelfed/Misskey account
- `[fenliu]` - Connection to FenLiu queue service
- `run_continuously` - Keep polling or exit after `max_reblog` posts
- `delay_between_posts` - Seconds between reblogs (0 for no delay)
- `reblog_sensitive` - Whether to boost sensitive/NSFW posts
- `max_reblog` - Stop after boosting N posts (0 for unlimited)
- `fenliu.skip_missing_alt_text` - Skip posts where any attachment lacks alt text (default: `false`)

> **Security:** `config.toml` is created with `0600` permissions (owner read/write only).
> If you copy or restore the file from another location, re-apply: `chmod 600 config.toml`.
> Zhongli will refuse to start if it detects the file is readable by group or world.
>
> **Debug log:** When using `--logging-config logging-config.toml`, debug output is written to
> `~/.cache/zhongli/zhongli.log`. This directory is created automatically and is accessible only
> by the owner. Never configure `/tmp/` as a log destination — it is world-readable.

## Usage

```bash
zhongli config.toml                 # Run with config file
zhongli config.toml --max-posts 10  # Override max posts
zhongli --help                      # Show all options
```

## How It Works

1. **Poll FenLiu Queue** - Get next curated post
2. **Validate** - Quick checks (has content, not a reply, respects sensitive setting)
3. **Find on Fediverse** - Search for post by URL
4. **Check for Duplicates** - Compare attachments (URL, hash, perceptual)
5. **Reblog** - Boost to your account with circuit breaker protection
6. **Report Feedback** - ACK (success), NACK (transient error), ERROR (permanent)
7. **Repeat** - Until configured limit or continuous mode ends

## Features

- **FenLiu Integration** - Consume pre-curated, pre-filtered posts
- **Duplicate Prevention** - Three-layer attachment detection (URL, SHA-256, dHash)
- **Reliable Reblogging** - Circuit breaker pattern, retry logic, error classification
- **Smart Feedback** - ACK/NACK/ERROR reporting to FenLiu
- **Production Ready** - 80+ tests, full type checking, comprehensive error handling

## Development

```bash
uv sync              # Install deps
prek run --all-files # Pre-commit checks
pytest               # Run tests (80+ tests)
nox                  # Full CI simulation
```

## Recent Work

- ✅ Phase 3: Validation optimized for FenLiu pre-filtered posts
- ✅ Phase 2: Full FenLiu-only mode operational
- ✅ Phase 1: FenLiu infrastructure complete with 80+ tests
- ✅ Attachment deduplication system (URL, content hash, perceptual hash)
- ✅ Circuit breaker pattern integrated
- ✅ Complete feedback mechanism (ACK/NACK/ERROR)

## Next Steps

**Phase 5** - UX polish and observability (metrics, dry-run mode, progress indicators)

## License

[GNU AGPL v3.0](http://www.gnu.org/licenses/agpl-3.0.html)

## Support

- [Buy me coffee](https://www.buymeacoffee.com/marvin8)
- Monero: `88xtj3hqQEpXrb5KLCigRF1azxDh8r9XvYZPuXwaGaX5fWtgub1gQsn8sZCmEGhReZMww6RRaq5HZ48HjrNqmeccUHcwABg`
