Skip to content

Commit

Permalink
Update CodeBergRepository.kt
Browse files Browse the repository at this point in the history
  • Loading branch information
Jvr authored Mar 12, 2024
1 parent 3526245 commit f061d7e
Showing 1 changed file with 119 additions and 146 deletions.
265 changes: 119 additions & 146 deletions app/src/main/kotlin/com/apkupdater/repository/CodeBergRepository.kt
Original file line number Diff line number Diff line change
Expand Up @@ -15,190 +15,163 @@ import com.apkupdater.prefs.Prefs
import com.apkupdater.service.CodeBergService
import com.apkupdater.util.combine
import com.apkupdater.util.filterVersionTag
import io.github.g00fy2.versioncompare.Version
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.catch
import kotlinx.coroutines.flow.collect
import kotlinx.coroutines.flow.flow
import java.util.Scanner


class CodeBergRepository(
private val service: CodeBergService,
private val prefs: Prefs
) {
) {

suspend fun updates(apps: List<AppInstalled>) = flow {
val checks = mutableListOf(selfCheck())
suspend fun updates(apps: List<AppInstalled>) = flow {
val checks = mutableListOf<Flow<List<AppUpdate>>>()

CodeBergApps.forEachIndexed { i, app ->
if (i != 0) {
apps.find { it.packageName == app.packageName }?.let {
checks.add(checkApp(apps, app.user, app.repo, app.packageName, it.version, app.extra))
}
CodeBergApps.forEachIndexed { i, app ->
if (i != 0) {
apps.find { it.packageName == app.packageName }?.let {
checks.add(checkApp(apps, app.user, app.repo, app.packageName, it.version, app.extra))
}
}

checks.combine { all ->
emit(all.flatMap { it })
}.collect()
}.catch {
emit(emptyList())
Log.e("CodeBergRepository", "Error fetching releases.", it)
}

suspend fun search(text: String) = flow {
val checks = mutableListOf<Flow<List<AppUpdate>>>()
checks.combine { all ->
emit(all.flatMap { it })
}.collect()
}.catch {
emit(emptyList())
Log.e("CodeBergRepository", "Error fetching releases.", it)
}

CodeBergApps.forEach { app ->
if (app.repo.contains(text, true) || app.user.contains(text, true) || app.packageName.contains(text, true)) {
checks.add(checkApp(null, app.user, app.repo, app.packageName, "?", null))
}
}
suspend fun search(text: String) = flow {
val checks = mutableListOf<Flow<List<AppUpdate>>>()

if (checks.isEmpty()) {
emit(Result.success(emptyList()))
} else {
checks.combine { all ->
val r = all.flatMap { it }
emit(Result.success(r))
}.collect()
CodeBergApps.forEach { app ->
if (app.repo.contains(text, true) || app.user.contains(text, true) || app.packageName.contains(text, true)) {
checks.add(checkApp(null, app.user, app.repo, app.packageName, "?", null))
}
}.catch {
emit(Result.failure(it))
Log.e("CodeBergRepository", "Error searching.", it)
}

private fun selfCheck() = flow {
val releases = service.getReleases().filter { filterPreRelease(it) }
val versions = getVersions(releases[0].name)

if (versions.second > BuildConfig.VERSION_CODE.toLong()) {
emit(listOf(AppUpdate(
name = "APKUpdater",
packageName = BuildConfig.APPLICATION_ID,
version = versions.first,
oldVersion = BuildConfig.VERSION_NAME,
versionCode = versions.second,
oldVersionCode = BuildConfig.VERSION_CODE.toLong(),
source = CodeBergSource,
link = releases[0].assets[0].browser_download_url,
whatsNew = releases[0].body
)))
} else {
// We need to emit empty so it can be combined later
emit(listOf())
}
}.catch {
emit(emptyList())
Log.e("CodeBergRepository", "Error checking self-update.", it)
if (checks.isEmpty()) {
emit(Result.success(emptyList()))
} else {
checks.combine { all ->
val r = all.flatMap { it }
emit(Result.success(r))
}.collect()
}
}.catch {
emit(Result.failure(it))
Log.e("CodeBergRepository", "Error searching.", it)
}

private fun checkApp(
apps: List<AppInstalled>?,
user: String,
repo: String,
packageName: String,
currentVersion: String,
extra: Regex?
) = flow {
val releases = service.getReleases(user, repo)
.filter { filterPreRelease(it) }
.filter { findApkAsset(it.assets).isNotEmpty() }

if (releases.isNotEmpty() && Version(filterVersionTag(releases[0].tag_name)) > Version(currentVersion)) {
val app = apps?.getApp(packageName)
emit(listOf(AppUpdate(
name = repo,
packageName = packageName,
version = releases[0].tag_name,
oldVersion = app?.version ?: "?",
versionCode = 0L,
oldVersionCode = app?.versionCode ?: 0L,
source = CodeBergSource,
link = findApkAssetArch(releases[0].assets, extra),
whatsNew = releases[0].body,
iconUri = if (apps == null) Uri.parse(releases[0].author.avatar_url) else Uri.EMPTY
)))
} else {
emit(emptyList())
}
}.catch {
private fun checkApp(
apps: List<AppInstalled>?,
user: String,
repo: String,
packageName: String,
currentVersion: String,
extra: Regex?
) = flow {
val releases = service.getReleases(user, repo)
.filter { filterPreRelease(it) }
.filter { findApkAsset(it.assets).isNotEmpty() }

if (releases.isNotEmpty() && Version(filterVersionTag(releases[0].tag_name)) > Version(currentVersion)) {
val app = apps?.getApp(packageName)
emit(listOf(AppUpdate(
name = repo,
packageName = packageName,
version = releases[0].tag_name,
oldVersion = app?.version ?: "?",
versionCode = 0L,
oldVersionCode = app?.versionCode ?: 0L,
source = CodeBergSource,
link = findApkAssetArch(releases[0].assets, extra),
whatsNew = releases[0].body,
iconUri = if (apps == null) Uri.parse(releases[0].author.avatar_url) else Uri.EMPTY
)))
} else {
emit(emptyList())
Log.e("CodeBergRepository", "Error fetching releases for $packageName.", it)
}
}.catch {
emit(emptyList())
Log.e("CodeBergRepository", "Error fetching releases for $packageName.", it)
}

private fun getVersions(name: String) = runCatching {
val scanner = Scanner(name)
val version = scanner.next()
val versionCode = scanner.next().trim('(', ')').toLong()
Pair(version, versionCode)
}.getOrDefault(Pair(name, 0L))
private fun getVersions(name: String) = runCatching {
val scanner = Scanner(name)
val version = scanner.next()
val versionCode = scanner.next().trim('(', ')').toLong()
Pair(version, versionCode)
}.getOrDefault(Pair(name, 0L))

private fun filterPreRelease(release: CodeBergRelease) = when {
prefs.ignorePreRelease.get() && release.prerelease -> false
else -> true
}
private fun filterPreRelease(release: CodeBergRelease) = when {
prefs.ignorePreRelease.get() && release.prerelease -> false
else -> true
}

private fun findApkAsset(assets: List<CodeBergReleaseAsset>) = assets
private fun findApkAsset(assets: List<CodeBergReleaseAsset>) = assets
.filter { it.browser_download_url.endsWith(".apk", true) }
.maxByOrNull { it.size }
?.browser_download_url
.orEmpty()

private fun findApkAssetArch(
assets: List<CodeBergReleaseAsset>,
extra: Regex?
): String {
val apks = assets
.filter { it.browser_download_url.endsWith(".apk", true) }
.maxByOrNull { it.size }
?.browser_download_url
.orEmpty()

private fun findApkAssetArch(
assets: List<CodeBergReleaseAsset>,
extra: Regex?
): String {
val apks = assets
.filter { it.browser_download_url.endsWith(".apk", true) }
.filter { filterExtra(it, extra) }

when {
apks.isEmpty() -> return ""
apks.size == 1 -> return apks.first().browser_download_url
else -> {
// Try to match exact arch
Build.SUPPORTED_ABIS.forEach { arch ->
apks.forEach { apk ->
if (apk.browser_download_url.contains(arch, true)) {
return apk.browser_download_url
}
.filter { filterExtra(it, extra) }

when {
apks.isEmpty() -> return ""
apks.size == 1 -> return apks.first().browser_download_url
else -> {
// Try to match exact arch
Build.SUPPORTED_ABIS.forEach { arch ->
apks.forEach { apk ->
if (apk.browser_download_url.contains(arch, true)) {
return apk.browser_download_url
}
}
// Try to match arm64
if (Build.SUPPORTED_ABIS.contains("arm64-v8a")) {
apks.forEach { apk ->
if (apk.browser_download_url.contains("arm64", true)) {
return apk.browser_download_url
}
}
// Try to match arm64
if (Build.SUPPORTED_ABIS.contains("arm64-v8a")) {
apks.forEach { apk ->
if (apk.browser_download_url.contains("arm64", true)) {
return apk.browser_download_url
}
}
// Try to match x64
if (Build.SUPPORTED_ABIS.contains("x86_64")) {
apks.forEach { apk ->
if (apk.browser_download_url.contains("x64", true)) {
return apk.browser_download_url
}
}
// Try to match x64
if (Build.SUPPORTED_ABIS.contains("x86_64")) {
apks.forEach { apk ->
if (apk.browser_download_url.contains("x64", true)) {
return apk.browser_download_url
}
}
// Try to match arm
if (Build.SUPPORTED_ABIS.contains("armeabi-v7a")) {
apks.forEach { apk ->
if (apk.browser_download_url.contains("arm", true)) {
return apk.browser_download_url
}
}
// Try to match arm
if (Build.SUPPORTED_ABIS.contains("armeabi-v7a")) {
apks.forEach { apk ->
if (apk.browser_download_url.contains("arm", true)) {
return apk.browser_download_url
}
}
// If no match, return biggest apk in the hope it's universal
return apks.maxByOrNull { it.size }?.browser_download_url.orEmpty()
}
// If no match, return biggest apk in the hope it's universal
return apks.maxByOrNull { it.size }?.browser_download_url.orEmpty()
}
}
}

private fun filterExtra(asset: CodeBergReleaseAsset, extra: Regex?) = when(extra) {
null -> true
else -> asset.browser_download_url.matches(extra)
}

private fun filterExtra(asset: CodeBergReleaseAsset, extra: Regex?) = when(extra) {
null -> true
else -> asset.browser_download_url.matches(extra)
}

}

0 comments on commit f061d7e

Please sign in to comment.