Mod sizes are updated to proper values upon selection (#8648)

* Mod sizes are updated to proper values upon selection

---------

Co-authored-by: vegeta1k95 <vfylfhby>
This commit is contained in:
vegeta1k95
2023-02-11 22:48:12 +01:00
committed by GitHub
parent 47bbd996ae
commit aaf06b7589
2 changed files with 77 additions and 6 deletions

View File

@ -250,6 +250,43 @@ object Github {
return null
}
class Tree {
class TreeFile {
var size: Long = 0L
}
var url: String = ""
var tree = ArrayList<TreeFile>()
}
fun getRepoSize(repo: Repo): Float {
val link = "https://api.github.com/repos/${repo.full_name}/git/trees/${repo.default_branch}?recursive=true"
var retries = 2
while (retries > 0) {
retries--
// obey rate limit
if (RateLimit.waitForLimit()) return 0f
// try download
val inputStream = download(link) {
if (it.responseCode == 403 || it.responseCode == 200 && retries == 1) {
// Pass the response headers to the rate limit handler so it can process the rate limit headers
RateLimit.notifyHttpResponse(it)
retries++ // An extra retry so the 403 is ignored in the retry count
}
} ?: continue
val tree = json().fromJson(Tree::class.java, inputStream.bufferedReader().readText())
var totalSizeBytes = 0L
for (file in tree.tree)
totalSizeBytes += file.size
return totalSizeBytes / 1024f
}
return 0f
}
/**
* Parsed GitHub repo search response
* @property total_count Total number of hits for the search (ignoring paging window)
@ -268,6 +305,9 @@ object Github {
/** Part of [RepoSearch] in Github API response - one repository entry in [items][RepoSearch.items] */
@Suppress("PropertyName")
class Repo {
var hasUpdatedSize = false
var name = ""
var full_name = ""
var description: String? = null

View File

@ -10,6 +10,7 @@ import com.badlogic.gdx.scenes.scene2d.ui.ScrollPane
import com.badlogic.gdx.scenes.scene2d.ui.Table
import com.badlogic.gdx.scenes.scene2d.ui.TextButton
import com.badlogic.gdx.utils.Align
import com.badlogic.gdx.utils.Json
import com.badlogic.gdx.utils.SerializationException
import com.unciv.MainMenuScreen
import com.unciv.UncivGame
@ -47,8 +48,13 @@ import com.unciv.ui.utils.extensions.toTextButton
import com.unciv.utils.Log
import com.unciv.utils.concurrency.Concurrency
import com.unciv.utils.concurrency.launchOnGLThread
import com.unciv.utils.concurrency.withGLContext
import kotlinx.coroutines.Job
import kotlinx.coroutines.isActive
import java.io.IOException
import java.net.HttpURLConnection
import java.net.URL
import java.net.URLConnection
import kotlin.math.max
/**
@ -73,8 +79,7 @@ class ModManagementScreen(
private var lastSelectedButton: Button? = null
private var lastSyncMarkedButton: Button? = null
private var selectedModName = ""
private var selectedAuthor = ""
private var selectedMod: Github.Repo? = null
private val modDescriptionLabel: WrappableLabel
@ -357,8 +362,6 @@ class ModManagementScreen(
}
private fun addModInfoToActionTable(modName: String, repoUrl: String, updatedAt: String, author: String, modSize: Int) {
// remember selected mod - for now needed only to display a background-fetched image while the user is watching
selectedModName = modName
selectedAuthor = author
// Display metadata
if (author.isNotEmpty())
@ -407,6 +410,13 @@ class ModManagementScreen(
return downloadButton
}
private fun updateModInfo() {
if (selectedMod != null) {
modActionTable.clear()
addModInfoToActionTable(selectedMod!!)
}
}
/** Used as onClick handler for the online Mod list buttons */
private fun onlineButtonAction(repo: Github.Repo, button: Button) {
syncOnlineSelected(repo.name, button)
@ -417,6 +427,26 @@ class ModManagementScreen(
val label = if (installedModInfo[repo.name]?.state?.hasUpdate == true)
"Update [${repo.name}]"
else "Download [${repo.name}]"
if (!repo.hasUpdatedSize) {
Concurrency.run("GitHubParser") {
try {
val repoSize = Github.getRepoSize(repo)
if (repoSize > 0f) {
launchOnGLThread {
repo.size = repoSize.toInt()
repo.hasUpdatedSize = true
if (selectedMod == repo)
updateModInfo()
}
}
} catch (ignore: IOException) {
/* Parsing of mod size failed, do nothing */
}
}.start()
}
rightSideButton.setText(label.tr())
rightSideButton.onClick {
rightSideButton.setText("Downloading...".tr())
@ -426,8 +456,8 @@ class ModManagementScreen(
}
}
modActionTable.clear()
addModInfoToActionTable(repo)
selectedMod = repo
updateModInfo()
}
/** Download and install a mod in the background, called both from the right-bottom button and the URL entry popup */
@ -481,6 +511,7 @@ class ModManagementScreen(
* Display single mod metadata, offer additional actions (delete is elsewhere)
*/
private fun refreshInstalledModActions(mod: Ruleset) {
selectedMod = null
modActionTable.clear()
// show mod information first
addModInfoToActionTable(mod.name, mod.modOptions)