PreviewUrl: create the task and the service
This commit is contained in:
parent
1109d9f88a
commit
bd5ac514ef
|
@ -35,6 +35,7 @@ import org.matrix.android.sdk.api.session.group.GroupService
|
|||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
||||
import org.matrix.android.sdk.api.session.identity.IdentityService
|
||||
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
|
||||
import org.matrix.android.sdk.api.session.media.MediaService
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
||||
import org.matrix.android.sdk.api.session.profile.ProfileService
|
||||
import org.matrix.android.sdk.api.session.pushers.PushersService
|
||||
|
@ -181,6 +182,11 @@ interface Session :
|
|||
*/
|
||||
fun widgetService(): WidgetService
|
||||
|
||||
/**
|
||||
* Returns the media service associated with the session
|
||||
*/
|
||||
fun mediaService(): MediaService
|
||||
|
||||
/**
|
||||
* Returns the integration manager service associated with the session
|
||||
*/
|
||||
|
|
|
@ -29,14 +29,19 @@ interface MediaService {
|
|||
|
||||
/**
|
||||
* Get Raw Url Preview data from the homeserver. There is no cache management for this request
|
||||
* @param url The url to get the preview data from
|
||||
* @param timestamp The optional timestamp
|
||||
*/
|
||||
suspend fun getRawPreviewUrl(url: String): JsonDict
|
||||
suspend fun getRawPreviewUrl(url: String, timestamp: Long?): JsonDict
|
||||
|
||||
/**
|
||||
* Get Url Preview data from the homeserver, or from cache, depending on the cache strategy
|
||||
* @param url
|
||||
* @param url The url to get the preview data from
|
||||
* @param timestamp The optional timestamp. Note that this parameter is not taken into account
|
||||
* if the data is already in cache and the cache strategy allow to use it
|
||||
* @param cacheStrategy the cache strategy, see the type for more details
|
||||
*/
|
||||
suspend fun getPreviewUrl(url: String, cacheStrategy: CacheStrategy): PreviewUrlData
|
||||
suspend fun getPreviewUrl(url: String, timestamp: Long?, cacheStrategy: CacheStrategy): PreviewUrlData
|
||||
|
||||
/**
|
||||
* Clear the cache of all retrieved UrlPreview data
|
||||
|
|
|
@ -43,6 +43,7 @@ import org.matrix.android.sdk.api.session.file.FileService
|
|||
import org.matrix.android.sdk.api.session.group.GroupService
|
||||
import org.matrix.android.sdk.api.session.homeserver.HomeServerCapabilitiesService
|
||||
import org.matrix.android.sdk.api.session.integrationmanager.IntegrationManagerService
|
||||
import org.matrix.android.sdk.api.session.media.MediaService
|
||||
import org.matrix.android.sdk.api.session.permalinks.PermalinkService
|
||||
import org.matrix.android.sdk.api.session.profile.ProfileService
|
||||
import org.matrix.android.sdk.api.session.pushers.PushersService
|
||||
|
@ -102,6 +103,7 @@ internal class DefaultSession @Inject constructor(
|
|||
private val permalinkService: Lazy<PermalinkService>,
|
||||
private val secureStorageService: Lazy<SecureStorageService>,
|
||||
private val profileService: Lazy<ProfileService>,
|
||||
private val mediaService: Lazy<MediaService>,
|
||||
private val widgetService: Lazy<WidgetService>,
|
||||
private val syncThreadProvider: Provider<SyncThread>,
|
||||
private val contentUrlResolver: ContentUrlResolver,
|
||||
|
@ -263,6 +265,8 @@ internal class DefaultSession @Inject constructor(
|
|||
|
||||
override fun widgetService(): WidgetService = widgetService.get()
|
||||
|
||||
override fun mediaService(): MediaService = mediaService.get()
|
||||
|
||||
override fun integrationManagerService() = integrationManagerService
|
||||
|
||||
override fun callSignalingService(): CallSignalingService = callSignalingService.get()
|
||||
|
|
|
@ -0,0 +1,40 @@
|
|||
/*
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.session.media
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import io.realm.kotlin.where
|
||||
import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntity
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import org.matrix.android.sdk.internal.util.awaitTransaction
|
||||
import javax.inject.Inject
|
||||
|
||||
internal interface ClearPreviewUrlCacheTask : Task<Unit, Unit>
|
||||
|
||||
internal class DefaultClearPreviewUrlCacheTask @Inject constructor(
|
||||
@SessionDatabase private val monarchy: Monarchy
|
||||
) : ClearPreviewUrlCacheTask {
|
||||
|
||||
override suspend fun execute(params: Unit) {
|
||||
monarchy.awaitTransaction { realm ->
|
||||
realm.where<PreviewUrlCacheEntity>()
|
||||
.findAll()
|
||||
.deleteAllFromRealm()
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
/*
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.session.media
|
||||
|
||||
import org.matrix.android.sdk.api.cache.CacheStrategy
|
||||
import org.matrix.android.sdk.api.session.events.model.Event
|
||||
import org.matrix.android.sdk.api.session.media.MediaService
|
||||
import org.matrix.android.sdk.api.session.media.PreviewUrlData
|
||||
import org.matrix.android.sdk.api.util.JsonDict
|
||||
import javax.inject.Inject
|
||||
|
||||
internal class DefaultMediaService @Inject constructor(
|
||||
private val clearPreviewUrlCacheTask: ClearPreviewUrlCacheTask,
|
||||
private val getPreviewUrlTask: GetPreviewUrlTask,
|
||||
private val getRawPreviewUrlTask: GetRawPreviewUrlTask
|
||||
) : MediaService {
|
||||
override fun extractUrls(event: Event): List<String> {
|
||||
TODO("Not yet implemented")
|
||||
}
|
||||
|
||||
override suspend fun getRawPreviewUrl(url: String, timestamp: Long?): JsonDict {
|
||||
return getRawPreviewUrlTask.execute(GetRawPreviewUrlTask.Params(url, timestamp))
|
||||
}
|
||||
|
||||
override suspend fun getPreviewUrl(url: String, timestamp: Long?, cacheStrategy: CacheStrategy): PreviewUrlData {
|
||||
return getPreviewUrlTask.execute(GetPreviewUrlTask.Params(url, timestamp, cacheStrategy))
|
||||
}
|
||||
|
||||
override suspend fun clearCache() {
|
||||
clearPreviewUrlCacheTask.execute(Unit)
|
||||
}
|
||||
}
|
|
@ -0,0 +1,122 @@
|
|||
/*
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.session.media
|
||||
|
||||
import com.zhuinden.monarchy.Monarchy
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.matrix.android.sdk.api.cache.CacheStrategy
|
||||
import org.matrix.android.sdk.api.session.media.PreviewUrlData
|
||||
import org.matrix.android.sdk.api.util.JsonDict
|
||||
import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntity
|
||||
import org.matrix.android.sdk.internal.database.query.get
|
||||
import org.matrix.android.sdk.internal.database.query.getOrCreate
|
||||
import org.matrix.android.sdk.internal.di.SessionDatabase
|
||||
import org.matrix.android.sdk.internal.network.executeRequest
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import org.matrix.android.sdk.internal.util.awaitTransaction
|
||||
import java.util.Date
|
||||
import javax.inject.Inject
|
||||
|
||||
internal interface GetPreviewUrlTask : Task<GetPreviewUrlTask.Params, PreviewUrlData> {
|
||||
data class Params(
|
||||
val url: String,
|
||||
val timestamp: Long?,
|
||||
val cacheStrategy: CacheStrategy
|
||||
)
|
||||
}
|
||||
|
||||
internal class DefaultGetPreviewUrlTask @Inject constructor(
|
||||
private val mediaAPI: MediaAPI,
|
||||
private val eventBus: EventBus,
|
||||
@SessionDatabase private val monarchy: Monarchy
|
||||
) : GetPreviewUrlTask {
|
||||
|
||||
override suspend fun execute(params: GetPreviewUrlTask.Params): PreviewUrlData {
|
||||
return when (params.cacheStrategy) {
|
||||
CacheStrategy.NoCache -> doRequest(params.url, params.timestamp)
|
||||
is CacheStrategy.TtlCache -> doRequestWithCache(
|
||||
params.url,
|
||||
params.timestamp,
|
||||
params.cacheStrategy.validityDurationInMillis,
|
||||
params.cacheStrategy.strict
|
||||
)
|
||||
CacheStrategy.InfiniteCache -> doRequestWithCache(
|
||||
params.url,
|
||||
params.timestamp,
|
||||
Long.MAX_VALUE,
|
||||
true
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private suspend fun doRequest(url: String, timestamp: Long?): PreviewUrlData {
|
||||
return executeRequest<JsonDict>(eventBus) {
|
||||
apiCall = mediaAPI.getPreviewUrlData(url, timestamp)
|
||||
}
|
||||
.toPreviewUrlData(url)
|
||||
}
|
||||
|
||||
private fun JsonDict.toPreviewUrlData(url: String): PreviewUrlData {
|
||||
return PreviewUrlData(
|
||||
url = (get("og:url") as? String) ?: url,
|
||||
siteName = get("og:site_name") as? String,
|
||||
title = get("og:title") as? String,
|
||||
description = get("og:description") as? String,
|
||||
mxcUrl = get("og:image") as? String
|
||||
)
|
||||
}
|
||||
|
||||
private suspend fun doRequestWithCache(url: String, timestamp: Long?, validityDurationInMillis: Long, strict: Boolean): PreviewUrlData {
|
||||
// Get data from cache
|
||||
var dataFromCache: PreviewUrlData? = null
|
||||
var isCacheValid = false
|
||||
monarchy.doWithRealm { realm ->
|
||||
val entity = PreviewUrlCacheEntity.get(realm, url)
|
||||
dataFromCache = entity?.toDomain()
|
||||
isCacheValid = entity != null && Date().time < entity.lastUpdatedTimestamp + validityDurationInMillis
|
||||
}
|
||||
|
||||
val finalDataFromCache = dataFromCache
|
||||
if (finalDataFromCache != null && isCacheValid) {
|
||||
return finalDataFromCache
|
||||
}
|
||||
|
||||
// No cache or outdated cache
|
||||
val data = try {
|
||||
doRequest(url, timestamp)
|
||||
} catch (throwable: Throwable) {
|
||||
// In case of error, we can return value from cache even if outdated
|
||||
return finalDataFromCache
|
||||
?.takeIf { !strict }
|
||||
?: throw throwable
|
||||
}
|
||||
|
||||
// Store cache
|
||||
monarchy.awaitTransaction { realm ->
|
||||
val previewUrlCacheEntity = PreviewUrlCacheEntity.getOrCreate(realm, url)
|
||||
previewUrlCacheEntity.urlFromServer = data.url
|
||||
previewUrlCacheEntity.siteName = data.siteName
|
||||
previewUrlCacheEntity.title = data.title
|
||||
previewUrlCacheEntity.description = data.description
|
||||
previewUrlCacheEntity.mxcUrl = data.mxcUrl
|
||||
|
||||
previewUrlCacheEntity.lastUpdatedTimestamp = Date().time
|
||||
}
|
||||
|
||||
return data
|
||||
}
|
||||
}
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.session.media
|
||||
|
||||
import org.greenrobot.eventbus.EventBus
|
||||
import org.matrix.android.sdk.api.util.JsonDict
|
||||
import org.matrix.android.sdk.internal.network.executeRequest
|
||||
import org.matrix.android.sdk.internal.task.Task
|
||||
import javax.inject.Inject
|
||||
|
||||
internal interface GetRawPreviewUrlTask : Task<GetRawPreviewUrlTask.Params, JsonDict> {
|
||||
data class Params(
|
||||
val url: String,
|
||||
val timestamp: Long?
|
||||
)
|
||||
}
|
||||
|
||||
internal class DefaultGetRawPreviewUrlTask @Inject constructor(
|
||||
private val mediaAPI: MediaAPI,
|
||||
private val eventBus: EventBus
|
||||
) : GetRawPreviewUrlTask {
|
||||
|
||||
override suspend fun execute(params: GetRawPreviewUrlTask.Params): JsonDict {
|
||||
return executeRequest(eventBus) {
|
||||
apiCall = mediaAPI.getPreviewUrlData(params.url, params.timestamp)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -39,5 +39,5 @@ internal interface MediaAPI {
|
|||
* if it does not have the requested version available.
|
||||
*/
|
||||
@GET(NetworkConstants.URI_API_MEDIA_PREFIX_PATH_R0 + "preview_url")
|
||||
fun getPreviewUrlData(@Query("url") url: String, @Query("ts") ts: Int?): Call<JsonDict>
|
||||
fun getPreviewUrlData(@Query("url") url: String, @Query("ts") ts: Long?): Call<JsonDict>
|
||||
}
|
||||
|
|
|
@ -16,8 +16,10 @@
|
|||
|
||||
package org.matrix.android.sdk.internal.session.media
|
||||
|
||||
import dagger.Binds
|
||||
import dagger.Module
|
||||
import dagger.Provides
|
||||
import org.matrix.android.sdk.api.session.media.MediaService
|
||||
import org.matrix.android.sdk.internal.session.SessionScope
|
||||
import retrofit2.Retrofit
|
||||
|
||||
|
@ -34,6 +36,15 @@ internal abstract class MediaModule {
|
|||
}
|
||||
}
|
||||
|
||||
// @Binds
|
||||
// abstract fun bindGetHomeServerCapabilitiesTask(task: DefaultGetHomeServerCapabilitiesTask): GetHomeServerCapabilitiesTask
|
||||
@Binds
|
||||
abstract fun bindMediaService(service: DefaultMediaService): MediaService
|
||||
|
||||
@Binds
|
||||
abstract fun bindGetRawPreviewUrlTask(task: DefaultGetRawPreviewUrlTask): GetRawPreviewUrlTask
|
||||
|
||||
@Binds
|
||||
abstract fun bindGetPreviewUrlTask(task: DefaultGetPreviewUrlTask): GetPreviewUrlTask
|
||||
|
||||
@Binds
|
||||
abstract fun bindClearMediaCacheTask(task: DefaultClearPreviewUrlCacheTask): ClearPreviewUrlCacheTask
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
/*
|
||||
* Copyright 2020 The Matrix.org Foundation C.I.C.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
* You may obtain a copy of the License at
|
||||
*
|
||||
* http://www.apache.org/licenses/LICENSE-2.0
|
||||
*
|
||||
* Unless required by applicable law or agreed to in writing, software
|
||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
* See the License for the specific language governing permissions and
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package org.matrix.android.sdk.internal.session.media
|
||||
|
||||
import org.matrix.android.sdk.api.session.media.PreviewUrlData
|
||||
import org.matrix.android.sdk.internal.database.model.PreviewUrlCacheEntity
|
||||
|
||||
/**
|
||||
* PreviewUrlCacheEntity -> PreviewUrlData
|
||||
*/
|
||||
internal fun PreviewUrlCacheEntity.toDomain() = PreviewUrlData(
|
||||
url = urlFromServer ?: url,
|
||||
siteName = siteName,
|
||||
title = title,
|
||||
description = description,
|
||||
mxcUrl = mxcUrl
|
||||
)
|
Loading…
Reference in New Issue