mirror of
				https://gitlab.com/foxixus/neomovies_mobile.git
				synced 2025-10-29 10:38:49 +05:00 
			
		
		
		
	- Created complete TorrentEngine library module with LibTorrent4j - Full torrent management (add, pause, resume, remove) - Magnet link metadata extraction - File priority management (even during download) - Foreground service with persistent notification - Room database for state persistence - Reactive Flow API for UI updates - Integrated TorrentEngine with MainActivity via MethodChannel - addTorrent, getTorrents, pauseTorrent, resumeTorrent, removeTorrent - setFilePriority for dynamic file selection - Full JSON serialization for Flutter communication - Created new NeoMoviesApiClient for Go-based backend - Email verification flow (register, verify, resendCode) - Google OAuth support - Torrent search via RedAPI - Multiple player support (Alloha, Lumex, Vibix) - Enhanced reactions system (likes/dislikes) - All movies/TV shows endpoints - Updated dependencies and build configuration - Java 17 compatibility - Updated Kotlin coroutines to 1.9.0 - Fixed build_runner version conflict - Added torrentengine module to settings.gradle.kts - Added comprehensive documentation - TorrentEngine README with usage examples - DEVELOPMENT_SUMMARY with full implementation details - ProGuard rules for library This is a complete rewrite of torrent functionality as a reusable library.
		
			
				
	
	
		
			269 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			269 lines
		
	
	
		
			8.7 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # TorrentEngine Library
 | ||
| 
 | ||
| Мощная библиотека для Android, обеспечивающая полноценную работу с торрентами через LibTorrent4j.
 | ||
| 
 | ||
| ## 🎯 Возможности
 | ||
| 
 | ||
| - ✅ **Загрузка из magnet-ссылок** - получение метаданных и загрузка файлов
 | ||
| - ✅ **Выбор файлов** - возможность выбирать какие файлы загружать до и во время загрузки
 | ||
| - ✅ **Управление приоритетами** - изменение приоритета файлов в активной раздаче
 | ||
| - ✅ **Фоновый сервис** - непрерывная работа в фоне с foreground уведомлением
 | ||
| - ✅ **Постоянное уведомление** - нельзя закрыть пока активны загрузки
 | ||
| - ✅ **Персистентность** - сохранение состояния в Room database
 | ||
| - ✅ **Реактивность** - Flow API для мониторинга изменений
 | ||
| - ✅ **Полная статистика** - скорость, пиры, сиды, прогресс, ETA
 | ||
| - ✅ **Pause/Resume/Remove** - полный контроль над раздачами
 | ||
| 
 | ||
| ## 📦 Установка
 | ||
| 
 | ||
| ### 1. Добавьте модуль в `settings.gradle.kts`:
 | ||
| 
 | ||
| ```kotlin
 | ||
| include(":torrentengine")
 | ||
| ```
 | ||
| 
 | ||
| ### 2. Добавьте зависимость в `app/build.gradle.kts`:
 | ||
| 
 | ||
| ```kotlin
 | ||
| dependencies {
 | ||
|     implementation(project(":torrentengine"))
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### 3. Добавьте permissions в `AndroidManifest.xml`:
 | ||
| 
 | ||
| ```xml
 | ||
| <uses-permission android:name="android.permission.INTERNET" />
 | ||
| <uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
 | ||
| <uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
 | ||
| ```
 | ||
| 
 | ||
| ## 🚀 Использование
 | ||
| 
 | ||
| ### Инициализация
 | ||
| 
 | ||
| ```kotlin
 | ||
| val torrentEngine = TorrentEngine.getInstance(context)
 | ||
| torrentEngine.startStatsUpdater() // Запустить обновление статистики
 | ||
| ```
 | ||
| 
 | ||
| ### Добавление торрента
 | ||
| 
 | ||
| ```kotlin
 | ||
