diff --git a/README.md b/README.md index ed9513c..f8ad67e 100644 --- a/README.md +++ b/README.md @@ -79,6 +79,7 @@ Some of the features ReVanced API include: - 📢 **Announcements**: Post and get announcements - ℹ️ **About**: Get more information such as a description, ways to donate to, and links of the hoster of ReVanced API +- 💊 **Manager**: Get the latest updates of ReVanced Manager and its downloaders - 🧩 **Patches**: Get the latest updates of ReVanced Patches, directly from ReVanced API - 👥 **Contributors**: List all contributors involved in the project diff --git a/configuration.example.toml b/configuration.example.toml index 71f983b..5fd9d08 100644 --- a/configuration.example.toml +++ b/configuration.example.toml @@ -20,6 +20,8 @@ public-key-id = 3897925568445097277 [manager] repository = "revanced-manager" asset-regex = "apk$" +downloaders-repository = "revanced-manager-downloaders" +downloaders-asset-regex = "apk$" [contributors-repositories] revanced-patcher = "ReVanced Patcher" diff --git a/src/main/kotlin/app/revanced/api/configuration/repository/ConfigurationRepository.kt b/src/main/kotlin/app/revanced/api/configuration/repository/ConfigurationRepository.kt index 4c46887..1affbfb 100644 --- a/src/main/kotlin/app/revanced/api/configuration/repository/ConfigurationRepository.kt +++ b/src/main/kotlin/app/revanced/api/configuration/repository/ConfigurationRepository.kt @@ -23,8 +23,8 @@ import kotlin.io.path.createDirectories * The repository storing the configuration for the API. * * @property organization The API backends organization name where the repositories are. - * @property patches The source of the patches. - * @property manager The source of the manager. + * @property patches The configuration for patches. + * @property manager The configuration for the manager. * @property contributorsRepositoryNames The friendly name of repos mapped to the repository names to get contributors from. * @property backendServiceName The name of the backend service to use for the repositories, contributors, etc. * @property apiVersion The version to use for the API. @@ -38,8 +38,8 @@ import kotlin.io.path.createDirectories @Serializable internal class ConfigurationRepository( val organization: String, - val patches: SignedAssetConfiguration, - val manager: AssetConfiguration, + val patches: PatchesConfiguration, + val manager: ManagerConfiguration, @SerialName("contributors-repositories") val contributorsRepositoryNames: Map, @SerialName("backend-service-name") @@ -65,22 +65,20 @@ internal class ConfigurationRepository( } /** - * Am asset configuration whose asset is signed. + * A configuration for [PatchesService]. * - * [PatchesService] for example uses [BackendRepository] to get assets from its releases. - * A release contains multiple assets. - * - * This configuration is used in [ConfigurationRepository] - * to determine which release assets from repositories to get and to verify them. - * - * @property repository The repository in which releases are made to get an asset. - * @property assetRegex The regex matching the asset name. - * @property signatureAssetRegex The regex matching the signature asset name to verify the asset. - * @property publicKeyFile The public key file to verify the signature of the asset. - * @property publicKeyId The ID of the public key to verify the signature of the asset. + * @property repository The patches repository. + * @property assetRegex The regex matching the patches asset name + * in releases from the patches repository. + * @property signatureAssetRegex The regex matching the patches signature asset name + * in releases from the patches repository. + * @property publicKeyFile The public key file to verify the signature of the patches asset + * in releases from the patches repository. + * @property publicKeyId The ID of the public key to verify the signature of the patches asset + * in releases from the patches repository. */ @Serializable - internal class SignedAssetConfiguration( + internal class PatchesConfiguration( val repository: String, @Serializable(with = RegexSerializer::class) @SerialName("asset-regex") @@ -96,23 +94,26 @@ internal class ConfigurationRepository( ) /** - * Am asset configuration. - * - * [ManagerService] for example uses [BackendRepository] to get assets from its releases. - * A release contains multiple assets. - * - * This configuration is used in [ConfigurationRepository] - * to determine which release assets from repositories to get and to verify them. - * - * @property repository The repository in which releases are made to get an asset. - * @property assetRegex The regex matching the asset name. + * A configuration for [ManagerService]. + + * @property repository The manager repository. + * @property assetRegex The regex matching the manager asset name + * in releases from the manager repository. + * @property downloadersRepository The manager downloaders repository. + * @property downloadersAssetRegex The regex matching the manager downloaders asset name + * in releases from the manager downloaders repository. */ @Serializable - internal class AssetConfiguration( + internal class ManagerConfiguration( val repository: String, @Serializable(with = RegexSerializer::class) @SerialName("asset-regex") val assetRegex: Regex, + @SerialName("downloaders-repository") + val downloadersRepository: String, + @Serializable(with = RegexSerializer::class) + @SerialName("downloaders-asset-regex") + val downloadersAssetRegex: Regex, ) } diff --git a/src/main/kotlin/app/revanced/api/configuration/routes/ManagerRoute.kt b/src/main/kotlin/app/revanced/api/configuration/routes/ManagerRoute.kt index e3ef9c9..6ab1bd8 100644 --- a/src/main/kotlin/app/revanced/api/configuration/routes/ManagerRoute.kt +++ b/src/main/kotlin/app/revanced/api/configuration/routes/ManagerRoute.kt @@ -35,6 +35,26 @@ internal fun Route.managerRoute() = route("manager") { call.respond(managerService.latestVersion(prerelease)) } } + + route("downloaders") { + installManagerDownloadersRouteDocumentation() + + get { + val prerelease = call.parameters["prerelease"]?.toBoolean() ?: false + + call.respond(managerService.latestDownloadersRelease(prerelease)) + } + + route("version") { + installManagerDownloadersVersionRouteDocumentation() + + get { + val prerelease = call.parameters["prerelease"]?.toBoolean() ?: false + + call.respond(managerService.latestDownloadersVersion(prerelease)) + } + } + } } } @@ -77,3 +97,35 @@ private fun Route.installManagerVersionRouteDocumentation() = installNotarizedRo } } } + +private fun Route.installManagerDownloadersRouteDocumentation() = installNotarizedRoute { + tags = setOf("Manager") + + get = GetInfo.builder { + description("Get the current manager downloaders release") + summary("Get current manager downloaders release") + parameters(prereleaseParameter) + response { + description("The latest manager downloaders release") + mediaTypes("application/json") + responseCode(HttpStatusCode.OK) + responseType() + } + } +} + +private fun Route.installManagerDownloadersVersionRouteDocumentation() = installNotarizedRoute { + tags = setOf("Manager") + + get = GetInfo.builder { + description("Get the current manager downloaders release version") + summary("Get current manager downloaders release version") + parameters(prereleaseParameter) + response { + description("The current manager downloaders release version") + mediaTypes("application/json") + responseCode(HttpStatusCode.OK) + responseType() + } + } +} \ No newline at end of file diff --git a/src/main/kotlin/app/revanced/api/configuration/services/ManagerService.kt b/src/main/kotlin/app/revanced/api/configuration/services/ManagerService.kt index 2bf0703..ae1b116 100644 --- a/src/main/kotlin/app/revanced/api/configuration/services/ManagerService.kt +++ b/src/main/kotlin/app/revanced/api/configuration/services/ManagerService.kt @@ -34,4 +34,29 @@ internal class ManagerService( return ApiReleaseVersion(managerRelease.tag) } + + suspend fun latestDownloadersRelease(prerelease: Boolean): ApiRelease { + val downloaderPluginsRelease = backendRepository.release( + configurationRepository.organization, + configurationRepository.manager.downloadersRepository, + prerelease, + ) + + return ApiRelease( + downloaderPluginsRelease.tag, + downloaderPluginsRelease.createdAt, + downloaderPluginsRelease.releaseNote, + downloaderPluginsRelease.assets.first(configurationRepository.manager.downloadersAssetRegex).downloadUrl, + ) + } + + suspend fun latestDownloadersVersion(prerelease: Boolean): ApiReleaseVersion { + val downloaderPluginsRelease = backendRepository.release( + configurationRepository.organization, + configurationRepository.manager.downloadersRepository, + prerelease, + ) + + return ApiReleaseVersion(downloaderPluginsRelease.tag) + } }