Cleanup
This commit is contained in:
parent
b31d3802eb
commit
c0d1ce96d1
@ -1,27 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.data.network
|
|
||||||
|
|
||||||
import com.topjohnwu.magisk.Config
|
|
||||||
import com.topjohnwu.magisk.model.entity.GithubRepo
|
|
||||||
import io.reactivex.Single
|
|
||||||
import retrofit2.http.GET
|
|
||||||
import retrofit2.http.Query
|
|
||||||
|
|
||||||
|
|
||||||
interface GithubApiServices {
|
|
||||||
|
|
||||||
@GET("users/Magisk-Modules-Repo/repos")
|
|
||||||
fun fetchRepos(
|
|
||||||
@Query("page") page: Int,
|
|
||||||
@Query("per_page") count: Int = REPOS_PER_PAGE,
|
|
||||||
@Query("sort") sortOrder: String = when (Config.get<Int>(Config.Key.REPO_ORDER)) {
|
|
||||||
Config.Value.ORDER_DATE -> "updated"
|
|
||||||
Config.Value.ORDER_NAME -> "full_name"
|
|
||||||
else -> "updated"
|
|
||||||
}
|
|
||||||
): Single<List<GithubRepo>>
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val REPOS_PER_PAGE = 100
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -40,22 +40,6 @@ interface GithubRawApiServices {
|
|||||||
|
|
||||||
//endregion
|
//endregion
|
||||||
|
|
||||||
//region topjohnwu/Magisk/master
|
|
||||||
|
|
||||||
@GET("$MAGISK_MASTER/scripts/module_installer.sh")
|
|
||||||
@Streaming
|
|
||||||
fun fetchModuleInstaller(): Single<ResponseBody>
|
|
||||||
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
//region Magisk-Modules-Repo
|
|
||||||
|
|
||||||
@GET("$MAGISK_MODULES/{$MODULE}/master/{$FILE}")
|
|
||||||
@Streaming
|
|
||||||
fun fetchFile(@Path(MODULE) id: String, @Path(FILE) file: String): Single<ResponseBody>
|
|
||||||
|
|
||||||
//endregion
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This method shall be used exclusively for fetching files from urls from previous requests.
|
* This method shall be used exclusively for fetching files from urls from previous requests.
|
||||||
* Him, who uses it in a wrong way, shall die in an eternal flame.
|
* Him, who uses it in a wrong way, shall die in an eternal flame.
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.data.network
|
|
||||||
|
|
||||||
import io.reactivex.Single
|
|
||||||
import okhttp3.ResponseBody
|
|
||||||
import retrofit2.http.GET
|
|
||||||
import retrofit2.http.Path
|
|
||||||
import retrofit2.http.Streaming
|
|
||||||
|
|
||||||
|
|
||||||
interface GithubServices {
|
|
||||||
|
|
||||||
@GET("Magisk-Modules-Repo/{$MODULE}/archive/master.zip")
|
|
||||||
@Streaming
|
|
||||||
fun fetchModuleZip(@Path(MODULE) module: String): Single<ResponseBody>
|
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
private const val MODULE = "module"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,98 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.data.repository
|
|
||||||
|
|
||||||
import android.content.Context
|
|
||||||
import com.topjohnwu.magisk.Config
|
|
||||||
import com.topjohnwu.magisk.data.database.RepositoryDao
|
|
||||||
import com.topjohnwu.magisk.data.network.GithubApiServices
|
|
||||||
import com.topjohnwu.magisk.data.network.GithubRawApiServices
|
|
||||||
import com.topjohnwu.magisk.data.network.GithubServices
|
|
||||||
import com.topjohnwu.magisk.model.entity.GithubRepo
|
|
||||||
import com.topjohnwu.magisk.model.entity.toRepository
|
|
||||||
import com.topjohnwu.magisk.utils.Utils
|
|
||||||
import com.topjohnwu.magisk.utils.toSingle
|
|
||||||
import com.topjohnwu.magisk.utils.writeToFile
|
|
||||||
import com.topjohnwu.magisk.utils.writeToString
|
|
||||||
import io.reactivex.Completable
|
|
||||||
import io.reactivex.Single
|
|
||||||
|
|
||||||
class ModuleRepository(
|
|
||||||
private val context: Context,
|
|
||||||
private val apiRaw: GithubRawApiServices,
|
|
||||||
private val api: GithubApiServices,
|
|
||||||
private val apiWeb: GithubServices,
|
|
||||||
private val repoDao: RepositoryDao
|
|
||||||
) {
|
|
||||||
|
|
||||||
fun fetchModules(force: Boolean = false) =
|
|
||||||
if (force) fetchRemoteRepos() else fetchCachedOrdered()
|
|
||||||
.flatMap { if (it.isEmpty()) fetchRemoteRepos() else it.toSingle() }
|
|
||||||
|
|
||||||
private fun fetchRemoteRepos() = fetchAllRepos()
|
|
||||||
.map {
|
|
||||||
it.mapNotNull {
|
|
||||||
runCatching {
|
|
||||||
fetchProperties(it.name, it.updatedAtMillis).blockingGet()
|
|
||||||
}.getOrNull()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
//either github apparently returns repos incorrectly or ...
|
|
||||||
//either ways this fixes duplicates
|
|
||||||
.map { it.distinctBy { it.id } }
|
|
||||||
.doOnSuccess { repoDao.insert(it) }
|
|
||||||
|
|
||||||
private fun fetchCachedOrdered() = Single.fromCallable {
|
|
||||||
when (Config.get<Int>(Config.Key.REPO_ORDER)) {
|
|
||||||
Config.Value.ORDER_DATE -> repoDao.fetchAll()
|
|
||||||
Config.Value.ORDER_NAME -> repoDao.fetchAllOrderByName()
|
|
||||||
else -> repoDao.fetchAll()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun fetchInstalledModules() = Single.fromCallable { Utils.loadModulesLeanback() }
|
|
||||||
.map { it.values.toList() }
|
|
||||||
|
|
||||||
fun fetchInstallFile(module: String) = apiRaw
|
|
||||||
.fetchFile(module, FILE_INSTALL_SH)
|
|
||||||
.map { it.writeToFile(context, FILE_INSTALL_SH) }
|
|
||||||
|
|
||||||
fun fetchReadme(module: String) = apiRaw
|
|
||||||
.fetchFile(module, FILE_README_MD)
|
|
||||||
.map { it.writeToString() }
|
|
||||||
|
|
||||||
fun fetchConfig(module: String) = apiRaw
|
|
||||||
.fetchFile(module, FILE_CONFIG_SH)
|
|
||||||
.map { it.writeToFile(context, FILE_CONFIG_SH) }
|
|
||||||
|
|
||||||
fun fetchInstallZip(module: String) = apiWeb
|
|
||||||
.fetchModuleZip(module)
|
|
||||||
.map { it.writeToFile(context, FILE_INSTALL_ZIP) }
|
|
||||||
|
|
||||||
fun fetchInstaller() = apiRaw
|
|
||||||
.fetchModuleInstaller()
|
|
||||||
.map { it.writeToFile(context, FILE_MODULE_INSTALLER_SH) }
|
|
||||||
|
|
||||||
fun deleteAllCached() = Completable.fromCallable { repoDao.deleteAll() }
|
|
||||||
|
|
||||||
|
|
||||||
private fun fetchProperties(module: String, lastChanged: Long) = apiRaw
|
|
||||||
.fetchFile(module, "module.prop")
|
|
||||||
.map { it.toRepository(lastChanged) }
|
|
||||||
|
|
||||||
private fun fetchAllRepos(page: Int = 0): Single<List<GithubRepo>> = api.fetchRepos(page)
|
|
||||||
.flatMap {
|
|
||||||
if (it.size == GithubApiServices.REPOS_PER_PAGE) {
|
|
||||||
fetchAllRepos(page + 1).map { newList -> it + newList }
|
|
||||||
} else {
|
|
||||||
Single.just(it)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
const val FILE_INSTALL_SH = "install.sh"
|
|
||||||
const val FILE_README_MD = "README.md"
|
|
||||||
const val FILE_CONFIG_SH = "config.sh"
|
|
||||||
const val FILE_INSTALL_ZIP = "install.zip"
|
|
||||||
const val FILE_MODULE_INSTALLER_SH = "module_installer.sh"
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -3,9 +3,7 @@ package com.topjohnwu.magisk.di
|
|||||||
import com.squareup.moshi.Moshi
|
import com.squareup.moshi.Moshi
|
||||||
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory
|
||||||
import com.topjohnwu.magisk.Constants
|
import com.topjohnwu.magisk.Constants
|
||||||
import com.topjohnwu.magisk.data.network.GithubApiServices
|
|
||||||
import com.topjohnwu.magisk.data.network.GithubRawApiServices
|
import com.topjohnwu.magisk.data.network.GithubRawApiServices
|
||||||
import com.topjohnwu.magisk.data.network.GithubServices
|
|
||||||
import okhttp3.OkHttpClient
|
import okhttp3.OkHttpClient
|
||||||
import okhttp3.logging.HttpLoggingInterceptor
|
import okhttp3.logging.HttpLoggingInterceptor
|
||||||
import org.koin.dsl.module
|
import org.koin.dsl.module
|
||||||
@ -23,8 +21,6 @@ val networkingModule = module {
|
|||||||
|
|
||||||
single { createRetrofit(get(), get(), get()) }
|
single { createRetrofit(get(), get(), get()) }
|
||||||
|
|
||||||
single { createApiService<GithubServices>(get(), Constants.GITHUB_URL) }
|
|
||||||
single { createApiService<GithubApiServices>(get(), Constants.GITHUB_API_URL) }
|
|
||||||
single { createApiService<GithubRawApiServices>(get(), Constants.GITHUB_RAW_API_URL) }
|
single { createApiService<GithubRawApiServices>(get(), Constants.GITHUB_RAW_API_URL) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ import org.koin.dsl.module
|
|||||||
|
|
||||||
val repositoryModule = module {
|
val repositoryModule = module {
|
||||||
single { MagiskRepository(get(), get(), get()) }
|
single { MagiskRepository(get(), get(), get()) }
|
||||||
single { ModuleRepository(get(), get(), get(), get(), get()) }
|
|
||||||
single { LogRepository(get()) }
|
single { LogRepository(get()) }
|
||||||
single { AppRepository(get()) }
|
single { AppRepository(get()) }
|
||||||
single { SettingRepository(get()) }
|
single { SettingRepository(get()) }
|
||||||
|
@ -18,7 +18,7 @@ val viewModelModules = module {
|
|||||||
viewModel { HomeViewModel(get()) }
|
viewModel { HomeViewModel(get()) }
|
||||||
viewModel { SuperuserViewModel(get(), get(), get(), get()) }
|
viewModel { SuperuserViewModel(get(), get(), get(), get()) }
|
||||||
viewModel { HideViewModel(get(), get()) }
|
viewModel { HideViewModel(get(), get()) }
|
||||||
viewModel { ModuleViewModel(get(), get(), get(), get()) }
|
viewModel { ModuleViewModel(get(), get(), get()) }
|
||||||
viewModel { LogViewModel(get(), get()) }
|
viewModel { LogViewModel(get(), get()) }
|
||||||
viewModel { (action: String, uri: Uri?) -> FlashViewModel(action, uri, get()) }
|
viewModel { (action: String, uri: Uri?) -> FlashViewModel(action, uri, get()) }
|
||||||
viewModel { SuRequestViewModel(get(), get(), get(SUTimeout), get()) }
|
viewModel { SuRequestViewModel(get(), get(), get(SUTimeout), get()) }
|
||||||
|
@ -1,18 +0,0 @@
|
|||||||
package com.topjohnwu.magisk.model.entity
|
|
||||||
|
|
||||||
import com.squareup.moshi.Json
|
|
||||||
import com.squareup.moshi.JsonClass
|
|
||||||
import com.topjohnwu.magisk.utils.timeFormatStandard
|
|
||||||
import com.topjohnwu.magisk.utils.toTime
|
|
||||||
import timber.log.Timber
|
|
||||||
|
|
||||||
@JsonClass(generateAdapter = true)
|
|
||||||
data class GithubRepo(
|
|
||||||
@Json(name = "name") val name: String,
|
|
||||||
@Json(name = "updated_at") val updatedAt: String
|
|
||||||
) {
|
|
||||||
val updatedAtMillis by lazy {
|
|
||||||
updatedAt.toTime(timeFormatStandard)
|
|
||||||
.apply { Timber.i("$name updated @ $this ($updatedAt)") }
|
|
||||||
}
|
|
||||||
}
|
|
@ -16,7 +16,6 @@ import com.topjohnwu.magisk.Config
|
|||||||
import com.topjohnwu.magisk.KConfig
|
import com.topjohnwu.magisk.KConfig
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.data.database.RepoDatabaseHelper
|
import com.topjohnwu.magisk.data.database.RepoDatabaseHelper
|
||||||
import com.topjohnwu.magisk.data.repository.ModuleRepository
|
|
||||||
import com.topjohnwu.magisk.data.repository.SettingRepository
|
import com.topjohnwu.magisk.data.repository.SettingRepository
|
||||||
import org.koin.android.ext.android.inject
|
import org.koin.android.ext.android.inject
|
||||||
|
|
||||||
@ -27,7 +26,6 @@ abstract class BasePreferenceFragment : PreferenceFragmentCompat(),
|
|||||||
protected val prefs: SharedPreferences by inject()
|
protected val prefs: SharedPreferences by inject()
|
||||||
protected val app: App by inject()
|
protected val app: App by inject()
|
||||||
protected val settingRepo: SettingRepository by inject()
|
protected val settingRepo: SettingRepository by inject()
|
||||||
protected val moduleRepo: ModuleRepository by inject()
|
|
||||||
|
|
||||||
override fun onCreateView(
|
override fun onCreateView(
|
||||||
inflater: LayoutInflater,
|
inflater: LayoutInflater,
|
||||||
|
@ -11,7 +11,6 @@ import com.skoumal.teanity.util.KObservableField
|
|||||||
import com.topjohnwu.magisk.BR
|
import com.topjohnwu.magisk.BR
|
||||||
import com.topjohnwu.magisk.R
|
import com.topjohnwu.magisk.R
|
||||||
import com.topjohnwu.magisk.data.database.RepoDatabaseHelper
|
import com.topjohnwu.magisk.data.database.RepoDatabaseHelper
|
||||||
import com.topjohnwu.magisk.data.repository.ModuleRepository
|
|
||||||
import com.topjohnwu.magisk.model.entity.Repo
|
import com.topjohnwu.magisk.model.entity.Repo
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.ModuleRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.ModuleRvItem
|
||||||
import com.topjohnwu.magisk.model.entity.recycler.RepoRvItem
|
import com.topjohnwu.magisk.model.entity.recycler.RepoRvItem
|
||||||
@ -21,18 +20,15 @@ import com.topjohnwu.magisk.model.events.OpenChangelogEvent
|
|||||||
import com.topjohnwu.magisk.model.events.OpenFilePickerEvent
|
import com.topjohnwu.magisk.model.events.OpenFilePickerEvent
|
||||||
import com.topjohnwu.magisk.tasks.UpdateRepos
|
import com.topjohnwu.magisk.tasks.UpdateRepos
|
||||||
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
import com.topjohnwu.magisk.ui.base.MagiskViewModel
|
||||||
|
import com.topjohnwu.magisk.utils.Utils
|
||||||
import com.topjohnwu.magisk.utils.toSingle
|
import com.topjohnwu.magisk.utils.toSingle
|
||||||
import com.topjohnwu.magisk.utils.update
|
import com.topjohnwu.magisk.utils.update
|
||||||
import com.topjohnwu.magisk.utils.zip
|
|
||||||
import io.reactivex.Single
|
import io.reactivex.Single
|
||||||
import io.reactivex.android.schedulers.AndroidSchedulers
|
|
||||||
import io.reactivex.disposables.Disposable
|
import io.reactivex.disposables.Disposable
|
||||||
import io.reactivex.schedulers.Schedulers
|
|
||||||
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
import me.tatarka.bindingcollectionadapter2.OnItemBind
|
||||||
|
|
||||||
class ModuleViewModel(
|
class ModuleViewModel(
|
||||||
private val resources: Resources,
|
private val resources: Resources,
|
||||||
private val moduleRepo: ModuleRepository,
|
|
||||||
private val repoDatabase: RepoDatabaseHelper,
|
private val repoDatabase: RepoDatabaseHelper,
|
||||||
private val repoUpdater: UpdateRepos
|
private val repoUpdater: UpdateRepos
|
||||||
) : MagiskViewModel() {
|
) : MagiskViewModel() {
|
||||||
@ -62,33 +58,9 @@ class ModuleViewModel(
|
|||||||
fun repoPressed(item: RepoRvItem) = OpenChangelogEvent(item.item).publish()
|
fun repoPressed(item: RepoRvItem) = OpenChangelogEvent(item.item).publish()
|
||||||
fun downloadPressed(item: RepoRvItem) = InstallModuleEvent(item.item).publish()
|
fun downloadPressed(item: RepoRvItem) = InstallModuleEvent(item.item).publish()
|
||||||
|
|
||||||
fun refreshNew(forceReload: Boolean) {
|
fun refresh(force: Boolean) {
|
||||||
val updateInstalled = moduleRepo.fetchInstalledModules()
|
Single.fromCallable { Utils.loadModulesLeanback() }
|
||||||
.flattenAsFlowable { it }
|
.map { it.values.toList() }
|
||||||
.map { ModuleRvItem(it) }
|
|
||||||
.toList()
|
|
||||||
.map { it to itemsInstalled.calculateDiff(it) }
|
|
||||||
|
|
||||||
val updateRemote = moduleRepo.fetchModules(forceReload)
|
|
||||||
|
|
||||||
zip(updateInstalled, updateRemote) { installed, remote -> installed to remote }
|
|
||||||
.observeOn(AndroidSchedulers.mainThread())
|
|
||||||
.map {
|
|
||||||
itemsInstalled.update(it.first.first, it.first.second)
|
|
||||||
it.second
|
|
||||||
}
|
|
||||||
.observeOn(Schedulers.computation())
|
|
||||||
.flattenAsFlowable { it }
|
|
||||||
.map { RepoRvItem(it) }
|
|
||||||
.toList()
|
|
||||||
.doOnSuccess { allItems.update(it) }
|
|
||||||
.flatMap { queryRaw() }
|
|
||||||
.applyViewModel(this)
|
|
||||||
.subscribeK { itemsRemote.update(it.first, it.second) }
|
|
||||||
}
|
|
||||||
|
|
||||||
fun refresh/*Old*/(force: Boolean) {
|
|
||||||
moduleRepo.fetchInstalledModules()
|
|
||||||
.flattenAsFlowable { it }
|
.flattenAsFlowable { it }
|
||||||
.map { ModuleRvItem(it) }
|
.map { ModuleRvItem(it) }
|
||||||
.toList()
|
.toList()
|
||||||
|
Loading…
Reference in New Issue
Block a user