# pyTorrent Monopage web UI dla rTorrent inspirowany workflow ruTorrent. ## Funkcje - Flask + Flask-SocketIO. - SQLite na preferencje, profile SCGI, motyw Bootstrapa i font UI. - Dowolna liczba profili rTorrent per user. - Profile można dodawać i edytować z UI; flaga zdalnej lokalizacji ukrywa CPU/RAM hosta aplikacji, żeby nie mylić ich z zasobami zdalnego rTorrenta; publiczny IP dla port check jest dalej sprawdzany zdalnie, jeśli rTorrent to obsługuje. - Przełączanie aktywnego rTorrent z UI. - Live lista torrentów przez WebSocket. - Cache aplikacyjny i wysyłanie patchy bez przeładowywania całej tabeli. - Operacje usera wykonywane w ThreadPoolExecutor. - Akcje `move` i `remove` są wykonywane per profil w kolejności zlecenia, więc późniejsze usunięcie poczeka na wcześniejsze przenoszenia. - Log jobsów pokazuje krótką datę i godzinę w tabeli oraz pełny timestamp w tooltipie. - Masowe start/pause/stop/resume/recheck/remove/move. - Move obsługuje `move_data=true`, który fizycznie przenosi dane po stronie rTorrent w tle i odpytuje plik statusu, dzięki czemu długie `mv` nie kończy się timeoutem SCGI; jeśli cel już istnieje, jest nadpisywany (`force`), a timeouty z `mkdir`/startu/pollingu move nie przerywają operacji. Potem aktualizuje katalog torrenta, a `recheck` domyślnie włącza się przy fizycznym przenoszeniu. - Modal dodawania wielu magnetów. - Dolny status bar: CPU, RAM, wersja rTorrent, prędkości, limity, total DL/UP oraz status portu, gdy port check jest włączony. - Prawoklik na torrentach. - Skróty klawiaturowe. - Szczegóły: General, Files, Peers, Trackers, Log. - Smart Queue pokazuje domyślnie 10 ostatnich operacji; można rozwinąć historię do 100 wpisów. - GeoIP peerów z MaxMind GeoLite2-City.mmdb, z cache IP. - Cache-busting statyków przez MD5 i nagłówki cache. - Preferencje wyglądu: domyślny Bootstrap albo Bootswatch: Flatly, Litera, Lumen, Minty, Sketchy, Solar, Spacelab, United, Zephyr. - Preferencje fontu: domyślny font motywu, Adwaita Mono oraz dodatkowe pasujące fonty. ## Uruchomienie ```bash ./install.sh . venv/bin/activate python app.py ``` Domyślnie: `http://127.0.0.1:8090`. ## Uruchomienie produkcyjne Preferowany wariant bez deweloperskiego Werkzeug: ```bash . venv/bin/activate gunicorn --worker-class gthread --workers 1 --threads 32 --bind 0.0.0.0:8090 --access-logfile - --error-logfile - wsgi:app ``` Note: aplikacja zostaje przy `async_mode="threading"`, więc WebSocket, `start_background_task`, kolejka operacji i poller działają w tym samym modelu co wcześniej. Alternatywy przeanalizowane, ale nie wdrożone: - `eventlet` przez Gunicorn: działa z Flask-SocketIO, ale wymaga green threads i monkey-patching; większe ryzyko regresji dla operacji plikowych/SCGI. - `gevent` przez Gunicorn: dobry wariant produkcyjny, ale wymaga dodatkowych zależności i testów zgodności. - wiele workerów Gunicorn: wymaga Redis/RabbitMQ/Kafka jako message queue dla Socket.IO, więc nie jest zamiennikiem 1:1. ## Profil SCGI Przykład: ```txt scgi://127.0.0.1:5000/RPC2 ``` Po stronie rTorrent: ```txt network.scgi.open_port = 127.0.0.1:5000 ``` ## GeoIP Instalator pobiera bazę GeoLite2-City jednorazowo do: ```txt data/GeoLite2-City.mmdb ``` Można też uruchomić ręcznie: ```bash ./scripts/download_geoip.sh ``` Skrypt używa głównego źródła `https://git.io/GeoLite2-City.mmdb`, a przy błędzie fallbacku `https://github.com/P3TERX/GeoLite.mmdb/raw/download/GeoLite2-City.mmdb`. Katalog `data` ma uprawnienia `755`, a plik bazy `644`. ## API docs Dokumentacja OpenAPI jest dostępna pod `/docs`. Endpoint `/api/profiles` obsługuje `max_parallel_jobs` z domyślną wartością `5` oraz `is_remote`; `PUT /api/profiles/{profile_id}` edytuje istniejący profil. Endpoint `/api/preferences` obsługuje m.in. `theme`, `bootstrap_theme`, `font_family`, `table_columns_json`, `peers_refresh_seconds` i `port_check_enabled`. Endpoint `/api/port-check` zwraca status portu wraz z `checked_at`; dla zdalnego profilu publiczny IP jest pobierany przez rTorrent z fallbackami `ifconfig.co`, `ifconfig.me` i `ipapi.linuxiarz.pl`, jeśli dana konfiguracja rTorrenta wspiera zdalne polecenia, a metoda `POST` wymusza ponowny check z pominięciem cache. Endpoint `/api/system/status` dla zdalnego profilu zwraca `usage_available=false` i nie odczytuje CPU/RAM. `/api/openapi.json` zawiera reusable schemas dla głównych odpowiedzi API, w tym `TorrentListResponse`, `TorrentSummary`, `TorrentFilterSummary`, `CleanupSummary` i `AppStatus`. `GET /api/torrents` dokumentuje teraz pole `summary` używane przez sidebar filters.