diff --git a/README.md b/README.md
index 28bb534..b2e968f 100644
--- a/README.md
+++ b/README.md
@@ -1,39 +1,38 @@
# transmission-telegram
-#### Manage your transmission through Telegram.
+#### Управляйте Transmission через Telegram.
## CLI
-### Install
+### Установка
-Just [download](https://github.com/pyed/transmission-telegram/releases) the appropriate binary for your OS, place `transmission-telegram` in your `$PATH` and you are good to go.
+Просто [скачайте](https://github.com/pyed/transmission-telegram/releases) подходящий бинарный файл для вашей ОС, поместите `transmission-telegram` в ваш `$PATH` и готово.
-Or if you have `Go` installed: `go get -u github.com/pyed/transmission-telegram`
+Или, если у вас установлен `Go`: `go get -u github.com/pyed/transmission-telegram`
-## Usage
+## Использование
[Wiki](https://github.com/pyed/transmission-telegram/wiki)
-
-## Docker Alternate Installation Route
+## Установка через Docker
### Standalone
-```
+```bash
docker run -d --name transmission-telegram \
kevinhalpin/transmission-telegram:latest \
--token= \
--master= \
+-token=<Ваш Токен Бота> \
+-master=<Ваш Username> \
-url= \
--username= \
--password=
+-username= \
+-password=
```
-### docker-compose Example
+### Пример docker-compose
-```
+```yaml
version: '2.4'
services:
transmission:
@@ -57,5 +56,174 @@ telegram-transmission-bot:
- emby
network_mode: 'host'
image: kevinhalpin/transmission-telegram:latest
- command: '-token=${TELEGRAM_TRANSMISSION_BOT} -master=${TELEGRAM_USERNAME} -url=${TRANSMISSION_URL} - username=${TRANSMISSION_USERNAME} -password=${PASS}'
+ command: '-token=${TELEGRAM_TRANSMISSION_BOT} -master=${TELEGRAM_USERNAME} -url=${TRANSMISSION_URL} -username=${TRANSMISSION_USERNAME} -password=${PASS}'
```
+
+## Возможности
+
+Этот проект представляет собой Telegram-бота для управления клиентом BitTorrent Transmission. Бот позволяет:
+
+- **Просмотр торрентов**: список всех торрентов, фильтрация по статусу (загрузка, раздача, на паузе, проверка), поиск по имени или трекеру
+- **Управление торрентами**: добавление (по URL, magnet-ссылке или файлу .torrent), запуск, остановка, удаление, проверка целостности
+- **Мониторинг**: просмотр статистики, скорости загрузки/отдачи, информации о конкретных торрентах с live-обновлениями
+- **Настройки**: установка лимитов скорости, изменение директории загрузки, сортировка торрентов
+- **Уведомления**: автоматические уведомления о завершении загрузок через мониторинг RPC API (работает автоматически, без дополнительной настройки)
+
+Бот работает только с авторизованными пользователями (masters), что обеспечивает безопасность управления вашими торрентами.
+
+## Настройка уведомлений о завершении загрузок
+
+Бот автоматически отправляет уведомления в Telegram, когда торрент завершает загрузку. Для этого используется **мониторинг через RPC API** (рекомендуемый метод), который работает без дополнительной настройки.
+
+### Метод 1: Мониторинг через RPC API (рекомендуется) ⭐
+
+Этот метод работает автоматически и не требует дополнительной настройки. Бот периодически опрашивает Transmission через RPC API и отслеживает изменение статуса торрентов с "Загрузка" на "Раздача".
+
+#### Как это работает
+
+1. **Автоматический запуск**: Мониторинг запускается автоматически при старте бота
+2. **Polling**: Бот опрашивает статус торрентов каждые 10 секунд через RPC API
+3. **Обнаружение завершения**: При переходе торрента из статуса "Downloading" в "Seeding" (или при достижении 100% загрузки) отправляется уведомление
+4. **Активация**: Отправьте боту любое сообщение (например, `/help`), чтобы он запомнил ваш chat ID для отправки уведомлений
+
+#### Преимущества
+
+- ✅ Не требует доступа к файловой системе
+- ✅ Не требует настройки логирования в Transmission
+- ✅ Работает в любой конфигурации (Docker, standalone, и т.д.)
+- ✅ Более надежный и быстрый метод
+- ✅ Не зависит от формата логов
+
+#### Пример уведомления
+
+Когда торрент завершит загрузку, вы получите сообщение вида:
+```
+✅ Completed: My-Torrent-Name
+```
+
+### Метод 2: Мониторинг через лог-файл (альтернативный)
+
+Альтернативный метод - мониторинг лог-файла Transmission. Этот метод требует дополнительной настройки, но может быть полезен в некоторых случаях.
+
+#### Шаг 1: Включение логирования в Transmission
+
+1. Откройте настройки Transmission (через веб-интерфейс или конфигурационный файл `settings.json`)
+2. Включите логирование, установив параметр `"message-level": 2` (или выше) в `settings.json`
+3. Убедитесь, что логирование включено: `"logging-enabled": true`
+
+Для Docker-контейнера Transmission (linuxserver/transmission) логи обычно находятся в:
+- `/config/transmission.log` (внутри контейнера)
+- `${CONFIG}/transmission/transmission.log` (на хосте, если смонтирован volume)
+
+**Пример настройки в `settings.json`:**
+```json
+{
+ "logging-enabled": true,
+ "message-level": 2
+}
+```
+
+#### Шаг 2: Настройка бота для мониторинга логов
+
+Добавьте параметр `-transmission-logfile` с путем к лог-файлу Transmission при запуске бота.
+
+#### Для CLI:
+
+```bash
+transmission-telegram \
+ -token=<Ваш Токен Бота> \
+ -master=<Ваш Username> \
+ -url= \
+ -transmission-logfile=/path/to/transmission.log
+```
+
+#### Для Docker Standalone:
+
+```bash
+docker run -d --name transmission-telegram \
+ -v /path/to/transmission.log:/transmission.log:ro \
+ kevinhalpin/transmission-telegram:latest \
+ -token=<Ваш Токен Бота> \
+ -master=<Ваш Username> \
+ -url= \
+ -transmission-logfile=/transmission.log
+```
+
+#### Для docker-compose:
+
+```yaml
+version: '2.4'
+services:
+ transmission:
+ container_name: transmission
+ environment:
+ - PUID=${PUID_DOCKUSER}
+ - PGID=${PGID_APPZ}
+ image: linuxserver/transmission
+ network_mode: 'host'
+ hostname: 'transmission'
+ volumes:
+ - ${CONFIG}/transmission:/config
+ - ${DATA}/transmission/downloads:/downloads
+
+ telegram-transmission-bot:
+ container_name: telegram-transmission-bot
+ restart: on-failure
+ depends_on:
+ - transmission
+ network_mode: 'host'
+ image: kevinhalpin/transmission-telegram:latest
+ volumes:
+ - ${CONFIG}/transmission/transmission.log:/transmission.log:ro
+ command: >
+ -token=${TELEGRAM_TRANSMISSION_BOT}
+ -master=${TELEGRAM_USERNAME}
+ -url=${TRANSMISSION_URL}
+ -username=${TRANSMISSION_USERNAME}
+ -password=${PASS}
+ -transmission-logfile=/transmission.log
+```
+
+#### Шаг 3: Активация уведомлений
+
+**Важно**: После запуска бота с параметром `-transmission-logfile`, отправьте боту любое сообщение (например, `/help` или `list`). Это необходимо для того, чтобы бот запомнил ваш chat ID и мог отправлять уведомления.
+
+#### Как это работает
+
+Бот мониторит указанный лог-файл в реальном времени и ищет строки с паттерном `"Incomplete" to "Complete"`, которые Transmission записывает при завершении загрузки торрента. При обнаружении такой строки бот автоматически извлекает имя завершенного торрента и отправляет уведомление в Telegram.
+
+**Пример строки в логе Transmission:**
+```
+[2017-02-22 21:00:00.898] My-Torrent-Name State changed from "Incomplete" to "Complete" (torrent.c:2218)
+```
+
+### Устранение проблем
+
+#### Устранение проблем (метод через лог-файл)
+
+- **Уведомления не приходят**:
+ - Убедитесь, что логирование включено в Transmission (`logging-enabled: true`)
+ - Проверьте, что путь к лог-файлу указан правильно
+ - Убедитесь, что бот имеет доступ на чтение к лог-файлу
+ - Отправьте боту сообщение после запуска, чтобы он запомнил ваш chat ID
+
+- **Лог-файл не найден**:
+ - Проверьте путь к файлу в настройках Transmission
+ - Для Docker: убедитесь, что volume с лог-файлом смонтирован правильно
+ - Проверьте права доступа к файлу
+
+- **Бот не видит изменения в логе**:
+ - Убедитесь, что Transmission действительно пишет в указанный файл
+ - Проверьте уровень логирования (`message-level` должен быть 2 или выше)
+
+#### Устранение проблем (метод через RPC API)
+
+- **Уведомления не приходят**:
+ - Убедитесь, что бот имеет доступ к Transmission RPC API
+ - Проверьте, что Transmission работает и доступен по указанному URL
+ - Отправьте боту сообщение после запуска, чтобы он запомнил ваш chat ID
+ - Проверьте логи бота на наличие ошибок подключения к Transmission
+
+- **Задержка уведомлений**:
+ - Бот опрашивает статус каждые 10 секунд, поэтому может быть небольшая задержка
+ - Это нормальное поведение и не требует настройки
diff --git a/main.go b/main.go
index 64137ec..21756d2 100644
--- a/main.go
+++ b/main.go
@@ -134,6 +134,9 @@ var (
// chatID will be used to keep track of which chat to send completion notifictions.
chatID int64
+ // torrentState stores previous state of torrents for completion detection
+ torrentStates = make(map[int]torrentState)
+
// logging
logger = log.New(os.Stdout, "", log.LstdFlags)
@@ -151,6 +154,12 @@ var (
"`", "'")
)
+// torrentState stores the state of a torrent for completion detection
+type torrentState struct {
+ Status int
+ PercentDone float64
+}
+
// we need a type for masters for the flag package to parse them as a slice
type masterSlice []string
@@ -303,6 +312,9 @@ func init() {
}
func main() {
+ // Start torrent completion monitoring via RPC polling
+ go monitorTorrentCompletion()
+
for update := range Updates {
// ignore edited messages
if update.Message == nil {
@@ -315,8 +327,8 @@ func main() {
continue
}
- // update chatID for complete notification
- if TransLogFile != "" && chatID != update.Message.Chat.ID {
+ // update chatID for complete notification (used by both log monitoring and RPC polling)
+ if chatID != update.Message.Chat.ID {
chatID = update.Message.Chat.ID
}
@@ -1537,6 +1549,70 @@ func getVersion(ud tgbotapi.Update) {
send(fmt.Sprintf("Transmission *%s*\nTransmission-telegram *%s*", Client.Version(), VERSION), ud.Message.Chat.ID, true)
}
+// monitorTorrentCompletion monitors torrents via RPC API polling to detect completion
+// It checks for status change from Downloading to Seeding, indicating completion
+func monitorTorrentCompletion() {
+ // Polling interval - check every 10 seconds
+ ticker := time.NewTicker(10 * time.Second)
+ defer ticker.Stop()
+
+ logger.Printf("[INFO] Starting torrent completion monitoring via RPC polling")
+
+ for range ticker.C {
+ // Skip if no chatID is set yet
+ if chatID == 0 {
+ continue
+ }
+
+ // Get current torrents
+ torrents, err := Client.GetTorrents()
+ if err != nil {
+ logger.Printf("[ERROR] Failed to get torrents for monitoring: %s", err)
+ continue
+ }
+
+ // Check each torrent for completion
+ for _, torrent := range torrents {
+ prevState, exists := torrentStates[torrent.ID]
+
+ // Detect completion: transition from Downloading to Seeding with 100% done
+ completed := false
+ if exists && prevState.Status == transmission.StatusDownloading {
+ // Case 1: Status changed from Downloading to Seeding (most common)
+ if torrent.Status == transmission.StatusSeeding && torrent.PercentDone >= 1.0 {
+ completed = true
+ }
+ // Case 2: Torrent reached 100% while still in Downloading status
+ // (status might change to Seeding in next poll)
+ if torrent.Status == transmission.StatusDownloading &&
+ prevState.PercentDone < 1.0 &&
+ torrent.PercentDone >= 1.0 {
+ completed = true
+ }
+ }
+
+ if completed {
+ // Send completion notification
+ msg := fmt.Sprintf("✅ Completed: %s", torrent.Name)
+ send(msg, chatID, false)
+ logger.Printf("[INFO] Torrent completed: %s (ID: %d)", torrent.Name, torrent.ID)
+ }
+
+ // Update state - only track downloading torrents to save memory
+ if torrent.Status == transmission.StatusDownloading ||
+ torrent.Status == transmission.StatusDownloadPending {
+ torrentStates[torrent.ID] = torrentState{
+ Status: torrent.Status,
+ PercentDone: torrent.PercentDone,
+ }
+ } else {
+ // Remove completed or stopped torrents from tracking
+ delete(torrentStates, torrent.ID)
+ }
+ }
+ }
+}
+
// send takes a chat id and a message to send, returns the message id of the send message
func send(text string, chatID int64, markdown bool) int {
// set typing action