Add missing chapters at MangasProject. (#2637)
Add missing chapters at MangasProject
This commit is contained in:
		
							parent
							
								
									c3984f4887
								
							
						
					
					
						commit
						57efc954a9
					
				@ -5,7 +5,7 @@ ext {
 | 
				
			|||||||
    appName = 'Tachiyomi: mangásPROJECT'
 | 
					    appName = 'Tachiyomi: mangásPROJECT'
 | 
				
			||||||
    pkgNameSuffix = 'pt.mangasproject'
 | 
					    pkgNameSuffix = 'pt.mangasproject'
 | 
				
			||||||
    extClass = '.MangasProjectFactory'
 | 
					    extClass = '.MangasProjectFactory'
 | 
				
			||||||
    extVersionCode = 8
 | 
					    extVersionCode = 9
 | 
				
			||||||
    libVersion = '1.2'
 | 
					    libVersion = '1.2'
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -12,6 +12,7 @@ import eu.kanade.tachiyomi.source.online.HttpSource
 | 
				
			|||||||
import eu.kanade.tachiyomi.util.asJsoup
 | 
					import eu.kanade.tachiyomi.util.asJsoup
 | 
				
			||||||
import okhttp3.FormBody
 | 
					import okhttp3.FormBody
 | 
				
			||||||
import okhttp3.Headers
 | 
					import okhttp3.Headers
 | 
				
			||||||
 | 
					import okhttp3.HttpUrl
 | 
				
			||||||
import okhttp3.Interceptor
 | 
					import okhttp3.Interceptor
 | 
				
			||||||
import okhttp3.OkHttpClient
 | 
					import okhttp3.OkHttpClient
 | 
				
			||||||
import okhttp3.Request
 | 
					import okhttp3.Request
 | 
				
			||||||
@ -24,10 +25,12 @@ import java.text.SimpleDateFormat
 | 
				
			|||||||
import java.util.Locale
 | 
					import java.util.Locale
 | 
				
			||||||
import java.util.concurrent.TimeUnit
 | 
					import java.util.concurrent.TimeUnit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
abstract class MangasProject(override val name: String,
 | 
					abstract class MangasProject(
 | 
				
			||||||
                             override val baseUrl: String) : HttpSource() {
 | 
					    override val name: String,
 | 
				
			||||||
 | 
					    override val baseUrl: String
 | 
				
			||||||
 | 
					) : HttpSource() {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override val lang = "pt"
 | 
					    override val lang = "pt-BR"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override val supportsLatest = true
 | 
					    override val supportsLatest = true
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -51,16 +54,12 @@ abstract class MangasProject(override val name: String,
 | 
				
			|||||||
    override fun popularMangaParse(response: Response): MangasPage {
 | 
					    override fun popularMangaParse(response: Response): MangasPage {
 | 
				
			||||||
        val result = response.asJsonObject()
 | 
					        val result = response.asJsonObject()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        // If "most_read" have boolean false value, then it doesn't have next page.
 | 
					 | 
				
			||||||
        if (!result["most_read"]!!.isJsonArray)
 | 
					 | 
				
			||||||
            return MangasPage(emptyList(), false)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        val popularMangas = result["most_read"].array
 | 
					        val popularMangas = result["most_read"].array
 | 
				
			||||||
            .map { popularMangaItemParse(it.obj) }
 | 
					            .map { popularMangaItemParse(it.obj) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val page = response.request().url().queryParameter("page")!!.toInt()
 | 
					        val hasNextPage = response.request().url().queryParameter("page")!!.toInt() < 10
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return MangasPage(popularMangas, page < 10)
 | 
					        return MangasPage(popularMangas, hasNextPage)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun popularMangaItemParse(obj: JsonObject) = SManga.create().apply {
 | 
					    private fun popularMangaItemParse(obj: JsonObject) = SManga.create().apply {
 | 
				
			||||||
@ -74,17 +73,14 @@ abstract class MangasProject(override val name: String,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun latestUpdatesParse(response: Response): MangasPage {
 | 
					    override fun latestUpdatesParse(response: Response): MangasPage {
 | 
				
			||||||
        if (response.code() == 500)
 | 
					 | 
				
			||||||
            return MangasPage(emptyList(), false)
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        val result = response.asJsonObject()
 | 
					        val result = response.asJsonObject()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val latestMangas = result["releases"].array
 | 
					        val latestMangas = result["releases"].array
 | 
				
			||||||
            .map { latestMangaItemParse(it.obj) }
 | 
					            .map { latestMangaItemParse(it.obj) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val page = response.request().url().queryParameter("page")!!.toInt()
 | 
					        val hasNextPage = response.request().url().queryParameter("page")!!.toInt() < 5
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return MangasPage(latestMangas, page < 5)
 | 
					        return MangasPage(latestMangas, hasNextPage)
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun latestMangaItemParse(obj: JsonObject) = SManga.create().apply {
 | 
					    private fun latestMangaItemParse(obj: JsonObject) = SManga.create().apply {
 | 
				
			||||||
@ -123,9 +119,8 @@ abstract class MangasProject(override val name: String,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun mangaDetailsRequest(manga: SManga): Request {
 | 
					    override fun mangaDetailsRequest(manga: SManga): Request {
 | 
				
			||||||
        val newHeaders = Headers.Builder()
 | 
					        val newHeaders = headersBuilder()
 | 
				
			||||||
            .add("User-Agent", USER_AGENT)
 | 
					            .removeAll("X-Requested-With")
 | 
				
			||||||
            .add("Referer", baseUrl)
 | 
					 | 
				
			||||||
            .build()
 | 
					            .build()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return GET(baseUrl + manga.url, newHeaders)
 | 
					        return GET(baseUrl + manga.url, newHeaders)
 | 
				
			||||||
@ -145,30 +140,21 @@ abstract class MangasProject(override val name: String,
 | 
				
			|||||||
            .substringAfter("Completo")
 | 
					            .substringAfter("Completo")
 | 
				
			||||||
            .substringBefore("+")
 | 
					            .substringBefore("+")
 | 
				
			||||||
            .split("&")
 | 
					            .split("&")
 | 
				
			||||||
            .map { it.trim() }
 | 
					            .groupBy({ it.contains("(Arte)") }, {
 | 
				
			||||||
 | 
					                it.replace(" (Arte)", "")
 | 
				
			||||||
        val seriesAuthor = seriesAuthors
 | 
					                    .trim()
 | 
				
			||||||
            .filter { !it.contains("(Arte)") }
 | 
					                    .split(", ")
 | 
				
			||||||
            .joinToString("; ") {
 | 
					 | 
				
			||||||
                it.split(", ")
 | 
					 | 
				
			||||||
                    .reversed()
 | 
					                    .reversed()
 | 
				
			||||||
                    .joinToString(" ")
 | 
					                    .joinToString(" ")
 | 
				
			||||||
            }
 | 
					            })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return SManga.create().apply {
 | 
					        return SManga.create().apply {
 | 
				
			||||||
            thumbnail_url = seriesData.select("div.series-img > div.cover > img").attr("src")
 | 
					            thumbnail_url = seriesData.select("div.series-img > div.cover > img").attr("src")
 | 
				
			||||||
            description = seriesData.select("span.series-desc").text()
 | 
					            description = seriesData.select("span.series-desc").text()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            status = parseStatus(seriesBlocked, isCompleted)
 | 
					            status = parseStatus(seriesBlocked, isCompleted)
 | 
				
			||||||
            author = seriesAuthor
 | 
					            author = seriesAuthors[false]?.joinToString("; ") ?: author
 | 
				
			||||||
            artist = seriesAuthors.filter { it.contains("(Arte)") }
 | 
					            artist = seriesAuthors[true]?.joinToString("; ") ?: author
 | 
				
			||||||
                .map { it.replace("\\(Arte\\)".toRegex(), "").trim() }
 | 
					 | 
				
			||||||
                .joinToString("; ") {
 | 
					 | 
				
			||||||
                    it.split(", ")
 | 
					 | 
				
			||||||
                        .reversed()
 | 
					 | 
				
			||||||
                        .joinToString(" ")
 | 
					 | 
				
			||||||
                }
 | 
					 | 
				
			||||||
                .ifEmpty { seriesAuthor }
 | 
					 | 
				
			||||||
            genre = seriesData.select("div#series-data ul.tags li")
 | 
					            genre = seriesData.select("div#series-data ul.tags li")
 | 
				
			||||||
                .joinToString { it.text() }
 | 
					                .joinToString { it.text() }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -215,7 +201,7 @@ abstract class MangasProject(override val name: String,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
        while (result["chapters"]!!.isJsonArray) {
 | 
					        while (result["chapters"]!!.isJsonArray) {
 | 
				
			||||||
            chapters += result["chapters"].array
 | 
					            chapters += result["chapters"].array
 | 
				
			||||||
                .map { chapterListItemParse(it.obj) }
 | 
					                .flatMap { chapterListItemParse(it.obj) }
 | 
				
			||||||
                .toMutableList()
 | 
					                .toMutableList()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
            val newRequest = chapterListRequestPaginated(mangaUrl, mangaId, ++page)
 | 
					            val newRequest = chapterListRequestPaginated(mangaUrl, mangaId, ++page)
 | 
				
			||||||
@ -225,32 +211,37 @@ abstract class MangasProject(override val name: String,
 | 
				
			|||||||
        return chapters
 | 
					        return chapters
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun chapterListItemParse(obj: JsonObject): SChapter {
 | 
					    private fun chapterListItemParse(obj: JsonObject): List<SChapter> {
 | 
				
			||||||
        val scan = obj["releases"].obj.entrySet().first().value.obj
 | 
					 | 
				
			||||||
        val chapterName = obj["chapter_name"]!!.string
 | 
					        val chapterName = obj["chapter_name"]!!.string
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return SChapter.create().apply {
 | 
					        return obj["releases"].obj.entrySet().map {
 | 
				
			||||||
            name = "Cap. ${obj["number"].string}" + (if (chapterName == "") "" else " - $chapterName")
 | 
					            val release = it.value.obj
 | 
				
			||||||
            date_upload = parseChapterDate(obj["date_created"].string.substringBefore("T"))
 | 
					
 | 
				
			||||||
            scanlator = scan["scanlators"]!!.array
 | 
					            SChapter.create().apply {
 | 
				
			||||||
                .joinToString { it.obj["name"].string }
 | 
					                name = "Cap. ${obj["number"].string}" + (if (chapterName == "") "" else " - $chapterName")
 | 
				
			||||||
            url = scan["link"].string
 | 
					                date_upload = parseChapterDate(obj["date_created"].string.substringBefore("T"))
 | 
				
			||||||
            chapter_number = obj["number"].string.toFloatOrNull() ?: 0f
 | 
					                scanlator = release["scanlators"]!!.array
 | 
				
			||||||
 | 
					                    .map { scanObj -> scanObj.obj["name"].string }
 | 
				
			||||||
 | 
					                    .sorted()
 | 
				
			||||||
 | 
					                    .joinToString()
 | 
				
			||||||
 | 
					                url = release["link"].string
 | 
				
			||||||
 | 
					                chapter_number = obj["number"].string.toFloatOrNull() ?: 0f
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun parseChapterDate(date: String?) : Long {
 | 
					    private fun parseChapterDate(date: String?) : Long {
 | 
				
			||||||
        return try {
 | 
					        return try {
 | 
				
			||||||
            SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH).parse(date).time
 | 
					            DATE_FORMATTER.parse(date).time
 | 
				
			||||||
        } catch (e: ParseException) {
 | 
					        } catch (e: ParseException) {
 | 
				
			||||||
            0L
 | 
					            0L
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun pageListRequest(chapter: SChapter): Request {
 | 
					    override fun pageListRequest(chapter: SChapter): Request {
 | 
				
			||||||
        val newHeaders = Headers.Builder()
 | 
					        val newHeaders = headersBuilder()
 | 
				
			||||||
            .add("User-Agent", USER_AGENT)
 | 
					            .set("Referer", baseUrl + chapter.url)
 | 
				
			||||||
            .add("Referer", baseUrl + chapter.url)
 | 
					            .removeAll("X-Requested-With")
 | 
				
			||||||
            .build()
 | 
					            .build()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return GET(baseUrl + chapter.url, newHeaders)
 | 
					        return GET(baseUrl + chapter.url, newHeaders)
 | 
				
			||||||
@ -276,38 +267,44 @@ abstract class MangasProject(override val name: String,
 | 
				
			|||||||
            return result
 | 
					            return result
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        val document = result.asJsoup()
 | 
					        val document = result.asJsoup()
 | 
				
			||||||
        val readerSrc = document.select("script[src*=\"reader.\"]")
 | 
					        val token = document.select("script[src*=\"reader.\"]")
 | 
				
			||||||
            ?.attr("src") ?: ""
 | 
					            ?.let {
 | 
				
			||||||
 | 
					                HttpUrl.parse(it.attr("abs:src"))!!
 | 
				
			||||||
        val token = TOKEN_REGEX.find(readerSrc)?.groupValues?.get(1) ?: ""
 | 
					                    .queryParameter("token")
 | 
				
			||||||
 | 
					            } ?: throw Exception("Não foi possível obter o token de leitura.")
 | 
				
			||||||
        if (token.isEmpty())
 | 
					 | 
				
			||||||
            throw Exception("Não foi possível obter o token de leitura.")
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return chain.proceed(pageListApiRequest(request.url().toString(), token))
 | 
					        return chain.proceed(pageListApiRequest(request.url().toString(), token))
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun pageListParse(response: Response): List<Page> {
 | 
					    override fun pageListParse(response: Response): List<Page> {
 | 
				
			||||||
        val result = response.asJsonObject()
 | 
					        val result = response.asJsonObject()
 | 
				
			||||||
 | 
					        val chapterUrl = response.request().header("Referer")!!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        return result["images"].array
 | 
					        return result["images"].array
 | 
				
			||||||
            .filter { it.string.startsWith("http") }
 | 
					            .filter { it.string.startsWith("http") }
 | 
				
			||||||
            .mapIndexed { i, obj -> Page(i, "", obj.string)}
 | 
					            .mapIndexed { i, obj -> Page(i, chapterUrl, obj.string)}
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun fetchImageUrl(page: Page): Observable<String> {
 | 
					    override fun fetchImageUrl(page: Page): Observable<String> = Observable.just(page.imageUrl!!)
 | 
				
			||||||
        return Observable.just(page.imageUrl!!)
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    override fun imageUrlParse(response: Response): String = ""
 | 
					    override fun imageUrlParse(response: Response): String = ""
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    override fun imageRequest(page: Page): Request {
 | 
				
			||||||
 | 
					        val newHeaders = headersBuilder()
 | 
				
			||||||
 | 
					            .set("Referer", page.url)
 | 
				
			||||||
 | 
					            .removeAll("X-Requested-With")
 | 
				
			||||||
 | 
					            .build()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        return GET(page.imageUrl!!, newHeaders)
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    private fun Response.asJsonObject(): JsonObject = JSON_PARSER.parse(body()!!.string()).obj
 | 
					    private fun Response.asJsonObject(): JsonObject = JSON_PARSER.parse(body()!!.string()).obj
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    companion object {
 | 
					    companion object {
 | 
				
			||||||
        private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36"
 | 
					        private const val USER_AGENT = "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.87 Safari/537.36"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        private val TOKEN_REGEX = "token=(.*)&id".toRegex()
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
        private val JSON_PARSER by lazy { JsonParser() }
 | 
					        private val JSON_PARSER by lazy { JsonParser() }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        private val DATE_FORMATTER by lazy { SimpleDateFormat("yyyy-MM-dd", Locale.ENGLISH) }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -18,4 +18,7 @@ class LeitorNet : MangasProject("Leitor.net", "https://leitor.net") {
 | 
				
			|||||||
    override val id: Long = 2225174659569980836
 | 
					    override val id: Long = 2225174659569980836
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class MangaLivre : MangasProject("MangaLivre", "https://mangalivre.net")
 | 
					class MangaLivre : MangasProject("MangaLivre", "https://mangalivre.net") {
 | 
				
			||||||
 | 
					    // Hardcode the id because the language wasn't specific.
 | 
				
			||||||
 | 
					    override val id: Long = 4762777556012432014
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user