Article Backup
Скрипт для локального бэкапа статей с платформ Sponsr.ru и Boosty.to.
Конвертирует статьи в Markdown с YAML-метаданными, скачивает изображения и другие медиафайлы, поддерживает инкрементальную синхронизацию.
Возможности
- Полный архив статей одного или нескольких авторов
- Инкрементальная синхронизация — после первой загрузки проверяет только новые посты (⚡ до 98% быстрее повторных запусков)
- Конвертация в Markdown с frontmatter (title, date, tags, source)
- Локальное сохранение изображений, видео, аудио, PDF
- Гибкая фильтрация типов скачиваемых файлов (image, video, audio, document)
- Встроенные видео: для Sponsr сохраняются embed-ссылки, для Boosty
ok_videoприоритетно скачивается как локальный asset (с fallback на внешнюю ссылку) - Нормализация разметки Sponsr (вложенный em/strong, кавычки, bidi-маркеры)
- Исправление внутренних ссылок между статьями
- Интеграция с Hugo для просмотра в браузере (поддержка тем, улучшенная типографика)
- SQLite-индекс для быстрого поиска
Установка
Требуется Python 3.10+
Вариант 1: Через pip (рекомендуется)
pip install article-backup
Вариант 2: Из исходников
git clone https://github.com/strannick-ru/article-backup.git
cd article-backup
python -m venv venv
source venv/bin/activate # Linux/macOS
# venv\Scripts\activate # Windows
pip install -r requirements.txt
Настройка
1. Создайте конфиг
cp config.yaml.example config.yaml
2. Заполните config.yaml
output_dir: ./backup
hugo:
base_url: "https://example.com/"
title: "Бэкап статей"
language_code: "ru"
sync:
# stop: остановиться, если авторизация любого источника не прошла
# continue: пропустить проблемные источники и собрать сайт из доступных данных
on_error: stop
auth:
sponsr_cookie_file: ./sponsr_cookie.txt
boosty_cookie_file: ./boosty_cookie.txt
boosty_auth_file: ./boosty_auth.txt
sources:
- platform: sponsr
author: pushkin
display_name: "Пушкин. Проза"
asset_types: ["image", "document"] # Скачивать только картинки и документы
- platform: boosty
author: lermontov
display_name: "Лермонтов. Стихи"
3. Получите токены авторизации
Sponsr
- Войдите на sponsr.ru
- Откройте DevTools (F12) → Network
- Перезагрузите страницу
- Найдите любой запрос → Headers → Cookie
- Скопируйте значение в
sponsr_cookie.txt
Boosty
- Войдите на boosty.to
- Откройте DevTools (F12) → Console
- Вставьте код:
const cookie = document.cookie;
const auth = JSON.parse(decodeURIComponent(document.cookie.match(/auth=([^;]+)/)[1]));
console.log("Cookie:\n" + cookie + "\n\nAuthorization:\nBearer " + auth.accessToken);
- Скопируйте Cookie в
boosty_cookie.txt - Скопируйте Authorization в
boosty_auth.txt
Использование
Синхронизация всех авторов
# Если установлено через pip
article-backup
# Или из исходников
python backup.py
Перед скачиванием выполняется проверка авторизации для всех источников. По умолчанию sync.on_error: stop: если один токен протух, скачивание не начинается и команда завершается с ошибкой. Если указать sync.on_error: continue, источники с ошибками авторизации будут пропущены, остальные источники синхронизируются, а Docker-запуск продолжит сборку Hugo-сайта.
Скачать один пост по URL
article-backup "https://sponsr.ru/author/12345/post-title/"
article-backup "https://boosty.to/author/posts/uuid"
Указать другой конфиг
article-backup -c /path/to/config.yaml
Инкрементальная синхронизация
После первого полного запуска скрипт автоматически переключается в инкрементальный режим:
Первый запуск (полная загрузка):
[sponsr] Синхронизация author...
Полная загрузка индекса...
Получено 2156/2156 постов...
✓ Архив полностью синхронизирован
Повторные запуски (только новые посты):
[sponsr] Синхронизация author...
Инкрементальный режим...
Получено 20/2156 постов... (чанк уже скачан)
Получено 40/2156 постов... (чанк уже скачан)
⚡ Остановлено на 40 постах (все новые загружены)
Найдено постов: 40, новых: 0
Производительность:
- Автор с 2000+ постами: первый запуск ~30 мин, повторные ~30 сек
- Проверка обновлений для 10 авторов: ~5 мин вместо часов
Статус синхронизации хранится в backup/index.db (таблица sync_state). Старые базы данных автоматически обновляются при первом запуске новой версии.
Разработка
Соглашения по релизам
- Сообщения git-коммитов, аннотации git-тегов и тексты release notes оформляются на русском языке.
Тесты
Проект использует встроенный unittest.
python -m unittest -q
Docker
Для серверов с устаревшим Python можно использовать Docker.
Для пользователей (готовый образ)
По умолчанию docker-compose.yml использует готовый образ из GitHub Container Registry (GHCR), что значительно ускоряет установку.
Для удобства используйте скрипт run-docker.sh, который автоматически подхватывает output_dir из вашего config.yaml и монтирует правильный volume.
# Синхронизация + сборка сайта (рекомендуемый способ)
./run-docker.sh
# Скачать один пост
./run-docker.sh "https://sponsr.ru/author/123/"
# Только пересборка сайта
./run-docker.sh hugo
Для разработчиков (сборка из исходников)
Если вы хотите внести изменения в код и протестировать их в Docker, используйте конфиг docker-compose-dev.yml:
# Сборка образа
docker compose -f docker-compose-dev.yml build
# Запуск
docker compose -f docker-compose-dev.yml run --rm backup
Cron
Для автоматической синхронизации добавьте в crontab:
# Каждый день в 3:00
0 3 * * * cd /path/to/article-backup && ./run-docker.sh >> /var/log/article-backup.log 2>&1
Структура выходных файлов
backup/
├── index.db # SQLite-индекс
├── sponsr/
│ └── pushkin/
│ ├── _index.md
│ └── posts/
│ └── 2026-01-31-article-title/
│ ├── index.md # Статья с frontmatter
│ └── assets/ # Медиафайлы
└── boosty/
└── lermontov/
└── posts/
└── 2026-01-31-another-article/
├── index.md
└── assets/
Интеграция с Hugo
После каждого запуска backup.py:
- Автоматически создаётся симлинк
site/content → output_dir - Генерируется
site/hugo.tomlиз секцииhugo:в конфиге
# Запуск локального сервера
cd site && hugo server -D
Откройте http://localhost:1313
Настройка Hugo
Параметры Hugo задаются в config.yaml:
hugo:
base_url: "https://example.com/" # URL сайта для production
title: "Мой архив статей" # Заголовок сайта
language_code: "ru" # Язык контента
default_theme: "sepia" # Тема по умолчанию: light, dark, sepia, gruvbox, everforest
Сайт поддерживает переключение тем "на лету" (кнопки в углу экрана). Выбор пользователя сохраняется в браузере.
Если секция hugo: не указана, используются значения по умолчанию (http://localhost:1313/).
RSS-ленты
Для каждого автора автоматически генерируется RSS-фид:
http://localhost:1313/sponsr/pushkin/index.xmlhttp://localhost:1313/boosty/lermontov/index.xml
На странице автора отображается ссылка 📡 для подписки.
Субдомены для авторов (nginx)
Каждого автора можно раздавать на отдельном субдомене. При использовании Docker CSS автоматически копируется в папки авторов.
# Docker (CSS копируется автоматически)
docker compose run --rm backup && docker compose run --rm hugo
# Или локально через build.sh
cd site && ./build.sh
Пример конфига nginx:
server {
listen 80;
server_name pushkin.example.site;
root /var/www/backup/site/public/sponsr/pushkin;
index index.html;
# Корень показывает список постов
location = / {
try_files /posts/index.html =404;
}
location / {
try_files $uri $uri/ =404;
}
}
Формат статьи
---
title: "Заголовок статьи"
date: 2024-01-15T12:00:00
source: https://sponsr.ru/pushkin/12345/...
author: pushkin
platform: sponsr
post_id: 12345
tags: ["тег1", "тег2"]
---
# Заголовок статьи
Текст статьи...
Metadata
Release files for article-backup 0.3.14
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | Actions |
|---|---|---|---|---|
| article_backup-0.3.14.tar.gz | 53.3 kB | Without provenance | Details for article_backup-0.3.14.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| article_backup-0.3.14-py3-none-any.whl | Python 3 | none | any | Details for article_backup-0.3.14-py3-none-any.whl |
Total release size: 93.0 kB
Release files / article_backup-0.3.14.tar.gz
| Download URL | article_backup-0.3.14.tar.gz |
|---|---|
| Size | 53.3 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
9ad6c6738a7d2568890375c712d1d8f51f5153e82ff8c852ce512d7a9f797d2e
|
|
BLAKE2b-256 checksum How to use checksums |
29392e5e5e702958b0b26a121076d889669c184f8272a32ec8c913935c541022
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Release files / article_backup-0.3.14-py3-none-any.whl
| Download URL | article_backup-0.3.14-py3-none-any.whl |
|---|---|
| Size | 39.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c69c247bd44bdba6e784ba830cb6d258fd6640bb0221c651ceb1265396faabfd
|
|
BLAKE2b-256 checksum How to use checksums |
f747bae7d415526ef5bd70b2aaabd8022f37522fb7721259064036824b3cc7c3
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/6.2.0 CPython/3.10.12
|
Security for article-backup 0.3.14
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.