LynxScans move to MangaThemesia (#17262)

This commit is contained in:
AwkwardPeak7 2023-07-26 20:30:01 +05:00 committed by GitHub
parent 369e48f362
commit 17f6640380
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
18 changed files with 35 additions and 254 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.3 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 100 KiB

View File

@ -0,0 +1,34 @@
package eu.kanade.tachiyomi.extension.en.lynxscans
import eu.kanade.tachiyomi.multisrc.mangathemesia.MangaThemesia
import eu.kanade.tachiyomi.network.interceptor.rateLimit
import okhttp3.Interceptor
import okhttp3.Response
class LynxScans : MangaThemesia("LynxScans", "https://lynxscans.com", "en", "/comics") {
override val versionId = 3
override val hasProjectPage = true
override val client = super.client.newBuilder()
.addNetworkInterceptor(::pageSpeedRedirectIntercept)
.rateLimit(2)
.build()
private fun pageSpeedRedirectIntercept(chain: Interceptor.Chain): Response {
val request = chain.request()
if (request.url.pathSegments.contains("wp-content") || request.method == "POST") {
return chain.proceed(request)
}
val newUrl = request.url.newBuilder()
.setQueryParameter("PageSpeed", "noscript")
.build()
val newRequest = request.newBuilder()
.url(newUrl)
.build()
return chain.proceed(newRequest)
}
}

View File

@ -61,6 +61,7 @@ class MangaThemesiaGenerator : ThemeSourceGenerator {
SingleLang("Legion Scan", "https://legionscans.com", "es", overrideVersionCode = 6), SingleLang("Legion Scan", "https://legionscans.com", "es", overrideVersionCode = 6),
SingleLang("LianScans", "https://www.lianscans.my.id", "id", isNsfw = true), SingleLang("LianScans", "https://www.lianscans.my.id", "id", isNsfw = true),
SingleLang("Lunar Scans", "https://lunarscan.org", "en", isNsfw = true), SingleLang("Lunar Scans", "https://lunarscan.org", "en", isNsfw = true),
SingleLang("LynxScans", "https://lynxscans.com", "en"),
SingleLang("Magus Manga", "https://magusmanga.com", "ar"), SingleLang("Magus Manga", "https://magusmanga.com", "ar"),
SingleLang("Manga Indo.me", "https://mangaindo.me", "id", className = "MangaIndoMe"), SingleLang("Manga Indo.me", "https://mangaindo.me", "id", className = "MangaIndoMe"),
SingleLang("Manga Raw.org", "https://mangaraw.org", "ja", className = "MangaRawOrg", overrideVersionCode = 1), SingleLang("Manga Raw.org", "https://mangaraw.org", "ja", className = "MangaRawOrg", overrideVersionCode = 1),

View File

@ -1,2 +0,0 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest package="eu.kanade.tachiyomi.extension" />

View File

@ -1,12 +0,0 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
apply plugin: 'kotlinx-serialization'
ext {
extName = 'LynxScans'
pkgNameSuffix = 'en.lynxscans'
extClass = '.LynxScans'
extVersionCode = 7
}
apply from: "$rootDir/common.gradle"

Binary file not shown.

Before

Width:  |  Height:  |  Size: 8.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 4.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 23 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 169 KiB

View File

@ -1,130 +0,0 @@
package eu.kanade.tachiyomi.extension.en.lynxscans
import eu.kanade.tachiyomi.network.GET
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 kotlinx.serialization.decodeFromString
import kotlinx.serialization.json.Json
import okhttp3.Request
import okhttp3.Response
import uy.kohesive.injekt.injectLazy
class LynxScans : HttpSource() {
override val baseUrl: String = "https://lynxscans.com"
private val apiUrl: String = "https://api.lynxscans.com/api"
override val lang: String = "en"
override val name: String = "LynxScans"
override val versionId = 2
override val supportsLatest: Boolean = true
private val json: Json by injectLazy()
// Popular
override fun popularMangaRequest(page: Int): Request {
return GET("$apiUrl/comics?page=$page", headers)
}
override fun popularMangaParse(response: Response): MangasPage {
val data = json.decodeFromString<Popular>(response.body.string())
val titles = data.comics.data.map(PopularComicsData::toSManga)
return MangasPage(titles, !data.comics.next_page_url.isNullOrEmpty())
}
// Latest
override fun latestUpdatesRequest(page: Int): Request {
return GET("$apiUrl/latest?page=$page", headers)
}
override fun latestUpdatesParse(response: Response): MangasPage {
val data = json.decodeFromString<Latest>(response.body.string())
val titles = data.chapters.data.distinctBy { it.comic_titleSlug }.map(LatestChaptersData::toSManga)
return MangasPage(titles, !data.chapters.next_page_url.isNullOrEmpty())
}
// Search
override fun searchMangaParse(response: Response): MangasPage {
throw UnsupportedOperationException("Not used")
}
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
throw Exception("Search is not supported")
}
// Details
override fun mangaDetailsParse(response: Response): SManga {
val data = json.decodeFromString<MangaDetails>(response.body.string())
return data.comic.toSManga()
}
override fun mangaDetailsRequest(manga: SManga): Request {
val titleId = manga.url.substringAfterLast("/")
return GET("$apiUrl/comics/$titleId", headers)
}
override fun getMangaUrl(manga: SManga): String {
val titleId = manga.url.substringAfterLast("/")
return "$baseUrl/comics/$titleId"
}
// Chapters
override fun chapterListRequest(manga: SManga): Request {
return mangaDetailsRequest(manga)
}
override fun chapterListParse(response: Response): List<SChapter> {
val data = json.decodeFromString<MangaDetails>(response.body.string())
val chapters: MutableList<SChapter> = mutableListOf()
data.comic.volumes.forEach { volume ->
volume.chapters.forEach { chapter ->
chapters.add(
SChapter.create().apply {
url = "/comics/${data.comic.titleSlug}/volume/${volume.number}/chapter/${chapter.number}"
name = volume.name + " " + (if (!chapter.name.contains("chapter", true)) "Chapter ${chapter.number} " else "") + chapter.name
},
)
}
}
return chapters
}
override fun getChapterUrl(chapter: SChapter): String {
val chapterPath = chapter.url.substringAfter("/")
return "$baseUrl/$chapterPath"
}
// Page
override fun pageListRequest(chapter: SChapter): Request {
val chapterPath = chapter.url.substringAfter("/")
return GET("$apiUrl/$chapterPath", headers)
}
override fun pageListParse(response: Response): List<Page> {
val data = json.decodeFromString<PageList>(response.body.string())
return data.pages.mapIndexed { idx, it ->
Page(idx, imageUrl = it.thumb)
}
}
// Unused
override fun imageUrlParse(response: Response): String = throw UnsupportedOperationException("Not Used")
}

View File

@ -1,110 +0,0 @@
package eu.kanade.tachiyomi.extension.en.lynxscans
import eu.kanade.tachiyomi.source.model.SManga
import kotlinx.serialization.Serializable
@Serializable
data class Latest(
val chapters: LatestChapters,
)
@Serializable
data class LatestChapters(
val next_page_url: String?,
val data: List<LatestChaptersData>,
)
@Serializable
data class LatestChaptersData(
val comic_title: String,
val comic_thumb: String,
val comic_titleSlug: String,
) {
fun toSManga(): SManga = SManga.create().apply {
title = this@LatestChaptersData.comic_title
thumbnail_url = this@LatestChaptersData.comic_thumb
url = "/comics/" + this@LatestChaptersData.comic_titleSlug
}
}
@Serializable
data class Popular(
val comics: PopularComics,
)
@Serializable
data class PopularComics(
val next_page_url: String?,
val data: List<PopularComicsData>,
)
@Serializable
data class PopularComicsData(
val title: String,
val thumb: String,
val titleSlug: String,
) {
fun toSManga(): SManga = SManga.create().apply {
title = this@PopularComicsData.title
thumbnail_url = this@PopularComicsData.thumb
url = "/comics/" + this@PopularComicsData.titleSlug
}
}
@Serializable
data class MangaDetails(
val comic: MangaDetailsComicData,
)
@Serializable
data class MangaDetailsComicData(
val title: String,
val thumb: String,
val titleSlug: String,
val artist: String,
val author: String,
val description: String,
val tags: List<MangaDetailsTag>,
val volumes: List<MangaDetailsVolume>,
) {
fun toSManga(): SManga = SManga.create().apply {
title = this@MangaDetailsComicData.title
thumbnail_url = this@MangaDetailsComicData.thumb
url = "/comics/" + this@MangaDetailsComicData.titleSlug
author = if (this@MangaDetailsComicData.author != "blank") this@MangaDetailsComicData.author else null
artist = if (this@MangaDetailsComicData.artist != "blank") this@MangaDetailsComicData.artist else null
description = this@MangaDetailsComicData.description
genre = this@MangaDetailsComicData.tags.joinToString { it.name }
status = SManga.UNKNOWN
}
}
@Serializable
data class MangaDetailsTag(
val name: String,
)
@Serializable
data class MangaDetailsVolume(
val chapters: List<MangaDetailsChapter>,
val name: String,
val number: Int,
)
@Serializable
data class MangaDetailsChapter(
val name: String,
val number: Int,
)
@Serializable
data class PageList(
val pages: List<Page>,
)
@Serializable
data class Page(
val thumb: String,
)