From 031890deb6bf87d95e51ee7cb6d264e2fef1295d Mon Sep 17 00:00:00 2001 From: AwkwardPeak7 <48650614+AwkwardPeak7@users.noreply.github.com> Date: Sun, 3 May 2026 02:21:13 +0500 Subject: [PATCH] extract apk icon (#1966) --- .../manga/impl/extension/Extension.kt | 32 +++++++++++++++++++ 1 file changed, 32 insertions(+) diff --git a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/Extension.kt b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/Extension.kt index 567728be..945ee682 100644 --- a/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/Extension.kt +++ b/server/src/main/kotlin/suwayomi/tachidesk/manga/impl/extension/Extension.kt @@ -14,6 +14,8 @@ import eu.kanade.tachiyomi.source.CatalogueSource import eu.kanade.tachiyomi.source.Source import eu.kanade.tachiyomi.source.SourceFactory import io.github.oshai.kotlinlogging.KotlinLogging +import net.dongliu.apk.parser.ApkFile +import net.dongliu.apk.parser.bean.Icon import okhttp3.CacheControl import okio.buffer import okio.sink @@ -37,7 +39,9 @@ import suwayomi.tachidesk.manga.impl.util.PackageTools.getPackageInfo import suwayomi.tachidesk.manga.impl.util.PackageTools.loadExtensionSources import suwayomi.tachidesk.manga.impl.util.network.await import suwayomi.tachidesk.manga.impl.util.source.GetCatalogueSource +import suwayomi.tachidesk.manga.impl.util.storage.ImageResponse.clearCachedImage import suwayomi.tachidesk.manga.impl.util.storage.ImageResponse.getImageResponse +import suwayomi.tachidesk.manga.impl.util.storage.ImageResponse.saveImage import suwayomi.tachidesk.manga.model.table.ExtensionTable import suwayomi.tachidesk.manga.model.table.SourceTable import suwayomi.tachidesk.server.ApplicationDirs @@ -155,6 +159,7 @@ object Extension { dex2jar(apkFilePath, jarFilePath, fileNameWithoutType) extractAssetsFromApk(apkFilePath, jarFilePath) + extractAndCacheApkIcon(apkFilePath, apkName) // clean up File(apkFilePath).delete() @@ -228,6 +233,33 @@ object Extension { } } + private fun extractAndCacheApkIcon( + apkFilePath: String, + apkName: String, + ) { + val iconCacheDir = "${applicationDirs.extensionsRoot}/icon" + try { + val iconData = + ApkFile(File(apkFilePath)).use { apk -> + apk.allIcons + .filterIsInstance() + .mapNotNull { it.data?.let { data -> data to it.density } } + .maxByOrNull { (_, density) -> density } + ?.first + } + if (iconData == null) { + logger.warn { "No icon found in APK $apkName" } + return + } + + File(iconCacheDir).mkdirs() + clearCachedImage(iconCacheDir, apkName) + saveImage("$iconCacheDir/$apkName", iconData.inputStream(), null) + } catch (e: Exception) { + logger.warn(e) { "Failed to extract icon from APK $apkName" } + } + } + private fun extractAssetsFromApk( apkPath: String, jarPath: String,