Architecture and development¶
This page is for people who want to understand, modify, or contribute to the application. Installation and operation instructions remain in the user guides.
Runtime flow¶
Panel / source CLI
-> atomic sources.toml replacement
-> transactional SQLite source runtime mirror
Built-in / extension providers
-> provider discovery using that mirror and typed registry
-> SQLite media and job state
-> yt-dlp / ffmpeg download artifacts
-> MTProto or Bot API delivery
-> Telegram delivery records
Discovery records media before work is queued. Download and Telegram delivery
are separate durable jobs, so a delivery failure does not repeat a completed
download. Workers claim jobs with leases. An ambiguous Telegram result becomes
uncertain and is not retried automatically because Telegram may already have
accepted the message.
Storage state and replicas¶
SQLite records the backup lifecycle, confirmed Telegram deliveries, and the current storage location. Media content remains as regular files in the configured storage. Moving a file between local and mounted storage updates its database location without changing the completed delivery state.
Module map¶
| Module | Responsibility |
|---|---|
cli.py, setup.py |
Commands, guided setup, and generated private configuration |
config.py |
TOML parsing, environment overrides, and validation |
extension_api.py, extensions.py |
Stable contracts, entry-point loading, typed capability registry, and lifecycle |
extension_catalog.py, extension_install.py, extension_management.py, extension_state.py |
Trusted short-name resolution, same-environment installation, one-command enable transactions, and managed sidecars |
network.py |
Task-scoped route leases and unified HTTP/process connection behavior |
source_catalog.py |
Catalog validation, atomic writes, and SQLite reconciliation |
sources.py, youtube.py |
Built-in provider discovery and normalized media metadata |
service.py |
Polling, worker orchestration, retries, and graceful shutdown |
store.py |
SQLite schema, migrations, jobs, leases, and tracked resources |
downloader.py |
yt-dlp/ffmpeg execution and derived media artifacts |
telegram_mtproto.py, telegram.py |
MTProto and Bot API media transports |
control.py |
Authorized Telegram control panel and tracked-file operations |
config.toml supplies process-wide settings and the catalog path. Application
writes and database reconciliation pass through SourceCatalogManager: it
locks the catalog directory, replaces sources.toml atomically, then reconciles
the database in one transaction. Manual edits become active through its
apply path. A failed reconciliation restores the previous catalog bytes. The
SQLite copy is operational state, not a second configuration authority.
Local environment¶
Python 3.11 or newer is supported. Install ffmpeg and ffprobe when testing
media workflows.
git clone https://github.com/dreaifekks/asmr-tg-backup.git
cd asmr-tg-backup
python3 -m venv .venv
.venv/bin/python -m pip install -e ".[docs]"
Source builds that exercise MTProto need their own complete Telegram application configuration. Unit tests must use mocks and temporary files; they must not contact a real provider, bot, destination, or private data directory.
For a long-running source checkout, create a private config from the source configuration example, then register the current virtual environment directly:
.venv/bin/asmr-tg-backup service install \
--config ~/.config/asmr-tg-backup/config.toml
The generated unit records the current virtualenv interpreter and config path. Packaged installations use the same command from the PyPI guide.
Validate a change¶
git diff --check
PYTHONDONTWRITEBYTECODE=1 PYTHONPATH=src \
.venv/bin/python -m unittest discover -s tests -v
.venv/bin/mkdocs build --strict --clean
Serve the bilingual documentation locally with:
.venv/bin/mkdocs serve --dev-addr 127.0.0.1:8001
English pages use page.md; Simplified Chinese pages use page.zh.md. Keep
paired pages structurally aligned whenever user-visible behavior changes.
Invariants¶
- Run only one application process against a database and MTProto session pair.
- Keep discovery, download, and delivery state durable across restarts.
- Keep the logical backup and storage lifecycle in SQLite instead of deriving delivery state from a file path.
- Keep
sources.tomlauthoritative for sources and the filter; SQLite holds only their runtime mirror and operational state. - Keep extensions outside SQLite/job/delivery ownership and import only IDs explicitly enabled in process configuration.
- Keep each network route fixed for one request, subprocess, upload, or client connection; switch only at a safe retry/reconnect boundary.
- Never retry
uncertainTelegram delivery automatically. - Keep tokens, application credentials, Twitch credentials, private configuration, databases, downloads, and sessions out of logs, command-line arguments, fixtures, packages built from a source checkout, and commits.
- Keep local resource deletion opt-in and limited to exact SQLite-tracked regular files below configured managed storage roots.
See Contributing for the complete contribution workflow and checklist.