From 5ecf3c3f87657872da8cb0e3c7ff9d75424d7b3e Mon Sep 17 00:00:00 2001 From: aminecmi Date: Tue, 8 Nov 2022 21:31:40 +0100 Subject: [PATCH] Mercury api in common code. --- .../android/api/mercury/MercuryApi.kt | 35 ---- .../android/api/mercury/MercuryModels.kt | 59 ------- .../android/api/mercury/MercuryService.kt | 10 -- .../android/fragments/ArticleFragment.kt | 142 ++++++++-------- .../apps/readerforselfossv2/DI/modules.kt | 2 + .../readerforselfossv2/model/MercuryModel.kt | 157 ++++++++++++++++++ .../readerforselfossv2/model/ResultModel.kt | 40 +++++ .../readerforselfossv2/model/SelfossModel.kt | 18 -- .../repository/RepositoryImpl.kt | 7 +- .../readerforselfossv2/rest/MercuryApi.kt | 43 +++++ .../readerforselfossv2/rest/SelfossApi.kt | 48 ++---- 11 files changed, 328 insertions(+), 233 deletions(-) delete mode 100644 androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryApi.kt delete mode 100644 androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryModels.kt delete mode 100644 androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryService.kt create mode 100644 shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/MercuryModel.kt create mode 100644 shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/ResultModel.kt create mode 100644 shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/MercuryApi.kt diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryApi.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryApi.kt deleted file mode 100644 index dc2357e..0000000 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryApi.kt +++ /dev/null @@ -1,35 +0,0 @@ -package bou.amine.apps.readerforselfossv2.android.api.mercury - -import com.google.gson.GsonBuilder -import okhttp3.OkHttpClient -import okhttp3.logging.HttpLoggingInterceptor -import retrofit2.Call -import retrofit2.Retrofit -import retrofit2.converter.gson.GsonConverterFactory - -class MercuryApi() { - private val service: MercuryService - - init { - - val interceptor = HttpLoggingInterceptor() - interceptor.level = HttpLoggingInterceptor.Level.NONE - val client = OkHttpClient.Builder().addInterceptor(interceptor).build() - - val gson = GsonBuilder() - .setLenient() - .create() - val retrofit = - Retrofit - .Builder() - .baseUrl("https://www.amine-louveau.fr") - .client(client) - .addConverterFactory(GsonConverterFactory.create(gson)) - .build() - service = retrofit.create(MercuryService::class.java) - } - - fun parseUrl(url: String): Call { - return service.parseUrl(url) - } -} diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryModels.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryModels.kt deleted file mode 100644 index de4e5cc..0000000 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryModels.kt +++ /dev/null @@ -1,59 +0,0 @@ -package bou.amine.apps.readerforselfossv2.android.api.mercury - -import android.os.Parcel -import android.os.Parcelable -import com.google.gson.annotations.SerializedName - -class ParsedContent( - @SerializedName("title") val title: String, - @SerializedName("content") val content: String?, - @SerializedName("date_published") val date_published: String, - @SerializedName("lead_image_url") val lead_image_url: String?, - @SerializedName("dek") val dek: String, - @SerializedName("url") val url: String, - @SerializedName("domain") val domain: String, - @SerializedName("excerpt") val excerpt: String, - @SerializedName("total_pages") val total_pages: Int, - @SerializedName("rendered_pages") val rendered_pages: Int, - @SerializedName("next_page_url") val next_page_url: String -) : Parcelable { - - companion object { - @JvmField - val CREATOR: Parcelable.Creator = - object : Parcelable.Creator { - override fun createFromParcel(source: Parcel): ParsedContent = ParsedContent(source) - override fun newArray(size: Int): Array = arrayOfNulls(size) - } - } - - constructor(source: Parcel) : this( - title = source.readString().orEmpty(), - content = source.readString(), - date_published = source.readString().orEmpty(), - lead_image_url = source.readString(), - dek = source.readString().orEmpty(), - url = source.readString().orEmpty(), - domain = source.readString().orEmpty(), - excerpt = source.readString().orEmpty(), - total_pages = source.readInt(), - rendered_pages = source.readInt(), - next_page_url = source.readString().orEmpty() - ) - - override fun describeContents() = 0 - - override fun writeToParcel(dest: Parcel, flags: Int) { - dest.writeString(title) - dest.writeString(content) - dest.writeString(date_published) - dest.writeString(lead_image_url) - dest.writeString(dek) - dest.writeString(url) - dest.writeString(domain) - dest.writeString(excerpt) - dest.writeInt(total_pages) - dest.writeInt(rendered_pages) - dest.writeString(next_page_url) - } -} diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryService.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryService.kt deleted file mode 100644 index ce1b3e0..0000000 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/api/mercury/MercuryService.kt +++ /dev/null @@ -1,10 +0,0 @@ -package bou.amine.apps.readerforselfossv2.android.api.mercury - -import retrofit2.Call -import retrofit2.http.GET -import retrofit2.http.Query - -interface MercuryService { - @GET("parser.php") - fun parseUrl(@Query("link") link: String): Call -} diff --git a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt index d7d726f..b90f18a 100644 --- a/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt +++ b/androidApp/src/main/java/bou/amine/apps/readerforselfossv2/android/fragments/ArticleFragment.kt @@ -21,8 +21,6 @@ import androidx.core.widget.NestedScrollView import androidx.fragment.app.Fragment import bou.amine.apps.readerforselfossv2.android.ImageActivity import bou.amine.apps.readerforselfossv2.android.R -import bou.amine.apps.readerforselfossv2.android.api.mercury.MercuryApi -import bou.amine.apps.readerforselfossv2.android.api.mercury.ParsedContent import bou.amine.apps.readerforselfossv2.android.databinding.FragmentArticleBinding import bou.amine.apps.readerforselfossv2.android.model.ParecelableItem import bou.amine.apps.readerforselfossv2.android.model.toModel @@ -32,6 +30,7 @@ import bou.amine.apps.readerforselfossv2.android.utils.openInBrowserAsNewTask import bou.amine.apps.readerforselfossv2.android.utils.shareLink import bou.amine.apps.readerforselfossv2.model.SelfossModel import bou.amine.apps.readerforselfossv2.repository.Repository +import bou.amine.apps.readerforselfossv2.rest.MercuryApi import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded import bou.amine.apps.readerforselfossv2.utils.getImages @@ -49,9 +48,6 @@ import org.kodein.di.DI import org.kodein.di.DIAware import org.kodein.di.android.x.closestDI import org.kodein.di.instance -import retrofit2.Call -import retrofit2.Callback -import retrofit2.Response import java.net.MalformedURLException import java.net.URL import java.util.* @@ -81,6 +77,9 @@ class ArticleFragment : Fragment(), DIAware { private var font = "" private var staticBar = false + private val mercuryApi : MercuryApi by instance() + + override fun onCreate(savedInstanceState: Bundle?) { super.onCreate(savedInstanceState) @@ -249,88 +248,79 @@ class ArticleFragment : Fragment(), DIAware { private fun getContentFromMercury() { if (repository.isNetworkAvailable()) { binding.progressBar.visibility = View.VISIBLE - val parser = MercuryApi() - parser.parseUrl(url).enqueue( - object : Callback { - override fun onResponse( - call: Call, - response: Response - ) { - // TODO: clean all the following after finding the mercury content issue - try { - if (response.body() != null && response.body()!!.content != null && !response.body()!!.content.isNullOrEmpty()) { + CoroutineScope(Dispatchers.Main).launch { + val response = mercuryApi.query(url) + if (response.success) { + try { + if (response.data != null && response.data!!.content != null && !response.data!!.content.isNullOrEmpty()) { + try { + binding.titleView.text = response.data!!.title + if (typeface != null) { + binding.titleView.typeface = typeface + } try { - binding.titleView.text = response.body()!!.title - if (typeface != null) { - binding.titleView.typeface = typeface - } + // Note: Mercury may return relative urls... If it does the url val will not be changed. + URL(response.data!!.url) + url = response.data!!.url + } catch (e: MalformedURLException) { + // Mercury returned a relative url. We do nothing. + } + } catch (e: Exception) { + } + + try { + contentText = response.data!!.content.orEmpty() + htmlToWebview() + } catch (e: Exception) { + } + + try { + if (response.data!!.lead_image_url != null && !response.data!!.lead_image_url.isNullOrEmpty() && context != null) { + binding.imageView.visibility = View.VISIBLE try { - // Note: Mercury may return relative urls... If it does the url val will not be changed. - URL(response.body()!!.url) - url = response.body()!!.url - } catch (e: MalformedURLException) { - // Mercury returned a relative url. We do nothing. + Glide + .with(requireContext()) + .asBitmap() + .load( + response.data!!.lead_image_url.orEmpty() + ) + .apply(RequestOptions.fitCenterTransform()) + .into(binding.imageView) + } catch (e: Exception) { } - } catch (e: Exception) { + } else { + binding.imageView.visibility = View.GONE } - - try { - contentText = response.body()!!.content.orEmpty() - htmlToWebview() - } catch (e: Exception) { - } - - try { - if (response.body()!!.lead_image_url != null && !response.body()!!.lead_image_url.isNullOrEmpty() && context != null) { - binding.imageView.visibility = View.VISIBLE - try { - Glide - .with(requireContext()) - .asBitmap() - .load( - response.body()!!.lead_image_url.orEmpty() - ) - .apply(RequestOptions.fitCenterTransform()) - .into(binding.imageView) - } catch (e: Exception) { - } - } else { - binding.imageView.visibility = View.GONE - } - } catch (e: Exception) { - if (context != null) { - } - } - - try { - binding.nestedScrollView.scrollTo(0, 0) - - binding.progressBar.visibility = View.GONE - } catch (e: Exception) { - if (context != null) { - } - } - } else { - try { - openInBrowserAfterFailing() - } catch (e: Exception) { - if (context != null) { - } + } catch (e: Exception) { + if (context != null) { } } - } catch (e: Exception) { - if (context != null) { + + try { + binding.nestedScrollView.scrollTo(0, 0) + + binding.progressBar.visibility = View.GONE + } catch (e: Exception) { + if (context != null) { + } + } + } else { + try { + openInBrowserAfterFailing() + } catch (e: Exception) { + if (context != null) { + } } } + } catch (e: Exception) { + if (context != null) { + } } - - override fun onFailure( - call: Call, - t: Throwable - ) = openInBrowserAfterFailing() + } else { + openInBrowserAfterFailing() } - ) + } } } diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/DI/modules.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/DI/modules.kt index 7888376..170dc2f 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/DI/modules.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/DI/modules.kt @@ -1,5 +1,6 @@ package bou.amine.apps.readerforselfossv2.DI +import bou.amine.apps.readerforselfossv2.rest.MercuryApi import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.service.AppSettingsService import org.kodein.di.DI @@ -10,4 +11,5 @@ import org.kodein.di.singleton val networkModule by DI.Module { bind() with singleton { AppSettingsService() } bind() with singleton { SelfossApi(instance()) } + bind() with singleton { MercuryApi() } } \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/MercuryModel.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/MercuryModel.kt new file mode 100644 index 0000000..aa13349 --- /dev/null +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/MercuryModel.kt @@ -0,0 +1,157 @@ +package bou.amine.apps.readerforselfossv2.model + +import bou.amine.apps.readerforselfossv2.utils.DateUtils +import bou.amine.apps.readerforselfossv2.utils.getHtmlDecoded +import kotlinx.serialization.KSerializer +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.PrimitiveKind +import kotlinx.serialization.descriptors.PrimitiveSerialDescriptor +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import kotlinx.serialization.json.* + +class MercuryModel { + + @Serializable + class ParsedContent( + val title: String, + val content: String?, + val lead_image_url: String?, + val url: String + ) + + @Serializable + data class Tag( + val tag: String, + val color: String, + val unread: Int + ) + + @Serializable + class Stats( + val total: Int, + val unread: Int, + val starred: Int + ) + + @Serializable + data class Spout( + val name: String, + val description: String + ) + + @Serializable + data class ApiVersion( + val version: String?, + val apiversion: String? + ) { + fun getApiMajorVersion() : Int { + var versionNumber = 0 + if (apiversion != null) { + versionNumber = apiversion.substringBefore(".").toInt() + } + return versionNumber + } + } + + @Serializable + data class Source( + val id: Int, + val title: String, + @Serializable(with = TagsListSerializer::class) + val tags: List, + val spout: String, + val error: String, + val icon: String? + ) + + @Serializable + data class Item( + val id: Int, + val datetime: String, + val title: String, + val content: String, + @Serializable(with = BooleanSerializer::class) + var unread: Boolean, + @Serializable(with = BooleanSerializer::class) + var starred: Boolean, + val thumbnail: String?, + val icon: String?, + val link: String, + val sourcetitle: String, + @Serializable(with = TagsListSerializer::class) + val tags: List + ) { + // TODO: maybe find a better way to handle these kind of urls + fun getLinkDecoded(): String { + var stringUrl: String + stringUrl = + if (link.startsWith("http://news.google.com/news/") || link.startsWith("https://news.google.com/news/")) { + if (link.contains("&url=")) { + link.substringAfter("&url=") + } else { + this.link.replace("&", "&") + } + } else { + this.link.replace("&", "&") + } + + // handle :443 => https + if (stringUrl.contains(":443")) { + stringUrl = stringUrl.replace(":443", "").replace("http://", "https://") + } + + // handle url not starting with http + if (stringUrl.startsWith("//")) { + stringUrl = "http:$stringUrl" + } + + return stringUrl + } + + fun sourceAndDateText(): String = + this.sourcetitle.getHtmlDecoded() + DateUtils.parseRelativeDate(this.datetime) + + fun toggleStar(): Item { + this.starred = !this.starred + return this + } + } + + // TODO: this seems to be super slow. + object TagsListSerializer : KSerializer> { + override fun deserialize(decoder: Decoder): List { + return when(val json = ((decoder as JsonDecoder).decodeJsonElement())) { + is JsonArray -> json.toList().map { it.toString() } + else -> json.toString().split(",") + } + + } + + override val descriptor: SerialDescriptor + get() = PrimitiveSerialDescriptor("tags", PrimitiveKind.STRING) + + override fun serialize(encoder: Encoder, value: List) { + TODO("Not yet implemented") + } + } + + object BooleanSerializer : KSerializer { + override fun deserialize(decoder: Decoder): Boolean { + val json = ((decoder as JsonDecoder).decodeJsonElement()).jsonPrimitive + return if (json.booleanOrNull != null) { + json.boolean + } else { + json.int == 1 + } + } + + override val descriptor: SerialDescriptor + get() = PrimitiveSerialDescriptor("b", PrimitiveKind.BOOLEAN) + + override fun serialize(encoder: Encoder, value: Boolean) { + TODO("Not yet implemented") + } + } +} diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/ResultModel.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/ResultModel.kt new file mode 100644 index 0000000..1234c68 --- /dev/null +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/ResultModel.kt @@ -0,0 +1,40 @@ +package bou.amine.apps.readerforselfossv2.model + +import io.ktor.client.call.* +import io.ktor.client.statement.* +import io.ktor.http.* +import kotlinx.serialization.Serializable + +@Serializable +class SuccessResponse(val success: Boolean) { + val isSuccess: Boolean + get() = success +} + +class StatusAndData(val success: Boolean, val data: T? = null) { + companion object { + fun succes(d: T): StatusAndData { + return StatusAndData(true, d) + } + + fun error(): StatusAndData { + return StatusAndData(false) + } + } +} + +suspend fun maybeResponse(r: HttpResponse): SuccessResponse { + return if (r.status.isSuccess()) { + r.body() + } else { + SuccessResponse(false) + } +} + +suspend inline fun bodyOrFailure(r: HttpResponse): StatusAndData { + return if (r.status.isSuccess()) { + StatusAndData.succes(r.body()) + } else { + StatusAndData.error() + } +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt index 591ccdb..d36a9b6 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/model/SelfossModel.kt @@ -20,12 +20,6 @@ class SelfossModel { val unread: Int ) - @Serializable - class SuccessResponse(val success: Boolean) { - val isSuccess: Boolean - get() = success - } - @Serializable class Stats( val total: Int, @@ -152,16 +146,4 @@ class SelfossModel { TODO("Not yet implemented") } } - - class StatusAndData(val success: Boolean, val data: T? = null) { - companion object { - fun succes(d: T): StatusAndData { - return StatusAndData(true, d) - } - - fun error(): StatusAndData { - return StatusAndData(false) - } - } - } } diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt index 8996e8e..5a81ba2 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/repository/RepositoryImpl.kt @@ -3,6 +3,7 @@ package bou.amine.apps.readerforselfossv2.repository import bou.amine.apps.readerforselfossv2.dao.* import bou.amine.apps.readerforselfossv2.model.NetworkUnavailableException import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.model.StatusAndData import bou.amine.apps.readerforselfossv2.rest.SelfossApi import bou.amine.apps.readerforselfossv2.service.AppSettingsService import bou.amine.apps.readerforselfossv2.utils.* @@ -40,7 +41,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap suspend fun getNewerItems(): ArrayList { // TODO: Use the updatedSince parameter - var fetchedItems: SelfossModel.StatusAndData> = SelfossModel.StatusAndData.error() + var fetchedItems: StatusAndData> = StatusAndData.error() var fromDB = false if (isNetworkAvailable()) { fetchedItems = api.getItems( @@ -65,7 +66,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap if (sourceFilter != null) { dbItems = dbItems.filter { it.sourcetitle == sourceFilter!!.title } } - fetchedItems = SelfossModel.StatusAndData.succes( + fetchedItems = StatusAndData.succes( dbItems.map { it.toView() } ) } @@ -81,7 +82,7 @@ class Repository(private val api: SelfossApi, private val appSettingsService: Ap } suspend fun getOlderItems(): ArrayList { - var fetchedItems: SelfossModel.StatusAndData> = SelfossModel.StatusAndData.error() + var fetchedItems: StatusAndData> = StatusAndData.error() if (isNetworkAvailable()) { val offset = items.size fetchedItems = api.getItems( diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/MercuryApi.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/MercuryApi.kt new file mode 100644 index 0000000..ab126bc --- /dev/null +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/MercuryApi.kt @@ -0,0 +1,43 @@ +package bou.amine.apps.readerforselfossv2.rest + +import bou.amine.apps.readerforselfossv2.model.* +import io.github.aakira.napier.Napier +import io.ktor.client.* +import io.ktor.client.plugins.cache.* +import io.ktor.client.plugins.contentnegotiation.* +import io.ktor.client.plugins.logging.* +import io.ktor.client.request.* +import io.ktor.serialization.kotlinx.json.* +import kotlinx.serialization.json.Json + +class MercuryApi() { + + var client = createHttpClient() + + private fun createHttpClient(): HttpClient { + return HttpClient { + install(ContentNegotiation) { + install(HttpCache) + json(Json { + prettyPrint = true + isLenient = true + ignoreUnknownKeys = true + }) + } + install(Logging) { + logger = object : Logger { + override fun log(message: String) { + Napier.d(message, tag = "LogMercuryCalls") + } + } + level = LogLevel.INFO + } + expectSuccess = false + } + } + + suspend fun query(url: String): StatusAndData = + bodyOrFailure(client.get("https://amine-louveau.fr/parser.php") { + parameter("link", url) + }) +} \ No newline at end of file diff --git a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApi.kt b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApi.kt index c9f5c9a..cf609ac 100644 --- a/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApi.kt +++ b/shared/src/commonMain/kotlin/bou/amine/apps/readerforselfossv2/rest/SelfossApi.kt @@ -1,6 +1,6 @@ package bou.amine.apps.readerforselfossv2.rest -import bou.amine.apps.readerforselfossv2.model.SelfossModel +import bou.amine.apps.readerforselfossv2.model.* import bou.amine.apps.readerforselfossv2.service.AppSettingsService import io.ktor.client.* import io.ktor.client.call.* @@ -66,7 +66,7 @@ class SelfossApi(private val appSettingsService: AppSettingsService) { client = createHttpClient() } - suspend fun login(): SelfossModel.SuccessResponse = + suspend fun login(): SuccessResponse = maybeResponse(client.get(url("/login")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) @@ -80,7 +80,7 @@ class SelfossApi(private val appSettingsService: AppSettingsService) { search: String?, updatedSince: String?, items: Int? = null - ): SelfossModel.StatusAndData> = + ): StatusAndData> = bodyOrFailure(client.get(url("/items")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) @@ -93,64 +93,64 @@ class SelfossApi(private val appSettingsService: AppSettingsService) { parameter("offset", offset) }) - suspend fun stats(): SelfossModel.StatusAndData = + suspend fun stats(): StatusAndData = bodyOrFailure(client.get(url("/stats")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) }) - suspend fun tags(): SelfossModel.StatusAndData> = + suspend fun tags(): StatusAndData> = bodyOrFailure(client.get(url("/tags")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) }) - suspend fun update(): SelfossModel.StatusAndData = + suspend fun update(): StatusAndData = bodyOrFailure(client.get(url("/update")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) }) - suspend fun spouts(): SelfossModel.StatusAndData> = + suspend fun spouts(): StatusAndData> = bodyOrFailure(client.get(url("/sources/spouts")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) }) - suspend fun sources(): SelfossModel.StatusAndData> = + suspend fun sources(): StatusAndData> = bodyOrFailure(client.get(url("/sources/list")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) }) - suspend fun version(): SelfossModel.StatusAndData = + suspend fun version(): StatusAndData = bodyOrFailure(client.get(url("/api/about"))) - suspend fun markAsRead(id: String): SelfossModel.SuccessResponse = + suspend fun markAsRead(id: String): SuccessResponse = maybeResponse(client.post(url("/mark/$id")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) }) - suspend fun unmarkAsRead(id: String): SelfossModel.SuccessResponse = + suspend fun unmarkAsRead(id: String): SuccessResponse = maybeResponse(client.post(url("/unmark/$id")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) }) - suspend fun starr(id: String): SelfossModel.SuccessResponse = + suspend fun starr(id: String): SuccessResponse = maybeResponse(client.post(url("/starr/$id")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) }) - suspend fun unstarr(id: String): SelfossModel.SuccessResponse = + suspend fun unstarr(id: String): SuccessResponse = maybeResponse(client.post(url("/unstarr/$id")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) }) - suspend fun markAllAsRead(ids: List): SelfossModel.SuccessResponse = + suspend fun markAllAsRead(ids: List): SuccessResponse = maybeResponse(client.submitForm( url = url("/mark"), formParameters = Parameters.build { @@ -167,7 +167,7 @@ class SelfossApi(private val appSettingsService: AppSettingsService) { tags: String, filter: String, version: Int - ): SelfossModel.SuccessResponse = + ): SuccessResponse = maybeResponse( if (version > 1) { createSource2(title, url, spout, tags, filter) @@ -212,25 +212,9 @@ class SelfossApi(private val appSettingsService: AppSettingsService) { } ) - suspend fun deleteSource(id: Int): SelfossModel.SuccessResponse = + suspend fun deleteSource(id: Int): SuccessResponse = maybeResponse(client.delete(url("/source/$id")) { parameter("username", appSettingsService.getUserName()) parameter("password", appSettingsService.getPassword()) }) - - suspend fun maybeResponse(r: HttpResponse): SelfossModel.SuccessResponse { - return if (r.status.isSuccess()) { - r.body() - } else { - SelfossModel.SuccessResponse(false) - } - } - - suspend inline fun bodyOrFailure(r: HttpResponse): SelfossModel.StatusAndData { - return if (r.status.isSuccess()) { - SelfossModel.StatusAndData.succes(r.body()) - } else { - SelfossModel.StatusAndData.error() - } - } } \ No newline at end of file