diff --git a/src/all/batoto/AndroidManifest.xml b/src/all/batoto/AndroidManifest.xml
index 30deb7f79..88d434029 100644
--- a/src/all/batoto/AndroidManifest.xml
+++ b/src/all/batoto/AndroidManifest.xml
@@ -1,2 +1,23 @@
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/all/batoto/build.gradle b/src/all/batoto/build.gradle
index ce51ef55a..0dc98db63 100644
--- a/src/all/batoto/build.gradle
+++ b/src/all/batoto/build.gradle
@@ -5,7 +5,7 @@ ext {
extName = 'Bato.to'
pkgNameSuffix = 'all.batoto'
extClass = '.BatoToFactory'
- extVersionCode = 9
+ extVersionCode = 10
libVersion = '1.2'
containsNsfw = true
}
diff --git a/src/all/batoto/src/eu/kanade/tachiyomi/extension/all/batoto/BatoTo.kt b/src/all/batoto/src/eu/kanade/tachiyomi/extension/all/batoto/BatoTo.kt
index a85bb0c16..ac1f3468e 100644
--- a/src/all/batoto/src/eu/kanade/tachiyomi/extension/all/batoto/BatoTo.kt
+++ b/src/all/batoto/src/eu/kanade/tachiyomi/extension/all/batoto/BatoTo.kt
@@ -2,12 +2,15 @@ package eu.kanade.tachiyomi.extension.all.batoto
import com.squareup.duktape.Duktape
import eu.kanade.tachiyomi.network.GET
+import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.model.Filter
import eu.kanade.tachiyomi.source.model.FilterList
+import eu.kanade.tachiyomi.source.model.MangasPage
import eu.kanade.tachiyomi.source.model.Page
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource
+import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.HttpUrl.Companion.toHttpUrlOrNull
import okhttp3.OkHttpClient
import okhttp3.Request
@@ -17,6 +20,8 @@ import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import java.util.Calendar
import java.util.concurrent.TimeUnit
+import okhttp3.Response
+import rx.Observable
open class BatoTo(
override val lang: String,
@@ -67,76 +72,108 @@ open class BatoTo(
override fun popularMangaNextPageSelector() = latestUpdatesNextPageSelector()
- override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
- return if (query.isNotBlank()) {
- GET("$baseUrl/search?word=$query&page=$page")
- } else {
- val url = "$baseUrl/browse".toHttpUrlOrNull()!!.newBuilder()
- url.addQueryParameter("page", page.toString())
- url.addQueryParameter("langs", siteLang)
- filters.forEach { filter ->
- when (filter) {
- is OriginFilter -> {
- val originToInclude = mutableListOf()
- filter.state.forEach { content ->
- if (content.state) {
- originToInclude.add(content.name)
- }
- }
- if (originToInclude.isNotEmpty()) {
- url.addQueryParameter(
- "origs",
- originToInclude
- .joinToString(",")
- )
- }
+ override fun fetchSearchManga(page: Int, query: String, filters: FilterList): Observable {
+ return when {
+ query.startsWith("ID:") -> {
+ val id = query.substringAfter("ID:")
+ client.newCall(GET("https://bato.to/series/$id", headers)).asObservableSuccess()
+ .map { response ->
+ queryIDParse(response, id)
}
- is StatusFilter -> {
- if (filter.state != 0) {
- url.addQueryParameter("release", filter.toUriPart())
- }
+ }
+ query.isNotBlank() -> {
+ val url = "$baseUrl/search".toHttpUrlOrNull()!!.newBuilder()
+ val letterFilter = filters.findInstance()!!
+ url.addQueryParameter("word", query)
+ url.addQueryParameter("page", "$page")
+ if (letterFilter.state){
+ url.addQueryParameter("mode", "letter")
+ }
+ client.newCall(GET(url.build().toString(), headers)).asObservableSuccess()
+ .map { response ->
+ queryParse(response)
}
- is GenreFilter -> {
- val genreToInclude = filter.state
- .filter { it.isIncluded() }
- .map { it.name }
+ }
- val genreToExclude = filter.state
- .filter { it.isExcluded() }
- .map { it.name }
+ else -> {
+ val sortFilter = filters.findInstance()!!
+ val reverseSortFilter = filters.findInstance()!!
+ val statusFilter = filters.findInstance()!!
+ val langFilter = filters.findInstance()!!
+ val originFilter = filters.findInstance()!!
+ val genreFilter = filters.findInstance()!!
+ val minChapterFilter = filters.findInstance()!!
+ val maxChapterFilter = filters.findInstance()!!
+ val url = "$baseUrl/browse".toHttpUrlOrNull()!!.newBuilder()
+ url.addQueryParameter("page", page.toString())
- if (genreToInclude.isNotEmpty() || genreToExclude.isNotEmpty()) {
- url.addQueryParameter(
- "genres",
- genreToInclude
- .joinToString(",") +
- "|" +
- genreToExclude
- .joinToString(",")
- )
- }
- }
- is ChapterFilter -> {
- if (filter.state != 0) {
- url.addQueryParameter("chapters", filter.toUriPart())
- }
- }
- is SortBy -> {
- if (filter.state != 0) {
- url.addQueryParameter("sort", filter.toUriPart())
- }
+ with (langFilter) {
+ if (this.selected.isEmpty()) {
+ url.addQueryParameter("langs", siteLang)
+ } else {
+ val selection = "${this.selected.joinToString(",")},$siteLang"
+ url.addQueryParameter("langs", selection)
}
}
+
+ with (genreFilter) {
+ url.addQueryParameter("genres", included.joinToString(",") + "|" + excluded.joinToString(",")
+ )
+ }
+
+ with (statusFilter) {
+ url.addQueryParameter("release", this.selected)
+ }
+
+ with (sortFilter) {
+ if (reverseSortFilter.state) {
+ url.addQueryParameter("sort","${this.selected}.az")
+ } else {
+ url.addQueryParameter("sort","${this.selected}.za")
+ }
+ }
+
+ if (originFilter.selected.isNotEmpty()) {
+ url.addQueryParameter("origs", originFilter.selected.joinToString(","))
+ }
+
+ if (maxChapterFilter.state.isNotEmpty() or minChapterFilter.state.isNotEmpty()) {
+ url.addQueryParameter("chapters", minChapterFilter.state + "-" + maxChapterFilter.state)
+ }
+
+ client.newCall(GET(url.build().toString(), headers)).asObservableSuccess()
+ .map { response ->
+ queryParse(response)
+ }
}
- GET(url.build().toString(), headers)
}
}
- override fun searchMangaSelector() = latestUpdatesSelector()
+ private fun queryIDParse(response: Response, id: String): MangasPage {
+ val document = response.asJsoup()
+ val infoElement = document.select("div#mainer div.container-fluid")
+ val manga = SManga.create()
+ manga.title = infoElement.select("h3").text()
+ manga.thumbnail_url = document.select("div.attr-cover img")
+ .attr("abs:src")
+ manga.url = infoElement.select("h3 a").attr("abs:href")
+ return MangasPage(listOf(manga), false)
+ }
- override fun searchMangaFromElement(element: Element) = latestUpdatesFromElement(element)
+ private fun queryParse(response: Response): MangasPage {
+ val mangas = mutableListOf()
+ val document = response.asJsoup()
+ document.select(latestUpdatesSelector()).forEach { element ->
+ mangas.add(latestUpdatesFromElement(element))
+ }
+ val nextPage = document.select(latestUpdatesNextPageSelector()) != null
+ return MangasPage(mangas, nextPage)
+ }
- override fun searchMangaNextPageSelector() = latestUpdatesNextPageSelector()
+ override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request = throw UnsupportedOperationException("Not used")
+ override fun searchMangaSelector() = throw UnsupportedOperationException("Not used")
+ override fun searchMangaFromElement(element: Element) = throw UnsupportedOperationException("Not used")
+ override fun searchMangaNextPageSelector() = throw UnsupportedOperationException("Not used")
override fun mangaDetailsRequest(manga: SManga): Request {
if (manga.url.startsWith("http")) {
@@ -315,206 +352,401 @@ open class BatoTo(
override fun imageUrlParse(document: Document): String = throw UnsupportedOperationException("Not used")
- private class OriginFilter(genres: List) : Filter.Group("Origin", genres)
- private class GenreFilter(genres: List) : Filter.Group("Genres", genres)
-
- private class ChapterFilter : UriPartFilter(
- "Chapters",
- arrayOf(
- Pair("