Skip to content

Commit

Permalink
Merge pull request #3 from LaatonWalaBhoot/trunk
Browse files Browse the repository at this point in the history
Migrating to KMP
  • Loading branch information
saket committed Jan 2, 2024
2 parents 9c811d9 + 00a5655 commit d2a66c2
Show file tree
Hide file tree
Showing 29 changed files with 2,119 additions and 189 deletions.
21 changes: 4 additions & 17 deletions build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,18 +1,5 @@
buildscript {
repositories {
mavenCentral()
gradlePluginPortal()
}

dependencies {
classpath("org.jetbrains.kotlin:kotlin-gradle-plugin:1.8.21") // Don't forget to update KSP.
classpath("com.vanniktech:gradle-maven-publish-plugin:0.24.0")
classpath("org.jetbrains.dokka:dokka-gradle-plugin:1.8.10")
}
}

allprojects {
repositories {
mavenCentral()
}
plugins {
alias(libs.plugins.androidLibrary).apply(false)
alias(libs.plugins.kotlinMultiplatform).apply(false)
alias(libs.plugins.dokka)
}
28 changes: 28 additions & 0 deletions gradle/libs.versions.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
[versions]
agp = "8.2.0-beta06"
kotlin = "1.9.20"
dokka = "1.9.10"
ksoup = "0.0.6"
vanniktect-publish = "0.25.3"
ktor = "2.3.6"
compileSdk = "34"
minSdk = "24"
libraryVersion = "1.8.0"

[libraries]
kotlin-test = { module = "org.jetbrains.kotlin:kotlin-test", version.ref = "kotlin" }
ksoup = { module = "com.fleeksoft.ksoup:ksoup", version.ref = "ksoup" }
ktor-client-core = { module = "io.ktor:ktor-client-core", version.ref = "ktor" }
ktor-client-logging = { module = "io.ktor:ktor-client-logging", version.ref = "ktor" }
ktor-client-darwin = { module = "io.ktor:ktor-client-darwin", version.ref = "ktor" }
ktor-client-mock = { module = "io.ktor:ktor-client-mock", version.ref = "ktor" }
ktor-client-okhttp = { module = "io.ktor:ktor-client-okhttp", version.ref = "ktor" }

[plugins]
androidApplication = { id = "com.android.application", version.ref = "agp" }
androidLibrary = { id = "com.android.library", version.ref = "agp" }
kotlinAndroid = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin" }
kotlinMultiplatform = { id = "org.jetbrains.kotlin.multiplatform", version.ref = "kotlin" }
kotlinCocoapods = { id = "org.jetbrains.kotlin.native.cocoapods", version.ref = "kotlin" }
dokka = { id = "org.jetbrains.dokka", version.ref = "dokka" }
vanniktectPublish = { id = "com.vanniktech.maven.publish.base", version.ref = "vanniktect-publish" }
3 changes: 2 additions & 1 deletion gradle/wrapper/gradle-wrapper.properties
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
#Sun Nov 26 06:58:58 IST 2023
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.1.1-all.zip
distributionUrl=https\://services.gradle.org/distributions/gradle-8.2-bin.zip
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
18 changes: 18 additions & 0 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
pluginManagement {
repositories {
google()
gradlePluginPortal()
mavenCentral()
}
}

dependencyResolutionManagement {
repositories {
google()
mavenCentral()
}
}

rootProject.name = "unfurl"
include(":unfurl")
81 changes: 71 additions & 10 deletions unfurl/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,15 +1,76 @@
plugins {
id("java-library")
kotlin("jvm")
alias(libs.plugins.kotlinMultiplatform)
alias(libs.plugins.androidLibrary)
alias(libs.plugins.dokka)
id("maven-publish")
}
apply(plugin = "com.vanniktech.maven.publish")

dependencies {
api("com.squareup.okhttp3:okhttp:4.9.0") // Updating to 5.x? See cli/build.gradle.kts.
api("org.jsoup:jsoup:1.16.1")
group = "me.saket.unfurl"
version = libs.versions.libraryVersion.get()

testImplementation("junit:junit:4.13.2")
testImplementation("com.google.truth:truth:1.1.3")
testImplementation("com.google.testparameterinjector:test-parameter-injector:1.8")
testImplementation("com.squareup.okhttp3:mockwebserver:4.10.0")
@OptIn(org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi::class)
kotlin {
explicitApi()

jvm()

androidTarget {
compilations.all {
kotlinOptions {
jvmTarget = "17"
}
}
}

listOf(
iosX64(),
iosArm64(),
iosSimulatorArm64()
).forEach {
it.binaries.framework {
baseName = "unfurl"
isStatic = true
}
}

sourceSets {
sourceSets {
commonMain.dependencies {
implementation(libs.ktor.client.core)
implementation(libs.ksoup)
}
commonTest.dependencies {
implementation(libs.kotlin.test)
implementation(libs.ktor.client.mock)
}

jvmMain.dependencies {
implementation(libs.ktor.client.okhttp)
}

jvmTest.dependencies {
implementation(libs.kotlin.test)
}

androidMain.dependencies {
implementation(libs.ktor.client.okhttp)
}

iosMain.dependencies {
implementation(libs.ktor.client.darwin)
}
}
}
}

android {
namespace = "me.saket.unfurl"
compileSdk = libs.versions.compileSdk.get().toInt()
defaultConfig {
minSdk = libs.versions.minSdk.get().toInt()
}
compileOptions {
sourceCompatibility = JavaVersion.VERSION_17
targetCompatibility = JavaVersion.VERSION_17
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package me.saket.unfurl

import io.ktor.client.engine.HttpClientEngine
import io.ktor.client.engine.okhttp.OkHttp

internal actual fun provideHttpClientEngine(): HttpClientEngine {
return OkHttp.create {
}
}
5 changes: 5 additions & 0 deletions unfurl/src/commonMain/kotlin/me/saket/unfurl/Platform.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
package me.saket.unfurl

import io.ktor.client.engine.HttpClientEngine

internal expect fun provideHttpClientEngine(): HttpClientEngine
22 changes: 22 additions & 0 deletions unfurl/src/commonMain/kotlin/me/saket/unfurl/UnfurlLogger.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package me.saket.unfurl

public interface UnfurlLogger {
public fun log(message: String)
public fun log(e: Throwable, message: String)

public object Println : UnfurlLogger {
override fun log(e: Throwable, message: String) {
println(message)
println(e.stackTraceToString())
}

override fun log(message: String) {
println(message)
}
}

public object NoOp : UnfurlLogger {
override fun log(message: String): Unit = Unit
override fun log(e: Throwable, message: String): Unit = Unit
}
}
Original file line number Diff line number Diff line change
@@ -1,24 +1,24 @@
package me.saket.unfurl

import okhttp3.HttpUrl
import io.ktor.http.Url

/**
* @param url May or may not be equal to the original URL used with [Unfurler.unfurl].
* This can happen in situations where HTTP 3xx redirects are followed. For example,
* `https://youtu.be/foo` will redirect to `https://www.youtube.com/watch?v=foo`.
*/
data class UnfurlResult(
val url: HttpUrl,
public data class UnfurlResult(
val url: Url,
val title: String?,
val description: String?,
val favicon: HttpUrl?,
val thumbnail: HttpUrl?,
val favicon: Url?,
val thumbnail: Url?,
val contentPreview: ContentPreview? = null,
) {

/**
* Additional metadata that can be populated by extensions.
* See `TweetContentPreview` for an example.
*/
interface ContentPreview
public interface ContentPreview
}
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
package me.saket.unfurl

import io.ktor.client.HttpClient
import io.ktor.http.Url
import me.saket.unfurl.extension.HtmlTagsBasedUnfurler
import me.saket.unfurl.extension.UnfurlerExtension
import me.saket.unfurl.extension.UnfurlerScope
import me.saket.unfurl.extension.toHttpUrlOrNull
import me.saket.unfurl.internal.NullableLruCache
import okhttp3.HttpUrl
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient

class Unfurler(
public class Unfurler(
cacheSize: Int = 100,
extensions: List<UnfurlerExtension> = emptyList(),
val httpClient: OkHttpClient = defaultOkHttpClient(),
val logger: UnfurlLogger = UnfurlLogger.Println,
public val httpClient: HttpClient = defaultHttpClient(),
public val logger: UnfurlLogger = UnfurlLogger.Println,
) {
private val extensions = extensions + HtmlTagsBasedUnfurler()
private val cache = NullableLruCache<String, UnfurlResult?>(cacheSize)

private val extensionScope = object : UnfurlerScope {
override val httpClient: OkHttpClient get() = this@Unfurler.httpClient
override val httpClient: HttpClient get() = this@Unfurler.httpClient
override val logger: UnfurlLogger get() = this@Unfurler.logger
}

fun unfurl(url: String): UnfurlResult? {
public fun unfurl(url: String): UnfurlResult? {
return cache.computeIfAbsent(url) {
try {
url.toHttpUrlOrNull()?.let { httpUrl ->
Expand All @@ -37,16 +37,15 @@ class Unfurler(
}
}

fun unfurl(url: HttpUrl): UnfurlResult? {
public fun unfurl(url: Url): UnfurlResult? {
return unfurl(url.toString())
}

companion object {
fun defaultOkHttpClient(): OkHttpClient {
return OkHttpClient.Builder()
.followRedirects(true)
.followSslRedirects(true)
.build()
public companion object {
public fun defaultHttpClient(): HttpClient {
return HttpClient(provideHttpClientEngine()) {
followRedirects = true
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,10 @@ import me.saket.unfurl.extension.UnfurlerExtension
message = "Renamed to UnfurlerExtension",
replaceWith = ReplaceWith("me.saket.unfurl.extension.UnfurlerExtension")
)
interface UnfurlerDelegate : UnfurlerExtension
public interface UnfurlerDelegate : UnfurlerExtension

@Deprecated(
message = "Renamed to UnfurlerExtensionScope",
replaceWith = ReplaceWith("me.saket.unfurl.extension.UnfurlerScope")
)
typealias UnfurlerDelegateScope = me.saket.unfurl.extension.UnfurlerScope
public typealias UnfurlerDelegateScope = me.saket.unfurl.extension.UnfurlerScope
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,4 @@ package me.saket.unfurl.delegates.html
message = "Renamed to HtmlTagsBasedUnfurler",
replaceWith = ReplaceWith("me.saket.unfurl.extension.HtmlTagsBasedUnfurler")
)
typealias HtmlTagsBasedUnfurler = me.saket.unfurl.extension.HtmlTagsBasedUnfurler
public typealias HtmlTagsBasedUnfurler = me.saket.unfurl.extension.HtmlTagsBasedUnfurler
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package me.saket.unfurl

import io.ktor.client.HttpClient
import me.saket.unfurl.delegates.UnfurlerDelegate
import okhttp3.OkHttpClient

@Deprecated(
message = """"delegates" parameter has been renamed to "extensions"""",
Expand All @@ -10,11 +10,11 @@ import okhttp3.OkHttpClient
"me.saket.unfurl.Unfurler"
),
)
fun Unfurler(
public fun Unfurler(
cacheSize: Int = 100,
delegates: List<UnfurlerDelegate>,
httpClient: OkHttpClient = Unfurler.defaultOkHttpClient(),
) = Unfurler(
httpClient: HttpClient = Unfurler.defaultHttpClient(),
): Unfurler = Unfurler(
cacheSize = cacheSize,
extensions = delegates,
httpClient = httpClient,
Expand All @@ -27,10 +27,10 @@ fun Unfurler(
"me.saket.unfurl.Unfurler"
),
)
fun Unfurler(
public fun Unfurler(
cacheSize: Int = 100,
delegates: List<UnfurlerDelegate>,
) = Unfurler(
): Unfurler = Unfurler(
cacheSize = cacheSize,
extensions = delegates,
)
Expand All @@ -42,8 +42,8 @@ fun Unfurler(
"me.saket.unfurl.Unfurler"
),
)
fun Unfurler(
public fun Unfurler(
delegates: List<UnfurlerDelegate>
) = Unfurler(
): Unfurler = Unfurler(
extensions = delegates,
)

0 comments on commit d2a66c2

Please sign in to comment.