Loading app/build.gradle +3 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,9 @@ dependencies { // implementation "com.squareup.moshi:moshi-adapters:1.5.0" implementation "com.squareup.okhttp3:okhttp:4.9.2" // JSON Converter implementation 'com.squareup.retrofit2:converter-gson:2.5.0' // YAML factory implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.11.2" Loading app/src/main/java/foundation/e/apps/api/cleanapk/ApplicationDeserializer.kt 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright ECORP SAS 2022 * Apps Quickly and easily install Android apps onto your device! * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package foundation.e.apps.api.cleanapk import com.google.gson.Gson import com.google.gson.JsonDeserializationContext import com.google.gson.JsonDeserializer import com.google.gson.JsonElement import foundation.e.apps.api.cleanapk.data.app.Application class ApplicationDeserializer : JsonDeserializer<Application> { override fun deserialize( json: JsonElement?, typeOfT: java.lang.reflect.Type?, context: JsonDeserializationContext? ): Application { val gson = Gson() val application = gson.fromJson(json?.asJsonObject?.toString(), Application::class.java) val lastUpdate = application.app.latest_downloaded_version val lastUpdatedOn = json?.asJsonObject?.get("app")?.asJsonObject?.get(lastUpdate) ?.asJsonObject?.get("update_on")?.asString ?: "" application.app.updatedOn = lastUpdatedOn return application } } app/src/main/java/foundation/e/apps/api/cleanapk/CleanAPKRepository.kt +3 −2 Original line number Diff line number Diff line Loading @@ -27,7 +27,8 @@ import retrofit2.Response import javax.inject.Inject class CleanAPKRepository @Inject constructor( private val cleanAPKInterface: CleanAPKInterface private val cleanAPKInterface: CleanAPKInterface, private val cleanApkAppDetailApi: CleanApkAppDetailApi ) { suspend fun getHomeScreenData( Loading @@ -42,7 +43,7 @@ class CleanAPKRepository @Inject constructor( architectures: List<String>? = null, type: String? = null ): Response<Application> { return cleanAPKInterface.getAppOrPWADetailsByID(id, architectures, type) return cleanApkAppDetailApi.getAppOrPWADetailsByID(id, architectures, type) } suspend fun searchApps( Loading app/src/main/java/foundation/e/apps/api/cleanapk/CleanApkAppDetailApi.kt 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * * * Copyright ECORP SAS 2022 * * Apps Quickly and easily install Android apps onto your device! * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.api.cleanapk import foundation.e.apps.api.cleanapk.data.app.Application import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Query interface CleanApkAppDetailApi { companion object { // API endpoints const val BASE_URL = "https://api.cleanapk.org/v2/" } @GET("apps?action=app_detail") suspend fun getAppOrPWADetailsByID( @Query("id") id: String, @Query("architectures") architectures: List<String>? = null, @Query("type") type: String? = null ): Response<Application> } app/src/main/java/foundation/e/apps/api/cleanapk/RetrofitModule.kt +32 −0 Original line number Diff line number Diff line Loading @@ -22,12 +22,15 @@ import android.os.Build import android.util.Log import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.dataformat.yaml.YAMLFactory import com.google.gson.Gson import com.google.gson.GsonBuilder import com.squareup.moshi.Moshi import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import foundation.e.apps.api.cleanapk.data.app.Application import foundation.e.apps.api.ecloud.EcloudApiInterface import foundation.e.apps.api.exodus.ExodusTrackerApi import foundation.e.apps.api.fdroid.FdroidApiInterface Loading @@ -39,6 +42,7 @@ import okhttp3.Protocol import okhttp3.Response import okhttp3.ResponseBody.Companion.toResponseBody import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.jackson.JacksonConverterFactory import retrofit2.converter.moshi.MoshiConverterFactory import java.net.ConnectException Loading @@ -65,6 +69,24 @@ object RetrofitModule { .create(CleanAPKInterface::class.java) } /** * Provides an instance of Retrofit to work with CleanAPK API * @return instance of [CleanApkAppDetailApi] */ @Singleton @Provides fun provideCleanAPKDetailApi( okHttpClient: OkHttpClient, @Named("gsonCustomAdapter") gson: Gson ): CleanApkAppDetailApi { return Retrofit.Builder() .baseUrl(CleanAPKInterface.BASE_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(CleanApkAppDetailApi::class.java) } @Singleton @Provides fun provideExodusApi(okHttpClient: OkHttpClient, moshi: Moshi): ExodusTrackerApi { Loading Loading @@ -114,6 +136,16 @@ object RetrofitModule { .build() } @Singleton @Provides @Named("gsonCustomAdapter") fun getGson(): Gson { return GsonBuilder() .registerTypeAdapter(Application::class.java, ApplicationDeserializer()) .enableComplexMapKeySerialization() .create() } /** * Used in above [provideFdroidApi]. * Reference: https://stackoverflow.com/a/69859687 Loading Loading
app/build.gradle +3 −0 Original line number Diff line number Diff line Loading @@ -125,6 +125,9 @@ dependencies { // implementation "com.squareup.moshi:moshi-adapters:1.5.0" implementation "com.squareup.okhttp3:okhttp:4.9.2" // JSON Converter implementation 'com.squareup.retrofit2:converter-gson:2.5.0' // YAML factory implementation "com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.11.2" Loading
app/src/main/java/foundation/e/apps/api/cleanapk/ApplicationDeserializer.kt 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * Copyright ECORP SAS 2022 * Apps Quickly and easily install Android apps onto your device! * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <https://www.gnu.org/licenses/>. */ package foundation.e.apps.api.cleanapk import com.google.gson.Gson import com.google.gson.JsonDeserializationContext import com.google.gson.JsonDeserializer import com.google.gson.JsonElement import foundation.e.apps.api.cleanapk.data.app.Application class ApplicationDeserializer : JsonDeserializer<Application> { override fun deserialize( json: JsonElement?, typeOfT: java.lang.reflect.Type?, context: JsonDeserializationContext? ): Application { val gson = Gson() val application = gson.fromJson(json?.asJsonObject?.toString(), Application::class.java) val lastUpdate = application.app.latest_downloaded_version val lastUpdatedOn = json?.asJsonObject?.get("app")?.asJsonObject?.get(lastUpdate) ?.asJsonObject?.get("update_on")?.asString ?: "" application.app.updatedOn = lastUpdatedOn return application } }
app/src/main/java/foundation/e/apps/api/cleanapk/CleanAPKRepository.kt +3 −2 Original line number Diff line number Diff line Loading @@ -27,7 +27,8 @@ import retrofit2.Response import javax.inject.Inject class CleanAPKRepository @Inject constructor( private val cleanAPKInterface: CleanAPKInterface private val cleanAPKInterface: CleanAPKInterface, private val cleanApkAppDetailApi: CleanApkAppDetailApi ) { suspend fun getHomeScreenData( Loading @@ -42,7 +43,7 @@ class CleanAPKRepository @Inject constructor( architectures: List<String>? = null, type: String? = null ): Response<Application> { return cleanAPKInterface.getAppOrPWADetailsByID(id, architectures, type) return cleanApkAppDetailApi.getAppOrPWADetailsByID(id, architectures, type) } suspend fun searchApps( Loading
app/src/main/java/foundation/e/apps/api/cleanapk/CleanApkAppDetailApi.kt 0 → 100644 +41 −0 Original line number Diff line number Diff line /* * * * Copyright ECORP SAS 2022 * * Apps Quickly and easily install Android apps onto your device! * * * * This program is free software: you can redistribute it and/or modify * * it under the terms of the GNU General Public License as published by * * the Free Software Foundation, either version 3 of the License, or * * (at your option) any later version. * * * * This program is distributed in the hope that it will be useful, * * but WITHOUT ANY WARRANTY; without even the implied warranty of * * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * * GNU General Public License for more details. * * * * You should have received a copy of the GNU General Public License * * along with this program. If not, see <https://www.gnu.org/licenses/>. * */ package foundation.e.apps.api.cleanapk import foundation.e.apps.api.cleanapk.data.app.Application import retrofit2.Response import retrofit2.http.GET import retrofit2.http.Query interface CleanApkAppDetailApi { companion object { // API endpoints const val BASE_URL = "https://api.cleanapk.org/v2/" } @GET("apps?action=app_detail") suspend fun getAppOrPWADetailsByID( @Query("id") id: String, @Query("architectures") architectures: List<String>? = null, @Query("type") type: String? = null ): Response<Application> }
app/src/main/java/foundation/e/apps/api/cleanapk/RetrofitModule.kt +32 −0 Original line number Diff line number Diff line Loading @@ -22,12 +22,15 @@ import android.os.Build import android.util.Log import com.fasterxml.jackson.databind.ObjectMapper import com.fasterxml.jackson.dataformat.yaml.YAMLFactory import com.google.gson.Gson import com.google.gson.GsonBuilder import com.squareup.moshi.Moshi import com.squareup.moshi.kotlin.reflect.KotlinJsonAdapterFactory import dagger.Module import dagger.Provides import dagger.hilt.InstallIn import dagger.hilt.components.SingletonComponent import foundation.e.apps.api.cleanapk.data.app.Application import foundation.e.apps.api.ecloud.EcloudApiInterface import foundation.e.apps.api.exodus.ExodusTrackerApi import foundation.e.apps.api.fdroid.FdroidApiInterface Loading @@ -39,6 +42,7 @@ import okhttp3.Protocol import okhttp3.Response import okhttp3.ResponseBody.Companion.toResponseBody import retrofit2.Retrofit import retrofit2.converter.gson.GsonConverterFactory import retrofit2.converter.jackson.JacksonConverterFactory import retrofit2.converter.moshi.MoshiConverterFactory import java.net.ConnectException Loading @@ -65,6 +69,24 @@ object RetrofitModule { .create(CleanAPKInterface::class.java) } /** * Provides an instance of Retrofit to work with CleanAPK API * @return instance of [CleanApkAppDetailApi] */ @Singleton @Provides fun provideCleanAPKDetailApi( okHttpClient: OkHttpClient, @Named("gsonCustomAdapter") gson: Gson ): CleanApkAppDetailApi { return Retrofit.Builder() .baseUrl(CleanAPKInterface.BASE_URL) .client(okHttpClient) .addConverterFactory(GsonConverterFactory.create(gson)) .build() .create(CleanApkAppDetailApi::class.java) } @Singleton @Provides fun provideExodusApi(okHttpClient: OkHttpClient, moshi: Moshi): ExodusTrackerApi { Loading Loading @@ -114,6 +136,16 @@ object RetrofitModule { .build() } @Singleton @Provides @Named("gsonCustomAdapter") fun getGson(): Gson { return GsonBuilder() .registerTypeAdapter(Application::class.java, ApplicationDeserializer()) .enableComplexMapKeySerialization() .create() } /** * Used in above [provideFdroidApi]. * Reference: https://stackoverflow.com/a/69859687 Loading