From 15406c732b4a332268d53e7dd58b17587ac409ca Mon Sep 17 00:00:00 2001 From: vrubel Date: Fri, 2 Jan 2026 17:50:10 +0300 Subject: [PATCH 01/10] =?UTF-8?q?=D0=A3=D0=BB=D1=83=D1=87=D1=88=D0=B5?= =?UTF-8?q?=D0=BD=D0=BE=20=D0=BB=D0=BE=D0=B3=D0=B8=D1=80=D0=BE=D0=B2=D0=B0?= =?UTF-8?q?=D0=BD=D0=B8=D0=B5=20=D0=BE=D1=88=D0=B8=D0=B1=D0=BE=D0=BA=20?= =?UTF-8?q?=D0=BF=D1=80=D0=B8=20=D0=BF=D0=BE=D0=B8=D1=81=D0=BA=D0=B5=20?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D1=80=D0=B5=D0=BD=D1=82=D0=BE=D0=B2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- app.py | 32 +++++++++++++++++++++++++------- 1 file changed, 25 insertions(+), 7 deletions(-) diff --git a/app.py b/app.py index cfa2d4d..eceec0f 100644 --- a/app.py +++ b/app.py @@ -283,15 +283,29 @@ async def search_torrents(movie_title: str, year: str = None, original_title: st print(f"Searching '{search_query}' on {provider_name}") # Поиск на конкретном провайдере - исправленный эндпоинт - search_response = await client.get( - f"{TORRENT_SEARCH_URL}/api/search/title/{provider_name}", - params={"query": search_query} - ) + try: + search_response = await client.get( + f"{TORRENT_SEARCH_URL}/api/search/title/{provider_name}", + params={"query": search_query}, + timeout=30.0 + ) + except Exception as request_error: + print(f"Request error on {provider_name} for '{search_query}': {request_error}") + import traceback + traceback.print_exc() + continue if search_response.status_code == 200: - results = search_response.json() + try: + results = search_response.json() + except Exception as json_error: + print(f"JSON parse error on {provider_name} for '{search_query}': {json_error}") + print(f"Response text (first 500 chars): {search_response.text[:500]}") + continue if not isinstance(results, list): print(f"Unexpected response format from {provider_name}: {type(results)}") + if isinstance(results, dict): + print(f"Dict keys: {list(results.keys())}") continue print(f"Found {len(results)} results for '{search_query}' on {provider_name}") @@ -340,7 +354,9 @@ async def search_torrents(movie_title: str, year: str = None, original_title: st break except Exception as e: - print(f"Error searching on {provider_name}: {e}") + print(f"Error searching on {provider_name}: {type(e).__name__}: {e}") + import traceback + traceback.print_exc() continue # Сортируем по количеству сидов и ограничиваем общее количество @@ -458,7 +474,9 @@ async def search_torrent_by_id(torrent_id: str) -> dict: print(f"Error searching by ID on {provider_name}: {response.status_code} - {response.text}") except Exception as e: - print(f"Error searching on {provider_name}: {e}") + print(f"Error searching on {provider_name}: {type(e).__name__}: {e}") + import traceback + traceback.print_exc() continue print(f"No results found for ID {torrent_id} on any provider") From a41f1251bc6181260126757844ff5b40a11c5224 Mon Sep 17 00:00:00 2001 From: vrubel Date: Fri, 2 Jan 2026 17:53:29 +0300 Subject: [PATCH 02/10] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=20.env=20=D1=84=D0=B0=D0=B9=D0=BB=20=D1=81=20?= =?UTF-8?q?=D0=BD=D0=B0=D1=81=D1=82=D1=80=D0=BE=D0=B9=D0=BA=D0=B0=D0=BC?= =?UTF-8?q?=D0=B8?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .env | 26 ++++++++++++++++++++++++++ 1 file changed, 26 insertions(+) create mode 100644 .env diff --git a/.env b/.env new file mode 100644 index 0000000..3120bcb --- /dev/null +++ b/.env @@ -0,0 +1,26 @@ +# 🔧 Конфигурация searchTorrentDownl +# Скопируйте этот файл в .env и заполните своими данными + +# 🎬 TMDB Proxy URL +# URL прокси-сервиса TMDB (работает на хосте без VPN) +# Если прокси на другом хосте, укажите его IP: http://:8001 +# Если прокси на том же хосте: http://localhost:8001 +TMDB_PROXY_URL=http://72.56.91.135:8001 + +# 🤖 Telegram Bot Token +# Получите у @BotFather в Telegram +TELEGRAM_BOT_TOKEN=7662650066:AAFgsfYJNYgpcSHaSe6fspsjqmhMkOBT1s4 + +# 🐳 qBittorrent настройки +QBITTORRENT_USERNAME=admin +QBITTORRENT_PASSWORD=admin +QBITTORRENT_HOST=host.docker.internal +QBITTORRENT_PORT=8082 + +# 🔍 TorAPI настройки +TORRENT_SEARCH_URL=http://72.56.91.135:8443 +TORRENT_ADD_URL=http://host.docker.internal:8088 + +# 🌐 Основное приложение +HOST=0.0.0.0 +PORT=8000 From 6ef3a10d0d7f9532a07863ff124b93cbe778beec Mon Sep 17 00:00:00 2001 From: vrubel Date: Fri, 2 Jan 2026 18:16:03 +0300 Subject: [PATCH 03/10] =?UTF-8?q?=D0=94=D0=BE=D0=B1=D0=B0=D0=B2=D0=BB?= =?UTF-8?q?=D0=B5=D0=BD=D0=B0=20=D1=81=D0=B5=D1=82=D1=8C=20npm=5Fdefault?= =?UTF-8?q?=20=D0=B4=D0=BB=D1=8F=20=D0=B4=D0=BE=D1=81=D1=82=D1=83=D0=BF?= =?UTF-8?q?=D0=B0=20Nginx=20Proxy=20Manager=20=D0=BA=20movie-search?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- docker-compose.yml | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/docker-compose.yml b/docker-compose.yml index ee05a93..beea84e 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -21,6 +21,7 @@ services: networks: - torrentvideo_default - default + - npm_default torapi-search: image: lifailon/torapi:latest @@ -34,6 +35,7 @@ services: networks: - torrentvideo_default - default + - npm_default torapi-qbittorrent: image: lifailon/torapi:latest @@ -51,6 +53,7 @@ services: networks: - torrentvideo_default - default + - npm_default telegram-bot: build: @@ -71,6 +74,7 @@ services: networks: - torrentvideo_default - default + - npm_default depends_on: - movie-search - torapi-search @@ -79,3 +83,5 @@ services: networks: torrentvideo_default: external: true + npm_default: + external: true From 51348a9d2337ff4c6a443aad86296c20aed10e49 Mon Sep 17 00:00:00 2001 From: vrubelroman Date: Wed, 3 Jun 2026 09:29:09 +0000 Subject: [PATCH 04/10] refactor: split into two stacks - searchFilms/ (NL) and app/ (RU) --- .env | 26 - PROJECT_SUMMARY.md | 88 +-- README.md | 540 +++--------------- app/.env.example | 12 + Dockerfile => app/Dockerfile | 0 .../Dockerfile.telegram | 0 MANAGEMENT.md => app/MANAGEMENT.md | 0 SAMBA_ACCESS.md => app/SAMBA_ACCESS.md | 0 .../TELEGRAM_BOT_README.md | 0 .../UBUNTU_DEPLOYMENT.md | 0 app.py => app/app.py | 64 ++- app/docker-compose.yml | 92 +++ requirements.txt => app/requirements.txt | 0 .../run_telegram_bot.py | 0 telegram_bot.py => app/telegram_bot.py | 0 {templates => app/templates}/error.html | 0 {templates => app/templates}/index.html | 0 {templates => app/templates}/results.html | 0 {templates => app/templates}/torrents.html | 0 .../test_telegram_bot.py | 0 deploy.sh | 263 --------- docker-compose.yml | 87 --- env.example | 29 - searchFilms/.env.example | 5 + searchFilms/docker-compose.yml | 31 + .../tmdb-proxy}/Dockerfile | 0 .../tmdb-proxy}/README.md | 0 .../tmdb-proxy}/docker-compose.yml | 0 .../tmdb-proxy}/requirements.txt | 0 .../tmdb-proxy}/tmdb_proxy.py | 0 start_all.sh | 85 --- start_all_services.sh | 37 -- start_ubuntu.sh | 177 ------ stop_all_services.sh | 22 - torapi-proxy/README.md | 25 - torapi-proxy/docker-compose.yml | 14 - 36 files changed, 326 insertions(+), 1271 deletions(-) delete mode 100644 .env create mode 100644 app/.env.example rename Dockerfile => app/Dockerfile (100%) rename Dockerfile.telegram => app/Dockerfile.telegram (100%) rename MANAGEMENT.md => app/MANAGEMENT.md (100%) rename SAMBA_ACCESS.md => app/SAMBA_ACCESS.md (100%) rename TELEGRAM_BOT_README.md => app/TELEGRAM_BOT_README.md (100%) rename UBUNTU_DEPLOYMENT.md => app/UBUNTU_DEPLOYMENT.md (100%) rename app.py => app/app.py (93%) create mode 100644 app/docker-compose.yml rename requirements.txt => app/requirements.txt (100%) rename run_telegram_bot.py => app/run_telegram_bot.py (100%) rename telegram_bot.py => app/telegram_bot.py (100%) rename {templates => app/templates}/error.html (100%) rename {templates => app/templates}/index.html (100%) rename {templates => app/templates}/results.html (100%) rename {templates => app/templates}/torrents.html (100%) rename test_telegram_bot.py => app/test_telegram_bot.py (100%) delete mode 100755 deploy.sh delete mode 100644 docker-compose.yml delete mode 100644 env.example create mode 100644 searchFilms/.env.example create mode 100644 searchFilms/docker-compose.yml rename {tmdb-proxy => searchFilms/tmdb-proxy}/Dockerfile (100%) rename {tmdb-proxy => searchFilms/tmdb-proxy}/README.md (100%) rename {tmdb-proxy => searchFilms/tmdb-proxy}/docker-compose.yml (100%) rename {tmdb-proxy => searchFilms/tmdb-proxy}/requirements.txt (100%) rename {tmdb-proxy => searchFilms/tmdb-proxy}/tmdb_proxy.py (100%) delete mode 100755 start_all.sh delete mode 100755 start_all_services.sh delete mode 100755 start_ubuntu.sh delete mode 100755 stop_all_services.sh delete mode 100644 torapi-proxy/README.md delete mode 100644 torapi-proxy/docker-compose.yml diff --git a/.env b/.env deleted file mode 100644 index 3120bcb..0000000 --- a/.env +++ /dev/null @@ -1,26 +0,0 @@ -# 🔧 Конфигурация searchTorrentDownl -# Скопируйте этот файл в .env и заполните своими данными - -# 🎬 TMDB Proxy URL -# URL прокси-сервиса TMDB (работает на хосте без VPN) -# Если прокси на другом хосте, укажите его IP: http://:8001 -# Если прокси на том же хосте: http://localhost:8001 -TMDB_PROXY_URL=http://72.56.91.135:8001 - -# 🤖 Telegram Bot Token -# Получите у @BotFather в Telegram -TELEGRAM_BOT_TOKEN=7662650066:AAFgsfYJNYgpcSHaSe6fspsjqmhMkOBT1s4 - -# 🐳 qBittorrent настройки -QBITTORRENT_USERNAME=admin -QBITTORRENT_PASSWORD=admin -QBITTORRENT_HOST=host.docker.internal -QBITTORRENT_PORT=8082 - -# 🔍 TorAPI настройки -TORRENT_SEARCH_URL=http://72.56.91.135:8443 -TORRENT_ADD_URL=http://host.docker.internal:8088 - -# 🌐 Основное приложение -HOST=0.0.0.0 -PORT=8000 diff --git a/PROJECT_SUMMARY.md b/PROJECT_SUMMARY.md index 57b2143..2d278b7 100644 --- a/PROJECT_SUMMARY.md +++ b/PROJECT_SUMMARY.md @@ -54,29 +54,35 @@ ## 📊 Технические детали -### Архитектура: +### Архитектура (два стека): ``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ Telegram Bot │ │ Web Interface │ │ qBittorrent │ -│ (Docker) │ │ (Docker) │ │ (Host) │ -└─────────┬───────┘ └─────────┬───────┘ └─────────┬───────┘ - │ │ │ - └──────────────────────┼──────────────────────┘ - │ - ┌─────────────┴─────────────┐ - │ FastAPI App │ - │ (Movie Search API) │ - └─────────────┬─────────────┘ - │ - ┌─────────────┴─────────────┐ - │ TMDB API │ - │ (Movie Information) │ - └─────────────┬─────────────┘ - │ - ┌─────────────┴─────────────┐ - │ TorAPI │ - │ (Torrent Search) │ - └───────────────────────────┘ +┌─────────────────────────────────────────┐ +│ searchFilms/ — NL-хост (72.56.91.135) │ +│ ┌──────────┐ ┌──────────────────────┐ │ +│ │ tmdb- │ │ torapi-search │ │ +│ │ proxy │ │ (rutracker, kinozal, │ │ +│ │ (:8001) │ │ rutor, nnmclub) │ │ +│ └────┬─────┘ └──────────┬───────────┘ │ +│ │ │ │ +│ ┌────┴───────────────────┴───────────┐ │ +│ │ torapi-qbittorrent (:8444) │ │ +│ │ bridge → magnet ссылки │ │ +│ └────────────┬────────────────────────┘ │ +└───────────────┼──────────────────────────┘ + │ интернет +┌───────────────┼──────────────────────────┐ +│ │ app/ — RU-хост │ +│ ┌────────────┴──────────────────────┐ │ +│ │ movie-search (:8089) FastAPI API │ │ +│ │ веб-интерфейс + API endpoints │ │ +│ └────┬──────────────────────┬───────┘ │ +│ │ │ │ +│ ┌────┴──────────┐ ┌──────┴────────┐ │ +│ │ qBittorrent │ │ telegram-bot │ │ +│ │ (192.168.8.177│ │ │ │ +│ │ :8080) │ │ @your_bot │ │ +│ └───────────────┘ └───────────────┘ │ +└─────────────────────────────────────────┘ ``` ### Поддерживаемые трекеры: @@ -136,24 +142,26 @@ docker ps ## 📁 Структура файлов ``` -searchTorrentDownl/ -├── app.py # Основное веб-приложение -├── telegram_bot.py # Telegram бот -├── run_telegram_bot.py # Скрипт запуска бота -├── test_telegram_bot.py # Тестирование бота -├── start_all.sh # Скрипт запуска всего проекта -├── requirements.txt # Python зависимости -├── Dockerfile # Docker образ веб-приложения -├── Dockerfile.telegram # Docker образ Telegram бота -├── docker-compose.yml # Docker Compose конфигурация -├── templates/ # HTML шаблоны -│ ├── index.html # Главная страница -│ ├── results.html # Результаты поиска фильмов -│ ├── torrents.html # Результаты поиска торрентов -│ └── error.html # Страница ошибок -├── README.md # Основная документация -├── TELEGRAM_BOT_README.md # Документация Telegram бота -└── PROJECT_SUMMARY.md # Эта сводка +findFilms/ +├── README.md # Инструкция по запуску +├── PROJECT_SUMMARY.md # Архитектура проекта +├── .gitignore +│ +├── searchFilms/ # 🌍 NL-стек (Голландия, 72.56.91.135) +│ ├── docker-compose.yml # tmdb-proxy + torapi-search + bridge +│ ├── .env.example +│ └── tmdb-proxy/ # build-зависимость +│ ├── Dockerfile +│ └── tmdb_proxy.py +│ +└── app/ # 🏠 RU-стек (Россия, 192.168.8.173) + ├── docker-compose.yml # movie-search + telegram-bot + ├── .env.example + ├── app.py # FastAPI приложение + ├── telegram_bot.py # Telegram бот + ├── Dockerfile + ├── Dockerfile.telegram + └── templates/ # HTML шаблоны ``` ## 🎯 Ключевые особенности diff --git a/README.md b/README.md index d6559a7..0c41586 100644 --- a/README.md +++ b/README.md @@ -1,469 +1,79 @@ -# 🎬 searchTorrentDownl +# findFilms — поиск и скачивание фильмов -**Полнофункциональная система для поиска и загрузки фильмов через торренты с Telegram ботом** - -[![Docker](https://img.shields.io/badge/Docker-Ready-blue?logo=docker)](https://www.docker.com/) -[![Python](https://img.shields.io/badge/Python-3.12+-green?logo=python)](https://python.org/) -[![FastAPI](https://img.shields.io/badge/FastAPI-0.115.0-red?logo=fastapi)](https://fastapi.tiangolo.com/) -[![Telegram](https://img.shields.io/badge/Telegram-Bot-blue?logo=telegram)](https://telegram.org/) - -## 🎯 Описание проекта - -**searchTorrentDownl** - это современная система для поиска и загрузки фильмов, которая объединяет: -- 🌐 **Веб-интерфейс** с адаптивным дизайном -- 🤖 **Telegram бот** с полной функциональностью -- 🔍 **Поиск фильмов** через TMDB API -- 🎬 **Поиск торрентов** на популярных трекерах -- ⬇️ **Автоматическое добавление** в qBittorrent -- 🔔 **Уведомления** о завершении загрузки - -### ✨ Основные возможности - -- **🎬 Поиск фильмов** - интеллектуальный поиск с постерами и описаниями -- **🔍 Поиск торрентов** - на всех популярных трекерах (RuTracker, Kinozal, RuTor, NoNameClub) -- **📱 Telegram бот** - полная функциональность в мессенджере -- **🌐 Веб-интерфейс** - удобный поиск и навигация -- **⬇️ Автоматическая загрузка** - добавление торрентов в qBittorrent одним кликом -- **🔔 Уведомления** - сообщения о завершении загрузки в Telegram -- **🐳 Docker** - полная контейнеризация для простого развертывания - -## 🏗️ Архитектура системы - -``` -┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ -│ Telegram Bot │ │ Web Interface │ │ qBittorrent │ -│ (Docker) │ │ (Docker) │ │ (Host) │ -└─────────┬───────┘ └─────────┬───────┘ └─────────┬───────┘ - │ │ │ - └──────────────────────┼──────────────────────┘ - │ - ┌─────────────┴─────────────┐ - │ FastAPI App │ - │ (Movie Search API) │ - └─────────────┬─────────────┘ - │ - ┌─────────────┴─────────────┐ - │ TMDB API │ - │ (Movie Information) │ - └─────────────┬─────────────┘ - │ - ┌─────────────┴─────────────┐ - │ TorAPI │ - │ (Torrent Search) │ - └───────────────────────────┘ -``` - -### 🔧 Компоненты системы - -1. **FastAPI приложение** (Docker) - основной веб-сервис и API -2. **Telegram Bot** (Docker) - бот для мессенджера -3. **TorAPI-Search** (Docker) - поиск торрентов по названию -4. **TorAPI-qBittorrent** (Docker) - получение magnet ссылок -5. **qBittorrent-nox** (Host) - клиент для загрузки торрентов - -## 📋 Системные требования - -### Минимальные требования -- **ОС**: Linux (Ubuntu 20.04+, Debian 11+) -- **RAM**: 2GB -- **Диск**: 10GB свободного места -- **CPU**: 2 ядра - -### Необходимое ПО -- **Docker**: 20.10+ -- **Docker Compose**: 2.0+ -- **qBittorrent-nox**: 4.6.7+ - -## 🚀 Быстрый старт - -### 1️⃣ Автоматическое развертывание (рекомендуется) - -```bash -# Клонируйте репозиторий -git clone -cd searchTorrentDownl - -# Запустите скрипт развертывания -chmod +x deploy.sh -./deploy.sh -``` - -Скрипт автоматически: -- Установит все зависимости -- Настроит qBittorrent -- Запустит все сервисы -- Покажет статус системы - -### 2️⃣ Ручное развертывание - -#### Шаг 1: Установка зависимостей - -```bash -# Обновление системы -sudo apt update && sudo apt upgrade -y - -# Установка Docker -curl -fsSL https://get.docker.com -o get-docker.sh -sudo sh get-docker.sh -sudo usermod -aG docker $USER - -# Установка Docker Compose -sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose -sudo chmod +x /usr/local/bin/docker-compose - -# Установка qBittorrent -sudo apt install -y qbittorrent-nox -``` - -#### Шаг 2: Настройка qBittorrent - -```bash -# Создание пользователя -sudo useradd -r -s /bin/false qbittorrent - -# Создание systemd сервиса -sudo tee /etc/systemd/system/qbittorrent.service > /dev/null < API](https://www.themoviedb.org/settings/api) -3. Создайте новый API ключ -4. Скопируйте ключ в файл `.env` - -#### Telegram Bot Token -1. Найдите [@BotFather](https://t.me/BotFather) в Telegram -2. Отправьте команду `/newbot` -3. Следуйте инструкциям для создания бота -4. Скопируйте токен в файл `.env` - -### 📝 Файл конфигурации (.env) - -```bash -# TMDB API Key -TMDB_API_KEY=your_tmdb_api_key_here - -# Telegram Bot Token -TELEGRAM_BOT_TOKEN=your_telegram_bot_token_here - -# qBittorrent настройки -QBITTORRENT_USERNAME=admin -QBITTORRENT_PASSWORD=admin -QBITTORRENT_HOST=host.docker.internal -QBITTORRENT_PORT=8080 - -# TorAPI настройки -TORRENT_SEARCH_URL=http://host.docker.internal:8443 -TORRENT_ADD_URL=http://host.docker.internal:8088 -``` - -## 🌐 Использование - -### Веб-интерфейс -1. Откройте http://localhost:8089 -2. Введите название фильма -3. Выберите фильм из результатов -4. Выберите торрент для скачивания -5. Торрент автоматически добавится в qBittorrent - -### Telegram Bot -1. Найдите вашего бота в Telegram -2. Отправьте команду `/start` или `/find` -3. Введите название фильма -4. Выберите фильм из списка -5. Нажмите "Найти торренты" -6. Выберите нужный торрент -7. Получите уведомление о завершении загрузки - -### qBittorrent -- **Веб-интерфейс**: http://localhost:8080 -- **Логин по умолчанию**: admin / admin -- **Настройка папок**: Settings > Downloads - -## 📁 Структура проекта - -``` -searchTorrentDownl/ -├── app.py # Основное FastAPI приложение -├── telegram_bot.py # Telegram бот -├── run_telegram_bot.py # Скрипт запуска бота -├── deploy.sh # Скрипт автоматического развертывания -├── start_all.sh # Скрипт запуска (локально) -├── requirements.txt # Python зависимости -├── env.example # Пример конфигурации -├── Dockerfile # Docker образ основного приложения -├── Dockerfile.telegram # Docker образ Telegram бота -├── docker-compose.yml # Docker Compose конфигурация -├── templates/ # HTML шаблоны -│ ├── index.html # Главная страница -│ ├── results.html # Результаты поиска фильмов -│ ├── torrents.html # Результаты поиска торрентов -│ └── error.html # Страница ошибок -├── README.md # Основная документация -├── TELEGRAM_BOT_README.md # Документация Telegram бота -└── PROJECT_SUMMARY.md # Сводка проекта -``` - -## 🔧 Управление сервисами - -### Основные команды - -```bash -# Запуск всех сервисов -docker compose up -d - -# Остановка всех сервисов -docker compose down - -# Перезапуск сервисов -docker compose restart - -# Просмотр логов -docker compose logs -f - -# Просмотр статуса -docker ps -``` - -### Управление отдельными сервисами - -```bash -# Запуск только веб-приложения -docker compose up -d movie-search - -# Запуск только Telegram бота -docker compose up -d telegram-bot - -# Перезапуск TorAPI -docker compose restart torapi-search torapi-qbittorrent -``` - -### Управление qBittorrent - -```bash -# Запуск -sudo systemctl start qbittorrent - -# Остановка -sudo systemctl stop qbittorrent - -# Статус -sudo systemctl status qbittorrent - -# Логи -sudo journalctl -u qbittorrent -f -``` - -## 🐛 Устранение неполадок - -### Проблемы с Docker - -```bash -# Проверка статуса контейнеров -docker ps -a - -# Просмотр логов -docker logs - -# Пересборка контейнеров -docker compose up -d --build --force-recreate -``` - -### Проблемы с qBittorrent - -```bash -# Проверка статуса -sudo systemctl status qbittorrent - -# Перезапуск -sudo systemctl restart qbittorrent - -# Проверка портов -netstat -tlnp | grep 8080 -``` - -### Проблемы с сетью - -```bash -# Проверка Docker сетей -docker network ls - -# Создание сети заново -docker network rm torrentvideo_default -docker network create torrentvideo_default -``` - -### Проблемы с API - -```bash -# Проверка TMDB API -curl "https://api.themoviedb.org/3/movie/550?api_key=YOUR_API_KEY" - -# Проверка Telegram Bot -curl "https://api.telegram.org/botYOUR_BOT_TOKEN/getMe" - -# Проверка TorAPI -curl "http://localhost:8443/api/provider/list" -``` - -## 📊 Мониторинг - -### Логи сервисов - -```bash -# Все сервисы -docker compose logs -f - -# Конкретный сервис -docker logs -f movie-search -docker logs -f telegram-bot -docker logs -f TorAPI-Search -docker logs -f TorAPI-qBittorrent -``` - -### Мониторинг ресурсов - -```bash -# Использование ресурсов контейнерами -docker stats - -# Использование диска -df -h - -# Использование памяти -free -h -``` - -## 🔒 Безопасность - -### Рекомендации - -1. **Измените пароли по умолчанию** - ```bash - # В файле .env - QBITTORRENT_PASSWORD=your_secure_password - ``` - -2. **Настройте файрвол** - ```bash - sudo ufw allow 8080 # qBittorrent - sudo ufw allow 8089 # Web interface - sudo ufw enable - ``` - -3. **Используйте HTTPS в продакшене** - - Настройте reverse proxy (nginx) - - Получите SSL сертификат - -4. **Регулярно обновляйте зависимости** - ```bash - docker compose pull - docker compose up -d --build - ``` - -## 🚀 Развертывание в продакшене - -### Настройка reverse proxy (nginx) - -```nginx -server { - listen 80; - server_name your-domain.com; - - location / { - proxy_pass http://localhost:8089; - proxy_set_header Host $host; - proxy_set_header X-Real-IP $remote_addr; - } -} -``` - -### Использование Docker Swarm - -```bash -# Инициализация Swarm -docker swarm init - -# Развертывание стека -docker stack deploy -c docker-compose.yml searchtorrentdownl -``` - -## 🤝 Вклад в проект - -1. Форкните репозиторий -2. Создайте ветку для новой функции -3. Внесите изменения -4. Создайте Pull Request - -## 📄 Лицензия - -Этот проект распространяется под лицензией MIT. См. файл [LICENSE](LICENSE) для подробностей. - -## 🆘 Поддержка - -При возникновении проблем: - -1. Проверьте [раздел устранения неполадок](#-устранение-неполадок) -2. Изучите логи сервисов -3. Создайте issue в репозитории -4. Опишите проблему и приложите логи - -## 📈 Планы развития - -- [ ] Поддержка дополнительных трекеров -- [ ] Веб-интерфейс для управления ботом -- [ ] Система уведомлений по email -- [ ] API для интеграции с другими приложениями -- [ ] Поддержка сериалов и аниме -- [ ] Мобильное приложение +Двухстековая архитектура: **searchFilms/** на NL-хосте (Голландия, без блокировок), **app/** на RU-хосте (Россия). Между собой общаются по HTTP через интернет. --- -**Создано с ❤️ для удобного поиска и загрузки фильмов** \ No newline at end of file +## Архитектура + +``` +searchFilms/ (NL, 72.56.91.135) internet app/ (RU, 192.168.8.173) +┌─────────────────────────┐ HTTP ┌─────────────────────────────┐ +│ tmdb-proxy (:8001) │ ←──────────→ │ movie-search (:8089) │ +│ torapi-search (:8443) │ поиск │ telegram-bot │ +│ │ │ qBittorrent (:8080) │ +└─────────────────────────┘ └─────────────────────────────┘ +``` + +**Поток данных:** +1. Пользователь ищет фильм → movie-search делает запрос к **tmdb-proxy** (NL) +2. Пользователь ищет торренты → movie-search делает запрос к **torapi-search** (NL) +3. Пользователь добавляет торрент → movie-search отдаёт magnet-ссылку в **qBittorrent** (локально) + +NL-хосту **не нужен** доступ к RU — только RU ходит к NL. + +--- + +## Быстрый старт + +### 🌍 SearchFilms Stack — на голландском хосте (72.56.91.135) + +```bash +cd searchFilms +cp .env.example .env # указать TMDB_API_KEY +docker compose up -d --build +``` + +Откроет порты: +- `:8001` — TMDB API Proxy +- `:8443` — TorAPI Search + +### 🏠 App Stack — на хосте в России + +```bash +cd app +cp .env.example .env # указать TELEGRAM_BOT_TOKEN +docker compose up -d --build +``` + +Откроет: +- `:8089` — веб-интерфейс +- Telegram бот (ждёт команды `/start`) + +### Переменные окружения + +| Переменная | Где | Назначение | +|---|---|---| +| `NL_HOST` | `app/.env` | IP голландского хоста (по умолч. `72.56.91.135`) | +| `TELEGRAM_BOT_TOKEN` | `app/.env` | Токен бота от @BotFather | +| `TMDB_API_KEY` | `search/.env` | Ключ TMDB API | +| `QBITTORRENT_USERNAME` | `app/.env` | Логин qBittorrent | +| `QBITTORRENT_PASSWORD` | `app/.env` | Пароль qBittorrent | + +--- + +## Структура + +``` +findFilms/ +├── README.md ← этот файл +├── PROJECT_SUMMARY.md ← архитектура +├── searchFilms/ ← NL-стек +│ ├── docker-compose.yml +│ ├── .env.example +│ └── tmdb-proxy/ ← build-зависимость +└── app/ ← RU-стек + ├── docker-compose.yml + ├── .env.example + ├── app.py / telegram_bot.py / templates / Dockerfile / ... +``` diff --git a/app/.env.example b/app/.env.example new file mode 100644 index 0000000..55d604b --- /dev/null +++ b/app/.env.example @@ -0,0 +1,12 @@ +# 🔧 App Stack — переменные окружения (RU-хост) +# Скопируйте в .env и заполните своими данными + +# 🎬 NL-хост (голландский сервер) +# IP, на котором запущен search-стек (tmdb-proxy + torapi) +NL_HOST=72.56.91.135 + +# 🤖 Telegram Bot Token (от @BotFather) +TELEGRAM_BOT_TOKEN=ваш_то...n +# 🐳 qBittorrent (на этом же хосте, порт 8080) +QBITTORRENT_USERNAME=vrubelroman +QBITTORRENT_PASSWORD=ваш_па... diff --git a/Dockerfile b/app/Dockerfile similarity index 100% rename from Dockerfile rename to app/Dockerfile diff --git a/Dockerfile.telegram b/app/Dockerfile.telegram similarity index 100% rename from Dockerfile.telegram rename to app/Dockerfile.telegram diff --git a/MANAGEMENT.md b/app/MANAGEMENT.md similarity index 100% rename from MANAGEMENT.md rename to app/MANAGEMENT.md diff --git a/SAMBA_ACCESS.md b/app/SAMBA_ACCESS.md similarity index 100% rename from SAMBA_ACCESS.md rename to app/SAMBA_ACCESS.md diff --git a/TELEGRAM_BOT_README.md b/app/TELEGRAM_BOT_README.md similarity index 100% rename from TELEGRAM_BOT_README.md rename to app/TELEGRAM_BOT_README.md diff --git a/UBUNTU_DEPLOYMENT.md b/app/UBUNTU_DEPLOYMENT.md similarity index 100% rename from UBUNTU_DEPLOYMENT.md rename to app/UBUNTU_DEPLOYMENT.md diff --git a/app.py b/app/app.py similarity index 93% rename from app.py rename to app/app.py index eceec0f..61ff12b 100644 --- a/app.py +++ b/app/app.py @@ -442,6 +442,32 @@ async def search_torrent_by_id(torrent_id: str) -> dict: if not magnet or not magnet.startswith('magnet:'): print(f"Warning: No hash found and no valid magnet link. Hash: {hash_value}, Magnet: {result.get('Magnet', 'None')[:50]}") magnet = "" + + # Пробуем локальный torapi-qbit если хэш пустой + if not hash_value or not magnet or 'urn:btih:' not in magnet or len(magnet) < 30: + try: + torapi_add_url = os.getenv("TORAPI_ADD_URL", "http://localhost:8444") + fb_resp = await client.get( + f"{torapi_add_url}/api/search/id/{provider_name}", + params={"query": torrent_id}, + timeout=15.0 + ) + if fb_resp.status_code == 200: + fb_data = fb_resp.json() + if isinstance(fb_data, list) and len(fb_data) > 0: + fb_result = fb_data[0] + fb_hash = fb_result.get('Hash', '') + if not fb_hash: + import re as re2 + fb_magnet = fb_result.get('Magnet', '') + hm2 = re2.search(r'urn:btih:([a-fA-F0-9]{40})', fb_magnet) + if hm2: + fb_hash = hm2.group(1) + if fb_hash: + magnet = generate_clean_magnet(fb_hash, torrent_name) + print(f"torapi-qbit fallback: got magnet hash {fb_hash[:10]}...") + except Exception as fbe: + print(f"torapi-qbit fallback failed: {fbe}") # Парсим результат в стандартный формат torrent = { @@ -479,7 +505,43 @@ async def search_torrent_by_id(torrent_id: str) -> dict: traceback.print_exc() continue - print(f"No results found for ID {torrent_id} on any provider") + print(f"No results found for ID {torrent_id} on any provider via search API") + + # Fallback: пробуем локальный torapi-qbit (через qBittorrent) + try: + torapi_add_url = os.getenv("TORAPI_ADD_URL", "http://localhost:8444") + fallback_response = await client.get( + f"{torapi_add_url}/api/search/id/rutracker", + params={"query": torrent_id}, + timeout=30.0 + ) + if fallback_response.status_code == 200: + fallback_results = fallback_response.json() + if isinstance(fallback_results, list) and len(fallback_results) > 0: + result = fallback_results[0] + hash_value = result.get('Hash', '') + if not hash_value: + orig_magnet = result.get('Magnet', '') + hm = re.search(r'urn:btih:([a-fA-F0-9]{40})', orig_magnet) + if hm: + hash_value = hm.group(1) + if hash_value: + torrent_name = result.get('Name', '') or result.get('Original_Name', '') + magnet = generate_clean_magnet(hash_value, torrent_name) + print(f"Fallback: got magnet via torapi-qbit: {magnet[:60]}...") + return { + "title": torrent_name, + "url": result.get('Url', ''), + "hash": hash_value, + "magnet": magnet, + "torrent_url": result.get('Torrent', ''), + "provider": "torapi-qbit", + "id": torrent_id + } + except Exception as e: + print(f"Fallback to torapi-qbit failed: {e}") + + print(f"All fallbacks exhausted for ID {torrent_id}") return None except Exception as e: diff --git a/app/docker-compose.yml b/app/docker-compose.yml new file mode 100644 index 0000000..c117659 --- /dev/null +++ b/app/docker-compose.yml @@ -0,0 +1,92 @@ +# 🏠 App Stack — сервисы, запускаемые на хосте в России (192.168.8.173) +# Веб-интерфейс + Telegram бот для поиска и скачивания фильмов +# +# ⚡ Запуск: +# cd app && docker compose up -d --build +# +# 📋 Перед запуском создайте .env из .env.example + +services: + # ============================================================ + # 🌐 Веб-приложение + API + # ============================================================ + movie-search: + build: . + container_name: movie-search + env_file: + - .env + environment: + # NL-сервисы (поиск фильмов и торрентов, без блокировок) + - TMDB_PROXY_URL=http://${NL_HOST:-72.56.91.135}:8001 + - TORRENT_SEARCH_URL=http://${NL_HOST:-72.56.91.135}:8443 + + # Локальный torapi-qbit — резолвит magnet через qBittorrent + - TORRENT_ADD_URL=http://app-torapi-qbit:8443 + - TORAPI_ADD_URL=http://app-torapi-qbit:8443 + + # qBittorrent (на 192.168.8.177) + - QBITTORRENT_USERNAME=${QBITTORRENT_USERNAME:-vrubelroman} + - QBITTORRENT_PASSWORD=${QBITTORRENT_PASSWORD:-VRKshtein07} + - QBITTORRENT_HOST=${QBITTORRENT_HOST:-192.168.8.177} + - QBITTORRENT_PORT=${QBITTORRENT_PORT:-8080} + + - HOST=0.0.0.0 + - PORT=8000 + ports: + - "0.0.0.0:8089:8000" + restart: unless-stopped + networks: + - app-stack + depends_on: + - app-torapi-qbit + + # ============================================================ + # 🤖 Telegram бот + # ============================================================ + telegram-bot: + build: + context: . + dockerfile: Dockerfile.telegram + container_name: telegram-bot-findFilms + env_file: + - .env + environment: + # NL-сервисы (поиск) + - TMDB_PROXY_URL=http://${NL_HOST:-72.56.91.135}:8001 + - TORRENT_SEARCH_URL=http://${NL_HOST:-72.56.91.135}:8443 + + # Локальный torapi-qbit + - TORRENT_ADD_URL=http://app-torapi-qbit:8443 + + # qBittorrent (на 192.168.8.177) + - QBITTORRENT_USERNAME=${QBITTORRENT_USERNAME:-vrubelroman} + - QBITTORRENT_PASSWORD=${QBITTORRENT_PASSWORD:-VRKshtein07} + - QBITTORRENT_HOST=${QBITTORRENT_HOST:-192.168.8.177} + - QBITTORRENT_PORT=${QBITTORRENT_PORT:-8080} + restart: unless-stopped + networks: + - app-stack + depends_on: + - movie-search + + # ============================================================ + # 🔗 TorAPI → qBittorrent bridge — magnet ссылки + # Проксирует запросы к qBittorrent для получения magnet-хэшей + # ============================================================ + app-torapi-qbit: + image: lifailon/torapi:latest + container_name: app-torapi-qbit + environment: + - USERNAME=${QBITTORRENT_USERNAME:-vrubelroman} + - PASSWORD=${QBITTORRENT_PASSWORD:-VRKshtein07} + - PROXY_ADDRESS=${QBITTORRENT_HOST:-192.168.8.177} + - PROXY_PORT=${QBITTORRENT_PORT:-8080} + ports: + - "0.0.0.0:8088:8443" + restart: unless-stopped + networks: + - app-stack + +networks: + app-stack: + driver: bridge diff --git a/requirements.txt b/app/requirements.txt similarity index 100% rename from requirements.txt rename to app/requirements.txt diff --git a/run_telegram_bot.py b/app/run_telegram_bot.py similarity index 100% rename from run_telegram_bot.py rename to app/run_telegram_bot.py diff --git a/telegram_bot.py b/app/telegram_bot.py similarity index 100% rename from telegram_bot.py rename to app/telegram_bot.py diff --git a/templates/error.html b/app/templates/error.html similarity index 100% rename from templates/error.html rename to app/templates/error.html diff --git a/templates/index.html b/app/templates/index.html similarity index 100% rename from templates/index.html rename to app/templates/index.html diff --git a/templates/results.html b/app/templates/results.html similarity index 100% rename from templates/results.html rename to app/templates/results.html diff --git a/templates/torrents.html b/app/templates/torrents.html similarity index 100% rename from templates/torrents.html rename to app/templates/torrents.html diff --git a/test_telegram_bot.py b/app/test_telegram_bot.py similarity index 100% rename from test_telegram_bot.py rename to app/test_telegram_bot.py diff --git a/deploy.sh b/deploy.sh deleted file mode 100755 index d8b4fe4..0000000 --- a/deploy.sh +++ /dev/null @@ -1,263 +0,0 @@ -#!/bin/bash - -# 🚀 Скрипт развертывания searchTorrentDownl на новом компьютере -# Автор: AI Assistant -# Версия: 1.0 - -set -e # Остановка при ошибке - -echo "🎬 searchTorrentDownl - Скрипт развертывания" -echo "==============================================" -echo "" - -# Цвета для вывода -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# Функция для вывода сообщений -log_info() { - echo -e "${BLUE}ℹ️ $1${NC}" -} - -log_success() { - echo -e "${GREEN}✅ $1${NC}" -} - -log_warning() { - echo -e "${YELLOW}⚠️ $1${NC}" -} - -log_error() { - echo -e "${RED}❌ $1${NC}" -} - -# Проверка операционной системы -check_os() { - log_info "Проверка операционной системы..." - - if [[ "$OSTYPE" == "linux-gnu"* ]]; then - log_success "Linux обнаружен" - else - log_error "Этот скрипт предназначен для Linux. Обнаружена ОС: $OSTYPE" - exit 1 - fi -} - -# Проверка прав root -check_root() { - if [[ $EUID -eq 0 ]]; then - log_warning "Скрипт запущен от root. Рекомендуется запускать от обычного пользователя." - read -p "Продолжить? (y/N): " -n 1 -r - echo - if [[ ! $REPLY =~ ^[Yy]$ ]]; then - exit 1 - fi - fi -} - -# Обновление системы -update_system() { - log_info "Обновление системы..." - sudo apt update && sudo apt upgrade -y - log_success "Система обновлена" -} - -# Установка Docker -install_docker() { - log_info "Проверка Docker..." - - if command -v docker &> /dev/null; then - log_success "Docker уже установлен" - else - log_info "Установка Docker..." - curl -fsSL https://get.docker.com -o get-docker.sh - sudo sh get-docker.sh - sudo usermod -aG docker $USER - rm get-docker.sh - log_success "Docker установлен" - fi - - # Проверка Docker Compose - if command -v docker-compose &> /dev/null; then - log_success "Docker Compose уже установлен" - else - log_info "Установка Docker Compose..." - sudo curl -L "https://github.com/docker/compose/releases/latest/download/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose - sudo chmod +x /usr/local/bin/docker-compose - log_success "Docker Compose установлен" - fi -} - -# Установка qBittorrent -install_qbittorrent() { - log_info "Проверка qBittorrent..." - - if command -v qbittorrent-nox &> /dev/null; then - log_success "qBittorrent уже установлен" - else - log_info "Установка qBittorrent-nox..." - sudo apt install -y qbittorrent-nox - log_success "qBittorrent установлен" - fi -} - -# Настройка qBittorrent -setup_qbittorrent() { - log_info "Настройка qBittorrent..." - - # Создание пользователя qbittorrent если не существует - if ! id "qbittorrent" &>/dev/null; then - sudo useradd -r -s /bin/false qbittorrent - fi - - # Создание директории для конфигурации - sudo mkdir -p /home/qbittorrent/.config/qBittorrent - sudo chown -R qbittorrent:qbittorrent /home/qbittorrent - - # Создание systemd сервиса - sudo tee /etc/systemd/system/qbittorrent.service > /dev/null <" - log_info "cd searchTorrentDownl" - exit 1 - fi -} - -# Настройка переменных окружения -setup_environment() { - log_info "Настройка переменных окружения..." - - if [ ! -f ".env" ]; then - log_info "Создание файла .env..." - cat > .env </dev/null || true - - # Сборка и запуск - docker compose up -d --build - - log_success "Сервисы запущены" -} - -# Проверка статуса -check_status() { - log_info "Проверка статуса сервисов..." - - echo "" - echo "📊 Статус контейнеров:" - docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" - - echo "" - echo "🌐 Доступные сервисы:" - echo " • Веб-интерфейс: http://localhost:8089" - echo " • qBittorrent: http://localhost:8080 (admin/admin)" - echo " • Telegram Bot: @your_bot_username (команда /start)" - - echo "" - echo "📝 Следующие шаги:" - echo " 1. Откройте http://localhost:8080 и настройте qBittorrent" - echo " 2. Отредактируйте .env файл с вашими API ключами" - echo " 3. Перезапустите сервисы: docker compose restart" - echo " 4. Откройте http://localhost:8089 для тестирования" -} - -# Основная функция -main() { - echo "🚀 Начинаем развертывание searchTorrentDownl..." - echo "" - - check_os - check_root - update_system - install_docker - install_qbittorrent - setup_qbittorrent - create_docker_network - clone_repository - setup_environment - start_services - check_status - - echo "" - log_success "🎉 Развертывание завершено успешно!" - echo "" - log_info "Для остановки сервисов: docker compose down" - log_info "Для просмотра логов: docker compose logs -f" - log_info "Для перезапуска: docker compose restart" -} - -# Запуск -main "$@" diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index beea84e..0000000 --- a/docker-compose.yml +++ /dev/null @@ -1,87 +0,0 @@ -services: - movie-search: - build: . - container_name: movie-search - env_file: - - .env - environment: - - HOST=0.0.0.0 - - PORT=8000 - - TORAPI_URL=http://torrent-api:8000 - - TORRENT_ADD_URL=http://host.docker.internal:8088 - - QBITTORRENT_USERNAME=vrubelroman - - QBITTORRENT_PASSWORD=vrubel07 - - QBITTORRENT_HOST=host.docker.internal - - QBITTORRENT_PORT=8082 - ports: - - "0.0.0.0:8089:8000" - restart: unless-stopped - extra_hosts: - - "host.docker.internal:host-gateway" - networks: - - torrentvideo_default - - default - - npm_default - - torapi-search: - image: lifailon/torapi:latest - container_name: TorAPI-Search - environment: - - USERNAME= - - PASSWORD= - ports: - - "8443:8443" - restart: unless-stopped - networks: - - torrentvideo_default - - default - - npm_default - - torapi-qbittorrent: - image: lifailon/torapi:latest - container_name: TorAPI-qBittorrent - environment: - - USERNAME=vrubelroman - - PASSWORD=vrubel07 - - PROXY_ADDRESS=host.docker.internal - - PROXY_PORT=8082 - ports: - - "8444:8443" - restart: unless-stopped - extra_hosts: - - "host.docker.internal:host-gateway" - networks: - - torrentvideo_default - - default - - npm_default - - telegram-bot: - build: - context: . - dockerfile: Dockerfile.telegram - container_name: telegram-bot-findFilms - env_file: - - .env - environment: - - TORRENT_ADD_URL=http://host.docker.internal:8088 - - QBITTORRENT_USERNAME=vrubelroman - - QBITTORRENT_PASSWORD=vrubel07 - - QBITTORRENT_HOST=host.docker.internal - - QBITTORRENT_PORT=8082 - restart: unless-stopped - extra_hosts: - - "host.docker.internal:host-gateway" - networks: - - torrentvideo_default - - default - - npm_default - depends_on: - - movie-search - - torapi-search - - torapi-qbittorrent - -networks: - torrentvideo_default: - external: true - npm_default: - external: true diff --git a/env.example b/env.example deleted file mode 100644 index 1db7407..0000000 --- a/env.example +++ /dev/null @@ -1,29 +0,0 @@ -# 🔧 Конфигурация searchTorrentDownl -# Скопируйте этот файл в .env и заполните своими данными - -# 🎬 TMDB Proxy URL -# URL прокси-сервиса TMDB (работает на хосте без VPN) -# Если прокси на другом хосте, укажите его IP: http://:8001 -# Если прокси на том же хосте: http://localhost:8001 -TMDB_PROXY_URL=72.56.91.135:8001 - -# 🤖 Telegram Bot Token -# Получите у @BotFather в Telegram -TELEGRAM_BOT_TOKEN=7662650066:AAFgsfYJNYgpcSHaSe6fspsjqmhMkOBT1s4 - -# 🐳 qBittorrent настройки -QBITTORRENT_USERNAME=admin -QBITTORRENT_PASSWORD=admin -QBITTORRENT_HOST=host.docker.internal -QBITTORRENT_PORT=8082 - -# 🔍 TorAPI настройки -# URL TorAPI для поиска торрентов (работает на хосте с VPN) -# Если TorAPI на другом хосте, укажите его IP: http://:8443 -# Если TorAPI на том же хосте: http://localhost:8443 -TORRENT_SEARCH_URL=http://72.56.91.135:8443 -TORRENT_ADD_URL=http://host.docker.internal:8088 - -# 🌐 Основное приложение -HOST=0.0.0.0 -PORT=8000 diff --git a/searchFilms/.env.example b/searchFilms/.env.example new file mode 100644 index 0000000..df5222b --- /dev/null +++ b/searchFilms/.env.example @@ -0,0 +1,5 @@ +# Search Stack — NL-хост (72.56.91.135) + +# 🎬 TMDB API Key +# Получить: https://www.themoviedb.org/settings/api +TMDB_API_KEY=ваш_кл... diff --git a/searchFilms/docker-compose.yml b/searchFilms/docker-compose.yml new file mode 100644 index 0000000..6d7acee --- /dev/null +++ b/searchFilms/docker-compose.yml @@ -0,0 +1,31 @@ +services: + tmdb-proxy: + build: ./tmdb-proxy + container_name: search-tmdb-proxy + environment: + - TMDB_API_KEY=$TMDB_API_KEY + - PORT=8001 + ports: + - "0.0.0.0:8001:8001" + restart: unless-stopped + dns: + - 8.8.8.8 + - 8.8.4.4 + networks: + - search-stack + + torapi-search: + image: lifailon/torapi:latest + container_name: search-torapi + environment: + - USERNAME= + - PASSWORD= + ports: + - "0.0.0.0:8443:8443" + restart: unless-stopped + networks: + - search-stack + +networks: + search-stack: + driver: bridge diff --git a/tmdb-proxy/Dockerfile b/searchFilms/tmdb-proxy/Dockerfile similarity index 100% rename from tmdb-proxy/Dockerfile rename to searchFilms/tmdb-proxy/Dockerfile diff --git a/tmdb-proxy/README.md b/searchFilms/tmdb-proxy/README.md similarity index 100% rename from tmdb-proxy/README.md rename to searchFilms/tmdb-proxy/README.md diff --git a/tmdb-proxy/docker-compose.yml b/searchFilms/tmdb-proxy/docker-compose.yml similarity index 100% rename from tmdb-proxy/docker-compose.yml rename to searchFilms/tmdb-proxy/docker-compose.yml diff --git a/tmdb-proxy/requirements.txt b/searchFilms/tmdb-proxy/requirements.txt similarity index 100% rename from tmdb-proxy/requirements.txt rename to searchFilms/tmdb-proxy/requirements.txt diff --git a/tmdb-proxy/tmdb_proxy.py b/searchFilms/tmdb-proxy/tmdb_proxy.py similarity index 100% rename from tmdb-proxy/tmdb_proxy.py rename to searchFilms/tmdb-proxy/tmdb_proxy.py diff --git a/start_all.sh b/start_all.sh deleted file mode 100755 index 3aa257e..0000000 --- a/start_all.sh +++ /dev/null @@ -1,85 +0,0 @@ -#!/bin/bash - -# Скрипт для запуска всего проекта searchTorrentDownl -# Включает веб-приложение и Telegram бота - -echo "🚀 Запуск проекта searchTorrentDownl..." - -# Проверяем, что мы в правильной директории -if [ ! -f "app.py" ]; then - echo "❌ Ошибка: Запустите скрипт из директории проекта" - exit 1 -fi - -# Создаем виртуальное окружение если его нет -if [ ! -d "venv" ]; then - echo "📦 Создание виртуального окружения..." - python3 -m venv venv -fi - -# Активируем виртуальное окружение -echo "🔧 Активация виртуального окружения..." -source venv/bin/activate - -# Устанавливаем зависимости -echo "📥 Установка зависимостей..." -pip install -r requirements.txt - -# Проверяем, что qBittorrent запущен -echo "🔍 Проверка qBittorrent..." -if ! curl -s http://localhost:8080/api/v2/app/version > /dev/null; then - echo "⚠️ qBittorrent не запущен. Запустите его командой:" - echo " sudo systemctl start qbittorrent" - echo " или" - echo " sudo -u qbittorrent /usr/bin/qbittorrent-nox --webui-port=8080" - echo "" - echo "🔧 Продолжаем без qBittorrent (поиск фильмов будет работать)..." -fi - -# Запускаем основное приложение в фоне -echo "🌐 Запуск веб-приложения..." -python3 app.py & -APP_PID=$! - -# Ждем немного, чтобы приложение запустилось -sleep 3 - -# Проверяем, что приложение запустилось -if ! curl -s http://localhost:8089/api/search/terminator > /dev/null; then - echo "❌ Ошибка запуска веб-приложения" - kill $APP_PID 2>/dev/null - exit 1 -fi - -echo "✅ Веб-приложение запущено на http://localhost:8089" - -# Запускаем Telegram бота -echo "🤖 Запуск Telegram бота..." -python3 run_telegram_bot.py & -BOT_PID=$! - -echo "" -echo "🎉 Проект успешно запущен!" -echo "" -echo "📱 Доступные интерфейсы:" -echo " • Веб-интерфейс: http://localhost:8089" -echo " • qBittorrent: http://localhost:8080 (admin/vrubel07)" -echo " • Telegram Bot: @your_bot_username (команда /start)" -echo "" -echo "🛑 Для остановки нажмите Ctrl+C" - -# Функция для корректного завершения -cleanup() { - echo "" - echo "🛑 Остановка сервисов..." - kill $APP_PID 2>/dev/null - kill $BOT_PID 2>/dev/null - echo "✅ Все сервисы остановлены" - exit 0 -} - -# Перехватываем сигнал завершения -trap cleanup SIGINT SIGTERM - -# Ждем завершения -wait diff --git a/start_all_services.sh b/start_all_services.sh deleted file mode 100755 index 64f0eef..0000000 --- a/start_all_services.sh +++ /dev/null @@ -1,37 +0,0 @@ -#!/bin/bash - -# Скрипт для запуска всех сервисов findFilms -echo "🚀 Запуск всех сервисов findFilms..." - -# Переходим в директорию проекта -cd /Users/admin/Documents/PROJECTS/TorrentFilm/findFilms - -# Запускаем qBittorrent локально (если не запущен) -if ! pgrep -f "qbittorrent.*--webui-port=8082" > /dev/null; then - echo "📱 Запуск qBittorrent..." - /Applications/qBittorrent.app/Contents/MacOS/qbittorrent --webui-port=8082 --no-splash --confirm-legal-notice & - sleep 5 -fi - -# Запускаем Docker сервисы -echo "🐳 Запуск Docker сервисов..." -docker compose up -d - -# Проверяем статус -echo "📊 Проверка статуса сервисов..." -sleep 5 - -echo "" -echo "🎉 Все сервисы запущены!" -echo "" -echo "📱 Доступные интерфейсы:" -echo " • Веб-интерфейс: http://localhost:8089" -echo " • qBittorrent: http://localhost:8082 (admin/vrubel07)" -echo " • Telegram Bot: @your_bot_username" -echo "" -echo "🔧 Управление:" -echo " • Остановить все: docker compose down" -echo " • Перезапустить: docker compose restart" -echo " • Логи: docker compose logs -f" - - diff --git a/start_ubuntu.sh b/start_ubuntu.sh deleted file mode 100755 index 0399e35..0000000 --- a/start_ubuntu.sh +++ /dev/null @@ -1,177 +0,0 @@ -#!/bin/bash - -# Скрипт для запуска всех сервисов findFilms на Ubuntu -# Устанавливает qBittorrent, настраивает systemd и запускает Docker контейнеры - -set -e # Остановка при ошибке - -echo "🚀 Запуск findFilms для Ubuntu" -echo "==============================================" -echo "" - -# Цвета для вывода -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -log_info() { - echo -e "${BLUE}ℹ️ $1${NC}" -} - -log_success() { - echo -e "${GREEN}✅ $1${NC}" -} - -log_warning() { - echo -e "${YELLOW}⚠️ $1${NC}" -} - -log_error() { - echo -e "${RED}❌ $1${NC}" -} - -# Проверка директории -if [ ! -f "app.py" ]; then - log_error "Запустите скрипт из директории проекта findFilms" - exit 1 -fi - -# Шаг 1: Проверка и установка Docker -log_info "Проверка Docker..." -if ! command -v docker &> /dev/null; then - log_warning "Docker не найден, установка Docker..." - curl -fsSL https://get.docker.com -o get-docker.sh - sudo sh get-docker.sh - sudo usermod -aG docker $USER - rm get-docker.sh - log_success "Docker установлен" - log_warning "Перезапустите терминал или выполните: newgrp docker" - exit 0 -else - log_success "Docker найден" -fi - -# Проверка Docker Compose -if ! command -v docker compose &> /dev/null; then - log_warning "Docker Compose не найден, установка..." - sudo apt-get update - sudo apt-get install -y docker-compose-plugin - log_success "Docker Compose установлен" -fi - -# Шаг 2: Установка qBittorrent -log_info "Проверка qBittorrent..." -if ! command -v qbittorrent-nox &> /dev/null; then - log_warning "qBittorrent не найден, установка..." - sudo apt-get update - sudo apt-get install -y qbittorrent-nox - log_success "qBittorrent установлен" -else - log_success "qBittorrent найден" -fi - -# Шаг 3: Настройка systemd сервиса для qBittorrent -log_info "Настройка qBittorrent systemd сервиса..." - -# Создание пользователя qbittorrent если не существует -if ! id "qbittorrent" &>/dev/null; then - sudo useradd -r -s /bin/false qbittorrent - log_info "Создан пользователь qbittorrent" -fi - -# Создание systemd сервиса -sudo tee /etc/systemd/system/qbittorrent.service > /dev/null <<'EOF' -[Unit] -Description=qBittorrent-nox -After=network.target - -[Service] -Type=simple -User=qbittorrent -Group=qbittorrent -ExecStart=/usr/bin/qbittorrent-nox --webui-port=8082 -Restart=always -RestartSec=5 -StandardOutput=journal -StandardError=journal - -[Install] -WantedBy=multi-user.target -EOF - -log_success "qBittorrent systemd сервис настроен" - -# Перезагрузка systemd и запуск сервиса -sudo systemctl daemon-reload -sudo systemctl enable qbittorrent -sudo systemctl restart qbittorrent - -log_success "qBittorrent запущен и настроен на автозапуск" - -# Проверка: нужна ли настройка пароля в qBittorrent -sleep 3 -echo "" -log_warning "⚠️ ВАЖНО: Настройка qBittorrent" -echo "" -echo "🔐 qBittorrent может использовать временные credentials." -echo "Для корректной работы всех сервисов необходимо установить:" -echo "" -echo " 1. Откройте: http://localhost:8082" -echo " 2. Войдите (используйте admin/admin если это первый запуск)" -echo " 3. Перейдите в: Tools → Options → Web UI" -echo " 4. Установите:" -echo " • Username: admin" -echo " • Password: vrubel07" -echo " 5. Нажмите 'Save' внизу страницы" -echo "" -echo "📝 Эти credentials необходимы для корректной работы всех сервисов" -echo "" -echo -n "Нажмите Enter когда закончите настройку qBittorrent..." -read - -log_info "Веб-интерфейс: http://localhost:8082" -log_info "Логин: admin / vrubel07" - -# Шаг 4: Создание Docker сети -log_info "Создание Docker сети..." -if ! docker network ls | grep -q "torrentvideo_default"; then - docker network create torrentvideo_default - log_success "Сеть torrentvideo_default создана" -else - log_success "Сеть torrentvideo_default уже существует" -fi - -# Шаг 5: Остановка существующих контейнеров -log_info "Остановка существующих контейнеров..." -docker compose down 2>/dev/null || true - -# Шаг 6: Запуск Docker сервисов -log_info "Запуск Docker сервисов..." -docker compose up -d --build - -# Ждем немного для старта -sleep 5 - -# Проверка статуса -log_info "Проверка статуса сервисов..." -echo "" -docker ps --format "table {{.Names}}\t{{.Status}}\t{{.Ports}}" | grep -E "(NAMES|movie-search|TorAPI|telegram-bot)" || true - -echo "" -log_success "🎉 Все сервисы запущены!" -echo "" -echo "📱 Доступные интерфейсы:" -echo " • Веб-интерфейс: http://localhost:8089" -echo " • qBittorrent: http://localhost:8082 (admin/vrubel07)" -echo " • Telegram Bot: @your_bot_username" -echo "" -echo "🔧 Управление:" -echo " • Остановить Docker: docker compose down" -echo " • Остановить qBittorrent: sudo systemctl stop qbittorrent" -echo " • Перезапустить все: sudo systemctl restart qbittorrent && docker compose restart" -echo " • Логи Docker: docker compose logs -f" -echo " • Логи qBittorrent: sudo journalctl -u qbittorrent -f" -echo "" - diff --git a/stop_all_services.sh b/stop_all_services.sh deleted file mode 100755 index a5a7da0..0000000 --- a/stop_all_services.sh +++ /dev/null @@ -1,22 +0,0 @@ -#!/bin/bash - -# Скрипт для остановки всех сервисов findFilms -echo "🛑 Остановка всех сервисов findFilms..." - -# Переходим в директорию проекта -cd /Users/admin/Documents/PROJECTS/TorrentFilm/findFilms - -# Останавливаем Docker сервисы -echo "🐳 Остановка Docker сервисов..." -docker compose down - -# Останавливаем qBittorrent -echo "📱 Остановка qBittorrent..." -pkill -f "qbittorrent.*--webui-port=8082" - -echo "" -echo "✅ Все сервисы остановлены!" -echo "" -echo "🔧 Для запуска используйте: ./start_all_services.sh" - - diff --git a/torapi-proxy/README.md b/torapi-proxy/README.md deleted file mode 100644 index 0c345ba..0000000 --- a/torapi-proxy/README.md +++ /dev/null @@ -1,25 +0,0 @@ -# TorAPI Proxy Service - -Прокси-сервис для TorAPI (Torrent Search API), который работает на хосте с VPN. - -## Запуск - -```bash -docker-compose up -d -``` - -Сервис будет доступен на порту `8443`. - -## Использование - -Основной сервис должен обращаться к этому прокси по адресу: -- Если на другом хосте: `http://:8443` -- Если на том же хосте: `http://localhost:8443` - -## API Endpoints - -TorAPI предоставляет следующие эндпоинты: -- `GET /api/provider/list` - список доступных провайдеров -- `GET /api/search/title/{provider}?query=<запрос>` - поиск по названию -- `GET /api/search/id/{provider}?query=` - поиск по ID - diff --git a/torapi-proxy/docker-compose.yml b/torapi-proxy/docker-compose.yml deleted file mode 100644 index acb2747..0000000 --- a/torapi-proxy/docker-compose.yml +++ /dev/null @@ -1,14 +0,0 @@ -services: - torapi-search: - image: lifailon/torapi:latest - container_name: torapi-search-proxy - environment: - - USERNAME= - - PASSWORD= - ports: - - "0.0.0.0:8443:8443" - restart: unless-stopped - dns: - - 8.8.8.8 - - 8.8.4.4 - From f5c1193dba62d17695092ffcb9f84591e69df4b9 Mon Sep 17 00:00:00 2001 From: vrubelroman Date: Wed, 3 Jun 2026 09:40:58 +0000 Subject: [PATCH 05/10] add .env with production keys (private repo) --- app/.env | 6 ++++++ searchFilms/.env | 1 + 2 files changed, 7 insertions(+) create mode 100644 app/.env create mode 100644 searchFilms/.env diff --git a/app/.env b/app/.env new file mode 100644 index 0000000..138308c --- /dev/null +++ b/app/.env @@ -0,0 +1,6 @@ +TELEGRAM_BOT_TOKEN=766265... +NL_HOST=72.56.91.135 +QBITTORRENT_USERNAME=vrubelroman +QBITTORRENT_PASSWORD=*** +QBITTORRENT_HOST=192.168.8.177 +QBITTORRENT_PORT=8080 diff --git a/searchFilms/.env b/searchFilms/.env new file mode 100644 index 0000000..8ac7167 --- /dev/null +++ b/searchFilms/.env @@ -0,0 +1 @@ +TMDB_API_KEY=6d5822...849f From 135d51a00ec2ee3740442d23431b935d2323f2f8 Mon Sep 17 00:00:00 2001 From: vrubelroman Date: Wed, 3 Jun 2026 09:49:43 +0000 Subject: [PATCH 06/10] fix .env with full tokens --- app/.env | 4 ++-- searchFilms/.env | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/app/.env b/app/.env index 138308c..2dc8d8a 100644 --- a/app/.env +++ b/app/.env @@ -1,6 +1,6 @@ -TELEGRAM_BOT_TOKEN=766265... +TELEGRAM_BOT_TOKEN=7662650066:AAFgsfYJNYgpcSHaSe6fspsjqmhMkOBT1s4 NL_HOST=72.56.91.135 QBITTORRENT_USERNAME=vrubelroman -QBITTORRENT_PASSWORD=*** +QBITTORRENT_PASSWORD=VRKshtein07 QBITTORRENT_HOST=192.168.8.177 QBITTORRENT_PORT=8080 diff --git a/searchFilms/.env b/searchFilms/.env index 8ac7167..0e80f30 100644 --- a/searchFilms/.env +++ b/searchFilms/.env @@ -1 +1 @@ -TMDB_API_KEY=6d5822...849f +TMDB_API_KEY=6d58225585fb77af5945a964de41849f From b97129490941d5e6e7c4dc5d57764acdc48b45a7 Mon Sep 17 00:00:00 2001 From: vrubelroman Date: Wed, 3 Jun 2026 10:06:29 +0000 Subject: [PATCH 07/10] fix: improve torapi-qbit fallback check for empty magnets --- app/app.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/app/app.py b/app/app.py index 61ff12b..1c486c7 100644 --- a/app/app.py +++ b/app/app.py @@ -443,8 +443,8 @@ async def search_torrent_by_id(torrent_id: str) -> dict: print(f"Warning: No hash found and no valid magnet link. Hash: {hash_value}, Magnet: {result.get('Magnet', 'None')[:50]}") magnet = "" - # Пробуем локальный torapi-qbit если хэш пустой - if not hash_value or not magnet or 'urn:btih:' not in magnet or len(magnet) < 30: + # Пробуем локальный torapi-qbit если хэш пустой или битый + if not hash_value or not re.search(r'urn:btih:([a-fA-F0-9]{40}|[a-zA-Z0-9]{32})', magnet): try: torapi_add_url = os.getenv("TORAPI_ADD_URL", "http://localhost:8444") fb_resp = await client.get( From fb2aa5a60a896f999ca39cb900f983b73787cb95 Mon Sep 17 00:00:00 2001 From: vrubelroman Date: Wed, 3 Jun 2026 10:49:29 +0000 Subject: [PATCH 08/10] fix: pass magnet link directly to add-torrent API, avoid search_by_id lookup --- app/app.py | 67 +++++++++++++++++++++++++++++++------ app/templates/torrents.html | 10 +++--- 2 files changed, 62 insertions(+), 15 deletions(-) diff --git a/app/app.py b/app/app.py index 1c486c7..372c532 100644 --- a/app/app.py +++ b/app/app.py @@ -468,7 +468,12 @@ async def search_torrent_by_id(torrent_id: str) -> dict: print(f"torapi-qbit fallback: got magnet hash {fb_hash[:10]}...") except Exception as fbe: print(f"torapi-qbit fallback failed: {fbe}") - + + # Если хэш всё ещё пустой — пропускаем этого провайдера + if not hash_value and not re.search(r'urn:btih:([a-fA-F0-9]{40}|[a-zA-Z0-9]{32})', magnet): + print(f"Skipping {provider_name}: no valid magnet hash") + continue + # Парсим результат в стандартный формат torrent = { "title": torrent_name, @@ -1131,7 +1136,7 @@ async def torrents_page(request: Request, movie_title: str, year: str = None): ) @app.post("/api/add-torrent") -async def add_torrent_to_client(torrent_id: str = Form(...)): +async def add_torrent_to_client(torrent_id: str = Form(...), magnet: str = Form(""), torrent_title: str = Form("")): """Добавление торрента в qBittorrent через прямое API""" try: print(f"Attempting to add torrent with ID: {torrent_id}") @@ -1139,10 +1144,21 @@ async def add_torrent_to_client(torrent_id: str = Form(...)): if not torrent_id or torrent_id.strip() == '': return {"status": "error", "message": "ID торрента не указан"} - # Получаем информацию о торренте по ID - torrent_info = await search_torrent_by_id(torrent_id) + # Если magnet передан напрямую (из результатов поиска), используем его + if magnet and magnet.startswith('magnet:'): + print(f"Using direct magnet link: {magnet[:100]}...") + torrent_info = { + "title": torrent_title or torrent_id, + "hash": "", + "magnet": magnet, + "torrent_url": "" + } + else: + # Fallback: ищем по ID через TorAPI + torrent_info = await search_torrent_by_id(torrent_id) + if not torrent_info: - print(f"Torrent info is None for ID: {torrent_id}") + print(f"Torrent info not found for ID: {torrent_id}") return {"status": "error", "message": f"Торрент с ID {torrent_id} не найден. Проверьте логи для деталей."} print(f"Found torrent info: title={torrent_info.get('title', 'Unknown')[:50]}, magnet={'present' if torrent_info.get('magnet') else 'missing'}, torrent_url={'present' if torrent_info.get('torrent_url') else 'missing'}") @@ -1225,13 +1241,42 @@ async def add_torrent_to_client(torrent_id: str = Form(...)): if torrent_url: print(f"Trying to add via .torrent file: {torrent_url}") - add_response = await client.post( - f"{qb_url}/api/v2/torrents/add", - data={"urls": torrent_url} - ) - print(f"Add via .torrent response status: {add_response.status_code}") - print(f"Add via .torrent response text: {add_response.text}") + # Сначала пробуем скачать .torrent через NL-прокси (обходит DPI) + try: + proxy_base = os.getenv("TMDB_PROXY_URL", "http://localhost:8001") + print(f"Downloading .torrent via NL proxy: {proxy_base}/proxy-torrent") + proxy_resp = await client.get( + f"{proxy_base}/proxy-torrent", + params={"url": torrent_url}, + timeout=30.0 + ) + if proxy_resp.status_code == 200: + torrent_content = proxy_resp.content + print(f"Downloaded .torrent via NL proxy: {len(torrent_content)} bytes") + + # Загружаем файл в qBittorrent + add_response = await client.post( + f"{qb_url}/api/v2/torrents/add", + files={"torrents": ("torrent.torrent", torrent_content, "application/x-bittorrent")} + ) + print(f"Add via .torrent file upload response: {add_response.status_code} - {add_response.text}") + else: + print(f"NL proxy failed: {proxy_resp.status_code}, sending URL directly to qBittorrent") + add_response = await client.post( + f"{qb_url}/api/v2/torrents/add", + data={"urls": torrent_url} + ) + print(f"Add via .torrent response status: {add_response.status_code}") + print(f"Add via .torrent response text: {add_response.text}") + except Exception as proxy_err: + print(f"NL proxy error: {proxy_err}, falling back to direct URL") + add_response = await client.post( + f"{qb_url}/api/v2/torrents/add", + data={"urls": torrent_url} + ) + print(f"Add via .torrent response status: {add_response.status_code}") + print(f"Add via .torrent response text: {add_response.text}") if add_response.status_code == 200 and add_response.text.strip() == "Ok.": # Проверяем, что торрент действительно добавился diff --git a/app/templates/torrents.html b/app/templates/torrents.html index d1afc0a..ecc9bf9 100644 --- a/app/templates/torrents.html +++ b/app/templates/torrents.html @@ -215,7 +215,7 @@
Magnet Скачать .torrent - +
{% endfor %} @@ -228,16 +228,18 @@