Mangalib site update. Add prefs to image server (#2594)

Co-authored-by: Pavel Mosein <p.mosein@edadeal.ru>
This commit is contained in:
Pavka 2020-04-05 17:42:35 +03:00 committed by GitHub
parent 5ea83b7087
commit ab6d4d0a2e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 86 additions and 23 deletions

View File

@ -5,7 +5,7 @@ ext {
appName = 'Tachiyomi: MangaLib' appName = 'Tachiyomi: MangaLib'
pkgNameSuffix = 'ru.libmanga' pkgNameSuffix = 'ru.libmanga'
extClass = '.LibManga' extClass = '.LibManga'
extVersionCode = 14 extVersionCode = 15
libVersion = '1.2' libVersion = '1.2'
} }

View File

@ -1,23 +1,34 @@
package eu.kanade.tachiyomi.extension.ru.libmanga package eu.kanade.tachiyomi.extension.ru.libmanga
import android.app.Application
import android.content.SharedPreferences
import android.support.v7.preference.ListPreference
import android.support.v7.preference.PreferenceScreen
import com.github.salomonbrys.kotson.* import com.github.salomonbrys.kotson.*
import com.google.gson.JsonElement import com.google.gson.JsonElement
import com.google.gson.JsonParser import com.google.gson.JsonParser
import eu.kanade.tachiyomi.network.GET import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.POST import eu.kanade.tachiyomi.network.POST
import eu.kanade.tachiyomi.network.asObservableSuccess import eu.kanade.tachiyomi.network.asObservableSuccess
import eu.kanade.tachiyomi.source.ConfigurableSource
import eu.kanade.tachiyomi.source.model.* import eu.kanade.tachiyomi.source.model.*
import eu.kanade.tachiyomi.source.online.HttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.* import okhttp3.*
import org.jsoup.nodes.Element import org.jsoup.nodes.Element
import rx.Observable import rx.Observable
import uy.kohesive.injekt.Injekt
import uy.kohesive.injekt.api.get
import java.text.SimpleDateFormat import java.text.SimpleDateFormat
import java.util.* import java.util.*
import android.util.Base64.decode as base64Decode import android.util.Base64.decode as base64Decode
class LibManga : HttpSource() { class LibManga : ConfigurableSource, HttpSource() {
private val preferences: SharedPreferences by lazy {
Injekt.get<Application>().getSharedPreferences("source_${id}_2", 0x0000)
}
override val name: String = "Mangalib" override val name: String = "Mangalib"
@ -36,15 +47,51 @@ class LibManga : HttpSource() {
private val jsonParser = JsonParser() private val jsonParser = JsonParser()
private var server: String? = preferences.getString(SERVER_PREF, null)
override fun setupPreferenceScreen(screen: androidx.preference.PreferenceScreen) {
val serverPref = androidx.preference.ListPreference(screen.context).apply {
key = SERVER_PREF
title = SERVER_PREF_Title
entries = arrayOf("Основной", "Второй (тестовый)", "Сжатия (эконом трафика)")
entryValues = arrayOf("secondary", "fourth", "compress")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
server = newValue.toString()
true
}
}
screen.addPreference(serverPref)
}
override fun setupPreferenceScreen(screen: PreferenceScreen) {
val serverPref = ListPreference(screen.context).apply {
key = SERVER_PREF
title = SERVER_PREF_Title
entries = arrayOf("Основной", "Второй (тестовый)", "Сжатия (эконом трафика)")
entryValues = arrayOf("secondary", "fourth", "compress")
summary = "%s"
setOnPreferenceChangeListener { _, newValue ->
server = newValue.toString()
true
}
}
screen.addPreference(serverPref)
}
override fun latestUpdatesRequest(page: Int) = GET(baseUrl, headers) override fun latestUpdatesRequest(page: Int) = GET(baseUrl, headers)
private val latestUpdatesSelector = "div.updates__left" private val latestUpdatesSelector = "div.updates__left"
override fun latestUpdatesParse(response: Response): MangasPage { override fun latestUpdatesParse(response: Response): MangasPage {
val elements = response.asJsoup().select(latestUpdatesSelector) val elements = response.asJsoup().select(latestUpdatesSelector)
val latestMangas = elements?.map { latestUpdatesFromElement(it) } val latestMangas = elements?.map { latestUpdatesFromElement(it) }
if (latestMangas != null) if (latestMangas != null)
return MangasPage(latestMangas,false) // TODO: use API return MangasPage(latestMangas, false) // TODO: use API
return MangasPage(emptyList(), false) return MangasPage(emptyList(), false)
} }
@ -52,7 +99,7 @@ class LibManga : HttpSource() {
val link = element.select("a").first() val link = element.select("a").first()
val img = link.select("img").first() val img = link.select("img").first()
val manga = SManga.create() val manga = SManga.create()
manga.thumbnail_url = baseUrl+img.attr("data-src").substringAfter(baseUrl) manga.thumbnail_url = baseUrl + img.attr("data-src").substringAfter(baseUrl)
.replace("cover_thumb", "cover_250x350") .replace("cover_thumb", "cover_250x350")
manga.setUrlWithoutDomain(link.attr("href")) manga.setUrlWithoutDomain(link.attr("href"))
manga.title = img.attr("alt") manga.title = img.attr("alt")
@ -85,7 +132,7 @@ class LibManga : HttpSource() {
return fetchPopularMangaFromApi(page) return fetchPopularMangaFromApi(page)
} }
private fun fetchPopularMangaFromApi(page : Int): Observable<MangasPage> { private fun fetchPopularMangaFromApi(page: Int): Observable<MangasPage> {
return client.newCall(POST("$baseUrl/filterlist?dir=desc&sort=views&page=$page", catalogHeaders())) return client.newCall(POST("$baseUrl/filterlist?dir=desc&sort=views&page=$page", catalogHeaders()))
.asObservableSuccess() .asObservableSuccess()
.map { response -> .map { response ->
@ -130,8 +177,7 @@ class LibManga : HttpSource() {
body.select(".info-list__row:has(strong:contains(Перевод))") body.select(".info-list__row:has(strong:contains(Перевод))")
.first() .first()
.select("span.m-label") .select("span.m-label")
.text()) .text()) {
{
"продолжается" -> SManga.ONGOING "продолжается" -> SManga.ONGOING
"завершен" -> SManga.COMPLETED "завершен" -> SManga.COMPLETED
else -> SManga.UNKNOWN else -> SManga.UNKNOWN
@ -150,12 +196,28 @@ class LibManga : HttpSource() {
} }
private fun chapterFromElement(element: Element): SChapter { private fun chapterFromElement(element: Element): SChapter {
val chapterLink = element.select("div.chapter-item__name > a").first()
val chapter = SChapter.create() val chapter = SChapter.create()
chapter.setUrlWithoutDomain(chapterLink.attr("href"))
chapter.name = chapterLink.text() val chapterLink = element.select("div.chapter-item__name > a").first()
if (chapterLink != null) {
chapter.setUrlWithoutDomain(chapterLink.attr("href"))
} else {
// Found multiple translate. Get first one for now
val volume = element.attr("data-volume")
val number = element.attr("data-number")
val teams = jsonParser.parse(element.attr("data-teams"))
val team = teams[0]["slug"].nullString
val baseUrl = "${element.baseUri()}/v$volume/c$number"
val url = if (team != null) "${baseUrl}/$team" else baseUrl
chapter.setUrlWithoutDomain(url)
}
chapter.name = element.select("div.chapter-item__name").first().text()
chapter.date_upload = SimpleDateFormat("dd.MM.yyyy", Locale.US) chapter.date_upload = SimpleDateFormat("dd.MM.yyyy", Locale.US)
.parse(element.select("div.chapter-item__date").text()).time .parse(element.select("div.chapter-item__date").text()).time
return chapter return chapter
} }
@ -176,11 +238,12 @@ class LibManga : HttpSource() {
.replace(";", "") .replace(";", "")
val chapInfoJson = jsonParser.parse(chapInfo).obj val chapInfoJson = jsonParser.parse(chapInfo).obj
val servers = chapInfoJson["servers"].asJsonObject
val defaultServer: String = chapInfoJson["img"]["server"].string
val imgUrl: String = chapInfoJson["img"]["url"].string
val imageServerUrl: String = when(chapInfoJson["imgServer"].string){ val serverToUse = if (this.server == null) defaultServer else this.server
"compress" -> "https://img3.mangalib.me/" val imageServerUrl: String = servers[serverToUse].string
else -> "https://img2.mangalib.me/"
}
// Get pages // Get pages
val baseStr = document.select("span.pp") val baseStr = document.select("span.pp")
@ -195,7 +258,7 @@ class LibManga : HttpSource() {
val pages = mutableListOf<Page>() val pages = mutableListOf<Page>()
pagesJson.forEach { page -> pagesJson.forEach { page ->
pages.add(Page(page["p"].int, "", imageServerUrl + chapInfoJson["imgUrl"].string + page["u"].string)) pages.add(Page(page["p"].int, "", imageServerUrl + imgUrl + page["u"].string))
} }
return pages return pages
@ -246,14 +309,14 @@ class LibManga : HttpSource() {
if (!searchRequest.isNullOrEmpty()) { if (!searchRequest.isNullOrEmpty()) {
val popupSearchHeaders = headers val popupSearchHeaders = headers
.newBuilder() .newBuilder()
.add("Accept", "application/json, text/plain, */*") .add("Accept", "application/json, text/plain, */*")
.add("X-Requested-With", "XMLHttpRequest") .add("X-Requested-With", "XMLHttpRequest")
.build() .build()
// +200ms // +200ms
val popup = client.newCall( val popup = client.newCall(
GET("$baseUrl/search?query=$searchRequest", popupSearchHeaders)) GET("$baseUrl/search?query=$searchRequest", popupSearchHeaders))
.execute().body()!!.string() .execute().body()!!.string()
val jsonList = jsonParser.parse(popup).array val jsonList = jsonParser.parse(popup).array
@ -371,6 +434,6 @@ class LibManga : HttpSource() {
companion object { companion object {
private const val SERVER_PREF_Title = "Сервер изображений" private const val SERVER_PREF_Title = "Сервер изображений"
private const val SERVER_PREF = "imageServer" private const val SERVER_PREF = "MangaLibImageServer"
} }
} }