feat: cache manager and webapp manifest repository
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
package top.yeij.hearth.cache
|
||||
|
||||
import java.io.File
|
||||
|
||||
// 文件缓存:以 key 为文件名,内容以 UTF-8 纯文本落盘
|
||||
// File cache: uses key as filename, content stored as UTF-8 plain text
|
||||
class CacheManager(private val baseDir: File) {
|
||||
init { baseDir.mkdirs() }
|
||||
|
||||
fun save(key: String, content: String) {
|
||||
File(baseDir, key).writeText(content)
|
||||
}
|
||||
|
||||
fun load(key: String): String? {
|
||||
val f = File(baseDir, key)
|
||||
return if (f.exists()) f.readText() else null
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,51 @@
|
||||
package top.yeij.hearth.webapp
|
||||
|
||||
import com.google.gson.Gson
|
||||
import top.yeij.hearth.cache.CacheManager
|
||||
|
||||
// Web 应用清单条目
|
||||
// Web app manifest entry
|
||||
data class WebApp(val id: String, val name: String, val icon: String, val url: String)
|
||||
|
||||
// 网络抽象接口:Task 10 的 CardRepository 也会复用
|
||||
// HTTP abstraction reused by Task 10 CardRepository
|
||||
interface HttpClient {
|
||||
fun get(url: String): String?
|
||||
}
|
||||
|
||||
// 清单拉取仓库:拉取成功缓存 body 并解析;失败回退缓存;无缓存返回空列表
|
||||
// Manifest repository: on success cache + parse; on failure fall back to cache; no cache -> empty list
|
||||
class WebAppRepository(
|
||||
private val http: HttpClient,
|
||||
private val cache: CacheManager,
|
||||
private val manifestUrl: String,
|
||||
) {
|
||||
private val gson = Gson()
|
||||
|
||||
fun fetchManifest(): List<WebApp> {
|
||||
val body = http.get(manifestUrl)
|
||||
if (body != null) {
|
||||
cache.save(KEY, body)
|
||||
return parse(body)
|
||||
}
|
||||
val cached = cache.load(KEY) ?: return emptyList()
|
||||
return parse(cached)
|
||||
}
|
||||
|
||||
private fun parse(body: String): List<WebApp> {
|
||||
val root = gson.fromJson(body, Map::class.java)
|
||||
val apps = root["apps"] as? List<*> ?: return emptyList()
|
||||
return apps.mapNotNull { m ->
|
||||
val map = m as? Map<*, *> ?: return@mapNotNull null
|
||||
val id = map["id"] as? String ?: return@mapNotNull null
|
||||
val name = map["name"] as? String ?: return@mapNotNull null
|
||||
val icon = map["icon"] as? String ?: return@mapNotNull null
|
||||
val url = map["url"] as? String ?: return@mapNotNull null
|
||||
WebApp(id, name, icon, url)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
private const val KEY = "webapp-manifest"
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user