Added PizzaReader multisrc CMS (#7196)

* Added PizzaReader multisrc CMS

* Added PhoenixScans

* bump versionId
This commit is contained in:
FedericoHeichou 2021-08-08 17:37:34 +02:00 committed by GitHub
parent f50917ba3c
commit 029cf989b9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 232 additions and 7 deletions

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.2 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.0 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 471 KiB

View File

@ -1,5 +0,0 @@
package eu.kanade.tachiyomi.extension.it.phoenixscans
import eu.kanade.tachiyomi.multisrc.foolslide.FoolSlide
class PhoenixScans : FoolSlide("The Phoenix Scans", "https://www.phoenixscans.com", "it", "/reader")

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 30 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 43 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 56 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 193 KiB

View File

@ -0,0 +1,7 @@
package eu.kanade.tachiyomi.extension.it.phoenixscans
import eu.kanade.tachiyomi.multisrc.pizzareader.PizzaReader
class PhoenixScans : PizzaReader("Phoenix Scans", "https://www.phoenixscans.com", "it") {
override val versionId = 2
}

View File

@ -35,7 +35,6 @@ class FoolSlideGenerator : ThemeSourceGenerator {
SingleLang("Baixar Hentai", "https://leitura.baixarhentai.net", "pt-BR", isNsfw = true, overrideVersionCode = 3), SingleLang("Baixar Hentai", "https://leitura.baixarhentai.net", "pt-BR", isNsfw = true, overrideVersionCode = 3),
MultiLang("HNI-Scantrad", "https://hni-scantrad.com", listOf("fr", "en"), className = "HNIScantradFactory", pkgName = "hniscantrad", overrideVersionCode = 1), MultiLang("HNI-Scantrad", "https://hni-scantrad.com", listOf("fr", "en"), className = "HNIScantradFactory", pkgName = "hniscantrad", overrideVersionCode = 1),
SingleLang("QuegnaReader", "http://pignaquegna.altervista.org", "it"), SingleLang("QuegnaReader", "http://pignaquegna.altervista.org", "it"),
SingleLang("The Phoenix Scans", "https://www.phoenixscans.com", "it", className = "PhoenixScans"),
SingleLang("GTO The Great Site", "https://www.gtothegreatsite.net", "it", className = "GTO"), SingleLang("GTO The Great Site", "https://www.gtothegreatsite.net", "it", className = "GTO"),
SingleLang("NIFTeam", "http://read-nifteam.info", "it"), SingleLang("NIFTeam", "http://read-nifteam.info", "it"),
SingleLang("TuttoAnimeManga", "https://tuttoanimemanga.net", "it"), SingleLang("TuttoAnimeManga", "https://tuttoanimemanga.net", "it"),
@ -44,7 +43,7 @@ class FoolSlideGenerator : ThemeSourceGenerator {
SingleLang("Mabushimajo", "http://mabushimajo.com", "tr"), SingleLang("Mabushimajo", "http://mabushimajo.com", "tr"),
SingleLang("Hyakuro", "https://hyakuro.com", "en"), SingleLang("Hyakuro", "https://hyakuro.com", "en"),
SingleLang("Le Cercle du Scan", "https://lel.lecercleduscan.com", "fr", className = "LeCercleDuScan", overrideVersionCode = 1), SingleLang("Le Cercle du Scan", "https://lel.lecercleduscan.com", "fr", className = "LeCercleDuScan", overrideVersionCode = 1),
SingleLang("LetItGo Scans", "https://reader.letitgo.scans.today", "en", overrideVersionCode = 1) SingleLang("LetItGo Scans", "https://reader.letitgo.scans.today", "en", overrideVersionCode = 1),
) )
companion object { companion object {

View File

@ -0,0 +1,103 @@
package eu.kanade.tachiyomi.multisrc.pizzareader
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.network.asObservableSuccess
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.HttpSource
import okhttp3.Headers
import okhttp3.Request
import okhttp3.Response
import org.json.JSONObject
import rx.Observable
abstract class PizzaReader(
override val name: String,
override val baseUrl: String,
override val lang: String,
private val apiPath: String = "/api"
) : HttpSource() {
override val supportsLatest = true
open val apiUrl by lazy { "$baseUrl$apiPath" }
override fun headersBuilder() = Headers.Builder().apply {
add("Referer", baseUrl)
}
override fun popularMangaRequest(page: Int) =
GET("$apiUrl/comics", headers)
override fun popularMangaParse(response: Response) =
MangasPage(
JSONObject(response.asString()).run {
val arr = getJSONArray("comics")
(0 until arr.length()).map {
SManga.create().fromJSON(arr.getJSONObject(it))
}
},
false
)
override fun searchMangaRequest(page: Int, query: String, filters: FilterList) =
GET("$apiUrl/search/$query", headers)
override fun searchMangaParse(response: Response) =
MangasPage(
JSONObject(response.asString()).run {
val arr = getJSONArray("comics")
(0 until arr.length()).map {
SManga.create().fromJSON(arr.getJSONObject(it))
}
},
false
)
// TODO
override fun latestUpdatesRequest(page: Int): Request =
throw UnsupportedOperationException("Not used")
override fun latestUpdatesParse(response: Response): MangasPage =
throw UnsupportedOperationException("Not used")
// Workaround to allow "Open in browser" to use the real URL
override fun fetchMangaDetails(manga: SManga): Observable<SManga> =
client.newCall(chapterListRequest(manga)).asObservableSuccess()
.map { mangaDetailsParse(it).apply { initialized = true } }
// Return the real URL for "Open in browser"
override fun mangaDetailsRequest(manga: SManga) =
GET("$baseUrl${manga.url}", headers)
override fun mangaDetailsParse(response: Response): SManga =
SManga.create().fromJSON(JSONObject(response.asString()).getJSONObject("comic"))
override fun chapterListRequest(manga: SManga) = GET("$apiUrl${manga.url}", headers)
override fun chapterListParse(response: Response) =
JSONObject(response.asString()).getJSONObject("comic").run {
val arr = getJSONArray("chapters")
(0 until arr.length()).map {
SChapter.create().fromJSON(arr.getJSONObject(it))
}
}
override fun pageListRequest(chapter: SChapter) =
GET("$apiUrl${chapter.url}", headers)
override fun pageListParse(response: Response) =
JSONObject(response.asString()).getJSONObject("chapter").run {
val arr = getJSONArray("pages")
(0 until arr.length()).map {
Page(it, "", arr.getString(it))
}
}
override fun imageUrlParse(response: Response): String =
throw UnsupportedOperationException("Not used")
}

View File

@ -0,0 +1,94 @@
package eu.kanade.tachiyomi.multisrc.pizzareader
import eu.kanade.tachiyomi.source.model.SChapter
import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.Response
import org.json.JSONArray
import org.json.JSONObject
import java.text.DecimalFormat
// import java.time.OffsetDateTime
import java.text.SimpleDateFormat
import java.util.Locale
/** Returns the body of a response as a `String`. */
fun Response.asString(): String = body!!.string()
/**
* Formats the number according to [fmt].
*
* @param fmt A [DecimalFormat] string.
* @return A string representation of the number.
*/
fun Number.format(fmt: String): String = DecimalFormat(fmt).format(this)
/**
* Joins each value of a given [field] of the array using [sep].
*
* @param field The index of a [JSONArray].
* When its type is [String], it is treated as the key of a [JSONObject].
* @param sep The separator used to join the array.
* @return The joined string, or `null` if the array is empty.
*/
fun JSONArray.joinField(field: Int, sep: String = ", ") =
length().takeIf { it != 0 }?.run {
(0 until this).mapNotNull {
val obj = get(it)
if (obj != null && obj.toString() != "null") getJSONArray(it).getString(field)
else null
}.joinToString(sep)
}
/**
* Joins each value of a given [field] of the array using [sep].
*
* @param field The key of a [JSONObject].
* @param sep The separator used to join the array.
* @return The joined string, or `null` if the array is empty.
*/
fun JSONArray.joinField(field: String, sep: String = ", ") =
length().takeIf { it != 0 }?.run {
(0 until this).mapNotNull {
val obj = get(it)
if (obj != null && obj.toString() != "null") getJSONObject(it).getString(field)
else null
}.joinToString(sep)
}
/**
* Creates a [SManga] by parsing a [JSONObject].
*
* @param obj The object containing the manga info.
*/
fun SManga.fromJSON(obj: JSONObject) = apply {
url = obj.getString("url")
title = obj.getString("title")
description = obj.getString("description")
thumbnail_url = obj.getString("thumbnail")
author = obj.getString("author")
artist = obj.getString("artist")
genre = obj.getJSONArray("genres").joinField("slug")
status = when (obj.getString("status").substring(0, 7)) {
"In cors" -> SManga.ONGOING
"On goin" -> SManga.ONGOING
"Complet" -> SManga.COMPLETED
"Conclus" -> SManga.COMPLETED
"Conclud" -> SManga.COMPLETED
"Licenzi" -> SManga.LICENSED
"License" -> SManga.LICENSED
else -> SManga.UNKNOWN
}
}
/**
* Creates a [SChapter] by parsing a [JSONObject].
*
* @param obj The object containing the chapter info.
*/
fun SChapter.fromJSON(obj: JSONObject) = apply {
url = obj.getString("url")
chapter_number = obj.optString("chapter", "-1").toFloat() + "0.${obj.optInt("subchapter", 0)}".toFloat()
// date_upload = OffsetDateTime.parse(obj.getString("published_on")).toEpochSecond() // API 26
date_upload = SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSSSS", Locale.ITALY).parse(obj.getString("published_on"))?.time ?: 0L
scanlator = obj.getJSONArray("teams").joinField("name", " & ")
name = obj.getString("full_title")
}

View File

@ -0,0 +1,27 @@
package eu.kanade.tachiyomi.multisrc.pizzareader
// import generator.ThemeSourceData.MultiLang
import generator.ThemeSourceData.SingleLang
import generator.ThemeSourceGenerator
class PizzaReaderGenerator : ThemeSourceGenerator {
override val themePkg = "pizzareader"
override val themeClass = "PizzaReader"
override val baseVersionCode: Int = 0
override val sources = listOf(
SingleLang("Phoenix Scans", "https://www.phoenixscans.com", "it", className = "PhoenixScans", overrideVersionCode = 4),
// Current migrating to this CMS:
// SingleLang("GTO The Great Site", "https://reader.gtothegreatsite.net", "it", className = "GTO", overrideVersionCode = 4),
)
companion object {
@JvmStatic
fun main(args: Array<String>) {
PizzaReaderGenerator().createAll()
}
}
}