11package eu.kanade.tachiyomi.extension.en.readallcomicscom
22
33import eu.kanade.tachiyomi.network.GET
4- import eu.kanade.tachiyomi.network.asObservableSuccess
54import eu.kanade.tachiyomi.source.model.FilterList
65import eu.kanade.tachiyomi.source.model.MangasPage
76import eu.kanade.tachiyomi.source.model.Page
87import eu.kanade.tachiyomi.source.model.SChapter
98import eu.kanade.tachiyomi.source.model.SManga
10- import eu.kanade.tachiyomi.source.online.ParsedHttpSource
9+ import eu.kanade.tachiyomi.source.online.HttpSource
1110import eu.kanade.tachiyomi.util.asJsoup
1211import keiyoushi.utils.tryParse
1312import okhttp3.HttpUrl.Companion.toHttpUrl
1413import okhttp3.Request
1514import okhttp3.Response
16- import org.jsoup.nodes.Document
1715import org.jsoup.nodes.Element
18- import org.jsoup.select.Elements
1916import rx.Observable
2017import java.text.SimpleDateFormat
2118import java.util.Locale
2219import java.util.TimeZone
2320
24- class ReadAllComics : ParsedHttpSource () {
21+ class ReadAllComics : HttpSource () {
2522
2623 override val name = " ReadAllComics"
2724
@@ -31,125 +28,81 @@ class ReadAllComics : ParsedHttpSource() {
3128
3229 override val supportsLatest = false
3330
34- private lateinit var searchPageElements: Elements
35-
3631 override val client = network.cloudflareClient
3732
38- override fun popularMangaRequest (page : Int ): Request {
39- val url = baseUrl.toHttpUrl().newBuilder().apply {
40- addPathSegments(" page/$page " )
41- }.build()
33+ // Popular
4234
43- return GET (url, headers)
44- }
35+ override fun fetchPopularManga (page : Int ): Observable <MangasPage > = throw Exception (" Use search to find comics." )
4536
46- override fun popularMangaFromElement (element : Element ): SManga {
47- val manga = SManga .create().apply {
48- val category = element.classNames()
49- .firstOrNull { it.startsWith(" category-" ) }!!
50- .substringAfter(" category-" )
51- setUrlWithoutDomain(" /category/$category " )
52- title = category.replace(" -" , " " ).titleCaseWords()
53- thumbnail_url = element.selectFirst(" img" )?.attr(" src" )
54- }
55-
56- return manga
57- }
37+ override fun popularMangaRequest (page : Int ) = throw UnsupportedOperationException ()
38+ override fun popularMangaParse (response : Response ) = throw UnsupportedOperationException ()
5839
59- override fun popularMangaSelector () = " #post-area > div"
60- override fun popularMangaNextPageSelector () = " a.page-numbers.next"
61-
62- override fun fetchSearchManga (page : Int , query : String , filters : FilterList ): Observable <MangasPage > = if (page == 1 ) {
63- client.newCall(searchMangaRequest(page, query, filters))
64- .asObservableSuccess()
65- .map { searchMangaParse(it) }
66- } else {
67- Observable .just(searchPageParse(page))
68- }
40+ // Search
6941
7042 override fun searchMangaRequest (page : Int , query : String , filters : FilterList ): Request {
7143 val url = baseUrl.toHttpUrl().newBuilder().apply {
7244 addQueryParameter(" story" , query)
7345 addQueryParameter(" s" , " " )
7446 addQueryParameter(" type" , " comic" )
47+ if (page > 1 ) addQueryParameter(" paged" , page.toString())
7548 }.build()
7649
7750 return GET (url, headers)
7851 }
7952
8053 override fun searchMangaParse (response : Response ): MangasPage {
81- searchPageElements = response.asJsoup().select(searchMangaSelector())
82-
83- return searchPageParse(1 )
54+ val document = response.asJsoup()
55+ val mangas = document.select(" ul.list-story.categories li" ).map { mangaFromElement(it) }
56+ val hasNextPage = document.selectFirst(" a.next" ) != null
57+ return MangasPage (mangas, hasNextPage)
8458 }
8559
86- private fun searchPageParse (page : Int ): MangasPage {
87- val mangas = mutableListOf<SManga >()
88- val endRange = ((page * 24 ) - 1 ).let { if (it <= searchPageElements.lastIndex) it else searchPageElements.lastIndex }
60+ private fun mangaFromElement (element : Element ) = SManga .create().apply {
61+ val titleAnchor = element.selectFirst(" a.cat-title" )!!
62+ setUrlWithoutDomain(titleAnchor.attr(" abs:href" ))
63+ title = titleAnchor.text()
64+ thumbnail_url = element.selectFirst(" img.book-cover" )?.attr(" abs:src" )
65+ }
8966
90- for (i in (((page - 1 ) * 24 ).. endRange)) {
91- mangas.add(
92- searchMangaFromElement(searchPageElements[i]),
93- )
94- }
67+ // Manga details
9568
96- return MangasPage (mangas, endRange < searchPageElements.lastIndex)
69+ override fun mangaDetailsParse (response : Response ) = SManga .create().apply {
70+ val archive = response.asJsoup().selectFirst(" .description-archive" )!!
71+ title = archive.selectFirst(" h1" )!! .text()
72+ thumbnail_url = archive.selectFirst(" p img" )?.attr(" abs:src" )
73+ val infoStrongs = archive.select(" .b > p strong" )
74+ genre = infoStrongs.firstOrNull()?.text()
75+ author = infoStrongs.lastOrNull()?.text()
76+ description = archive.selectFirst(" #hidden-description" )?.wholeText()?.trim()
9777 }
9878
99- override fun searchMangaFromElement (element : Element ) = SManga .create().apply {
100- setUrlWithoutDomain(element.attr(" href" ))
101- title = element.text()
102- thumbnail_url = " "
103- }
79+ // Chapters
10480
105- override fun searchMangaSelector () = " .categories a"
106- override fun searchMangaNextPageSelector () = null
107-
108- override fun mangaDetailsParse (document : Document ) = SManga .create().apply {
109- title = document.selectFirst(" h1" )!! .text()
110- genre = document.select(" p strong" ).joinToString { it.text() }
111- author = document.select(" p > strong" ).last()?.text()
112- description = buildString {
113- document.select(" .b > strong" ).forEach { element ->
114- val vol = element.previousElementSibling()
115- if (isNotBlank()) {
116- append(" \n\n " )
117- }
118- if (vol?.tagName() == " span" ) {
119- append(vol.text(), " \n " )
120- }
121- append(element.text())
122- }
81+ override fun chapterListParse (response : Response ): List <SChapter > = response.asJsoup().select(" .list-story a" ).map { element ->
82+ SChapter .create().apply {
83+ setUrlWithoutDomain(element.attr(" abs:href" ))
84+ name = element.text()
85+ val year = name.substringAfterLast(' (' ).substringBefore(' )' )
86+ date_upload = dateFormat.tryParse(" $year -1-1" )
12387 }
124- thumbnail_url = document.select(" p img" ).attr(" abs:src" )
12588 }
12689
127- override fun chapterListSelector () = " .list-story a "
90+ // Pages
12891
129- override fun chapterFromElement (element : Element ) = SChapter .create().apply {
130- setUrlWithoutDomain(element.attr(" href" ))
131- name = element.text()
132- // can only get the year from chapter title
133- val year = name.substringAfterLast(' (' ).substringBefore(' )' )
134- date_upload = dateFormat.tryParse(" $year -1-1" )
92+ override fun pageListParse (response : Response ): List <Page > = response.asJsoup().select(" body img:not(div[id=logo] img)" ).mapIndexed { idx, element ->
93+ Page (idx, imageUrl = element.attr(" abs:src" ))
13594 }
13695
137- override fun pageListParse (document : Document ): List <Page > = document.select(" body img:not(body div[id=\" logo\" ] img)" ).mapIndexed { idx, element ->
138- Page (idx, " " , element.attr(" abs:src" ))
139- }
96+ override fun imageUrlParse (response : Response ) = throw UnsupportedOperationException ()
14097
141- private fun String.titleCaseWords (): String {
142- val words = this .split(" " )
143- return words.joinToString(" " ) { word -> word.replaceFirstChar { it.titlecase() } }
144- }
98+ // Latest (unsupported)
14599
146- override fun imageUrlParse (document : Document ) = throw UnsupportedOperationException ()
147100 override fun latestUpdatesRequest (page : Int ) = throw UnsupportedOperationException ()
148- override fun latestUpdatesFromElement (element : Element ) = throw UnsupportedOperationException ()
149- override fun latestUpdatesSelector () = throw UnsupportedOperationException ()
150- override fun latestUpdatesNextPageSelector () = throw UnsupportedOperationException ()
101+ override fun latestUpdatesParse (response : Response ) = throw UnsupportedOperationException ()
151102
152103 companion object {
153- val dateFormat = SimpleDateFormat (" yyyy-MM-dd" , Locale .US ).apply { timeZone = TimeZone .getTimeZone(" UTC" ) }
104+ val dateFormat = SimpleDateFormat (" yyyy-MM-dd" , Locale .US ).apply {
105+ timeZone = TimeZone .getTimeZone(" UTC" )
106+ }
154107 }
155108}
0 commit comments