RisensTeam - update for their new API (#4233)

This commit is contained in:
Mike 2020-08-27 23:21:10 -04:00 committed by GitHub
parent f9bf91b65b
commit e4af261b5a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 95 additions and 94 deletions

View File

@ -5,7 +5,7 @@ ext {
extName = 'Risens Team' extName = 'Risens Team'
pkgNameSuffix = 'ru.risensteam' pkgNameSuffix = 'ru.risensteam'
extClass = '.RisensTeam' extClass = '.RisensTeam'
extVersionCode = 1 extVersionCode = 2
libVersion = '1.2' libVersion = '1.2'
} }

View File

@ -1,27 +1,33 @@
package eu.kanade.tachiyomi.extension.ru.risensteam package eu.kanade.tachiyomi.extension.ru.risensteam
import com.github.salomonbrys.kotson.fromJson import com.github.salomonbrys.kotson.fromJson
import com.github.salomonbrys.kotson.get
import com.github.salomonbrys.kotson.int import com.github.salomonbrys.kotson.int
import com.github.salomonbrys.kotson.nullString
import com.github.salomonbrys.kotson.string import com.github.salomonbrys.kotson.string
import com.google.gson.Gson import com.google.gson.Gson
import com.google.gson.JsonArray
import com.google.gson.JsonElement
import com.google.gson.JsonObject import com.google.gson.JsonObject
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.source.model.FilterList 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.Page
import eu.kanade.tachiyomi.source.model.SChapter import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga import eu.kanade.tachiyomi.source.model.SManga
import eu.kanade.tachiyomi.source.online.ParsedHttpSource import eu.kanade.tachiyomi.source.online.HttpSource
import eu.kanade.tachiyomi.util.asJsoup import java.text.ParseException
import okhttp3.MultipartBody import java.text.SimpleDateFormat
import java.util.Locale
import okhttp3.MediaType
import okhttp3.Request import okhttp3.Request
import okhttp3.RequestBody import okhttp3.RequestBody
import okhttp3.Response import okhttp3.Response
import org.jsoup.nodes.Document import rx.Observable
import org.jsoup.nodes.Element
class RisensTeam : ParsedHttpSource() { class RisensTeam : HttpSource() {
override fun pageListParse(document: Document): List<Page> = throw Exception("Not Used")
override val name = "Risens Team" override val name = "Risens Team"
@ -31,111 +37,106 @@ class RisensTeam : ParsedHttpSource() {
override val supportsLatest = false override val supportsLatest = false
override val versionId: Int = 2
private val gson by lazy { Gson() } private val gson by lazy { Gson() }
override fun popularMangaRequest(page: Int): Request = // Popular (source only returns manga sorted by latest)
GET("$baseUrl/manga/page/$page/", headers)
override fun popularMangaRequest(page: Int): Request {
return GET("https://risens.team/api/title/list?type=1", headers)
}
private fun mangaFromJson(json: JsonElement): SManga {
return SManga.create().apply {
url = "${json["id"].int}/${json["furl"].string}"
title = json["title"].string
thumbnail_url = baseUrl + json["poster"].string
description = json["description"].nullString
status = try { if (json["active"].int == 1) SManga.ONGOING else SManga.UNKNOWN } catch (_: Exception) { SManga.UNKNOWN }
}
}
override fun popularMangaParse(response: Response): MangasPage {
val mangas = gson.fromJson<JsonArray>(response.body()!!.string())
.map { json -> mangaFromJson(json) }
return MangasPage(mangas, false)
}
// Latest
override fun latestUpdatesRequest(page: Int): Request = throw UnsupportedOperationException("Not used")
override fun latestUpdatesParse(response: Response): MangasPage = throw UnsupportedOperationException("Not used")
// Search
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request { override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
return POST(baseUrl, headers, buildRequestBody(query, page)) val rbody = RequestBody.create(MediaType.parse("application/json;charset=utf-8"), """{"queryString":"$query","limit":3}""")
return POST("$baseUrl/api/title/search", headers, rbody)
} }
private fun buildRequestBody(query: String, page: Int): RequestBody { override fun searchMangaParse(response: Response): MangasPage = popularMangaParse(response)
return MultipartBody.Builder()
.setType(MultipartBody.FORM) // Details
.addFormDataPart("do", "search")
.addFormDataPart("subaction", "search") override fun fetchMangaDetails(manga: SManga): Observable<SManga> {
.addFormDataPart("story", query) return client.newCall(apiMangaDetailsRequest(manga))
.addFormDataPart("catlist[]", "33") .asObservableSuccess()
.addFormDataPart("search_start", (page - 1).toString()) .map { response ->
.build() mangaDetailsParse(response).apply { initialized = true }
}
} }
override fun popularMangaSelector() = ".mb-2:not([align])" private fun apiMangaDetailsRequest(manga: SManga): Request {
return GET("$baseUrl/api/title/show/${manga.url.substringBefore("/")}")
override fun searchMangaSelector() = ".card.h-100"
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
val coverElem = element.select(".card-img-top").first()
val imgUrl = coverElem.attr("src")
manga.thumbnail_url = baseUrl + if (imgUrl.contains("/pagespeed_static/")) coverElem.attr("data-pagespeed-lazy-src") else imgUrl
manga.setUrlWithoutDomain(element.select("b-link").first().attr("to"))
manga.title = coverElem.attr("alt").split('/').first().replace("(Манга)", "").trim()
return manga
} }
override fun searchMangaFromElement(element: Element): SManga { override fun mangaDetailsRequest(manga: SManga): Request {
val manga = SManga.create() return GET("$baseUrl/title/${manga.url}")
val coverElem = element.select(".card-img-top").first()
manga.thumbnail_url = coverElem.attr("src")
manga.setUrlWithoutDomain(coverElem.parent().attr("href"))
manga.title = coverElem.attr("alt").split('/').first().replace("(Манга)", "").trim()
return manga
} }
override fun popularMangaNextPageSelector() = "b-list-group-item.next > a" override fun mangaDetailsParse(response: Response): SManga {
return mangaFromJson(gson.fromJson<JsonObject>(response.body()!!.string()))
override fun searchMangaNextPageSelector() = popularMangaNextPageSelector()
override fun mangaDetailsParse(document: Document): SManga {
val manga = SManga.create()
manga.thumbnail_url = baseUrl + document.select("b-img[fluid]").first().attr("src")
manga.genre = document.select("td:containsOwn(Жанр:) + td > a").joinToString { it.ownText() }
manga.description = document.select(".news-body").text()
manga.status = when (document.select("td:containsOwn(Состояние:) + td").first().ownText()) {
"Выход продолжается" -> SManga.ONGOING
"Выход завершён", "Выход завершен" -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
return manga
} }
// Chapters
override fun chapterListRequest(manga: SManga): Request = apiMangaDetailsRequest(manga)
override fun chapterListParse(response: Response): List<SChapter> { override fun chapterListParse(response: Response): List<SChapter> {
val document = response.asJsoup() return gson.fromJson<JsonObject>(response.body()!!.string())["entities"].asJsonArray.map { json ->
SChapter.create().apply {
val id = document.select("#reader").first().attr("src").split("?id=").last().toInt() url = json["id"].int.toString()
val jsonData = client.newCall(GET(baseUrl + MANGA_API_URL + id)).execute().body()!!.string() name = listOfNotNull(json["label"].nullString, json["name"].nullString).joinToString(" - ")
val jsonArray = gson.fromJson<List<JsonObject>>(jsonData) date_upload = json["updated_at"].toDate()
val chapters = mutableListOf<SChapter>()
jsonArray.forEach {
val chapter = SChapter.create()
chapter.url = CHAPTER_API_URL + it["id"].int
chapter.name = "Глава ${it["chapter"].string}"
chapter.chapter_number = it["chapter"].string.toFloat()
chapters.add(chapter)
} }
return chapters.reversed() }
}
private val simpleDateFormat by lazy {
SimpleDateFormat("yyyy-MM-dd HH:mm:ss", Locale.getDefault())
}
private fun JsonElement.toDate(): Long {
val date = this.nullString ?: return 0
return try {
simpleDateFormat.parse(date)?.time ?: 0
} catch (e: ParseException) {
0
}
}
// Pages
override fun pageListRequest(chapter: SChapter): Request {
return GET("$baseUrl/api/yandex/chapter/${chapter.url}", headers)
} }
override fun pageListParse(response: Response): List<Page> { override fun pageListParse(response: Response): List<Page> {
val jsonData = response.body()!!.string() return gson.fromJson<JsonArray>(response.body()!!.string())
val jsonArray = gson.fromJson<List<String>>(jsonData) .mapIndexed { i, json -> Page(i, "", json.string) }
val pages = mutableListOf<Page>()
jsonArray.forEachIndexed { index, imageUrl ->
pages.add(Page(index, imageUrl = imageUrl))
}
return pages
} }
override fun latestUpdatesRequest(page: Int): Request = throw Exception("Not Used") override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not used")
override fun chapterFromElement(element: Element): SChapter = throw Exception("Not Used")
override fun imageUrlParse(document: Document) = throw Exception("Not Used")
override fun chapterListSelector() = throw Exception("Not Used")
override fun latestUpdatesNextPageSelector() = throw Exception("Not Used")
override fun latestUpdatesFromElement(element: Element): SManga = throw Exception("Not Used")
override fun latestUpdatesSelector() = throw Exception("Not Used")
companion object {
const val MANGA_API_URL = "/risensteam/api/manga.php?id="
const val CHAPTER_API_URL = "/risensteam/api/chapter.php?id="
}
} }