Migrate Wikipedia settings, add wikipedia base url setting

This commit is contained in:
MM20
2022-01-11 22:16:47 +01:00
parent a5cb2e3314
commit b1412d24f1
12 changed files with 238 additions and 88 deletions
@@ -25,9 +25,10 @@ class Wikipedia(
override val label: String,
val id: Long,
val text: String,
val image: String?
val image: String?,
val wikipediaUrl: String,
) : Searchable() {
override val key = "wikipedia://$id"
override val key = "wikipedia://$wikipediaUrl:$id"
override suspend fun loadIcon(context: Context, size: Int): LauncherIcon? {
return null
@@ -47,70 +48,12 @@ class Wikipedia(
.enableUrlBarHiding()
.setShowTitle(true)
.build()
val uri = "${context.getString(R.string.wikipedia_url)}/wiki?curid=$id"
val uri = "${wikipediaUrl}/wiki?curid=$id"
intent.intent.data = Uri.parse(uri)
return intent.intent
}
companion object {
fun search(context: Context, query: String, client: OkHttpClient): Wikipedia? {
mutableListOf<Searchable>()
if (query.length < 4) return null
val prefs = LauncherPreferences.instance
if (!prefs.searchWikipedia ||
NetworkUtils.isOffline(context, prefs.searchWikipediaMobileData)) return null
val url = (context.getString(R.string.wikipedia_url) + "/w/api.php?action=query&"
+ "generator=search&redirects=true&gsrlimit=1&prop=extracts&format=json&gsrsearch="
+ query)
val request = Request.Builder()
.url(url)
.tag("onlinesearch")
.build()
try {
val response = client.newCall(request).execute()
val json = JSONObject(response.body?.string() ?: return null)
val pages = json.getJSONObject("query")
.getJSONObject("pages")
val it = pages.keys()
if (it.hasNext()) {
val key = it.next()
val id = pages.getJSONObject(key).getLong("pageid")
val title = pages.getJSONObject(key).getString("title")
val text = pages.getJSONObject(key).getString("extract").also{
it.substring(0, min(500, it.length)) + ""
}
val image = getArticleImage(context, id, client)
return Wikipedia(
label = title,
text = text,
id = id,
image = image
)
}
} catch (e: IOException) {
} catch (e: JSONException) {
}
return null
}
private fun getArticleImage(context: Context, id: Long, client: OkHttpClient): String? {
if (!LauncherPreferences.instance.searchWikipediaPictures) return null
val width = context.resources.displayMetrics.widthPixels / 2
val url = (context.getString(R.string.wikipedia_url) + "/w/api.php?action=query&"
+ "prop=pageimages&format=json&pageids=$id&pithumbsize=$width")
val request = Request.Builder()
.url(url)
.tag("onlinesearch")
.build()
val response = client.newCall(request).execute()
val json = JSONObject(response.body?.string() ?: return null)
return json.getJSONObject("query")
.getJSONObject("pages")
.getJSONObject(id.toString())
.optJSONObject("thumbnail")
?.getString("source")
}
}
}
@@ -1,15 +1,12 @@
package de.mm20.launcher2.wikipedia
import android.content.Context
import android.util.Log
import de.mm20.launcher2.crashreporter.CrashReporter
import de.mm20.launcher2.preferences.LauncherDataStore
import de.mm20.launcher2.search.data.Wikipedia
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.channelFlow
import kotlinx.coroutines.flow.collectLatest
import kotlinx.coroutines.flow.map
import kotlinx.coroutines.withContext
import kotlinx.coroutines.*
import kotlinx.coroutines.flow.*
import okhttp3.OkHttpClient
import org.koin.core.component.KoinComponent
import org.koin.core.component.inject
@@ -25,28 +22,40 @@ class WikipediaRepositoryImpl(
private val context: Context
) : WikipediaRepository, KoinComponent {
private val scope = CoroutineScope(Dispatchers.Main + Job())
private val dataStore: LauncherDataStore by inject()
private val httpClient by lazy {
OkHttpClient
.Builder()
.connectTimeout(200, TimeUnit.MILLISECONDS)
.readTimeout(3000, TimeUnit.MILLISECONDS)
.writeTimeout(1000, TimeUnit.MILLISECONDS)
.build()
private val httpClient = OkHttpClient
.Builder()
.connectTimeout(200, TimeUnit.MILLISECONDS)
.readTimeout(3000, TimeUnit.MILLISECONDS)
.writeTimeout(1000, TimeUnit.MILLISECONDS)
.build()
private lateinit var retrofit: Retrofit
init {
scope.launch {
dataStore.data
.map { it.wikipediaSearch.customUrl }
.distinctUntilChanged()
.collectLatest {
retrofit = Retrofit.Builder()
.client(httpClient)
.baseUrl(it.takeIf { !it.isNullOrBlank() }
?: context.getString(R.string.wikipedia_url))
.addConverterFactory(GsonConverterFactory.create())
.build()
wikipediaService = retrofit.create(WikipediaApi::class.java)
}
}
}
private val retrofit by lazy {
Retrofit.Builder()
.client(httpClient)
.baseUrl(context.getString(R.string.wikipedia_url))
.addConverterFactory(GsonConverterFactory.create())
.build()
}
private val wikipediaService by lazy {
private lateinit var wikipediaService: WikipediaApi
/*by lazy {
retrofit.create(WikipediaApi::class.java)
}
}*/
override fun search(query: String): Flow<Wikipedia?> = channelFlow {
@@ -54,6 +63,8 @@ class WikipediaRepositoryImpl(
withContext(Dispatchers.IO) {
httpClient.dispatcher.cancelAll()
}
if (!::wikipediaService.isInitialized) return@channelFlow
if (query.isBlank()) return@channelFlow
dataStore.data.map { it.wikipediaSearch }.collectLatest {
@@ -67,6 +78,8 @@ class WikipediaRepositoryImpl(
private suspend fun queryWikipedia(query: String, loadImages: Boolean): Wikipedia? {
val wikipediaService = wikipediaService
val wikipediaUrl = retrofit.baseUrl().toString()
val result = try {
wikipediaService.search(query)
@@ -92,7 +105,8 @@ class WikipediaRepositoryImpl(
label = page.title,
id = page.pageid,
text = page.extract,
image = image
image = image,
wikipediaUrl = wikipediaUrl
)
}
@@ -1,5 +1,6 @@
package de.mm20.launcher2.wikipedia
import android.content.Context
import de.mm20.launcher2.search.SearchableDeserializer
import de.mm20.launcher2.search.SearchableSerializer
import de.mm20.launcher2.search.data.Searchable
@@ -14,6 +15,7 @@ class WikipediaSerializer : SearchableSerializer {
json.put("text", searchable.text)
json.put("id", searchable.id)
json.put("image", searchable.image)
json.put("wikipedia_url", searchable.wikipediaUrl)
return json.toString()
}
@@ -21,14 +23,15 @@ class WikipediaSerializer : SearchableSerializer {
get() = "wikipedia"
}
class WikipediaDeserializer : SearchableDeserializer {
class WikipediaDeserializer(val context: Context) : SearchableDeserializer {
override fun deserialize(serialized: String): Searchable? {
val json = JSONObject(serialized)
return Wikipedia(
label = json.getString("label"),
text = json.getString("text"),
id = json.getLong("id"),
image = json.optString("image")
image = json.optString("image"),
wikipediaUrl = json.optString("wikipedia_url").takeIf { !it.isNullOrBlank() } ?: return null,
)
}
}