Added latestRelease to PupilHttpClient
This commit is contained in:
@@ -32,7 +32,9 @@ import kotlinx.coroutines.flow.flow
|
|||||||
import kotlinx.coroutines.flow.flowOn
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.*
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class RemoteSourceInfo(
|
data class RemoteSourceInfo(
|
||||||
@@ -41,6 +43,18 @@ data class RemoteSourceInfo(
|
|||||||
val version: String
|
val version: String
|
||||||
)
|
)
|
||||||
|
|
||||||
|
class Release(
|
||||||
|
val version: String,
|
||||||
|
val apkUrl: String,
|
||||||
|
val updateNotes: Map<Locale, String>
|
||||||
|
)
|
||||||
|
|
||||||
|
private val localeMap = mapOf(
|
||||||
|
"한국어" to Locale.KOREAN,
|
||||||
|
"日本語" to Locale.JAPANESE,
|
||||||
|
"English" to Locale.ENGLISH
|
||||||
|
)
|
||||||
|
|
||||||
class PupilHttpClient(engine: HttpClientEngine) {
|
class PupilHttpClient(engine: HttpClientEngine) {
|
||||||
private val httpClient = HttpClient(engine) {
|
private val httpClient = HttpClient(engine) {
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
@@ -52,10 +66,7 @@ class PupilHttpClient(engine: HttpClientEngine) {
|
|||||||
httpClient.get("https://tom5079.github.io/PupilSources/versions.json").body()
|
httpClient.get("https://tom5079.github.io/PupilSources/versions.json").body()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun downloadApk(sourceInfo: RemoteSourceInfo, dest: File) = flow {
|
fun downloadApk(url: String, dest: File) = flow {
|
||||||
val url =
|
|
||||||
"https://github.com/tom5079/PupilSources/releases/download/${sourceInfo.name}-${sourceInfo.version}/${sourceInfo.projectName}-release.apk"
|
|
||||||
|
|
||||||
httpClient.prepareGet(url).execute { response ->
|
httpClient.prepareGet(url).execute { response ->
|
||||||
val channel = response.bodyAsChannel()
|
val channel = response.bodyAsChannel()
|
||||||
val contentLength = response.contentLength() ?: -1
|
val contentLength = response.contentLength() ?: -1
|
||||||
@@ -77,4 +88,43 @@ class PupilHttpClient(engine: HttpClientEngine) {
|
|||||||
|
|
||||||
emit(Float.POSITIVE_INFINITY)
|
emit(Float.POSITIVE_INFINITY)
|
||||||
}.flowOn(Dispatchers.IO)
|
}.flowOn(Dispatchers.IO)
|
||||||
|
|
||||||
|
suspend fun latestRelease(beta: Boolean = true): Release = withContext(Dispatchers.IO) {
|
||||||
|
val releases = Json.parseToJsonElement(
|
||||||
|
httpClient.get("https://api.github.com/repos/tom5079/Pupil/releases").bodyAsText()
|
||||||
|
).jsonArray
|
||||||
|
|
||||||
|
val latestRelease = releases.first { release ->
|
||||||
|
beta || !release.jsonObject["prerelease"]!!.jsonPrimitive.boolean
|
||||||
|
}.jsonObject
|
||||||
|
|
||||||
|
val version = latestRelease["tag_name"]!!.jsonPrimitive.content
|
||||||
|
|
||||||
|
val apkUrl = latestRelease["assets"]!!.jsonArray.first { asset ->
|
||||||
|
val name = asset.jsonObject["name"]!!.jsonPrimitive.content
|
||||||
|
name.startsWith("Pupil-v") && name.endsWith(".apk")
|
||||||
|
}.jsonObject["browser_download_url"]!!.jsonPrimitive.content
|
||||||
|
|
||||||
|
val updateNotes: Map<Locale, String> = buildMap {
|
||||||
|
val body = latestRelease["body"]!!.jsonPrimitive.content
|
||||||
|
|
||||||
|
var locale: Locale? = null
|
||||||
|
val stringBuilder = StringBuilder()
|
||||||
|
body.lineSequence().forEach { line ->
|
||||||
|
localeMap[line.drop(3)]?.let { newLocale ->
|
||||||
|
if (locale != null) {
|
||||||
|
put(locale!!, stringBuilder.deleteCharAt(stringBuilder.length-1).toString())
|
||||||
|
stringBuilder.clear()
|
||||||
|
}
|
||||||
|
locale = newLocale
|
||||||
|
return@forEach
|
||||||
|
}
|
||||||
|
|
||||||
|
if (locale != null) stringBuilder.appendLine(line)
|
||||||
|
}
|
||||||
|
put(locale!!, stringBuilder.deleteCharAt(stringBuilder.length-1).toString())
|
||||||
|
}
|
||||||
|
|
||||||
|
Release(version, apkUrl, updateNotes)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
@@ -31,6 +31,7 @@ import org.junit.Test
|
|||||||
import xyz.quaver.pupil.util.PupilHttpClient
|
import xyz.quaver.pupil.util.PupilHttpClient
|
||||||
import xyz.quaver.pupil.util.RemoteSourceInfo
|
import xyz.quaver.pupil.util.RemoteSourceInfo
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.util.*
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@OptIn(ExperimentalCoroutinesApi::class)
|
@OptIn(ExperimentalCoroutinesApi::class)
|
||||||
@@ -65,9 +66,48 @@ class PupilHttpClientTest {
|
|||||||
|
|
||||||
val client = PupilHttpClient(mockEngine)
|
val client = PupilHttpClient(mockEngine)
|
||||||
|
|
||||||
client.downloadApk(RemoteSourceInfo("", "", ""), tempFile).collect()
|
client.downloadApk("http://a/", tempFile).collect()
|
||||||
|
|
||||||
assertArrayEquals(expected, tempFile.readBytes())
|
assertArrayEquals(expected, tempFile.readBytes())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun latestRelease() = runTest {
|
||||||
|
val expectedVersion = "5.3.7"
|
||||||
|
val expectedApkUrl = "https://github.com/tom5079/Pupil/releases/download/5.3.7/Pupil-v5.3.7.apk"
|
||||||
|
val expectedUpdateNotes = mapOf(
|
||||||
|
Locale.KOREAN to """
|
||||||
|
* 가끔씩 무한로딩 걸리는 현상 수정
|
||||||
|
* 백업시 즐겨찾기 태그도 백업되게 수정
|
||||||
|
* 이전 안드로이드에서 앱이 튕기는 오류 수정
|
||||||
|
""".trimIndent(),
|
||||||
|
Locale.JAPANESE to """
|
||||||
|
* 稀に接続不可になるバグを修正
|
||||||
|
* お気に入りタグを含むようバックアップ機能を修正
|
||||||
|
* 旧バージョンのアンドロイドでアプリがクラッシュするバグを解決
|
||||||
|
""".trimIndent(),
|
||||||
|
Locale.ENGLISH to """
|
||||||
|
* Fixed occasional outage
|
||||||
|
* Updated backup/restore feature to include favorite tags
|
||||||
|
* Fixed app crashing on older Androids
|
||||||
|
""".trimIndent()
|
||||||
|
)
|
||||||
|
|
||||||
|
val mockEngine = MockEngine { _ ->
|
||||||
|
val response = javaClass.getResource("/releases.json")!!.readText()
|
||||||
|
respond(response)
|
||||||
|
}
|
||||||
|
|
||||||
|
val client = PupilHttpClient(mockEngine)
|
||||||
|
|
||||||
|
val release = client.latestRelease()
|
||||||
|
|
||||||
|
assertEquals(expectedVersion, release.version)
|
||||||
|
assertEquals(expectedApkUrl, release.apkUrl)
|
||||||
|
|
||||||
|
println(expectedUpdateNotes)
|
||||||
|
println(release.updateNotes)
|
||||||
|
assertEquals(expectedUpdateNotes, release.updateNotes)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
2189
app/src/test/resources/releases.json
Normal file
2189
app/src/test/resources/releases.json
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user