Grabber
Utilities to extract media from supported sources and publish to Telegram/Telegraph.
Quick Start
- Install dependencies:
uv sync --dev
- Configure environment in
.env(at minimum):
BOT_TOKENTELEGRAPH_TOKENSHORT_NAMEAUTHOR_NAMEAUTHOR_URL
- Show supported entities:
uv run grabber -a
Run (CLI)
Example:
uv run grabber --publish --channel @your_channel --sources "https://example.com/post"
Send plain text to a channel:
uv run grabber --channel @your_channel --text "Some text"
Print unread Picazor album notification URLs:
uv run grabber --notifications picazor --number 10
Print profile URLs for the first unread Picazor album notifications scanned:
uv run grabber --notifications picazor --number 10 --profiles
Print Fapello feed image URLs:
uv run grabber --notifications fapello --number 10
Print unique Fapello profile URLs from the feed:
uv run grabber --notifications fapello --number 10 --profile
Search Fapello models:
uv run grabber --search fapello --query peachyxeena
Fapello notification/search modes and Picazor notification mode need these .env values from authenticated browser sessions:
FAPELLO_USER_ID=
FAPELLO_HASH=
PICAZOR_SESSION_TOKEN=
PICAZOR_CF_CLEARANCE=
PICAZOR_CSRF_TOKEN=
PICAZOR_LOCALE=en
Post text into a thread (discussion group):
uv run grabber --channel @your_channel --thread-id 123 --text "Some text in thread"
If --thread-id is omitted, grabber prints the resolved thread id so you can reuse it:
uv run grabber --channel @your_channel --text "Some text"
Output:
Text sent to @your_channel
Resolved thread id for reuse: --thread-id 123
Run Interactive Bot
uv run python -m grabber.core.bot.interactive_bot
Then use /post, select channel, and send source URLs.
Run Web UI
The web interface is served in two services:
web-api: FastAPI backend (session-protected endpoints)web-ui: React dashboard
Setup
- Add web environment variables:
WEB_UI_PASSWORD=your-strong-password
WEB_SESSION_SECRET=a-long-random-string
WEB_SESSION_TTL_SECONDS=86400
- Start the stack:
docker compose up --build web-api web-ui
-
Open
http://<your-vps-ip>:8888(or map another public port indocker-compose.yml). -
Log in with
WEB_UI_PASSWORD. After login:
- Enter one or more URLs and target channel
- Optionally enable tag mode/video mode
- Send plain text by checking Post text only
- Optionally provide a thread id (
--thread-id) for text replies/comments
Notes:
- The channel list is pulled from the existing bot
CHANNELSmapping (src/grabber/core/settings.py). - Entity list comes from
QUERY_MAPPING. - API routes are exposed under
/api/*and proxied by the UI.
Pornhub Video-to-Channel
Single-video Pornhub URLs are supported for direct Telegram delivery.
Requirements
- A target channel is mandatory (
--channelin CLI or bot channel picker). yt_dlpmust be available in the runtime environment.PORNHUB_COOKIES_FILE_PATHmust point to a valid Netscape-format cookies file.
Add to .env:
PORNHUB_COOKIES_FILE_PATH=/absolute/path/to/pornhub_cookies.txt
Supported Pornhub hosts
pornhub.comwww.pornhub.comm.pornhub.com
CLI example
uv run grabber \
--publish \
--channel -1003835153909 \
--sources "https://www.pornhub.com/view_video.php?viewkey=ph5abc123"
Note: CLI --channel must be a Telegram username/ID (for example @channel_name or -100...), not the interactive bot display label.
Delivery behavior
- Chooses the best format expected to fit Telegram Bot API upload limits (
<= 50MB). - If the selected media is oversized, it sends a link message fallback to the channel.
- If
--channelis missing, Pornhub execution fails fast with an explicit error. - If
PORNHUB_COOKIES_FILE_PATHis missing/invalid, execution fails fast. - Checkpoint dedupe is applied, and successful sends are committed.
Troubleshooting
PORNHUB_COOKIES_FILE_PATH is required...- Set
PORNHUB_COOKIES_FILE_PATHin.env.
- Set
...does not exist or is not a file- Fix the path and permissions for the cookies file.
yt_dlp is required to process Pornhub sources- Install dependencies in the same runtime where
grabberexecutes.
- Install dependencies in the same runtime where
ERROR: [PornHub] ... Unable to extract title- The adapter now auto-falls back to HTML media parsing when
yt_dlpmetadata extraction fails. - If it still fails, refresh/export cookies again and update
yt-dlpin your runtime.
- The adapter now auto-falls back to HTML media parsing when
- Oversized media warnings
- Expected behavior; the source falls back to link delivery.
Metadata
Release files for grabberlib2 0.46.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 | |
|---|---|---|---|
| grabberlib2-0.46.0.tar.gz | 218.4 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| grabberlib2-0.46.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 662.3 kB
Release files / grabberlib2-0.46.0.tar.gz
| Download URL | grabberlib2-0.46.0.tar.gz |
|---|---|
| Size | 218.4 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
fd17ccce557d4007366a337dd7c1aff0f86740ebb080011635c1762cb3909386
|
|
BLAKE2b-256 checksum How to use checksums |
f9448da44fb0a6ba4b9b547fc8ab61ae409c235768a1eddc9bc2543cabd5c270
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","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":null}
|
Release files / grabberlib2-0.46.0-py3-none-any.whl
| Download URL | grabberlib2-0.46.0-py3-none-any.whl |
|---|---|
| Size | 443.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
23e2788fde80f74fb47b70d91d977ba8231ebb51911ca717a05bc3efb6014d15
|
|
BLAKE2b-256 checksum How to use checksums |
b19971e926bddc3042a1d19744177767bac41671600623cbf1466b6fb52798a7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.11.15 {"installer":{"name":"uv","version":"0.11.15","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":null}
|