Added latestRelease to PupilHttpClient

This commit is contained in:
tom5079
2022-05-02 16:47:36 +09:00
parent 85a7eeeeea
commit e84c381423
3 changed files with 2284 additions and 5 deletions

View File

@@ -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)
}
} }

View File

@@ -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)
}
} }

File diff suppressed because it is too large Load Diff