77 lines
3.3 KiB
Kotlin
77 lines
3.3 KiB
Kotlin
|
package com.adlerosn.brasilfurfest.schedule.managers
|
||
|
|
||
|
import android.content.Context
|
||
|
import org.jetbrains.anko.doAsync
|
||
|
import org.jetbrains.anko.uiThread
|
||
|
import java.io.Serializable
|
||
|
import java.lang.IllegalStateException
|
||
|
import java.net.HttpURLConnection
|
||
|
import java.net.HttpURLConnection.HTTP_NOT_MODIFIED
|
||
|
import java.net.HttpURLConnection.HTTP_OK
|
||
|
import java.net.URL
|
||
|
|
||
|
class UpdateChecker(context: Context): Serializable {
|
||
|
val cacheManager = CacheManager(context)
|
||
|
private val baseJsonFileName = RemoteAssets.json.split('/').last()
|
||
|
val hasBaseJsonCached get() = baseJsonFileName.let {
|
||
|
cacheManager.getStamp(it) != null
|
||
|
}
|
||
|
|
||
|
fun downloadBaseJsonWithWatcher(watcher: (DownloadState, ByteArray?, Throwable?)->Any?) =
|
||
|
downloadWithWatcher(RemoteAssets.json, watcher)
|
||
|
|
||
|
fun downloadWithWatcher(httpThingToFetch: String, watcher: (DownloadState, ByteArray?, Throwable?)->Any?){
|
||
|
doAsync {
|
||
|
try {
|
||
|
val url = URL(httpThingToFetch)
|
||
|
val diskIdentifier = url.toString().split('/').filterNot { it.isBlank() }.last()
|
||
|
val connection = url.openConnection() as HttpURLConnection
|
||
|
cacheManager.getStamp(diskIdentifier)?.let {
|
||
|
connection.setRequestProperty("If-Modified-Since", it)
|
||
|
}
|
||
|
connection.useCaches = false
|
||
|
connection.connectTimeout = 3000
|
||
|
connection.readTimeout = 5000
|
||
|
connection.allowUserInteraction = false
|
||
|
connection.doOutput = false
|
||
|
connection.requestMethod = "GET"
|
||
|
uiThread { watcher(DownloadState.CONNECTING, null, null) }
|
||
|
connection.connect()
|
||
|
try {
|
||
|
val resCode = connection.responseCode
|
||
|
when (resCode) {
|
||
|
HTTP_OK -> {
|
||
|
uiThread { watcher(DownloadState.CACHE_MISS, null, null) }
|
||
|
val lastModified = connection.headerFields["last-modified"]?.firstOrNull()
|
||
|
val data = connection.inputStream.buffered().readBytes()
|
||
|
cacheManager[diskIdentifier] = Pair(data, lastModified ?: "")
|
||
|
uiThread { watcher(DownloadState.SUCCESS, data, null) }
|
||
|
}
|
||
|
HTTP_NOT_MODIFIED -> {
|
||
|
uiThread { watcher(DownloadState.CACHE_HIT, null, null) }
|
||
|
val bytes = cacheManager[diskIdentifier]?.first?.readBytes()
|
||
|
uiThread { watcher(DownloadState.SUCCESS, bytes, null) }
|
||
|
}
|
||
|
else -> {
|
||
|
throw IllegalStateException("Server replied with code $resCode. Expected either $HTTP_OK or $HTTP_NOT_MODIFIED.")
|
||
|
}
|
||
|
}
|
||
|
} catch (t: Throwable) {
|
||
|
uiThread { watcher(DownloadState.ERROR, null, t) }
|
||
|
} finally {
|
||
|
connection.disconnect()
|
||
|
}
|
||
|
} catch (t: Throwable){
|
||
|
uiThread { watcher(DownloadState.ERROR, null, t) }
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
enum class DownloadState{
|
||
|
CONNECTING,
|
||
|
CACHE_MISS,
|
||
|
CACHE_HIT,
|
||
|
ERROR,
|
||
|
SUCCESS
|
||
|
}
|
||
|
}
|