Browse Source

Added support for rTorrent file listing.

rewrite-connect
Eric Kok 8 years ago
parent
commit
8f48a3404c
  1. 7
      connect/src/main/java/org/transdroid/connect/clients/ClientDelegate.kt
  2. 3
      connect/src/main/java/org/transdroid/connect/clients/Feature.kt
  3. 9
      connect/src/main/java/org/transdroid/connect/clients/rtorrent/FileSpec.kt
  4. 46
      connect/src/main/java/org/transdroid/connect/clients/rtorrent/Rtorrent.kt
  5. 4
      connect/src/main/java/org/transdroid/connect/clients/rtorrent/Service.kt
  6. 8
      connect/src/main/java/org/transdroid/connect/model/Priority.kt
  7. 23
      connect/src/main/java/org/transdroid/connect/model/Torrent.kt
  8. 14
      connect/src/main/java/org/transdroid/connect/model/TorrentFile.kt
  9. 20
      connect/src/test/java/org/transdroid/connect/clients/rtorrent/RtorrentLiveTest.kt
  10. 18
      connect/src/test/java/org/transdroid/connect/clients/rtorrent/RtorrentMockTest.kt

7
connect/src/main/java/org/transdroid/connect/clients/ClientDelegate.kt

@ -5,6 +5,7 @@ import io.reactivex.Flowable @@ -5,6 +5,7 @@ import io.reactivex.Flowable
import io.reactivex.Single
import org.transdroid.connect.model.Torrent
import org.transdroid.connect.model.TorrentDetails
import org.transdroid.connect.model.TorrentFile
import java.io.InputStream
/**
@ -25,6 +26,12 @@ internal class ClientDelegate(private val client: Client, private val actual: An @@ -25,6 +26,12 @@ internal class ClientDelegate(private val client: Client, private val actual: An
throw UnsupportedFeatureException(client, Feature.LISTING)
}
override fun files(torrent: Torrent): Flowable<TorrentFile> {
if (client.supports(Feature.LISTING))
return (actual as Feature.Listing).files(torrent)
throw UnsupportedFeatureException(client, Feature.LISTING)
}
override fun details(torrent: Torrent): Single<TorrentDetails> {
if (client.supports(Feature.DETAILS))
return (actual as Feature.Details).details(torrent)

3
connect/src/main/java/org/transdroid/connect/clients/Feature.kt

@ -5,6 +5,7 @@ import io.reactivex.Flowable @@ -5,6 +5,7 @@ import io.reactivex.Flowable
import io.reactivex.Single
import org.transdroid.connect.model.Torrent
import org.transdroid.connect.model.TorrentDetails
import org.transdroid.connect.model.TorrentFile
import java.io.InputStream
import kotlin.reflect.KClass
@ -33,6 +34,8 @@ enum class Feature constructor(val type: KClass<*>) { @@ -33,6 +34,8 @@ enum class Feature constructor(val type: KClass<*>) {
fun torrents(): Flowable<Torrent>
fun files(torrent: Torrent): Flowable<TorrentFile>
}
interface Details {

9
connect/src/main/java/org/transdroid/connect/clients/rtorrent/FileSpec.kt

@ -0,0 +1,9 @@ @@ -0,0 +1,9 @@
package org.transdroid.connect.clients.rtorrent
data class FileSpec(
val pathName: String,
var size: Long,
var chunksDone: Long,
var chunksTotal: Long,
var priority: Long,
var pathFull: String)

46
connect/src/main/java/org/transdroid/connect/clients/rtorrent/Rtorrent.kt

@ -3,12 +3,11 @@ package org.transdroid.connect.clients.rtorrent @@ -3,12 +3,11 @@ package org.transdroid.connect.clients.rtorrent
import io.reactivex.Completable
import io.reactivex.Flowable
import io.reactivex.Single
import io.reactivex.functions.BiFunction
import nl.nl2312.xmlrpc.XmlRpcConverterFactory
import org.transdroid.connect.Configuration
import org.transdroid.connect.clients.Feature
import org.transdroid.connect.model.Torrent
import org.transdroid.connect.model.TorrentDetails
import org.transdroid.connect.model.TorrentStatus
import org.transdroid.connect.model.*
import org.transdroid.connect.util.OkHttpBuilder
import org.transdroid.connect.util.flatten
import retrofit2.Retrofit
@ -65,6 +64,16 @@ class Rtorrent(private val configuration: Configuration) : @@ -65,6 +64,16 @@ class Rtorrent(private val configuration: Configuration) :
.addArrayDeserializer(TrackerSpec::class.java) { arrayValues ->
TrackerSpec(arrayValues.asString(0))
}
.addArrayDeserializer(FileSpec::class.java) { arrayValues ->
FileSpec(
arrayValues.asString(0),
arrayValues.asLong(1),
arrayValues.asLong(2),
arrayValues.asLong(3),
arrayValues.asLong(4),
arrayValues.asString(5)
)
}
.create())
.build().create(Service::class.java)
@ -134,6 +143,30 @@ class Rtorrent(private val configuration: Configuration) : @@ -134,6 +143,30 @@ class Rtorrent(private val configuration: Configuration) :
}
}
override fun files(torrent: Torrent): Flowable<TorrentFile> {
return service.files(configuration.endpoint,
torrent.uniqueId,
"",
"f.path=",
"f.size_bytes=",
"f.completed_chunks=",
"f.size_chunks=",
"f.priority=",
"f.frozen_path=")
.flatten()
.zipWith(Flowable.range(0, Int.MAX_VALUE), BiFunction<FileSpec, Int, Pair<Int, FileSpec>> { file, index -> Pair(index, file) })
.map { (index, file) ->
TorrentFile(
index.toString(),
file.pathName,
file.pathFull.substring(torrent.locationDir.orEmpty().length),
file.pathName,
file.size,
file.size * (file.chunksDone / file.chunksTotal),
fileStatus(file.priority))
}
}
override fun details(torrent: Torrent): Single<TorrentDetails> {
return service.trackers(configuration.endpoint, torrent.uniqueId, "", "t.url=")
.flatten()
@ -214,6 +247,13 @@ class Rtorrent(private val configuration: Configuration) : @@ -214,6 +247,13 @@ class Rtorrent(private val configuration: Configuration) :
}
}
private fun fileStatus(state: Long): Priority =
when (state) {
0L -> Priority.OFF
2L -> Priority.HIGH
else -> Priority.NORMAL
}
private fun torrentTimeAdded(timeAdded: String?, timeCreated: Long): Date =
if (timeAdded.isNullOrBlank()) Date(timeCreated * 1000L) else Date(timeAdded!!.trim().toLong() * 1000L)

4
connect/src/main/java/org/transdroid/connect/clients/rtorrent/Service.kt

@ -17,6 +17,10 @@ internal interface Service { @@ -17,6 +17,10 @@ internal interface Service {
@POST("{endpoint}")
fun torrents(@Path("endpoint") endpoint: String?, @Body vararg args: String): Single<Array<TorrentSpec>>
@XmlRpc("f.multicall")
@POST("{endpoint}")
fun files(@Path("endpoint") endpoint: String?, @Body vararg args: String): Single<Array<FileSpec>>
@XmlRpc("t.multicall")
@POST("{endpoint}")
fun trackers(@Path("endpoint") endpoint: String?, @Body vararg args: String): Single<Array<TrackerSpec>>

8
connect/src/main/java/org/transdroid/connect/model/Priority.kt

@ -0,0 +1,8 @@ @@ -0,0 +1,8 @@
package org.transdroid.connect.model
enum class Priority {
OFF,
LOW,
NORMAL,
HIGH
}

23
connect/src/main/java/org/transdroid/connect/model/Torrent.kt

@ -87,22 +87,13 @@ data class Torrent( @@ -87,22 +87,13 @@ data class Torrent(
fun mimicStop(): Torrent = mimicStatus(TorrentStatus.QUEUED)
fun mimicNewLabel(newLabel: String): Torrent = Torrent(id, hash, name, statusCode, locationDir, rateDownload, rateUpload, seedersConnected,
seedersKnown, leechersConnected, leechersKnown, eta, downloadedEver, uploadedEver, totalSize, partDone, available, newLabel, dateAdded,
dateDone, error)
fun mimicChecking(): Torrent {
return mimicStatus(TorrentStatus.CHECKING)
}
fun mimicNewLocation(newLocation: String): Torrent {
return Torrent(id, hash, name, statusCode, newLocation, rateDownload, rateUpload, seedersConnected, seedersKnown, leechersConnected,
leechersKnown, eta, downloadedEver, uploadedEver, totalSize, partDone, available, label, dateAdded, dateDone, error)
}
private fun mimicStatus(newStatus: TorrentStatus): Torrent = Torrent(id, hash, name, newStatus, locationDir, rateDownload, rateUpload,
seedersConnected, seedersKnown, leechersConnected, leechersKnown, eta, downloadedEver, uploadedEver, totalSize, partDone, available,
label, dateAdded, dateDone, error)
fun mimicChecking(): Torrent = mimicStatus(TorrentStatus.CHECKING)
fun mimicNewLabel(newLabel: String): Torrent = this.copy(label = newLabel)
fun mimicNewLocation(newLocation: String): Torrent = this.copy(locationDir = newLocation)
private fun mimicStatus(newStatus: TorrentStatus): Torrent = this.copy(statusCode = newStatus)
override fun toString(): String = "($uniqueId) $name"

14
connect/src/main/java/org/transdroid/connect/model/TorrentFile.kt

@ -0,0 +1,14 @@ @@ -0,0 +1,14 @@
package org.transdroid.connect.model
data class TorrentFile(
val key: String,
val name: String,
val relativePath: String,
val fullPath: String,
val totalSize: Long,
val downloaded: Long,
val priority: Priority) {
fun mimicPriority(newPriority: Priority): TorrentFile = this.copy(priority = newPriority)
}

20
connect/src/test/java/org/transdroid/connect/clients/rtorrent/RtorrentLiveTest.kt

@ -43,18 +43,26 @@ class RtorrentLiveTest { @@ -43,18 +43,26 @@ class RtorrentLiveTest {
}
@Test
fun details() {
rtorrent.details(firstLiveTorrent())
fun torrents() {
rtorrent.torrents()
.toList()
.test()
.assertValue { it.trackers.isNotEmpty() }
.assertValue { it.size > 0 }
}
@Test
fun torrents() {
rtorrent.torrents()
fun files() {
rtorrent.files(firstLiveTorrent())
.toList()
.test()
.assertValue { torrents -> torrents.size > 0 }
.assertValue { it.size > 0 }
}
@Test
fun details() {
rtorrent.details(firstLiveTorrent())
.test()
.assertValue { it.trackers.isNotEmpty() }
}
@Test

18
connect/src/test/java/org/transdroid/connect/clients/rtorrent/RtorrentMockTest.kt

@ -7,6 +7,7 @@ import org.junit.Test @@ -7,6 +7,7 @@ import org.junit.Test
import org.transdroid.connect.Configuration
import org.transdroid.connect.clients.Client
import org.transdroid.connect.mock.MockTorrent
import org.transdroid.connect.model.Priority
class RtorrentMockTest {
@ -37,6 +38,23 @@ class RtorrentMockTest { @@ -37,6 +38,23 @@ class RtorrentMockTest {
server.takeRequest()
}
@Test
fun files() {
server.enqueue(mock("<array><data><value><array><data><value><string>ubuntu-17.04-desktop-amd64.iso</string></value><value><i8>1609039872</i8></value><value><i8>0</i8></value><value><i8>3069</i8></value><value><i8>1</i8></value><value><string>/downloads/ubuntu-17.04-desktop-amd64.iso</string></value></data></array></value></data></array>"))
rtorrent.files(MockTorrent.downloading)
.test()
.assertValue {
it.key == "0" &&
it.name == "ubuntu-17.04-desktop-amd64.iso" &&
it.relativePath == "ubuntu-17.04-desktop-amd64.iso" &&
it.fullPath == "ubuntu-17.04-desktop-amd64.iso" &&
it.totalSize == 1609039872L &&
it.downloaded == 0L &&
it.priority == Priority.NORMAL
}
server.takeRequest()
}
@Test
fun details() {
server.enqueue(mock("<array><data><value><array><data><value><string>http://torrent.ubuntu.com:6969/announce</string></value></data></array></value><value><array><data><value><string>http://ipv6.torrent.ubuntu.com:6969/announce</string></value></data></array></value></data></array>"))

Loading…
Cancel
Save