Added dynasty scans fixing issues mentioned in the other pull request (#154)

This commit is contained in:
Carlos 2018-01-18 13:08:11 -05:00 committed by inorichi
parent 62685514b9
commit 6f10dd3c99
6 changed files with 363 additions and 0 deletions

View File

@ -0,0 +1,13 @@
apply plugin: 'com.android.application'
apply plugin: 'kotlin-android'
ext {
appName = 'Tachiyomi: Dynasty'
pkgNameSuffix = "en.dynasty"
extClass = '.DynastyAnthologies; .DynastyIssues; .DynastySeries; .DynastyDoujins'
extVersionCode = 1
extVersionSuffix = 1
libVersion = '1.2'
}
apply from: "$rootDir/common.gradle"

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.extension.en.dynasty
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.Request
import org.jsoup.nodes.Document
class DynastyAnthologies : DynastyScans() {
override val name = "Dynasty-Anthologies"
override fun popularMangaInitialUrl() = "$baseUrl/anthologies?view=cover"
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
return GET("$baseUrl/search?q=$query&classes[]=Series&sort=", headers)
}
override fun mangaDetailsParse(document: Document): SManga {
val manga = SManga.create()
manga.thumbnail_url = baseUrl + document.select("div.span2 > img").attr("src")
parseHeader(document, manga)
parseGenres(document, manga)
parseDescription(document, manga)
return manga
}
}

View File

@ -0,0 +1,31 @@
package eu.kanade.tachiyomi.extension.en.dynasty
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.Request
import org.jsoup.nodes.Document
class DynastyDoujins : DynastyScans() {
override val name = "Dynasty-Doujins"
override fun popularMangaInitialUrl() = "$baseUrl/doujins?view=cover"
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
return GET("$baseUrl/search?q=$query&classes[]=Series&sort=", headers)
}
override fun mangaDetailsParse(document: Document): SManga {
val manga = SManga.create()
super.mangaDetailsParse(document)
parseThumbnail(manga)
manga.author = ".."
manga.status = SManga.UNKNOWN
parseGenres(document, manga)
return manga
}
override fun chapterListSelector() = "div.span9 > dl.chapter-list > dd"
}

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.extension.en.dynasty
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.Request
import org.jsoup.nodes.Document
class DynastyIssues : DynastyScans() {
override val name = "Dynasty-Issues"
override fun popularMangaInitialUrl() = "$baseUrl/issues?view=cover"
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
return GET("$baseUrl/search?q=$query&classes[]=Series&sort=", headers)
}
override fun mangaDetailsParse(document: Document): SManga {
val manga = SManga.create()
manga.thumbnail_url = baseUrl + document.select("div.span2 > img").attr("src")
parseHeader(document, manga)
parseGenres(document, manga)
parseDescription(document, manga)
return manga
}
}

View File

