mirror of
https://gitlab.com/foxixus/neomovies_mobile.git
synced 2025-10-28 01:58:50 +05:00
PROBLEM RESOLVED: - KAPT task ':torrentengine:kaptReleaseKotlin' was failing due to kotlinx-metadata-jvm version incompatibility - Error: 'Provided Metadata instance has version 2.1.0, while maximum supported version is 2.0.0' SOLUTION: - Updated Room from 2.6.1 to 2.7.0-alpha09 which supports Kotlin 2.1.0 metadata - Added KAPT configuration block with correctErrorTypes and useBuildCache optimizations - Kept KAPT instead of migrating to KSP as requested TESTING: - ✅ gradle :torrentengine:kaptDebugKotlin - SUCCESS - ✅ gradle :torrentengine:assembleDebug - SUCCESS - ✅ Local KAPT compilation works (falls back to Kotlin 1.9 in Alpha mode) The build now passes KAPT processing successfully while maintaining KAPT for annotation processing as requested.
TorrentEngine Library
Либа для моего клиента и других независимых проектов где нужен простой торрент движок.
Установка
1. Добавьте модуль в settings.gradle.kts:
include(":torrentengine")
2. Добавьте зависимость в app/build.gradle.kts:
dependencies {
implementation(project(":torrentengine"))
}
3. Добавьте permissions в AndroidManifest.xml:
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.POST_NOTIFICATIONS" />
Использование
Инициализация
val torrentEngine = TorrentEngine.getInstance(context)
torrentEngine.startStatsUpdater() // Запустить обновление статистики
Добавление торрента
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)
}
}
Получение списка торрентов (реактивно)
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()}")
}
}
}
Управление файлами в раздаче
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)
}
}
}
Пауза/Возобновление/Удаление
lifecycleScope.launch {
// Поставить на паузу
torrentEngine.pauseTorrent(infoHash)
// Возобновить
torrentEngine.resumeTorrent(infoHash)
// Удалить (с файлами или без)
torrentEngine.removeTorrent(infoHash, deleteFiles = true)
}
Множественное изменение приоритетов
lifecycleScope.launch {
val priorities = mapOf(
0 to FilePriority.MAXIMUM, // Первый файл - максимальный приоритет
1 to FilePriority.HIGH, // Второй - высокий
2 to FilePriority.DONT_DOWNLOAD // Третий - не загружать
)
torrentEngine.setFilePriorities(infoHash, priorities)
}
Модели данных
TorrentInfo
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
enum class TorrentState {
STOPPED,
QUEUED,
METADATA_DOWNLOADING,
CHECKING,
DOWNLOADING,
SEEDING,
FINISHED,
ERROR
}
FilePriority
enum class FilePriority(val value: Int) {
DONT_DOWNLOAD(0), // Не загружать
LOW(1), // Низкий приоритет
NORMAL(4), // Обычный (по умолчанию)
HIGH(6), // Высокий
MAXIMUM(7) // Максимальный (загружать первым)
}
Foreground Service
Сервис автоматически запускается при добавлении торрента и показывает постоянное уведомление с:
- Количеством активных торрентов
- Общей скоростью загрузки/отдачи
- Списком загружающихся файлов с прогрессом
- Кнопками управления (Pause All)
Уведомление нельзя закрыть пока есть активные торренты.
Персистентность
Все торренты сохраняются в Room database и автоматически восстанавливаются при перезапуске приложения.
Проверка видео файлов
val videoFiles = torrent.files.filter { it.isVideo() }
Получение share ratio
val ratio = torrent.getShareRatio()
Подсчет выбранных файлов
val selectedCount = torrent.getSelectedFilesCount()
val selectedSize = torrent.getSelectedSize()
Made with <3 by Erno/Foxix