Added PizzaReader multisrc CMS ()

* 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
multisrc
overrides
foolslide/phoenixscans
pizzareader
default/res
phoenixscans/src
src/main/java/eu/kanade/tachiyomi/multisrc

Binary file not shown.

Before

(image error) Size: 8.2 KiB

Binary file not shown.

Before

(image error) Size: 4.0 KiB

Binary file not shown.

Before

(image error) Size: 13 KiB

Binary file not shown.

Before

(image error) Size: 26 KiB

Binary file not shown.

Before

(image error) Size: 45 KiB

Binary file not shown.

Before

(image error) Size: 471 KiB

@ -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

(image error) Size: 25 KiB

Binary file not shown.

After

(image error) Size: 17 KiB

Binary file not shown.

After

(image error) Size: 30 KiB

Binary file not shown.

After

(image error) Size: 43 KiB

Binary file not shown.

After

(image error) Size: 56 KiB

Binary file not shown.

After

(image error) Size: 193 KiB

@ -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
}

@ -35,7 +35,6 @@ class FoolSlideGenerator : ThemeSourceGenerator {
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),
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("NIFTeam", "http://read-nifteam.info", "it"),
SingleLang("TuttoAnimeManga", "https://tuttoanimemanga.net", "it"),
@ -44,7 +43,7 @@ class FoolSlideGenerator : ThemeSourceGenerator {
SingleLang("Mabushimajo", "http://mabushimajo.com", "tr"),
SingleLang("Hyakuro", "https://hyakuro.com", "en"),
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 {

@ -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")
}

@ -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")
}

@ -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()
}
}
}