@ -0,0 +1,235 @@
package eu.kanade.tachiyomi.extension.en.dynasty
import android.net.Uri
import eu.kanade.tachiyomi.network.GET
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.ParsedHttpSource
import eu.kanade.tachiyomi.util.asJsoup
import okhttp3.Request
import okhttp3.Response
import org.json.JSONArray
import org.jsoup.nodes.Document
import org.jsoup.nodes.Element
import org.jsoup.nodes.Node
import org.jsoup.nodes.TextNode
import java.text.SimpleDateFormat
import java.util.*
import java.util.regex.Pattern
abstract class DynastyScans : ParsedHttpSource() {
override val baseUrl = "http://dynasty-scans.com"
abstract fun popularMangaInitialUrl(): String
override val lang = "en"
override val supportsLatest = false
var parent: List<Node> = ArrayList()
var list = InternalList(ArrayList(), "")
var imgList = InternalList(ArrayList(), "")
var _valid: Validate = Validate(false, -1)
override fun popularMangaRequest(page: Int): Request {
return GET(popularMangaInitialUrl(), headers)
}
override fun popularMangaSelector() = "ul.thumbnails > li.span2"
override fun popularMangaFromElement(element: Element): SManga {
val manga = SManga.create()
manga.setUrlWithoutDomain(element.select("a").attr("href"))
manga.title = element.select("div.caption").text()
return manga
}
override fun popularMangaParse(response: Response): MangasPage {
val mangas = response.asJsoup().select(popularMangaSelector()).map { element ->
popularMangaFromElement(element)
}
return MangasPage(mangas, false)
}
override fun searchMangaSelector() = "a.name"
override fun searchMangaFromElement(element: Element): SManga {
val manga = SManga.create()
manga.setUrlWithoutDomain(element.attr("href"))
manga.title = element.text()
return manga
}
override fun searchMangaNextPageSelector() = "div.pagination > ul > li.active + li > a"
private fun buildListfromResponse(): List<Node> {
return client.newCall(Request.Builder().headers(headers)
.url(popularMangaInitialUrl()).build()).execute().asJsoup()
.select("div#main").filter { it.hasText() }.first().childNodes()
}
protected fun parseThumbnail(manga: SManga) {
if (_valid.isManga) manga.thumbnail_url = baseUrl + imgList[_valid.pos].substringBefore('?')
}
protected fun parseHeader(document: Document, manga: SManga): Boolean {
val elements = document.select("div.tags > h2.tag-title").first().getElementsByTag("a")
if (elements.isEmpty()) {
return false
}
if (elements.lastIndex == 0) {
manga.author = elements[0].text()
} else {
manga.artist = elements[0].text()
manga.author = elements[1].text()
}
manga.status = document.select("div.tags > h2.tag-title > small").text().let {
when {
it.contains("Ongoing") -> SManga.ONGOING
it.contains("Completed") -> SManga.COMPLETED
else -> SManga.UNKNOWN
}
}
return true
}
protected fun parseGenres(document: Document, manga: SManga) {
manga.genre = ""
val glist = document.select("div.tags > div.tag-tags").first().getElementsByTag("a")
if (!glist.isEmpty()) {
for (g in glist) {
val s = g.text()
manga.genre += if (glist.last() == (g)) s else "$s, "
}
}
}
protected fun parseDescription(document: Document, manga: SManga) {
manga.description = document.select("div.tags > div.row div.description").text()
}
private fun getValid(manga: SManga): Validate {
if (parent.isEmpty()) parent = buildListfromResponse()
if (list.isEmpty()) list = InternalList(parent, "href")
if (imgList.isEmpty()) imgList = InternalList(parent, "src")
val pos = list.indexOf(manga.url.substringBeforeLast("/") + "/" + Uri.encode(manga.url.substringAfterLast("/")))
return Validate((pos > -1), pos)
}
override fun mangaDetailsParse(document: Document): SManga {
val manga = SManga.create()
_valid = getValid(manga)
return manga
}
override fun chapterListSelector() = "div.span10 > dl.chapter-list > dd"
override fun chapterListParse(response: Response): List<SChapter> {
return super.chapterListParse(response).asReversed()
}
override fun chapterFromElement(element: Element): SChapter {
val chapter = SChapter.create()
val nodes = InternalList(element.childNodes(), "text")
chapter.setUrlWithoutDomain(element.select("a.name").attr("href"))
chapter.name = nodes[0]
if (nodes.contains(" by ")) {
chapter.name += " by ${nodes[nodes.indexOfPartial(" by ") + 1]}"
if (nodes.contains(" and ")) {
chapter.name += " and ${nodes[nodes.indexOfPartial(" and ") + 1]}"
}
}
chapter.date_upload = nodes[nodes.indexOfPartial("released")].let {
SimpleDateFormat("MMM dd yy", Locale.ENGLISH).parse(it.substringAfter("released ").replace("\'", "")).time
}
return chapter
}
override fun pageListParse(document: Document): List<Page> {
val pages = mutableListOf<Page>()
try {
val script = document.select("script").last()
val p = Pattern.compile("(?s)(pages)\\s??=\\s??\\[(.*?)\\]")
val m = p.matcher(script.html())
var imageUrls = JSONArray()
while (m.find())
imageUrls = JSONArray("[" + m.group(2) + "]")
(0..imageUrls.length() - 1)
.map { imageUrls.getJSONObject(it) }
.map { baseUrl + it.get("image") }
.forEach { pages.add(Page(pages.size, "", it)) }
} catch (e: Exception) {
e.printStackTrace()
}
return pages
}
class InternalList : ArrayList<String> {
constructor(nodes: List<Node>, type: String) {
if (type == "text") {
for (node in nodes) {
if (node is TextNode) {
if (node.text() != " " && !node.text().contains("\n")) {
this.add(node.text())
}
} else if (node is Element) this.add(node.text())
}
}
if (type == "src") {
nodes
.filter { it is Element && it.hasClass("thumbnails") }
.flatMap { it.childNodes() }
.filterIsInstance<Element>()
.filter { it.hasClass("span2") }
.forEach { this.add(it.child(0).child(0).attr(type)) }
}
if (type == "href") {
nodes
.filter { it is Element && it.hasClass("thumbnails") }
.flatMap { it.childNodes() }
.filterIsInstance<Element>()
.filter { it.hasClass("span2") }
.forEach { this.add(it.child(0).attr(type)) }
}
}
fun indexOfPartial(partial: String): Int {
return (0..this.lastIndex).firstOrNull { this[it].contains(partial) }
?: -1
}
fun getItem(partial: String): String {
return (0..this.lastIndex)
.firstOrNull { super.get(it).contains(partial) }
?.let { super.get(it) }
?: ""
}
}
class Validate(_isManga: Boolean, _pos: Int) {
val isManga = _isManga
val pos = _pos
}
override fun popularMangaNextPageSelector() = ""
override fun latestUpdatesSelector() = ""
override fun latestUpdatesNextPageSelector() = ""
override fun imageUrlParse(document: Document): String = ""
override fun latestUpdatesFromElement(element: Element): SManga {
return popularMangaFromElement(element)
}
override fun latestUpdatesRequest(page: Int): Request {
return popularMangaRequest(page)
}
}

View File

@ -0,0 +1,28 @@
package eu.kanade.tachiyomi.extension.en.dynasty
import eu.kanade.tachiyomi.network.GET
import eu.kanade.tachiyomi.source.model.FilterList
import eu.kanade.tachiyomi.source.model.SManga
import okhttp3.Request
import org.jsoup.nodes.Document
class DynastySeries : DynastyScans() {
override val name = "Dynasty-Series"
override fun popularMangaInitialUrl() = "$baseUrl/series?view=cover"
override fun searchMangaRequest(page: Int, query: String, filters: FilterList): Request {
return GET("$baseUrl/search?q=$query&classes[]=Series&sort=", headers)
}
override fun mangaDetailsParse(document: Document): SManga {
val manga = SManga.create()
manga.thumbnail_url = baseUrl + document.select("div.span2 > img").attr("src")
parseHeader(document, manga)
parseGenres(document, manga)
parseDescription(document, manga)
return manga
}
}