Browse Source

Changed Kitsu to use Algoria search directly (#1514)

* Changed Kitsu to use Algoria search directly, was recommended by the Kitsu Dev team

* remove extra line

* fixed end date bug
added filtering out novel back in

* save the retrofit instances locally for search.
Carlos 6 years ago
parent
commit
fd825b1049

+ 48 - 9
app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuApi.kt

@@ -24,6 +24,22 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
             .build()
             .create(KitsuApi.Rest::class.java)
 
+    private val searchRest = Retrofit.Builder()
+            .baseUrl(algoliaKeyUrl)
+            .client(client)
+            .addConverterFactory(GsonConverterFactory.create())
+            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
+            .build()
+            .create(KitsuApi.SearchKeyRest::class.java)
+
+    private val algoliaRest = Retrofit.Builder()
+            .baseUrl(algoliaUrl)
+            .client(client)
+            .addConverterFactory(GsonConverterFactory.create())
+            .addCallAdapterFactory(RxJavaCallAdapterFactory.create())
+            .build()
+            .create(KitsuApi.AgoliaSearchRest::class.java)
+
     fun addLibManga(track: Track, userId: String): Observable<Track> {
         return Observable.defer {
             // @formatter:off
@@ -48,7 +64,6 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
                             )
                     )
             )
-            // @formatter:on
 
             rest.addLibManga(jsonObject("data" to data))
                     .map { json ->
@@ -77,12 +92,25 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
         }
     }
 
+
     fun search(query: String): Observable<List<TrackSearch>> {
-        return rest.search(query)
+        return searchRest
+                .getKey().map { json ->
+                    json["media"].asJsonObject["key"].string
+                }.flatMap { key ->
+                    algoliaSearch(key, query)
+                }
+    }
+
+
+    private fun algoliaSearch(key: String, query: String): Observable<List<TrackSearch>> {
+        val jsonObject = jsonObject("params" to "query=$query$algoliaFilter")
+        return algoliaRest
+                .getSearchQuery(algoliaAppId, key, jsonObject)
                 .map { json ->
-                    val data = json["data"].array
-                    data.map { KitsuManga(it.obj) }
-                            .filter { it.type != "novel" }
+                    val data = json["hits"].array
+                    data.map { KitsuSearchManga(it.obj) }
+                            .filter { it.subType != "novel" }
                             .map { it.toTrack() }
                 }
     }
@@ -143,10 +171,6 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
                 @Body data: JsonObject
         ): Observable<JsonObject>
 
-        @GET("manga")
-        fun search(
-                @Query("filter[text]", encoded = true) query: String
-        ): Observable<JsonObject>
 
         @GET("library-entries")
         fun findLibManga(
@@ -168,6 +192,16 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
 
     }
 
