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 22, 2024
1 parent f82ef10 commit a846461
Showing 1 changed file with 108 additions and 41 deletions.
149 changes: 108 additions & 41 deletions app/src/main/kotlin/com/apkupdater/repository/CodeBergRepository.kt
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package com.apkupdater.repository

import android.net.Uri
import android.os.Build
import android.util.Log
import io.github.g00fy2.versioncompare.Version
import com.apkupdater.BuildConfig
import com.apkupdater.data.codeberg.CodeBergApps
import com.apkupdater.data.codeberg.CodeBergRelease
import com.apkupdater.data.codeberg.CodeBergReleaseAsset
import com.apkupdater.data.ui.AppInstalled
import com.apkupdater.data.ui.AppUpdate
import com.apkupdater.data.ui.CodeBergSource
Expand All @@ -12,12 +16,11 @@ 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,
Expand All @@ -26,19 +29,46 @@ class CodeBergRepository(

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

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>>>()

CodeBergApps.forEach { app ->
apps.find { it.packageName == app.packageName }?.let {
checks.add(checkApp(apps, app.user, app.repo, app.packageName, it.version, null))
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))
}
}

if (checks.isEmpty()) {
emit(emptyList())
emit(Result.success(emptyList()))
} else {
checks.combine { all -> emit(all.flatMap { it }) }.collect()
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 suspend fun checkApp(
private fun checkApp(
apps: List<AppInstalled>?,
user: String,
repo: String,
Expand All @@ -47,21 +77,21 @@ class CodeBergRepository(
extra: Regex?
) = flow {
val releases = service.getReleases(user, repo)
.filter { Version(filterVersionTag(it.tag_name)) > Version(currentVersion) }
.filter { filterPreRelease(it) }
.filter { findApkAsset(it.assets).isNotEmpty() }

if (releases.isNotEmpty()) {
if (releases.isNotEmpty() && Version(filterVersionTag(releases[0].tag_name)) > Version(currentVersion)) {
val app = apps?.getApp(packageName)
emit(listOf(
AppUpdate(
emit(listOf(AppUpdate(
name = repo,
packageName = packageName,
version = releases[0].tag_name,
oldVersion = app?.version ?: "?",
versionCode = 0L,
oldVersionCode = app?.versionCode ?: 0L,
source = CodeBergSource,
link = getApkUrl(packageName, releases[0]),
whatsNew = releases[0].description,
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 {
Expand All @@ -72,40 +102,77 @@ class CodeBergRepository(
Log.e("CodeBergRepository", "Error fetching releases for $packageName.", it)
}

suspend fun search(text: String) = flow {
val checks = mutableListOf<Flow<List<AppUpdate>>>()
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))

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

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 filterPreRelease(release: CodeBergRelease) = when {
prefs.ignorePreRelease.get() && release.prerelease -> false
else -> true
}

private fun getApkUrl(
packageName: String,
release: CodeBergRelease
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 {
// TODO: Take into account arch
val source = release.assets.sources.find { it.url.endsWith(".apk", true) }
if (source != null) return source.url
val apks = assets
.filter { it.browser_download_url.endsWith(".apk", true) }
.filter { filterExtra(it, extra) }

val link = release.assets.links.find { it.url.endsWith(".apk", true) }
if (link != null) return link.url
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 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
}
}
}
// If no match, return biggest apk in the hope it's universal
return apks.maxByOrNull { it.size }?.browser_download_url.orEmpty()
}
}
}

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

}

0 comments on commit a846461

Please sign in to comment.