From f7709287034987644849cce34ce2775e141986ac Mon Sep 17 00:00:00 2001 From: C10udburst <18114966+C10udburst@users.noreply.github.com> Date: Thu, 4 Aug 2022 11:06:07 +0200 Subject: [PATCH] add apk downloading --- .../lagradost/gradle/CloudstreamExtension.kt | 14 ++-- .../com/lagradost/gradle/CloudstreamPlugin.kt | 2 + .../com/lagradost/gradle/DownloadUtils.kt | 70 +++++++++++++++++++ .../configuration/ApkConfigurationProvider.kt | 41 +++++++++++ .../gradle/configuration/Configurations.kt | 28 ++++++++ .../configuration/IConfigurationProvider.kt | 10 +++ 6 files changed, 160 insertions(+), 5 deletions(-) create mode 100644 src/main/kotlin/com/lagradost/gradle/DownloadUtils.kt create mode 100644 src/main/kotlin/com/lagradost/gradle/configuration/ApkConfigurationProvider.kt create mode 100644 src/main/kotlin/com/lagradost/gradle/configuration/Configurations.kt create mode 100644 src/main/kotlin/com/lagradost/gradle/configuration/IConfigurationProvider.kt diff --git a/src/main/kotlin/com/lagradost/gradle/CloudstreamExtension.kt b/src/main/kotlin/com/lagradost/gradle/CloudstreamExtension.kt index 347ad45..5ebc99c 100644 --- a/src/main/kotlin/com/lagradost/gradle/CloudstreamExtension.kt +++ b/src/main/kotlin/com/lagradost/gradle/CloudstreamExtension.kt @@ -8,18 +8,22 @@ import javax.inject.Inject abstract class CloudstreamExtension @Inject constructor(project: Project) { val userCache = project.gradle.gradleUserHomeDir.resolve("caches").resolve("cloudstream") - - var apkinfo: ApkInfo? = null + var apkinfo: ApkInfo = ApkInfo(this) internal set + fun overrideUrl(url: String) { + apkinfo.url = url + } + internal var pluginClassName: String? = null } -class ApkInfo(extension: CloudstreamExtension, val version: Int) { +class ApkInfo(extension: CloudstreamExtension) { val cache = extension.userCache.resolve("cloudstream") - val apkFile = cache.resolve("cloudstream-$version.apk") - val jarFile = cache.resolve("cloudstream-$version.jar") + var url = "https://github.com/recloudstream/cloudstream/releases/download/pre-release/app-debug.apk" + val apkFile = cache.resolve("cloudstream.apk") + val jarFile = cache.resolve("cloudstream.jar") } fun ExtensionContainer.getCloudstream(): CloudstreamExtension { diff --git a/src/main/kotlin/com/lagradost/gradle/CloudstreamPlugin.kt b/src/main/kotlin/com/lagradost/gradle/CloudstreamPlugin.kt index 4540e25..744c2a5 100644 --- a/src/main/kotlin/com/lagradost/gradle/CloudstreamPlugin.kt +++ b/src/main/kotlin/com/lagradost/gradle/CloudstreamPlugin.kt @@ -3,11 +3,13 @@ package com.lagradost.gradle import org.gradle.api.Plugin import org.gradle.api.Project import com.lagradost.gradle.tasks.registerTasks +import com.lagradost.gradle.configuration.registerConfigurations abstract class CloudstreamPlugin : Plugin { override fun apply(project: Project) { project.extensions.create("cloudstream", CloudstreamExtension::class.java, project) registerTasks(project) + registerConfigurations(project) } } \ No newline at end of file diff --git a/src/main/kotlin/com/lagradost/gradle/DownloadUtils.kt b/src/main/kotlin/com/lagradost/gradle/DownloadUtils.kt new file mode 100644 index 0000000..b93221a --- /dev/null +++ b/src/main/kotlin/com/lagradost/gradle/DownloadUtils.kt @@ -0,0 +1,70 @@ +package com.lagradost.gradle + +import org.gradle.api.Project +import org.gradle.api.internal.project.ProjectInternal +import org.gradle.internal.logging.progress.ProgressLogger +import org.gradle.internal.logging.progress.ProgressLoggerFactory +import org.gradle.internal.service.ServiceRegistry +import java.io.File +import java.io.FileOutputStream +import java.net.URL + + +fun createProgressLogger(project: Project, loggerCategory: String): ProgressLogger { + return createProgressLogger((project as ProjectInternal).services, loggerCategory) +} + +fun createProgressLogger(services: ServiceRegistry, loggerCategory: String): ProgressLogger { + val progressLoggerFactory = services.get(ProgressLoggerFactory::class.java) + return progressLoggerFactory.newOperation(loggerCategory).also { it.description = loggerCategory } +} + +fun URL.download(file: File, progressLogger: ProgressLogger) { + progressLogger.started() + try { + val tempFile = File.createTempFile(file.name, ".part", file.parentFile) + tempFile.deleteOnExit() + + val connection = this.openConnection() + val size = connection.contentLengthLong + val sizeText = toLengthText(size) + + connection.getInputStream().use { inputStream -> + var finished = false + var processedBytes: Long = 0 + try { + FileOutputStream(tempFile).use { os -> + val buf = ByteArray(1024 * 10) + var read: Int + while (inputStream.read(buf).also { read = it } >= 0) { + os.write(buf, 0, read) + processedBytes += read + progressLogger.progress("Downloading apk ${toLengthText(processedBytes)}/$sizeText") + } + os.flush() + finished = true + } + } finally { + if (finished) { + tempFile.renameTo(file) + } else { + tempFile.delete() + } + } + } + } finally { + progressLogger.completed() + } +} + +private fun toLengthText(bytes: Long): String { + return if (bytes < 1024) { + "$bytes B" + } else if (bytes < 1024 * 1024) { + (bytes / 1024).toString() + " KB" + } else if (bytes < 1024 * 1024 * 1024) { + String.format("%.2f MB", bytes / (1024.0 * 1024.0)) + } else { + String.format("%.2f GB", bytes / (1024.0 * 1024.0 * 1024.0)) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lagradost/gradle/configuration/ApkConfigurationProvider.kt b/src/main/kotlin/com/lagradost/gradle/configuration/ApkConfigurationProvider.kt new file mode 100644 index 0000000..67dc282 --- /dev/null +++ b/src/main/kotlin/com/lagradost/gradle/configuration/ApkConfigurationProvider.kt @@ -0,0 +1,41 @@ +package com.lagradost.gradle.configuration + +import com.lagradost.gradle.ApkInfo +import com.lagradost.gradle.createProgressLogger +import com.lagradost.gradle.download +import com.lagradost.gradle.getCloudstream +import com.googlecode.d2j.dex.Dex2jar +import com.googlecode.d2j.reader.BaseDexFileReader +import com.googlecode.d2j.reader.MultiDexFileReader +import groovy.json.JsonSlurper +import org.gradle.api.Project +import org.gradle.api.artifacts.Dependency +import java.lang.Integer.parseInt +import java.net.URL + +class ApkConfigurationProvider : IConfigurationProvider { + + override fun provide(project: Project, dependency: Dependency) { + val extension = project.extensions.getCloudstream() + val apkinfo = extension.apkinfo + + apkinfo.cache.mkdirs() + + if (!apkinfo.apkFile.exists()) { + project.logger.lifecycle("Downloading apk") + + val url = URL(apkinfo.url) + + url.download(apkinfo.apkFile, createProgressLogger(project, "Download apk")) + } + + if (!apkinfo.jarFile.exists()) { + project.logger.lifecycle("Converting apk to jar") + + val reader: BaseDexFileReader = MultiDexFileReader.open(Files.readAllBytes(apkinfo.apkFile.toPath())) + Dex2jar.from(reader).topoLogicalSort().skipDebug(false).noCode(true).to(apkinfo.jarFile.toPath()) + } + + project.dependencies.add("compileOnly", project.files(apkinfo.jarFile)) + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lagradost/gradle/configuration/Configurations.kt b/src/main/kotlin/com/lagradost/gradle/configuration/Configurations.kt new file mode 100644 index 0000000..8f3b11a --- /dev/null +++ b/src/main/kotlin/com/lagradost/gradle/configuration/Configurations.kt @@ -0,0 +1,28 @@ +package com.lagradost.gradle.configuration + +import org.gradle.api.Project + +fun registerConfigurations(project: Project) { + val providers = arrayOf(ApkConfigurationProvider()) + + for (provider in providers) { + project.configurations.register(provider.name) { + it.isTransitive = false + } + } + + project.afterEvaluate { + for (provider in providers) { + val configuration = project.configurations.getByName(provider.name) + val dependencies = configuration.dependencies + + require(dependencies.size <= 1) { + "Only one '${provider.name}' dependency should be specified, but ${dependencies.size} were!" + } + + for (dependency in dependencies) { + provider.provide(project, dependency) + } + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/com/lagradost/gradle/configuration/IConfigurationProvider.kt b/src/main/kotlin/com/lagradost/gradle/configuration/IConfigurationProvider.kt new file mode 100644 index 0000000..e91dac9 --- /dev/null +++ b/src/main/kotlin/com/lagradost/gradle/configuration/IConfigurationProvider.kt @@ -0,0 +1,10 @@ +package com.lagradost.gradle.configuration + +import org.gradle.api.Project +import org.gradle.api.artifacts.Dependency + +interface IConfigurationProvider { + val name: String + + fun provide(project: Project, dependency: Dependency) +} \ No newline at end of file