+    private interface SearchKeyRest {
+        @GET("media/")
+        fun getKey(): Observable<JsonObject>
+    }
+
+    private interface AgoliaSearchRest {
+        @POST("query/")
+        fun getSearchQuery(@Header("X-Algolia-Application-Id") appid: String, @Header("X-Algolia-API-Key") key: String, @Body json: JsonObject): Observable<JsonObject>
+    }
+
     private interface LoginRest {
 
         @FormUrlEncoded
@@ -188,6 +222,11 @@ class KitsuApi(private val client: OkHttpClient, interceptor: KitsuInterceptor)
         private const val baseUrl = "https://kitsu.io/api/edge/"
         private const val loginUrl = "https://kitsu.io/api/"
         private const val baseMangaUrl = "https://kitsu.io/manga/"
+        private const val algoliaKeyUrl = "https://kitsu.io/api/edge/algolia-keys/"
+        private const val algoliaUrl = "https://AWQO5J657S-dsn.algolia.net/1/indexes/production_media/"
+        private const val algoliaAppId = "AWQO5J657S"
+        private const val algoliaFilter = "&facetFilters=%5B%22kind%3Amanga%22%5D&attributesToRetrieve=%5B%22synopsis%22%2C%22canonicalTitle%22%2C%22chapterCount%22%2C%22posterImage%22%2C%22startDate%22%2C%22subtype%22%2C%22endDate%22%2C%20%22id%22%5D"
+
 
         fun mangaUrl(remoteId: Int): String {
             return baseMangaUrl + remoteId

+ 38 - 17
app/src/main/java/eu/kanade/tachiyomi/data/track/kitsu/KitsuModels.kt

@@ -7,38 +7,59 @@ import eu.kanade.tachiyomi.data.database.models.Track
 import eu.kanade.tachiyomi.data.track.TrackManager
 import eu.kanade.tachiyomi.data.track.model.TrackSearch
 
-open class KitsuManga(obj: JsonObject) {
+class KitsuSearchManga(obj: JsonObject) {
     val id by obj.byInt
-    val canonicalTitle by obj["attributes"].byString
-    val chapterCount = obj["attributes"].obj.get("chapterCount").nullInt
-    val type = obj["attributes"].obj.get("mangaType").nullString.orEmpty()
-    val original by obj["attributes"].obj["posterImage"].byString
-    val synopsis by obj["attributes"].byString
-    val startDate = obj["attributes"].obj.get("startDate").nullString.orEmpty()
-    open val status = obj["attributes"].obj.get("status").nullString.orEmpty()
+    private val canonicalTitle by obj.byString
+    private val chapterCount = obj.get("chapterCount").nullInt
+    val subType = obj.get("subType").nullString
+    val original by obj["posterImage"].byString
+    private val synopsis by obj.byString
+    private val startDate = obj.get("startDate").nullString
+    private val endDate = obj.get("endDate").nullString
 
     @CallSuper
     open fun toTrack() = TrackSearch.create(TrackManager.KITSU).apply {
-        media_id = [email protected]
+        media_id = this@KitsuSearchManga.id
         title = canonicalTitle
         total_chapters = chapterCount ?: 0
         cover_url = original
         summary = synopsis
         tracking_url = KitsuApi.mangaUrl(media_id)
-        publishing_status = [email protected]
-        publishing_type = type
+
+        if (endDate == null) {
+            publishing_status = "Publishing"
+        } else {
+            publishing_status = "Finished"
+        }
+        publishing_type = subType ?: ""
         start_date = startDate.orEmpty()
     }
 }
 
-class KitsuLibManga(obj: JsonObject, manga: JsonObject) : KitsuManga(manga) {
-    val libraryId by obj.byInt("id")
-    override val status by obj["attributes"].byString
-    val ratingTwenty = obj["attributes"].obj.get("ratingTwenty").nullString
+
+class KitsuLibManga(obj: JsonObject, manga: JsonObject) {
+    val id by manga.byInt
+    private val canonicalTitle by manga["attributes"].byString
+    private val chapterCount = manga["attributes"].obj.get("chapterCount").nullInt
+    val type = manga["attributes"].obj.get("mangaType").nullString.orEmpty()
+    val original by manga["attributes"].obj["posterImage"].byString
+    private val synopsis by manga["attributes"].byString
+    private val startDate = manga["attributes"].obj.get("startDate").nullString.orEmpty()
+    private val libraryId by obj.byInt("id")
+    val status by obj["attributes"].byString
+    private val ratingTwenty = obj["attributes"].obj.get("ratingTwenty").nullString
     val progress by obj["attributes"].byInt
 
-    override fun toTrack() = super.toTrack().apply {
-        media_id = libraryId // TODO migrate media ids to library ids
+    open fun toTrack() = TrackSearch.create(TrackManager.KITSU).apply {
+        media_id = libraryId
+        title = canonicalTitle
+        total_chapters = chapterCount ?: 0
+        cover_url = original
+        summary = synopsis
+        tracking_url = KitsuApi.mangaUrl(media_id)
+        publishing_status = [email protected]
+        publishing_type = type
+        start_date = startDate
         status = toTrackStatus()
         score = ratingTwenty?.let { it.toInt() / 2f } ?: 0f
         last_chapter_read = progress