| lifecycleScope.launch {
 | ||
|     try {
 | ||
|         val magnetUri = "magnet:?xt=urn:btih:..."
 | ||
|         val savePath = "${context.getExternalFilesDir(null)}/downloads"
 | ||
|         
 | ||
|         val infoHash = torrentEngine.addTorrent(magnetUri, savePath)
 | ||
|         Log.d("Torrent", "Added: $infoHash")
 | ||
|     } catch (e: Exception) {
 | ||
|         Log.e("Torrent", "Failed to add", e)
 | ||
|     }
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### Получение списка торрентов (реактивно)
 | ||
| 
 | ||
| ```kotlin
 | ||
| lifecycleScope.launch {
 | ||
|     torrentEngine.getAllTorrentsFlow().collect { torrents ->
 | ||
|         torrents.forEach { torrent ->
 | ||
|             println("${torrent.name}: ${torrent.progress * 100}%")
 | ||
|             println("Speed: ${torrent.downloadSpeed} B/s")
 | ||
|             println("Peers: ${torrent.numPeers}, Seeds: ${torrent.numSeeds}")
 | ||
|             println("ETA: ${torrent.getFormattedEta()}")
 | ||
|         }
 | ||
|     }
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### Управление файлами в раздаче
 | ||
| 
 | ||
| ```kotlin
 | ||
| lifecycleScope.launch {
 | ||
|     // Получить информацию о торренте
 | ||
|     val torrent = torrentEngine.getTorrent(infoHash)
 | ||
|     
 | ||
|     torrent?.files?.forEachIndexed { index, file ->
 | ||
|         println("File $index: ${file.path} (${file.size} bytes)")
 | ||
|         
 | ||
|         // Выбрать только видео файлы
 | ||
|         if (file.isVideo()) {
 | ||
|             torrentEngine.setFilePriority(infoHash, index, FilePriority.HIGH)
 | ||
|         } else {
 | ||
|             torrentEngine.setFilePriority(infoHash, index, FilePriority.DONT_DOWNLOAD)
 | ||
|         }
 | ||
|     }
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### Пауза/Возобновление/Удаление
 | ||
| 
 | ||
| ```kotlin
 | ||
| lifecycleScope.launch {
 | ||
|     // Поставить на паузу
 | ||
|     torrentEngine.pauseTorrent(infoHash)
 | ||
|     
 | ||
|     // Возобновить
 | ||
|     torrentEngine.resumeTorrent(infoHash)
 | ||
|     
 | ||
|     // Удалить (с файлами или без)
 | ||
|     torrentEngine.removeTorrent(infoHash, deleteFiles = true)
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### Множественное изменение приоритетов
 | ||
| 
 | ||
| ```kotlin
 | ||
| lifecycleScope.launch {
 | ||
|     val priorities = mapOf(
 | ||
|         0 to FilePriority.MAXIMUM,  // Первый файл - максимальный приоритет
 | ||
|         1 to FilePriority.HIGH,      // Второй - высокий
 | ||
|         2 to FilePriority.DONT_DOWNLOAD // Третий - не загружать
 | ||
|     )
 | ||
|     
 | ||
|     torrentEngine.setFilePriorities(infoHash, priorities)
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ## 📊 Модели данных
 | ||
| 
 | ||
| ### TorrentInfo
 | ||
| 
 | ||
| ```kotlin
 | ||
| data class TorrentInfo(
 | ||
|     val infoHash: String,
 | ||
|     val magnetUri: String,
 | ||
|     val name: String,
 | ||
|     val totalSize: Long,
 | ||
|     val downloadedSize: Long,
 | ||
|     val uploadedSize: Long,
 | ||
|     val downloadSpeed: Int,
 | ||
|     val uploadSpeed: Int,
 | ||
|     val progress: Float,
 | ||
|     val state: TorrentState,
 | ||
|     val numPeers: Int,
 | ||
|     val numSeeds: Int,
 | ||
|     val savePath: String,
 | ||
|     val files: List<TorrentFile>,
 | ||
|     val addedDate: Long,
 | ||
|     val finishedDate: Long?,
 | ||
|     val error: String?
 | ||
| )
 | ||
| ```
 | ||
| 
 | ||
| ### TorrentState
 | ||
| 
 | ||
| ```kotlin
 | ||
| enum class TorrentState {
 | ||
|     STOPPED,
 | ||
|     QUEUED,
 | ||
|     METADATA_DOWNLOADING,
 | ||
|     CHECKING,
 | ||
|     DOWNLOADING,
 | ||
|     SEEDING,
 | ||
|     FINISHED,
 | ||
|     ERROR
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ### FilePriority
 | ||
| 
 | ||
| ```kotlin
 | ||
| enum class FilePriority(val value: Int) {
 | ||
|     DONT_DOWNLOAD(0),  // Не загружать
 | ||
|     LOW(1),            // Низкий приоритет
 | ||
|     NORMAL(4),         // Обычный (по умолчанию)
 | ||
|     HIGH(6),           // Высокий
 | ||
|     MAXIMUM(7)         // Максимальный (загружать первым)
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ## 🔔 Foreground Service
 | ||
| 
 | ||
| Сервис автоматически запускается при добавлении торрента и показывает постоянное уведомление с:
 | ||
| - Количеством активных торрентов
 | ||
| - Общей скоростью загрузки/отдачи
 | ||
| - Списком загружающихся файлов с прогрессом
 | ||
| - Кнопками управления (Pause All)
 | ||
| 
 | ||
| Уведомление **нельзя закрыть** пока есть активные торренты.
 | ||
| 
 | ||
| ## 💾 Персистентность
 | ||
| 
 | ||
| Все торренты сохраняются в Room database и автоматически восстанавливаются при перезапуске приложения.
 | ||
| 
 | ||
| ## 🔧 Расширенные возможности
 | ||
| 
 | ||
| ### Проверка видео файлов
 | ||
| 
 | ||
| ```kotlin
 | ||
| val videoFiles = torrent.files.filter { it.isVideo() }
 | ||
| ```
 | ||
| 
 | ||
| ### Получение share ratio
 | ||
| 
 | ||
| ```kotlin
 | ||
| val ratio = torrent.getShareRatio()
 | ||
| ```
 | ||
| 
 | ||
| ### Подсчет выбранных файлов
 | ||
| 
 | ||
| ```kotlin
 | ||
| val selectedCount = torrent.getSelectedFilesCount()
 | ||
| val selectedSize = torrent.getSelectedSize()
 | ||
| ```
 | ||
| 
 | ||
| ## 📱 Интеграция с Flutter
 | ||
| 
 | ||
| Создайте MethodChannel для вызова из Flutter:
 | ||
| 
 | ||
| ```kotlin
 | ||
| class TorrentEngineChannel(private val context: Context) {
 | ||
|     private val torrentEngine = TorrentEngine.getInstance(context)
 | ||
|     private val channel = "com.neomovies/torrent"
 | ||
|     
 | ||
|     fun setupMethodChannel(flutterEngine: FlutterEngine) {
 | ||
|         MethodChannel(flutterEngine.dartExecutor.binaryMessenger, channel)
 | ||
|             .setMethodCallHandler { call, result ->
 | ||
|                 when (call.method) {
 | ||
|                     "addTorrent" -> {
 | ||
|                         val magnetUri = call.argument<String>("magnetUri")!!
 | ||
|                         val savePath = call.argument<String>("savePath")!!
 | ||
|                         
 | ||
|                         CoroutineScope(Dispatchers.IO).launch {
 | ||
|                             try {
 | ||
|                                 val hash = torrentEngine.addTorrent(magnetUri, savePath)
 | ||
|                                 result.success(hash)
 | ||
|                             } catch (e: Exception) {
 | ||
|                                 result.error("ERROR", e.message, null)
 | ||
|                             }
 | ||
|                         }
 | ||
|                     }
 | ||
|                     // ... другие методы
 | ||
|                 }
 | ||
|             }
 | ||
|     }
 | ||
| }
 | ||
| ```
 | ||
| 
 | ||
| ## 📄 Лицензия
 | ||
| 
 | ||
| MIT License - используйте свободно в любых проектах!
 | ||
| 
 | ||
| ## 🤝 Вклад
 | ||
| 
 | ||
| Библиотека разработана как универсальное решение для работы с торрентами в Android.
 | ||
| Может использоваться в любых проектах без ограничений.
 | ||
| 
 | ||
| ## 🐛 Известные проблемы
 | ||
| 
 | ||
| - LibTorrent4j требует минимум Android 5.0 (API 21)
 | ||
| - Для Android 13+ нужно запрашивать POST_NOTIFICATIONS permission
 | ||
| - Foreground service требует отображения уведомления
 | ||
| 
 | ||
| ## 📞 Поддержка
 | ||
| 
 | ||
| При возникновении проблем создайте issue с описанием и логами.
 |