-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathFileDownloader.kt
More file actions
61 lines (55 loc) · 2.1 KB
/
FileDownloader.kt
File metadata and controls
61 lines (55 loc) · 2.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
package com.nitrofs
import android.util.Log
import com.margelo.nitro.nitrofs.NitroFile
import io.ktor.client.HttpClient
import io.ktor.client.call.body
import io.ktor.client.engine.okhttp.OkHttp
import io.ktor.client.plugins.onDownload
import io.ktor.client.request.prepareGet
import io.ktor.http.HttpMethod
import io.ktor.http.isSuccess
import io.ktor.util.cio.writeChannel
import io.ktor.utils.io.ByteReadChannel
import io.ktor.utils.io.copyAndClose
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.withContext
import java.io.File
class FileDownloader {
suspend fun downloadFile(
serverUrl: String,
destinationPath: String,
onProgress: ((Double, Double) -> Unit)?
): NitroFile? {
var contentType = ""
val outputFile = File(destinationPath)
outputFile.parentFile?.mkdirs()
val client = HttpClient(OkHttp)
client.use { it
it.prepareGet(serverUrl) {
method = HttpMethod.Get
onDownload { totalBytesSent, contentLength ->
if (totalBytesSent > 0 && contentLength != null){
onProgress?.let {
withContext(Dispatchers.Main) {
onProgress.invoke(totalBytesSent.toDouble(), contentLength.toDouble())
}
}
}
}
}.execute { response ->
Log.d("TAG", "${response.status.isSuccess()} ${response.status.value} $serverUrl")
if (!response.status.isSuccess()) {
throw RuntimeException("HTTP ${response.status.value}: Failed to download file")
}
contentType = response.headers["Content-Type"] ?: "application/octet-stream"
val channel: ByteReadChannel = response.body()
channel.copyAndClose(outputFile.writeChannel())
}
}
return NitroFile(
name = outputFile.name,
path = outputFile.absolutePath,
mimeType = contentType
)
}
}