From e5aba62fddbbc3e62a80535c4823d708bf6a796b Mon Sep 17 00:00:00 2001 From: Vitor Pamplona Date: Wed, 24 May 2023 18:11:51 -0400 Subject: [PATCH] Imports BahaUrlPreview library to add the proxy connection into it. --- app/build.gradle | 3 +- .../amethyst/model/UrlCachedPreviewer.kt | 6 +- .../service/previews/BahaUrlPreview.kt | 48 ++++++++ .../service/previews/IUrlPreviewCallback.kt | 6 + .../amethyst/service/previews/UrlInfoItem.kt | 12 ++ .../service/previews/UrlPreviewUtils.kt | 116 ++++++++++++++++++ .../amethyst/ui/components/UrlPreview.kt | 4 +- .../amethyst/ui/components/UrlPreviewCard.kt | 2 +- .../amethyst/ui/components/UrlPreviewState.kt | 2 +- 9 files changed, 191 insertions(+), 8 deletions(-) create mode 100644 app/src/main/java/com/vitorpamplona/amethyst/service/previews/BahaUrlPreview.kt create mode 100644 app/src/main/java/com/vitorpamplona/amethyst/service/previews/IUrlPreviewCallback.kt create mode 100644 app/src/main/java/com/vitorpamplona/amethyst/service/previews/UrlInfoItem.kt create mode 100644 app/src/main/java/com/vitorpamplona/amethyst/service/previews/UrlPreviewUtils.kt diff --git a/app/build.gradle b/app/build.gradle index 8322d9d3b..86f4d18f9 100644 --- a/app/build.gradle +++ b/app/build.gradle @@ -131,7 +131,8 @@ dependencies { implementation 'com.squareup.retrofit2:converter-gson:2.9.0' // link preview - implementation 'tw.com.oneup.www:Baha-UrlPreview:1.0.1' + implementation 'org.jsoup:jsoup:1.13.1' + //implementation 'tw.com.oneup.www:Baha-UrlPreview:1.0.1' // Encrypted Key Storage implementation 'androidx.security:security-crypto-ktx:1.1.0-alpha06' diff --git a/app/src/main/java/com/vitorpamplona/amethyst/model/UrlCachedPreviewer.kt b/app/src/main/java/com/vitorpamplona/amethyst/model/UrlCachedPreviewer.kt index 833d1155b..e13a06396 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/model/UrlCachedPreviewer.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/model/UrlCachedPreviewer.kt @@ -1,8 +1,8 @@ package com.vitorpamplona.amethyst.model -import com.baha.url.preview.BahaUrlPreview -import com.baha.url.preview.IUrlPreviewCallback -import com.baha.url.preview.UrlInfoItem +import com.vitorpamplona.amethyst.service.previews.BahaUrlPreview +import com.vitorpamplona.amethyst.service.previews.IUrlPreviewCallback +import com.vitorpamplona.amethyst.service.previews.UrlInfoItem import kotlinx.coroutines.CoroutineScope import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.Job diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/previews/BahaUrlPreview.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/previews/BahaUrlPreview.kt new file mode 100644 index 000000000..e56493ceb --- /dev/null +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/previews/BahaUrlPreview.kt @@ -0,0 +1,48 @@ +package com.vitorpamplona.amethyst.service.previews + +import android.net.Uri +import kotlinx.coroutines.* +import java.util.* + +class BahaUrlPreview(val url: String, var callback: IUrlPreviewCallback?) { + val scope = CoroutineScope(Job() + Dispatchers.Main) + private val imageExtensionArray = arrayOf(".gif", ".png", ".jpg", ".jpeg", ".bmp", ".webp") + + fun fetchUrlPreview(timeOut: Int = 30000) { + val exceptionHandler = CoroutineExceptionHandler { coroutineContext, throwable -> + callback?.onFailed(throwable) + } + scope.launch(exceptionHandler) { + fetch(timeOut) + } + } + + private suspend fun fetch(timeOut: Int = 30000) { + lateinit var urlInfoItem: UrlInfoItem + if (checkIsImageUrl()) { + urlInfoItem = UrlInfoItem(url = url, image = url) + } else { + val document = getDocument(url, timeOut) + urlInfoItem = parseHtml(document) + urlInfoItem.url = url + } + callback?.onComplete(urlInfoItem) + } + + private fun checkIsImageUrl(): Boolean { + val uri = Uri.parse(url) + var isImage = false + for (imageExtension in imageExtensionArray) { + if (uri.path != null && uri.path!!.toLowerCase(Locale.getDefault()).endsWith(imageExtension)) { + isImage = true + break + } + } + return isImage + } + + fun cleanUp() { + scope.cancel() + callback = null + } +} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/previews/IUrlPreviewCallback.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/previews/IUrlPreviewCallback.kt new file mode 100644 index 000000000..6d9778312 --- /dev/null +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/previews/IUrlPreviewCallback.kt @@ -0,0 +1,6 @@ +package com.vitorpamplona.amethyst.service.previews + +interface IUrlPreviewCallback { + fun onComplete(urlInfo: UrlInfoItem) + fun onFailed(throwable: Throwable) +} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/previews/UrlInfoItem.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/previews/UrlInfoItem.kt new file mode 100644 index 000000000..553f9b1c1 --- /dev/null +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/previews/UrlInfoItem.kt @@ -0,0 +1,12 @@ +package com.vitorpamplona.amethyst.service.previews + +data class UrlInfoItem( + var url: String = "", + var title: String = "", + var description: String = "", + var image: String = "" +) { + fun allFetchComplete(): Boolean { + return title.isNotEmpty() && description.isNotEmpty() && image.isNotEmpty() + } +} diff --git a/app/src/main/java/com/vitorpamplona/amethyst/service/previews/UrlPreviewUtils.kt b/app/src/main/java/com/vitorpamplona/amethyst/service/previews/UrlPreviewUtils.kt new file mode 100644 index 000000000..62c6e83e9 --- /dev/null +++ b/app/src/main/java/com/vitorpamplona/amethyst/service/previews/UrlPreviewUtils.kt @@ -0,0 +1,116 @@ +package com.vitorpamplona.amethyst.service.previews + +import com.vitorpamplona.amethyst.service.HttpClient +import kotlinx.coroutines.Dispatchers +import kotlinx.coroutines.withContext +import org.jsoup.Jsoup +import org.jsoup.nodes.Document + +private const val ELEMENT_TAG_META = "meta" +private const val ATTRIBUTE_VALUE_PROPERTY = "property" +private const val ATTRIBUTE_VALUE_NAME = "name" +private const val ATTRIBUTE_VALUE_ITEMPROP = "itemprop" + +/* for if (urlInfo.title.isEmpty()) urlInfo.title = it.attr(CONTENT) + in META_OG_DESCRIPTION -> if (urlInfo.description.isEmpty()) { + urlInfo.description = + it.attr(CONTENT) + } + in META_OG_IMAGE -> if (urlInfo.image.isEmpty()) urlInfo.image = it.attr(CONTENT) + } + + when (it.attr(ATTRIBUTE_VALUE_NAME)) { + in META_NAME_TITLE -> if (urlInfo.title.isEmpty()) urlInfo.title = it.attr(CONTENT) + in META_NAME_DESCRIPTION -> if (urlInfo.description.isEmpty()) { + urlInfo.description = + it.attr(CONTENT) + } + in META_OG_IMAGE -> if (urlInfo.image.isEmpty()) urlInfo.image = it.attr(CONTENT) + } + + when (it.attr(ATTRIBUTE_VALUE_ITEMPROP)) { + in META_ITEMPROP_TITLE -> if (urlInfo.title.isEmpty()) { + urlInfo.title = + it.attr(CONTENT) + } + in META_ITEMPROP_DESCRIPTION -> if (urlInfo.description.isEmpty()) { + urlInfo.description = + it.attr( + CONTENT + ) + } + in META_ITEMPROP_IMAGE -> if (urlInfo.image.isEmpty()) { + urlInfo.image = it.attr( + CONTENT + ) + } + } + if (urlInfo.allFetchComplete()) { + return@withContext urlInfo + } + } + return@withContext urlInfo + } diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt index b4d914a40..a1d8e97ca 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreview.kt @@ -10,10 +10,10 @@ import androidx.compose.runtime.remember import androidx.compose.runtime.rememberCoroutineScope import androidx.compose.runtime.setValue import androidx.compose.ui.platform.LocalContext -import com.baha.url.preview.IUrlPreviewCallback -import com.baha.url.preview.UrlInfoItem import com.vitorpamplona.amethyst.R import com.vitorpamplona.amethyst.model.UrlCachedPreviewer +import com.vitorpamplona.amethyst.service.previews.IUrlPreviewCallback +import com.vitorpamplona.amethyst.service.previews.UrlInfoItem import kotlinx.coroutines.Dispatchers import kotlinx.coroutines.launch diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewCard.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewCard.kt index 88de0195b..ef5673f21 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewCard.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewCard.kt @@ -20,8 +20,8 @@ import androidx.compose.ui.res.stringResource import androidx.compose.ui.text.style.TextOverflow import androidx.compose.ui.unit.dp import coil.compose.AsyncImage -import com.baha.url.preview.UrlInfoItem import com.vitorpamplona.amethyst.R +import com.vitorpamplona.amethyst.service.previews.UrlInfoItem import java.net.URL @Composable diff --git a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewState.kt b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewState.kt index ee0089e56..e992924e1 100644 --- a/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewState.kt +++ b/app/src/main/java/com/vitorpamplona/amethyst/ui/components/UrlPreviewState.kt @@ -1,6 +1,6 @@ package com.vitorpamplona.amethyst.ui.components -import com.baha.url.preview.UrlInfoItem +import com.vitorpamplona.amethyst.service.previews.UrlInfoItem sealed class UrlPreviewState { object Loading : UrlPreviewState()